Skip to content

Commit

Permalink
FORGE-746: fully handle annotation elements of enum, class, and array…
Browse files Browse the repository at this point in the history
…s of each, type
  • Loading branch information
mbenson authored and gastaldi committed Jan 15, 2013
1 parent 600b4aa commit 0fb4a08
Show file tree
Hide file tree
Showing 3 changed files with 300 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012 Red Hat, Inc. and/or its affiliates.
* Copyright 2012-2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
Expand Down Expand Up @@ -30,6 +30,10 @@ public interface Annotation<O extends JavaSource<O>> extends Internal, Origin<O>

<T extends Enum<T>> T getEnumValue(Class<T> type, String name);

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

<T extends Enum<T>> T[] getEnumArrayValue(Class<T> type, String name);

String getLiteralValue();

String getLiteralValue(String name);
Expand All @@ -50,6 +54,10 @@ public interface Annotation<O extends JavaSource<O>> extends Internal, Origin<O>

Annotation<O> setEnumValue(Enum<?>... value);

Annotation<O> setEnumArrayValue(String name, Enum<?>... values);

Annotation<O> setEnumArrayValue(Enum<?>... values);

Annotation<O> setLiteralValue(String value);

Annotation<O> setLiteralValue(String name, String value);
Expand All @@ -65,4 +73,21 @@ public interface Annotation<O extends JavaSource<O>> extends Internal, Origin<O>
Annotation<O> setAnnotationValue();

Annotation<O> setAnnotationValue(String name);

Class<?> getClassValue();

Class<?> getClassValue(String name);

Class<?>[] getClassArrayValue();

Class<?>[] getClassArrayValue(String name);

Annotation<O> setClassValue(String name, Class<?> value);

Annotation<O> setClassValue(Class<?> value);

Annotation<O> setClassArrayValue(String name, Class<?>... values);

Annotation<O> setClassArrayValue(Class<?>... values);

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,29 @@
*/
package org.jboss.forge.parser.java.impl;

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

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TypeLiteral;
import org.jboss.forge.parser.JavaParser;
import org.jboss.forge.parser.java.Annotation;
import org.jboss.forge.parser.java.AnnotationTarget;
import org.jboss.forge.parser.java.JavaClass;
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.Strings;

Expand Down Expand Up @@ -311,6 +315,9 @@ public Annotation<O> setLiteralValue(final String name, final String value)
else if (!isSingleValue() && !isNormal() && DEFAULT_VALUE.equals(name))
{
convertTo(AnnotationType.SINGLE);
}
if (isSingleValue() && DEFAULT_VALUE.equals(name))
{
return setLiteralValue(value);
}

