001: /*
002: * Copyright (C) 2006, 2007, 2008 XStream Committers.
003: * All rights reserved.
004: *
005: * The software in this package is published under the terms of the BSD
006: * style license a copy of which has been included with this distribution in
007: * the LICENSE.txt file.
008: *
009: * Created on 02. March 2006 by Mauro Talevi
010: */
011: package com.thoughtworks.xstream.annotations;
012:
013: import java.lang.reflect.Field;
014: import java.lang.reflect.InvocationTargetException;
015: import java.util.HashMap;
016: import java.util.Map;
017:
018: import com.thoughtworks.xstream.converters.Converter;
019: import com.thoughtworks.xstream.converters.MarshallingContext;
020: import com.thoughtworks.xstream.converters.UnmarshallingContext;
021: import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
022: import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
023: import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
024: import com.thoughtworks.xstream.mapper.Mapper;
025:
026: /**
027: * ReflectionConverter which uses an AnnotationProvider to marshall and unmarshall fields based
028: * on the annotated converters.
029: *
030: * @author Guilherme Silveira
031: * @author Mauro Talevi
032: * @deprecated since 1.3, build into {@link ReflectionConverter}
033: */
034: @Deprecated
035: public class AnnotationReflectionConverter extends ReflectionConverter {
036:
037: private final AnnotationProvider annotationProvider;
038:
039: private final Map<Class<? extends Converter>, Converter> cachedConverters;
040:
041: @Deprecated
042: public AnnotationReflectionConverter(Mapper mapper,
043: ReflectionProvider reflectionProvider,
044: AnnotationProvider annotationProvider) {
045: super (mapper, reflectionProvider);
046: this .annotationProvider = annotationProvider;
047: this .cachedConverters = new HashMap<Class<? extends Converter>, Converter>();
048: }
049:
050: protected void marshallField(final MarshallingContext context,
051: Object newObj, Field field) {
052: XStreamConverter annotation = annotationProvider.getAnnotation(
053: field, XStreamConverter.class);
054: if (annotation != null) {
055: Class<? extends Converter> type = annotation.value();
056: ensureCache(type);
057: context.convertAnother(newObj, cachedConverters.get(type));
058: } else {
059: context.convertAnother(newObj);
060: }
061: }
062:
063: private void ensureCache(Class<? extends Converter> type) {
064: if (!this .cachedConverters.containsKey(type)) {
065: cachedConverters.put(type, newInstance(type));
066: }
067: }
068:
069: protected Object unmarshallField(
070: final UnmarshallingContext context, final Object result,
071: Class type, Field field) {
072: XStreamConverter annotation = annotationProvider.getAnnotation(
073: field, XStreamConverter.class);
074: if (annotation != null) {
075: Class<? extends Converter> converterType = annotation
076: .value();
077: ensureCache(converterType);
078: return context.convertAnother(result, type,
079: cachedConverters.get(converterType));
080: } else {
081: return context.convertAnother(result, type);
082: }
083: }
084:
085: /**
086: * Instantiates a converter using its default constructor.
087: *
088: * @param converterType the converter type to instantiate
089: * @return the new instance
090: */
091: private Converter newInstance(
092: Class<? extends Converter> converterType) {
093: Converter converter;
094: // TODO: We need a separate exception for runtime initialization.
095: try {
096: converter = converterType.getConstructor().newInstance();
097: } catch (InvocationTargetException e) {
098: throw new ObjectAccessException("Cannot construct "
099: + converterType.getName(), e.getCause());
100: } catch (InstantiationException e) {
101: throw new ObjectAccessException("Cannot construct "
102: + converterType.getName(), e);
103: } catch (IllegalAccessException e) {
104: throw new ObjectAccessException("Cannot construct "
105: + converterType.getName(), e);
106: } catch (NoSuchMethodException e) {
107: throw new ObjectAccessException("Cannot construct "
108: + converterType.getName(), e);
109: }
110: return converter;
111: }
112:
113: }
|