Coverage Report - org.simpleframework.xml.core.ClassInstantiator
 
Classes in this File Line Coverage Branch Coverage Complexity
ClassInstantiator
82%
23/28
90%
9/10
1.667
 
 1  
 /*
 2  
  * ClassInstantiator.java December 2009
 3  
  *
 4  
  * Copyright (C) 2009, Niall Gallagher <niallg@users.sf.net>
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License");
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
 15  
  * implied. See the License for the specific language governing 
 16  
  * permissions and limitations under the License.
 17  
  */
 18  
 
 19  
 package org.simpleframework.xml.core;
 20  
 
 21  
 import java.util.ArrayList;
 22  
 import java.util.List;
 23  
 
 24  
 /**
 25  
  * The <code>ClassInstantiator</code> is used for instantiating 
 26  
  * objects using either the default no argument constructor or one
 27  
  * that takes deserialized values as parameters. This also exposes 
 28  
  * the parameters and constructors used to instantiate the object.
 29  
  * 
 30  
  * @author Niall Gallagher
 31  
  */
 32  
 class ClassInstantiator implements Instantiator {
 33  
    
 34  
    /**
 35  
     * This contains a list of all the creators for the class.
 36  
     */
 37  
    private final List<Creator> creators;  
 38  
    
 39  
    /**
 40  
     * This is used to acquire a parameter by the parameter name.
 41  
     */
 42  
    private final ParameterMap registry;
 43  
    
 44  
    /**
 45  
     * This represents the default no argument constructor used.
 46  
     */
 47  
    private final Creator primary;
 48  
 
 49  
    /**
 50  
     * This contains the details for the class to instantiate.
 51  
     */
 52  
    private final Detail detail;
 53  
    
 54  
    /**
 55  
     * Constructor for the <code>ClassCreator</code> object. This is
 56  
     * used to create an object that contains all information that
 57  
     * relates to the construction of an instance. 
 58  
     * 
 59  
     * @param creators contains the list of all constructors available
 60  
     * @param primary this is the default no argument constructor
 61  
     * @param registry contains all parameters for the constructors
 62  
     * @param detail contains the details for the instantiated class
 63  
     */
 64  2370
    public ClassInstantiator(List<Creator> creators, Creator primary, ParameterMap registry, Detail detail) {
 65  2370
       this.creators = creators;
 66  2370
       this.registry = registry;
 67  2370
       this.primary = primary;
 68  2370
       this.detail = detail;
 69  2370
    }
 70  
 
 71  
    /**
 72  
     * This is used to determine if this <code>Creator</code> has a
 73  
     * default constructor. If the class does contain a no argument
 74  
     * constructor then this will return true.
 75  
     * 
 76  
     * @return true if the class has a default constructor
 77  
     */
 78  
    public boolean isDefault() {
 79  715346
       int count = creators.size();
 80  
       
 81  715346
       if(count <= 1) {
 82  715297
          return primary != null;
 83  
       }
 84  49
       return false;
 85  
    }
 86  
    
 87  
    /**
 88  
     * This is used to instantiate the object using the default no
 89  
     * argument constructor. If for some reason the object can not be
 90  
     * instantiated then this will throw an exception with the reason.
 91  
     * 
 92  
     * @return this returns the object that has been instantiated
 93  
     */
 94  
    public Object getInstance() throws Exception {
 95  0
       return primary.getInstance();
 96  
    }
 97  
    
 98  
    /**
 99  
     * This is used to instantiate the object using a constructor that
 100  
     * takes deserialized objects as arguments. The object that have
 101  
     * been deserialized can be taken from the <code>Criteria</code>
 102  
     * object which contains the deserialized values.
 103  
     * 
 104  
     * @param criteria this contains the criteria to be used
 105  
     * 
 106  
     * @return this returns the object that has been instantiated
 107  
     */
 108  
    public Object getInstance(Criteria criteria) throws Exception {
 109  276
       Creator creator = getCreator(criteria);
 110  
       
 111  276
       if(creator == null) {
 112  0
          throw new PersistenceException("Constructor not matched for %s", detail);
 113  
       }
 114  276
       return creator.getInstance(criteria);
 115  
    }
 116  
    
 117  
    /**
 118  
     * This is used to acquire an <code>Instantiator</code> which is used
 119  
     * to instantiate the object. If there is no match for the instantiator
 120  
     * then the default constructor is provided.
 121  
     * 
 122  
     * @param criteria this contains the criteria to be used for this
 123  
     * 
 124  
     * @return this returns the instantiator that has been matched
 125  
     */
 126  
    private Creator getCreator(Criteria criteria) throws Exception {
 127  276
       Creator result = primary;
 128  276
       double max = 0.0;
 129  
       
 130  276
       for(Creator instantiator : creators) {
 131  332
          double score = instantiator.getScore(criteria);
 132  
          
 133  332
          if(score > max) {
 134  284
             result = instantiator;
 135  284
             max = score;
 136  
          }
 137  332
       }
 138  276
       return result;
 139  
    }
 140  
 
 141  
    /**
 142  
     * This is used to acquire the named <code>Parameter</code> from
 143  
     * the creator. A parameter is taken from the constructor which
 144  
     * contains annotations for each object that is required. These
 145  
     * parameters must have a matching field or method.
 146  
     * 
 147  
     * @param name this is the name of the parameter to be acquired
 148  
     * 
 149  
     * @return this returns the named parameter for the creator
 150  
     */
 151  
    public Parameter getParameter(String name) {
 152  0
       return registry.get(name);
 153  
    }
 154  
    
 155  
    /**
 156  
     * This is used to acquire all parameters annotated for the class
 157  
     * schema. Providing all parameters ensures that they can be
 158  
     * validated against the annotated methods and fields to ensure
 159  
     * that each parameter is valid and has a corresponding match.
 160  
     * 
 161  
     * @return this returns the parameters declared in the schema     
 162  
     */
 163  
    public List<Parameter> getParameters() {
 164  0
       return registry.getAll();
 165  
    }
 166  
    
 167  
    /**
 168  
     * This is used to acquire all of the <code>Instantiator</code> 
 169  
     * objects used to create an instance of the object. Each represents 
 170  
     * a constructor and contains the parameters to the constructor. 
 171  
     * This is primarily used to validate each constructor against the
 172  
     * fields and methods annotated to ensure they are compatible.
 173  
     * 
 174  
     * @return this returns a list of instantiators for the creator
 175  
     */
 176  
    public List<Creator> getCreators() {
 177  2368
       return new ArrayList<Creator>(creators);
 178  
    }
 179  
    
 180  
    /**
 181  
     * This is used to acquire a description of the creator. This is
 182  
     * useful when debugging an issue as it allows a representation
 183  
     * of the instance to be viewed with the class it represents.
 184  
     * 
 185  
     * @return this returns a visible description of the creator
 186  
     */
 187  
    public String toString() {
 188  0
       return String.format("creator for %s", detail);
 189  
    }
 190  
 }