Expand Down Expand Up @@ -386,54 +393,33 @@ private <E extends Enum<E>> E convertLiteralToEnum(final Class<E> type, String l
@Override
public Annotation<O> setEnumValue(final String name, final Enum<?> value)
{
O origin = getOrigin();

if (origin instanceof JavaSource)
{
JavaSource<?> source = origin;
if (!source.hasImport(value.getDeclaringClass()))
{
source.addImport(value.getDeclaringClass());
}
}
return setLiteralValue(name, value.getDeclaringClass().getSimpleName() + "." + value.name());
return setEnumArrayValue(name, value);
}

@Override
public Annotation<O> setEnumValue(final Enum<?>... values)
{
O origin = getOrigin();
return setEnumArrayValue(values);
}

String result = new String();// = "{";
@Override
public Annotation<O> setEnumArrayValue(Enum<?>... values)
{
return setEnumArrayValue(DEFAULT_VALUE, values);
}

if (values.length > 1)
{
result = "{";
}
@Override
public Annotation<O> setEnumArrayValue(String name, final Enum<?>... values)
{
final List<String> literals = new ArrayList<String>();

if (origin instanceof JavaSource)
for (Enum<?> value : values)
{
JavaSource<?> source = origin;

for (Enum<?> value : values)
{
if (!source.hasImport(value.getDeclaringClass()))
{
source.addImport(value.getDeclaringClass());
}

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

result = result.substring(0, result.length() - 1);

if (values.length > 1)
{
result = result.concat("}");
}
getOrigin().addImport(value.getDeclaringClass());
literals.add(value.getDeclaringClass().getSimpleName() + "." + value.name());
}

return setLiteralValue(result);
return setLiteralValue(name,
literals.size() == 1 ? literals.get(0) : String.format("{%s}", Strings.join(literals, ",")));
}

/*
Expand Down Expand Up @@ -630,4 +616,178 @@ public Annotation<O> getAnnotationValue(String name)
return null;
}

@Override
public <E extends Enum<E>> E[] getEnumArrayValue(Class<E> type)
{
return getEnumArrayValue(type, DEFAULT_VALUE);
}

@Override
public <E extends Enum<E>> E[] getEnumArrayValue(Class<E> type, String name)
{
final Expression expr = getElementValueExpression(name);
if (expr instanceof ArrayInitializer)
{
final List<E> results = new ArrayList<E>();
@SuppressWarnings("unchecked")
final List<Expression> arrayElements = ((ArrayInitializer) expr).expressions();
for (Expression arrayElement : arrayElements)
{
final E instance = convertLiteralToEnum(type, arrayElement.toString());
results.add(instance);
}
@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;
}
}
return null;
}

@Override
public Class<?> getClassValue()
{
return getClassValue(DEFAULT_VALUE);
}

@Override
public Class<?> getClassValue(String name)
{
final TypeLiteral typeLiteral = getElementValueExpression(name);
return resolveTypeLiteral(typeLiteral);
}

@Override
public Class<?>[] getClassArrayValue()
{
return getClassArrayValue(DEFAULT_VALUE);
}

@Override
public Class<?>[] getClassArrayValue(String name)
{
final Expression expr = getElementValueExpression(name);
if (expr instanceof ArrayInitializer)
{
final List<Class<?>> result = new ArrayList<Class<?>>();
@SuppressWarnings("unchecked")
final List<Expression> arrayElements = ((ArrayInitializer) expr).expressions();
for (Expression expression : arrayElements)
{
final Class<?> type = resolveTypeLiteral((TypeLiteral) expression);
result.add(type);
}
return result.toArray(new Class[result.size()]);
}
else if (expr instanceof TypeLiteral)
{
return new Class[] { resolveTypeLiteral((TypeLiteral) expr) };
}
return null;
}

@Override
public Annotation<O> setClassValue(String name, Class<?> value)
{
if (!value.isPrimitive())
{
getOrigin().addImport(value);
}
return setLiteralValue(name, value.getSimpleName() + ".class");
}

@Override
public Annotation<O> setClassValue(Class<?> value)
{
return setClassValue(DEFAULT_VALUE, value);
}

@Override
public Annotation<O> setClassArrayValue(Class<?>... values)
{
return setClassArrayValue(DEFAULT_VALUE, values);
}

@Override
public Annotation<O> setClassArrayValue(String name, Class<?>... values)
{
final List<String> literals = new ArrayList<String>();

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

private <E extends Expression> E getElementValueExpression(String name)
{
if (isSingleValue() && DEFAULT_VALUE.equals(name))
{
@SuppressWarnings("unchecked")
final E result = (E) ((SingleMemberAnnotation) annotation).getValue();
return result;
}
if (isNormal())
{
for (Object v : ((NormalAnnotation) annotation).values())
{
if (v instanceof MemberValuePair)
{
MemberValuePair pair = (MemberValuePair) v;
if (pair.getName().getFullyQualifiedName().equals(name))
{
@SuppressWarnings("unchecked")
final E result = (E) pair.getValue();
return result;
}
}
}
}
return null;
}

private Class<?> resolveTypeLiteral(TypeLiteral typeLiteral)
{
final Type<O> type = new TypeImpl<O>(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;
}
}
}
Loading

0 comments on commit 0fb4a08

Please sign in to comment.