Skip to content

Commit

Permalink
FORGE 746: continued, enum/class/arrays thereof for AnnotationElement…
Browse files Browse the repository at this point in the history
….DefaultValue
  • Loading branch information
mbenson committed Jan 15, 2013
1 parent a03a105 commit 65058b9
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,28 @@ public interface DefaultValue

<T extends Enum<T>> T getEnum(Class<T> type);

<T extends Enum<T>> T[] getEnumArray(Class<T> type);

Annotation<JavaAnnotation> getAnnotation();

Class<?> getSingleClass();

Class<?>[] getClassArray();

DefaultValue setLiteral(String value);

DefaultValue setString(String value);

<T extends Enum<T>> DefaultValue setEnum(T... value);
<T extends Enum<T>> DefaultValue setEnum(T value);

<T extends Enum<T>> DefaultValue setEnumArray(T... values);

Annotation<JavaAnnotation> setAnnotation();

DefaultValue setSingleClass(Class<?> value);

DefaultValue setClassArray(Class<?>... values);

}

String getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,25 @@

package org.jboss.forge.parser.java.impl;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.TypeLiteral;
import org.eclipse.jdt.core.dom.PrimitiveType.Code;
import org.eclipse.jdt.core.dom.Type;
import org.jboss.forge.parser.JavaParser;
import org.jboss.forge.parser.java.Annotation;
import org.jboss.forge.parser.java.AnnotationElement;
import org.jboss.forge.parser.java.JavaAnnotation;
import org.jboss.forge.parser.java.JavaSource;
import org.jboss.forge.parser.java.Type;
import org.jboss.forge.parser.java.ast.AnnotationAccessor;
import org.jboss.forge.parser.java.util.Assert;
import org.jboss.forge.parser.java.util.Strings;
Expand Down Expand Up @@ -70,26 +74,9 @@ public String getLiteral()
}

@Override
public <E extends Enum<E>> E getEnum(Class<E> type)
public <E extends Enum<E>> E getEnum(final Class<E> type)
{
String literalValue = getLiteral();

E[] constants = type.getEnumConstants();

for (E inst : constants)
{
String[] tokens = literalValue.split("\\.");
if (tokens.length > 1)
{
literalValue = tokens[tokens.length - 1];
}

if (inst.name().equals(literalValue))
{
return inst;
}
}
return null;
return convertLiteralToEnum(type, getLiteral());
}

@Override
Expand All @@ -114,10 +101,9 @@ public DefaultValue setLiteral(String value)
{
String stub = "public @interface Stub { String stub() default " + value + "; }";
JavaAnnotation temp = (JavaAnnotation) JavaParser.parse(stub);
AnnotationTypeMemberDeclaration internal = (AnnotationTypeMemberDeclaration) temp.getAnnotations().get(0)
.getInternal();
member.setDefault((Expression)
ASTNode.copySubtree(ast, internal.getDefault()));
AnnotationTypeMemberDeclaration internal = (AnnotationTypeMemberDeclaration) temp.getAnnotationElements()
.get(0).getInternal();
member.setDefault((Expression) ASTNode.copySubtree(ast, internal.getDefault()));
}
return this;
}
Expand All @@ -129,48 +115,175 @@ public DefaultValue setString(String value)
return setLiteral(Strings.enquote(value));
}

@SuppressWarnings("unchecked")
@Override
public <T extends Enum<T>> DefaultValue setEnum(T values)
{
return setEnumArray(values);
}

@Override
public <T extends Enum<T>> DefaultValue setEnum(T... values)
public <T extends Enum<T>> DefaultValue setEnumArray(T... values)
{
JavaAnnotation origin = getOrigin();
Assert.notNull(values, "null array not accepted");

String result = new String();// = "{";
final List<String> literals = new ArrayList<String>();

if (values.length > 1)
for (Enum<?> value : values)
{
result = "{";
Assert.notNull(value, "null value not accepted");

getOrigin().addImport(value.getDeclaringClass());
literals.add(value.getDeclaringClass().getSimpleName() + "." + value.name());
}

JavaSource<?> source = origin;
return setLiteral(literals.size() == 1 ? literals.get(0) : String.format("{%s}", Strings.join(literals, ",")));
}

for (Enum<?> value : values)
@Override
public Annotation<JavaAnnotation> setAnnotation()
{
AnnotationValue result = new AnnotationValue(parent);
member.setDefault((Expression) result.getInternal());
return result;
}

@Override
public <E extends Enum<E>> E[] getEnumArray(Class<E> type)
{
Expression expr = member.getDefault();
if (expr instanceof ArrayInitializer)
{
if (!origin.hasImport(value.getDeclaringClass()))
final List<E> results = new ArrayList<E>();
@SuppressWarnings("unchecked")
final List<Expression> arrayElements = ((ArrayInitializer) expr).expressions();
for (Expression arrayElement : arrayElements)
{
source.addImport(value.getDeclaringClass());
results.add(convertLiteralToEnum(type, arrayElement.toString()));
}
@SuppressWarnings("unchecked")
final E[] result = (E[]) Array.newInstance(type, results.size());
return results.toArray(result);
}
else if (expr != null)
{
final E instance = convertLiteralToEnum(type, expr.toString());
if (type.isInstance(instance))
{
@SuppressWarnings("unchecked")
final E[] result = (E[]) Array.newInstance(type, 1);
result[0] = instance;
return result;
}

result = result.concat(value.getDeclaringClass().getSimpleName() + "." + value.name() + ",");
}
return null;
}

@Override
public DefaultValue setSingleClass(Class<?> value)
{
return setClassArray(value);
}

