001: package org.vraptor.converter;
002:
003: import java.lang.reflect.Array;
004: import java.util.HashMap;
005: import java.util.LinkedList;
006: import java.util.Map;
007:
008: import org.apache.log4j.Logger;
009: import org.vraptor.LogicRequest;
010: import org.vraptor.component.ComponentInstantiationException;
011: import org.vraptor.converter.basic.BasicConverters;
012: import org.vraptor.reflection.ReflectionUtil;
013:
014: /**
015: * Converter repository.
016: *
017: * @author Guilherme Silveira
018: */
019: public class SimpleConverterManager implements ConverterManager {
020:
021: private static final Logger LOG = Logger
022: .getLogger(SimpleConverterManager.class);
023:
024: private final LinkedList<Converter> converters;
025:
026: private final Map<Class<?>, Converter> cachedConverters;
027:
028: public SimpleConverterManager() {
029: cachedConverters = new HashMap<Class<?>, Converter>();
030: converters = new LinkedList<Converter>();
031: BasicConverters.register(this );
032: }
033:
034: /**
035: * Registers a new converter
036: *
037: * @param converter
038: * the converter itself
039: */
040: public void register(Converter converter) {
041: this .converters.addFirst(converter);
042: cachedConverters.clear();
043: }
044:
045: public Object convert(String[] arrayValue, String completeValue,
046: Class<?> originalType, LogicRequest context,
047: Class<? extends Converter> overridenConverter)
048: throws ConversionException {
049:
050: Class<?> type = originalType.isArray() ? originalType
051: .getComponentType() : originalType;
052:
053: Converter converter = overridenConverter == null ? findConverter(type)
054: : getConverter(overridenConverter);
055:
056: boolean isArray = originalType.isArray();
057:
058: if (isArray) {
059:
060: Object converted = Array.newInstance(type,
061: arrayValue.length);
062: for (int i = 0; i < arrayValue.length; i++) {
063: Array.set(converted, i, converter.convert(
064: arrayValue[i], type, context));
065: }
066: return converted;
067:
068: } else {
069: return converter.convert(completeValue, type, context);
070: }
071:
072: }
073:
074: private synchronized Converter getConverter(
075: Class<? extends Converter> converter)
076: throws ConversionException {
077: try {
078: return (Converter) ReflectionUtil.instantiate(converter);
079: } catch (ComponentInstantiationException e) {
080: throw new ConversionException("invalid_converter", e
081: .getMessage(), e);
082: }
083: }
084:
085: /**
086: * Finds a specific converter for a type
087: *
088: * @param type
089: * type
090: * @return conveter
091: * @throws ConversionException
092: * no converter was found
093: */
094: private Converter findConverter(Class<?> type)
095: throws ConversionException {
096: Converter converter = this .cachedConverters.get(type);
097: if (converter == null) {
098: for (Converter tempConverter : converters) {
099: if (correctConverter(tempConverter, type)) {
100: converter = tempConverter;
101: break;
102: }
103: }
104: if (converter == null) {
105: throw new ConversionException("no_converter_found",
106: "Unable to find converter for "
107: + type.getName());
108: }
109: }
110: LOG.debug("Found converter " + converter.getClass().getName());
111: return converter;
112: }
113:
114: /**
115: * Is it the correct converter for this type?
116: *
117: * @param converter
118: * the converter
119: * @param type
120: * the type
121: * @return true if responsible for this type
122: */
123: @SuppressWarnings("unchecked")
124: private boolean correctConverter(Converter converter, Class<?> type) {
125: for (Class supportedType : converter.getSupportedTypes()) {
126: if (supportedType.isAssignableFrom(type)) {
127: cachedConverters.put(type, converter);
128: return true;
129: }
130: }
131: return false;
132: }
133:
134: }
|