/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.reflect.plugins;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import org.jboss.reflect.spi.AnnotationInfo;
import org.jboss.reflect.spi.AnnotationValue;
import org.jboss.reflect.spi.ArrayInfo;
import org.jboss.reflect.spi.ClassInfo;
import org.jboss.reflect.spi.EnumInfo;
import org.jboss.reflect.spi.MethodInfo;
import org.jboss.reflect.spi.PrimitiveInfo;
import org.jboss.reflect.spi.PrimitiveValue;
import org.jboss.reflect.spi.TypeInfo;
import org.jboss.reflect.spi.TypeInfoFactory;
import org.jboss.reflect.spi.Value;
/**
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
* @version $Revision: 60147 $
*/
public class AnnotationValueFactory
{
public static Value createValue(AnnotationHelper annotationHelper, TypeInfo type, Object value)
{
Value rtnValue = null;
if (type instanceof ArrayInfo)
{
Object[] objects = getArray((ArrayInfo)type, value);
Value[] values = new Value[objects.length];
for (int i = 0 ; i < objects.length ; i++)
{
values[i] = createValue(annotationHelper, ((ArrayInfo)type).getComponentType(), objects[i]);
}
rtnValue = new ArrayValueImpl(type, values);
}
else if (type instanceof PrimitiveInfo)
{
rtnValue = new PrimitiveValue(value.toString(), (PrimitiveInfo)type);
}
else if (type.getName().equals("java.lang.String"))
{
rtnValue = new StringValueImpl((String)value, type);
}
else if (type instanceof AnnotationInfo)
{
rtnValue = annotationHelper.createAnnotationValue((AnnotationInfo)type, value);
}
else if (type instanceof EnumInfo)
{
rtnValue = new EnumValueImpl(type, value.toString());
}
else if (type instanceof ClassInfo)
{
// TODO JBMICROCONT-118 do not depend on Class
rtnValue = new ClassValueImpl(((Class)value).getName(), type);
}
return rtnValue;
}
public static AnnotationValue createAnnotationValue(TypeInfoFactory typeInfoFactory, AnnotationHelper annotationHelper, AnnotationInfo info, Object ann)
{
Annotation annotation = (Annotation)ann;
Class clazz = annotation.annotationType();
ClassInfo clazzInfo = (ClassInfo) typeInfoFactory.getTypeInfo(clazz);
HashMap<String, Value> attributes = new HashMap<String, Value>();
MethodInfo[] methods = clazzInfo.getDeclaredMethods();
if (methods != null)
{
for (int j = 0 ; j < methods.length ; j++)
{
try
{
Object val = methods[j].invoke(annotation, null);
TypeInfo typeInfo = methods[j].getReturnType();
Value value = createValue(annotationHelper, typeInfo, val);
attributes.put(methods[j].getName(), value);
}
catch (Throwable e)
{
throw new RuntimeException("Error retrieving annotation attribute values", e);
}
}
}
return new AnnotationValueImpl(info, attributes, annotation);
}
private static Object[] getArray(ArrayInfo arrayInfo, Object value)
{
TypeInfo componentType = arrayInfo.getComponentType();
if (!(componentType instanceof PrimitiveInfo))
{
return (Object[])value;
}
else
{
Object[] ret = null;
String typeName = componentType.getName();
if (typeName.equals("boolean"))
{
boolean[] input = (boolean[])value;
ret = new Boolean[input.length];
for (int i = 0 ; i < ret.length ; i++)
{
ret[i] = new Boolean(input[i]);
}
}
else if (typeName.equals("char"))
{
char[] input = (char[])value;
ret = new Character[input.length];
for (int i = 0 ; i < ret.length ; i++)
{
ret[i] = new Character(input[i]);
}
}
else if (typeName.equals("double"))
{
double[] input = (double[])value;
ret = new Double[input.length];
for (int i = 0 ; i < ret.length ; i++)
{
ret[i] = new Double(input[i]);
}
}
else if (typeName.equals("float"))
{
float[] input = (float[])value;
ret = new Float[input.length];
for (int i = 0 ; i < ret.length ; i++)
{
ret[i] = new Float(input[i]);
}
}
else if (typeName.equals("int"))
{
int[] input = (int[])value;
ret = new Integer[input.length];
for (int i = 0 ; i < ret.length ; i++)
{
ret[i] = new Integer(input[i]);
}
}
else if (typeName.equals("long"))
{
long[] input = (long[])value;
ret = new Long[input.length];
for (int i = 0 ; i < ret.length ; i++)
{
ret[i] = new Long(input[i]);
}
}
else if (typeName.equals("short"))
{
short[] input = (short[])value;
ret = new Short[input.length];
for (int i = 0 ; i < ret.length ; i++)
{
ret[i] = new Short(input[i]);
}
}
if (ret == null)
{
throw new RuntimeException("Array component type " + componentType + " is not handled");
}
return ret;
}
}
}