@Override
public DefaultValue setClassArray(Class<?>... values)
{
Assert.notNull(values, "null array not accepted");

result = result.substring(0, result.length() - 1);
final List<String> literals = new ArrayList<String>();
for (Class<?> value : values)
{
Assert.notNull(value, "null value not accepted");

if (!value.isPrimitive())
{
getOrigin().addImport(value);
}
literals.add(value.getSimpleName() + ".class");
}
return setLiteral(literals.size() == 1 ? literals.get(0) : String.format("{%s}", Strings.join(literals, ",")));
}

if (values.length > 1)
private <E extends Enum<E>> E convertLiteralToEnum(final Class<E> type, String literalValue)
{
for (E inst : type.getEnumConstants())
{
result = result.concat("}");
String[] tokens = literalValue.split("\\.");
if (tokens.length > 1)
{
literalValue = tokens[tokens.length - 1];
}

if (inst.name().equals(literalValue))
{
return inst;
}
}
return null;

}

return setLiteral(result);
@Override
public Class<?> getSingleClass()
{
final Expression expr = member.getDefault();
if (expr instanceof TypeLiteral)
{
return resolveTypeLiteral((TypeLiteral) expr);
}
return null;
}

@Override
public Annotation<JavaAnnotation> setAnnotation()
public Class<?>[] getClassArray()
{
AnnotationValue result = new AnnotationValue(parent);
member.setDefault((Expression) result.getInternal());
return result;
final Expression expr = member.getDefault();
if (expr instanceof ArrayInitializer)
{
final List<Class<?>> result = new ArrayList<Class<?>>();
@SuppressWarnings("unchecked")
final List<Expression> arrayElements = ((ArrayInitializer) expr).expressions();
for (Expression arrayElement : arrayElements)
{
result.add(resolveTypeLiteral((TypeLiteral) arrayElement));
}
return result.toArray(new Class[result.size()]);
}
if (expr instanceof TypeLiteral)
{
return new Class[] { resolveTypeLiteral((TypeLiteral) expr) };
}
return null;
}

private Class<?> resolveTypeLiteral(TypeLiteral typeLiteral)
{
final Type<JavaAnnotation> type = new TypeImpl<JavaAnnotation>(getOrigin(), typeLiteral.getType());
if (type.isPrimitive())
{
final Class<?>[] primitiveTypes = { boolean.class, byte.class, short.class, int.class, long.class,
float.class, double.class };
for (Class<?> c : primitiveTypes)
{
if (c.getSimpleName().equals(type.getName()))
{
return c;
}
}
return null;
}

final String classname = type.getQualifiedName();

try
{
return Class.forName(getOrigin().resolveType(classname));
}
catch (ClassNotFoundException e)
{
return null;
}
}
}

private final AnnotationAccessor<JavaAnnotation, AnnotationElement> annotations = new AnnotationAccessor<JavaAnnotation, AnnotationElement>();
Expand Down Expand Up @@ -392,7 +505,7 @@ public AnnotationElement setType(final String typeName)

Code primitive = PrimitiveType.toCode(typeName);

Type type = null;
org.eclipse.jdt.core.dom.Type type = null;
if (primitive != null)
{
type = ast.newPrimitiveType(primitive);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.jboss.forge.parser.java.JavaSource;
import org.jboss.forge.parser.java.Type;
import org.jboss.forge.parser.java.ValuePair;
import org.jboss.forge.parser.java.util.Assert;
import org.jboss.forge.parser.java.util.Strings;

/**
Expand Down Expand Up @@ -279,6 +280,8 @@ public Annotation<O> setName(final String className)
@Override
public Annotation<O> setLiteralValue(final String value)
{
Assert.notNull(value, "null not accepted");

if (isMarker())
{
convertTo(AnnotationType.SINGLE);
Expand Down Expand Up @@ -308,6 +311,8 @@ public Annotation<O> setLiteralValue(final String value)
@SuppressWarnings("unchecked")
public Annotation<O> setLiteralValue(final String name, final String value)
{
Assert.notNull(value, "null not accepted");

if (!isNormal() && !DEFAULT_VALUE.equals(name))
{
convertTo(AnnotationType.NORMAL);
Expand Down Expand Up @@ -411,10 +416,13 @@ public Annotation<O> setEnumArrayValue(Enum<?>... values)
@Override
public Annotation<O> setEnumArrayValue(String name, final Enum<?>... values)
{
Assert.notNull(values, "null array not accepted");

final List<String> literals = new ArrayList<String>();

for (Enum<?> value : values)
{
Assert.notNull(value, "null value not accepted");
getOrigin().addImport(value.getDeclaringClass());
literals.add(value.getDeclaringClass().getSimpleName() + "." + value.name());
}
Expand Down Expand Up @@ -699,6 +707,8 @@ else if (expr instanceof TypeLiteral)
@Override
public Annotation<O> setClassValue(String name, Class<?> value)
{
Assert.notNull(value, "null not accepted");

if (!value.isPrimitive())
{
getOrigin().addImport(value);
Expand All @@ -721,10 +731,14 @@ public Annotation<O> setClassArrayValue(Class<?>... values)
@Override
public Annotation<O> setClassArrayValue(String name, Class<?>... values)
{
Assert.notNull(values, "null array not accepted");

final List<String> literals = new ArrayList<String>();

for (Class<?> value : values)
{
Assert.notNull(value, "null value not accepted");

if (!value.isPrimitive())
{
getOrigin().addImport(value);
Expand Down

0 comments on commit 65058b9

Please sign in to comment.