All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.simpleframework.xml.core.ParameterFactory Maven / Gradle / Ivy

Go to download

Simple is a high performance XML serialization and configuration framework for Java

The newest version!
/*
 * ParameterFactory.java July 2006
 *
 * Copyright (C) 2006, Niall Gallagher 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
 * implied. See the License for the specific language governing 
 * permissions and limitations under the License.
 */

package org.simpleframework.xml.core;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementArray;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.ElementListUnion;
import org.simpleframework.xml.ElementMap;
import org.simpleframework.xml.ElementMapUnion;
import org.simpleframework.xml.ElementUnion;
import org.simpleframework.xml.Text;
import org.simpleframework.xml.stream.Format;

/**
 * The ParameterFactory object is used to create instances 
 * of the Parameter object. Each parameter created can be
 * used to validate against the annotated fields and methods to ensure
 * that the annotations are compatible. 
 * 

* The Parameter objects created by this are selected * using the XML annotation type. If the annotation type is not known * the factory will throw an exception, otherwise a parameter instance * is created that will expose the properties of the annotation. * * @author Niall Gallagher */ class ParameterFactory { /** * This format contains the style which is used to create names. */ private final Format format; /** * Constructor for the ParameterFactory object. This * factory is used for creating parameters within a constructor. * Parameters can be annotated in the same way as methods or * fields, this object is used to create such parameters. * * @param support this contains various support functions */ public ParameterFactory(Support support) { this.format = support.getFormat(); } /** * Creates a Parameter using the provided constructor * and the XML annotation. The parameter produced contains all * information related to the constructor parameter. It knows the * name of the XML entity, as well as the type. * * @param factory this is the constructor the parameter exists in * @param label represents the XML annotation for the contact * @param index the index of the parameter in the constructor * * @return returns the parameter instantiated for the field */ public Parameter getInstance(Constructor factory, Annotation label, int index) throws Exception { return getInstance(factory, label, null, index); } /** * Creates a Parameter using the provided constructor * and the XML annotation. The parameter produced contains all * information related to the constructor parameter. It knows the * name of the XML entity, as well as the type. * * @param factory this is the constructor the parameter exists in * @param label represents the XML annotation for the contact * @param entry this is the entry annotation for the parameter * @param index the index of the parameter in the constructor * * @return returns the parameter instantiated for the field */ public Parameter getInstance(Constructor factory, Annotation label, Annotation entry, int index) throws Exception { Constructor builder = getConstructor(label); if(entry != null) { return (Parameter)builder.newInstance(factory, label, entry, format, index); } return (Parameter)builder.newInstance(factory, label, format, index); } /** * Creates a constructor that is used to instantiate the parameter * used to represent the specified annotation. The constructor * created by this method takes three arguments, a constructor, * an annotation, and the parameter index. * * @param label the XML annotation representing the label * * @return returns a constructor for instantiating the parameter * * @throws Exception thrown if the annotation is not supported */ private Constructor getConstructor(Annotation label) throws Exception { ParameterBuilder builder = getBuilder(label); Constructor factory = builder.getConstructor(); if(!factory.isAccessible()) { factory.setAccessible(true); } return factory; } /** * Creates an entry that is used to select the constructor for the * parameter. Each parameter must implement a constructor that takes * a constructor, and annotation, and the index of the parameter. If * the annotation is not know this method throws an exception. * * @param label the XML annotation used to create the parameter * * @return this returns the entry used to create a constructor */ private ParameterBuilder getBuilder(Annotation label) throws Exception{ if(label instanceof Element) { return new ParameterBuilder(ElementParameter.class, Element.class); } if(label instanceof ElementList) { return new ParameterBuilder(ElementListParameter.class, ElementList.class); } if(label instanceof ElementArray) { return new ParameterBuilder(ElementArrayParameter.class, ElementArray.class); } if(label instanceof ElementMapUnion) { return new ParameterBuilder(ElementMapUnionParameter.class, ElementMapUnion.class, ElementMap.class); } if(label instanceof ElementListUnion) { return new ParameterBuilder(ElementListUnionParameter.class, ElementListUnion.class, ElementList.class); } if(label instanceof ElementUnion) { return new ParameterBuilder(ElementUnionParameter.class, ElementUnion.class, Element.class); } if(label instanceof ElementMap) { return new ParameterBuilder(ElementMapParameter.class, ElementMap.class); } if(label instanceof Attribute) { return new ParameterBuilder(AttributeParameter.class, Attribute.class); } if(label instanceof Text) { return new ParameterBuilder(TextParameter.class, Text.class); } throw new PersistenceException("Annotation %s not supported", label); } /** * The ParameterBuilder is used to create a constructor * that can be used to instantiate the correct parameter for the * XML annotation specified. The constructor requires three * arguments, the constructor, the annotation, and the index. * * @see java.lang.reflect.Constructor */ private static class ParameterBuilder { /** * This is the entry that is used to create the parameter. */ private final Class entry; /** * This is the XML annotation type within the constructor. */ private final Class label; /** * This is the parameter type that is to be instantiated. */ private final Class type; /** * Constructor for the PameterBuilder object. This * pairs the parameter type with the annotation argument used * within the constructor. This allows constructor to be selected. * * @param type this is the parameter type to be instantiated * @param label the type that is used within the constructor */ public ParameterBuilder(Class type, Class label) { this(type, label, null); } /** * Constructor for the PameterBuilder object. This * pairs the parameter type with the annotation argument used * within the constructor. This allows constructor to be selected. * * @param type this is the parameter type to be instantiated * @param label the type that is used within the constructor * @param entry this is the entry used to create the parameter */ public ParameterBuilder(Class type, Class label, Class entry) { this.label = label; this.entry = entry; this.type = type; } /** * Creates the constructor used to instantiate the label for * the XML annotation. The constructor returned will take two * arguments, a contact and the XML annotation type. * * @return returns the constructor for the label object */ public Constructor getConstructor() throws Exception { if(entry != null) { return getConstructor(label, entry); } return getConstructor(label); } /** * Creates the constructor used to instantiate the parameter * for the XML annotation. The constructor returned will take * two arguments, a contact and the XML annotation type. * * @param label the type that is used within the constructor * * @return returns the constructor for the parameter object */ public Constructor getConstructor(Class label) throws Exception { return getConstructor(Constructor.class, label, Format.class, int.class); } /** * Creates the constructor used to instantiate the parameter * for the XML annotation. The constructor returned will take * two arguments, a contact and the XML annotation type. * * @param label the type that is used within the constructor * @param entry this is the entry used to create the parameter * * @return returns the constructor for the parameter object */ public Constructor getConstructor(Class label, Class entry) throws Exception { return getConstructor(Constructor.class, label, entry, Format.class, int.class); } /** * Creates the constructor used to instantiate the parameter * for the XML annotation. The constructor returned will take * three arguments, a constructor, an annotation and a type. * * @param types these are the arguments for the constructor * * @return returns the constructor for the parameter object */ private Constructor getConstructor(Class... types) throws Exception { return type.getConstructor(types); } } }