org.simpleframework.xml.convert.ConverterFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simple-xml Show documentation
Show all versions of simple-xml Show documentation
Simple is a high performance XML serialization and configuration framework for Java
The newest version!
/*
* ConverterFactory.java January 2010
*
* Copyright (C) 2010, 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.convert;
import java.lang.reflect.Constructor;
import org.simpleframework.xml.util.Cache;
import org.simpleframework.xml.util.ConcurrentCache;
/**
* The ConverterFactory
is used to instantiate objects
* based on a provided type or annotation. This provides a single
* point of creation for all converters within the framework. For
* performance all the instantiated converters are cached against
* the class for that converter. This ensures the converters can
* be acquired without the overhead of instantiation.
*
* @author Niall Gallagher
*
* @see org.simpleframework.xml.convert.ConverterCache
*/
class ConverterFactory {
/**
* This is the cache that is used to cache converter instances.
*/
private final Cache cache;
/**
* Constructor for the ConverterFactory
object.
* This will create an internal cache which is used to cache all
* instantiations made by the factory. Caching the converters
* ensures there is no overhead with instantiations.
*/
public ConverterFactory() {
this.cache = new ConcurrentCache();
}
/**
* This is used to instantiate the converter based on the type
* provided. If the type provided can not be instantiated for
* some reason then an exception is thrown from this method.
*
* @param type this is the converter type to be instantiated
*
* @return this returns an instance of the provided type
*/
public Converter getInstance(Class type) throws Exception {
Converter converter = cache.fetch(type);
if(converter == null) {
return getConverter(type);
}
return converter;
}
/**
* This is used to instantiate the converter based on the type
* of the Convert
annotation provided. If the type
* can not be instantiated for some reason then an exception is
* thrown from this method.
*
* @param convert this is the annotation containing the type
*
* @return this returns an instance of the provided type
*/
public Converter getInstance(Convert convert) throws Exception {
Class type = convert.value();
if(type.isInterface()) {
throw new ConvertException("Can not instantiate %s", type);
}
return getInstance(type);
}
/**
* This is used to instantiate the converter based on the type
* provided. If the type provided can not be instantiated for
* some reason then an exception is thrown from this method.
*
* @param type this is the converter type to be instantiated
*
* @return this returns an instance of the provided type
*/
private Converter getConverter(Class type) throws Exception {
Constructor factory = getConstructor(type);
if(factory == null){
throw new ConvertException("No default constructor for %s", type);
}
return getConverter(type, factory);
}
/**
* This is used to instantiate the converter based on the type
* provided. If the type provided can not be instantiated for
* some reason then an exception is thrown from this method.
*
* @param type this is the converter type to be instantiated
* @param factory this is the constructor used to instantiate
*
* @return this returns an instance of the provided type
*/
private Converter getConverter(Class type, Constructor factory) throws Exception {
Converter converter = (Converter)factory.newInstance();
if(converter != null){
cache.cache(type, converter);
}
return converter;
}
/**
* This is used to acquire the default no argument constructor
* for the the provided type. If the constructor is not accessible
* then it will be made accessible so that it can be instantiated.
*
* @param type this is the type to acquire the constructor for
*
* @return this returns the constructor for the type provided
*/
private Constructor getConstructor(Class type) throws Exception {
Constructor factory = type.getDeclaredConstructor();
if(!factory.isAccessible()) {
factory.setAccessible(true);
}
return factory;
}
}