blob: 8b44a3b9567a72c3ff6035ba80b146ae0b8de0b8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You
* 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. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.abdera.converter;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.apache.abdera.Abdera;
@SuppressWarnings("unchecked")
public abstract class AbstractConversionContext
implements ConversionContext {
private transient final Abdera abdera;
private final Map<Class,Converter> converters =
new HashMap<Class,Converter>();
protected AbstractConversionContext() {
this(new Abdera());
}
protected AbstractConversionContext(Abdera abdera) {
this.abdera = abdera;
}
public Abdera getAbdera() {
return abdera;
}
public <T> Converter<T> getConverter(ObjectContext objectContext) {
try {
Class type = objectContext.getObjectType();
Converter<T> converter = converters.get(type);
if (converter == null) converter = objectContext.getConverter();
if (converter == null) {
for (Annotation annotation : objectContext.getAnnotations()) {
converter = converters.get(annotation.annotationType());
if (converter != null) return converter;
}
}
if (converter == null && !type.isAnnotation()) {
for (Class knownType : converters.keySet()) {
if (!knownType.isAnnotation() &&
knownType.isAssignableFrom(type)) {
return converters.get(knownType);
}
}
}
return converter;
} catch (Throwable t) {
throw new ConversionException(t);
}
}
public boolean hasConverter(ObjectContext objectContext) {
return getConverter(objectContext) != null;
}
public boolean hasConverter(Object object) {
return hasConverter(new ObjectContext(object));
}
public boolean hasConverter(
Object object,
Object parent,
AccessibleObject accessor) {
return hasConverter(new ObjectContext(object,parent,accessor));
}
public boolean hasConverter(Class<?> type) {
if (converters.containsKey(type)) return true;
if (!type.isAnnotation()) {
for (Class<?> t : converters.keySet()) {
if (!t.isAnnotation() &&
t.isAssignableFrom(type)) return true;
}
}
return false;
}
public boolean hasConverter(AccessibleObject accessor) {
Class<? extends Object> returnType = getReturnType(accessor);
org.apache.abdera.converter.annotation.Converter converter =
accessor.getAnnotation(org.apache.abdera.converter.annotation.Converter.class);
if (converter != null && hasConverter(converter.value())) return true;
if (returnType != null && hasConverter(returnType)) return true;
return false;
}
public void setConverter(Class<?> type, Converter<?> converter) {
converters.put(type, converter);
}
public <T> T convert(Object object) {
return (T)convert(object,new ObjectContext(object));
}
public <T> T convert(Object object, ObjectContext objectContext) {
if (objectContext == null) objectContext = new ObjectContext(object);
Converter<T> converter = getConverter(objectContext);
if (converter != null)
return convert(object,objectContext,converter);
else
throw new ConversionException(
"No converter available for " +
objectContext.getObjectType());
}
public <T> T convert(Object object, Converter<T> converter) {
return (T)convert(object,new ObjectContext(object),converter);
}
public <T> T convert(
Object object,
ObjectContext objectContext,
Converter<T> converter) {
if (objectContext == null) objectContext = new ObjectContext(object);
Converter<T> overrideConverter = getConverter(objectContext);
if (overrideConverter != null) converter = overrideConverter;
if (converter != null) {
return converter.convert(object, objectContext, this);
} else {
throw new ConversionException(
"No converter available for " +
objectContext.getObjectType());
}
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return copy();
}
}
protected Object copy() {
return new RuntimeException(new CloneNotSupportedException());
}
public static Class<? extends Object> getReturnType(
AccessibleObject accessor) {
if (accessor instanceof Field)
return ((Field)accessor).getType();
else if (accessor instanceof Method)
return ((Method)accessor).getReturnType();
else return null;
}
}