Coverage Report - org.simpleframework.xml.core.AnnotationFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
AnnotationFactory
100%
15/15
100%
6/6
2.5
 
 1  
 /*
 2  
  * AnnotationFactory.java January 2010
 3  
  *
 4  
  * Copyright (C) 2010, 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.annotation.Annotation;
 22  
 import java.lang.reflect.Proxy;
 23  
 import java.util.Collection;
 24  
 import java.util.Map;
 25  
 
 26  
 import org.simpleframework.xml.Element;
 27  
 import org.simpleframework.xml.ElementArray;
 28  
 import org.simpleframework.xml.ElementList;
 29  
 import org.simpleframework.xml.ElementMap;
 30  
 
 31  
 /**
 32  
  * The <code>AnnotationFactory</code> is used to create annotations
 33  
  * using a given class. This will classify the provided type as
 34  
  * either a list, map, array, or a default object. Depending on the
 35  
  * type provided a suitable annotation will be created. Annotations
 36  
  * produced by this will have default attribute values.
 37  
  * 
 38  
  * @author Niall Gallagher
 39  
  * 
 40  
  * @see org.simpleframework.xml.core.AnnotationHandler
 41  
  */
 42  
 class AnnotationFactory {  
 43  
    
 44  
    /**
 45  
     * This is used to determine if the defaults are required.
 46  
     */
 47  
    private final boolean required;
 48  
    
 49  
    /**
 50  
     * Constructor for the <code>AnnotationFactory</code> object. This
 51  
     * is used to create a factory for annotations used to provide
 52  
     * the default annotations for generated labels.
 53  
     * 
 54  
     * @param detail this contains details for the annotated class
 55  
     */
 56  6818
    public AnnotationFactory(Detail detail) {
 57  6818
       this.required = detail.isRequired();
 58  6818
    }
 59  
   
 60  
    /**
 61  
     * This is used to create an annotation for the provided type.
 62  
     * Annotations created are used to match the type provided. So
 63  
     * a <code>List</code> will have an <code>ElementList</code>
 64  
     * annotation for example. Matching the annotation to the
 65  
     * type ensures the best serialization for that type. 
 66  
     * 
 67  
     * @param type the type to create the annotation for
 68  
     * 
 69  
     * @return this returns the synthetic annotation to be used
 70  
     */
 71  
    public Annotation getInstance(Class type) throws Exception { 
 72  470
       ClassLoader loader = getClassLoader();
 73  
       
 74  470
       if(Map.class.isAssignableFrom(type)) {
 75  42
          return getInstance(loader, ElementMap.class);
 76  
       }
 77  428
       if(Collection.class.isAssignableFrom(type)) {
 78  28
          return getInstance(loader, ElementList.class);
 79  
       }
 80  400
       if(type.isArray()) {
 81  19
          return getInstance(loader, ElementArray.class);
 82  
       }
 83  381
       return getInstance(loader, Element.class);
 84  
    }
 85  
    
 86  
    /**
 87  
     * This will create a synthetic annotation using the provided 
 88  
     * interface. All attributes for the provided annotation will
 89  
     * have their default values. 
 90  
     * 
 91  
     * @param loader this is the class loader to load the annotation 
 92  
     * @param label this is the annotation interface to be used
 93  
     * 
 94  
     * @return this returns the synthetic annotation to be used
 95  
     */
 96  
    private Annotation getInstance(ClassLoader loader, Class label) throws Exception {
 97  470
       AnnotationHandler handler = new AnnotationHandler(label, required);
 98  470
       Class[] list = new Class[] {label};
 99  
       
 100  470
       return (Annotation) Proxy.newProxyInstance(loader, list, handler);
 101  
    }
 102  
    
 103  
    /**
 104  
     * This is used to create a suitable class loader to be used to
 105  
     * load the synthetic annotation classes. The class loader
 106  
     * provided will be the same as the class loader that was used
 107  
     * to load this class.
 108  
     * 
 109  
     * @return this returns the class loader that is to be used
 110  
     */
 111  
    private ClassLoader getClassLoader() throws Exception {
 112  470
       return AnnotationFactory.class.getClassLoader();
 113  
    }
 114  
 }