Coverage Report - org.simpleframework.xml.core.ArrayFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
ArrayFactory
80%
16/20
50%
4/8
2.6
 
 1  
 /*
 2  
  * ArrayFactory.java July 2006
 3  
  *
 4  
  * Copyright (C) 2006, 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.lang.reflect.Array;
 22  
 
 23  
 import org.simpleframework.xml.strategy.Type;
 24  
 import org.simpleframework.xml.strategy.Value;
 25  
 import org.simpleframework.xml.stream.InputNode;
 26  
 import org.simpleframework.xml.stream.Position;
 27  
 
 28  
 /**
 29  
  * The <code>ArrayFactory</code> is used to create object array
 30  
  * types that are compatible with the field type. This simply
 31  
  * requires the type of the array in order to instantiate that
 32  
  * array. However, this also performs a check on the field type 
 33  
  * to ensure that the array component types are compatible.
 34  
  * 
 35  
  * @author Niall Gallagher
 36  
  */ 
 37  
 class ArrayFactory extends Factory { 
 38  
         
 39  
    /**
 40  
     * Constructor for the <code>ArrayFactory</code> object. This is
 41  
     * given the array component type as taken from the field type 
 42  
     * of the source object. Each request for an array will return 
 43  
     * an array which uses a compatible component type.
 44  
     * 
 45  
     * @param context this is the context object for serialization
 46  
     * @param type the array component type for the field object
 47  
     */
 48  
    public ArrayFactory(Context context, Type type) {
 49  409
       super(context, type);                
 50  409
    }    
 51  
    
 52  
    /**
 53  
     * This is used to create a default instance of the field type. It
 54  
     * is up to the subclass to determine how to best instantiate an
 55  
     * object of the field type that best suits. This is used when the
 56  
     * empty value is required or to create the default type instance.
 57  
     * 
 58  
     * @return a type which is used to instantiate the collection     
 59  
     */
 60  
    @Override
 61  
    public Object getInstance() throws Exception {
 62  3
       Class type = getComponentType();
 63  
       
 64  3
       if(type != null) {
 65  3
          return Array.newInstance(type, 0);
 66  
       }
 67  0
       return null;
 68  
    }
 69  
 
 70  
    /**
 71  
     * Creates the array type to use. This will use the provided
 72  
     * XML element to determine the array type and provide a means
 73  
     * for creating an array with the <code>Value</code> object. If
 74  
     * the array size cannot be determined an exception is thrown.
 75  
     * 
 76  
     * @param node this is the input node for the array element
 77  
     * 
 78  
     * @return the object array type used for the instantiation
 79  
     */         
 80  
    public Instance getInstance(InputNode node) throws Exception {
 81  140
       Position line = node.getPosition();
 82  140
       Value value = getOverride(node);    
 83  
       
 84  140
       if(value == null) {
 85  0
          throw new ElementException("Array length required for %s at %s", type, line);         
 86  
       }      
 87  140
       Class type = value.getType();
 88  
       
 89  140
       return getInstance(value, type);
 90  
    }
 91  
 
 92  
    /**
 93  
     * Creates the array type to use. This will use the provided
 94  
     * XML element to determine the array type and provide a means
 95  
     * for creating an array with the <code>Value</code> object. If
 96  
     * the array types are not compatible an exception is thrown.
 97  
     * 
 98  
     * @param value this is the type object with the array details
 99  
     * @param entry this is the entry type for the array instance    
 100  
     * 
 101  
     * @return this object array type used for the instantiation  
 102  
     */
 103  
    private Instance getInstance(Value value, Class entry) throws Exception {
 104  140
       Class expect = getComponentType();
 105  
 
 106  140
       if(!expect.isAssignableFrom(entry)) {
 107  0
          throw new InstantiationException("Array of type %s cannot hold %s for %s", expect, entry, type);
 108  
       }
 109  140
       return new ArrayInstance(value);   
 110  
    }   
 111  
    
 112  
    /**
 113  
     * This is used to extract the component type for the array class
 114  
     * this factory represents. This is used when an array is to be
 115  
     * instantiated. If the class provided to the factory is not an
 116  
     * array then this will throw an exception.
 117  
     * 
 118  
     * @return this returns the component type for the array
 119  
     */
 120  
    private Class getComponentType() throws Exception {
 121  143
       Class expect = getType();
 122  
       
 123  143
       if(!expect.isArray()) {
 124  0
          throw new InstantiationException("The %s not an array for %s", expect, type);
 125  
       }
 126  143
       return expect.getComponentType();
 127  
    }
 128  
 }