/*
* ModeShape (http://www.modeshape.org)
*
* Licensed 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.
*/
package org.modeshape.sequencer.javafile;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.modeshape.common.util.CheckArg;
import org.modeshape.sequencer.javafile.metadata.AnnotationMetadata;
import org.modeshape.sequencer.javafile.metadata.EnumMetadata;
import org.modeshape.sequencer.javafile.metadata.FieldMetadata;
import org.modeshape.sequencer.javafile.metadata.ImportMetadata;
import org.modeshape.sequencer.javafile.metadata.MethodMetadata;
import org.modeshape.sequencer.javafile.metadata.ModifierMetadata;
import org.modeshape.sequencer.javafile.metadata.PackageMetadata;
import org.modeshape.sequencer.javafile.metadata.TypeMetadata;
import org.modeshape.sequencer.javafile.metadata.Variable;
/**
* Abstract definition of a <code>JavaMetadata<code>. This class exposes some useful methods, that can
* be used to create meta data of a compilation unit. Methods can also separately be used.
*/
public abstract class AbstractJavaMetadata {
/**
* Create a set of <code>ImportMetadata</code> of a compilation unit.
*
* @param unit - the compilation unit.
* @return all static import declarations from the compilation unit.
*/
@SuppressWarnings( "unchecked" )
protected List<ImportMetadata> createImportMetadata( CompilationUnit unit ) {
List<ImportMetadata> metadata = new ArrayList<ImportMetadata>();
List<ImportDeclaration> imports = unit.imports();
if (!imports.isEmpty()) {
for (ImportDeclaration importDeclaration : imports) {
if (importDeclaration.isOnDemand()) {
// typeImportOnDemand and staticImportOnDemand
metadata.add(ImportMetadata.onDemand(JavaMetadataUtil.getName(importDeclaration.getName())));
} else {
// singleTypeImport and singleStaticImport
metadata.add(ImportMetadata.single(JavaMetadataUtil.getName(importDeclaration.getName())));
}
}
}
return metadata;
}
/**
* Create a <code>PackageMetadata</code> of a compilation unit.
*
* @param unit - the compilation unit.
* @return the package meta data of a compilation unit.
*/
@SuppressWarnings( "unchecked" )
protected PackageMetadata createPackageMetadata( CompilationUnit unit ) {
PackageMetadata packageMetadata = null;
List<Annotation> annotations = null;
PackageDeclaration packageDeclaration = unit.getPackage();
if (packageDeclaration != null) {
annotations = packageDeclaration.annotations();
packageMetadata = new PackageMetadata(JavaMetadataUtil.getName(unit.getPackage().getName()));
if (!annotations.isEmpty()) {
for (Object object : annotations) {
packageMetadata.getAnnotations().add(createAnnotationMetadataFor((Annotation)object));
}
}
}
return packageMetadata;
}
@SuppressWarnings( "unchecked" )
protected AnnotationMetadata createAnnotationMetadataFor( Annotation annotation ) {
if (annotation instanceof NormalAnnotation) {
NormalAnnotation normalAnnotation = (NormalAnnotation)annotation;
Map<String, String> memberValues = new LinkedHashMap<String, String>();
List<MemberValuePair> values = normalAnnotation.values();
for (MemberValuePair pair : values) {
memberValues.put(pair.getName().getIdentifier(), JavaMetadataUtil.expressionString(pair.getValue()));
}
return AnnotationMetadata.normalAnnotation(JavaMetadataUtil.getName(normalAnnotation.getTypeName()), memberValues);
}
if (annotation instanceof MarkerAnnotation) {
MarkerAnnotation markerAnnotation = (MarkerAnnotation)annotation;
return AnnotationMetadata.markerAnnotation(JavaMetadataUtil.getName(markerAnnotation.getTypeName()));
}
if (annotation instanceof SingleMemberAnnotation) {
SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation)annotation;
return AnnotationMetadata.singleMemberAnnotation(JavaMetadataUtil.getName(singleMemberAnnotation.getTypeName()),
JavaMetadataUtil.expressionString(singleMemberAnnotation.getValue()));
}
return null;
}
/**
* Create a list with all top level types of a compilation unit.
*
* @param unit - the compilation unit.
* @return meta data for types in this compilation unit.
*/
@SuppressWarnings( "unchecked" )
protected List<TypeMetadata> createTypeMetadata( CompilationUnit unit ) {
List<TypeMetadata> metadata = new ArrayList<TypeMetadata>();
List<AbstractTypeDeclaration> topLevelType = unit.types();
for (AbstractTypeDeclaration abstractTypeDeclaration : topLevelType) {
// process TypeDeclaration (class, interface)
if (abstractTypeDeclaration instanceof TypeDeclaration) {
TypeDeclaration typeDeclaration = (TypeDeclaration)abstractTypeDeclaration;
if (typeDeclaration.isInterface()) {
// is an interface top level type
TypeMetadata interfaceMetadata = TypeMetadata.interfaceType(JavaMetadataUtil.getName(typeDeclaration.getName()));
// detect the interfaces, if any
for (Type superInterfaceType : (List<Type>)typeDeclaration.superInterfaceTypes()) {
interfaceMetadata.getInterfaceNames().add(getTypeName(superInterfaceType));
}
metadata.add(interfaceMetadata);
} else {
// is a class top level type
TypeMetadata classMetadata = TypeMetadata.classType(JavaMetadataUtil.getName(typeDeclaration.getName()));
processModifiersOfTypeDeclaration(typeDeclaration, classMetadata);
// set the superclass, if any
Type superClassType = typeDeclaration.getSuperclassType();
if (superClassType != null) {
classMetadata.setSuperTypeName(getTypeName(superClassType));
}
// detect the interfaces, if any
for (Type superInterfaceType : (List<Type>)typeDeclaration.superInterfaceTypes()) {
classMetadata.getInterfaceNames().add(getTypeName(superInterfaceType));
}
// fields of the class top level type
FieldDeclaration[] fieldDeclarations = typeDeclaration.getFields();
for (FieldDeclaration fieldDeclaration : fieldDeclarations) {
FieldMetadata fieldMetadata = getFieldMetadataFrom(fieldDeclaration);
classMetadata.getFields().add(fieldMetadata);
}
// methods of the class top level type
MethodDeclaration[] methodDeclarations = typeDeclaration.getMethods();
for (MethodDeclaration methodDeclaration : methodDeclarations) {
MethodMetadata methodMetadata = getMethodMetadataFrom(methodDeclaration);
classMetadata.getMethods().add(methodMetadata);
}
metadata.add(classMetadata);
}
}
// process EnumDeclaration
if (abstractTypeDeclaration instanceof EnumDeclaration) {
EnumDeclaration enumDeclaration = (EnumDeclaration)abstractTypeDeclaration;
// is a class top level type
EnumMetadata enumMetadata = TypeMetadata.enumType(JavaMetadataUtil.getName(enumDeclaration.getName()));
processModifiersOfTypeDeclaration(enumDeclaration, enumMetadata);
// Store the enum values
List<EnumConstantDeclaration> enumValues = enumDeclaration.enumConstants();
for (EnumConstantDeclaration enumValue : enumValues) {
enumMetadata.getValues().add(enumValue.getName().getIdentifier());
}
// Enums don't have superclasses
// detect the interfaces, if any
for (Type superInterfaceType : (List<Type>)enumDeclaration.superInterfaceTypes()) {
enumMetadata.getInterfaceNames().add(getTypeName(superInterfaceType));
}
/*
* It would be nice to be able to reuse the convenience methods from AbstractTypeDeclaration,
* but they don't exist in EnumDeclaration. So we improvise!
*/
List<BodyDeclaration> bodyDecls = enumDeclaration.bodyDeclarations();
for (BodyDeclaration bodyDecl : bodyDecls) {
if (bodyDecl instanceof FieldDeclaration) {
// fields of the class top level type
FieldMetadata fieldMetadata = getFieldMetadataFrom((FieldDeclaration)bodyDecl);
enumMetadata.getFields().add(fieldMetadata);
} else if (bodyDecl instanceof MethodDeclaration) {
// methods of the class top level type
MethodMetadata methodMetadata = getMethodMetadataFrom((MethodDeclaration)bodyDecl);
enumMetadata.getMethods().add(methodMetadata);
}
}
metadata.add(enumMetadata);
}
// process annotationTypeDeclaration
if (abstractTypeDeclaration instanceof AnnotationTypeDeclaration) {
// AnnotationTypeDeclaration annotationTypeDeclaration = (AnnotationTypeDeclaration)abstractTypeDeclaration;
// TODO get infos from annotation type declaration and create a annotation meta data object.
}
}
return metadata;
}
/**
* Process modifiers of {@link TypeDeclaration}.
*
* @param typeDeclaration - the type declaration.
* @param classMetadata - class meta data.
*/
@SuppressWarnings( "unchecked" )
protected void processModifiersOfTypeDeclaration( AbstractTypeDeclaration typeDeclaration,
TypeMetadata classMetadata ) {
List<IExtendedModifier> modifiers = typeDeclaration.modifiers();
for (IExtendedModifier extendedModifier : modifiers) {
if (extendedModifier.isAnnotation()) {
if (extendedModifier instanceof MarkerAnnotation) {
MarkerAnnotation marker = (MarkerAnnotation)extendedModifier;
classMetadata.getAnnotations().add(AnnotationMetadata.markerAnnotation(JavaMetadataUtil.getName(marker.getTypeName())));
}
} else {
Modifier modifier = (Modifier)extendedModifier;
classMetadata.getModifiers().add(new ModifierMetadata(modifier.getKeyword().toString()));
}
}
}
/**
* Gets a method meta data from {@link MethodDeclaration}.
*
* @param methodDeclaration - the MethodDeclaration.
* @return methodMetadata - the method meta data.
*/
protected MethodMetadata getMethodMetadataFrom( MethodDeclaration methodDeclaration ) {
if (methodDeclaration != null) {
if (methodDeclaration.isConstructor()) {
return getConstructorMetadataFrom(methodDeclaration);
}
return getMethodTypeMemberMetadataFrom(methodDeclaration);
}
return null;
}
/**
* Get {@link MethodMetadata}
*
* @param methodDeclaration
* @return methodTypeMemberMetadata
*/
@SuppressWarnings( "unchecked" )
protected MethodMetadata getMethodTypeMemberMetadataFrom( MethodDeclaration methodDeclaration ) {
MethodMetadata methodTypeMemberMetadata = MethodMetadata.methodMemberType(JavaMetadataUtil.getName(methodDeclaration.getName()));
processReturnTypeOfMethodDeclaration(methodDeclaration, methodTypeMemberMetadata);
processModifiersOfMethodDeclaration(methodDeclaration, methodTypeMemberMetadata);
processParametersOfMethodDeclaration(methodDeclaration, methodTypeMemberMetadata);
List<SingleVariableDeclaration> params = methodDeclaration.parameters();
for (SingleVariableDeclaration singleVariableDeclaration : params) {
singleVariableDeclaration.getName();
}
return methodTypeMemberMetadata;
}
/**
* Process return type of a {@link MethodDeclaration}.
*
* @param methodDeclaration - the method declaration.
* @param methodMetadata - the method meta data.
*/
protected void processReturnTypeOfMethodDeclaration( MethodDeclaration methodDeclaration,
MethodMetadata methodMetadata ) {
Type type = methodDeclaration.getReturnType2();
if (type.isPrimitiveType()) {
methodMetadata.setReturnType(FieldMetadata.primitiveType(((PrimitiveType)type).getPrimitiveTypeCode().toString()));
}
if (type.isSimpleType()) {
methodMetadata.setReturnType(FieldMetadata.simpleType(JavaMetadataUtil.getName(((SimpleType)type).getName())));
}
}
/**
* Process parameters of a {@link MethodDeclaration}.
*
* @param methodDeclaration - the method declaration.
* @param methodMetadata - the method meta data.
*/
@SuppressWarnings( "unchecked" )
protected void processParametersOfMethodDeclaration( MethodDeclaration methodDeclaration,
MethodMetadata methodMetadata ) {
for (SingleVariableDeclaration singleVariableDeclaration : (List<SingleVariableDeclaration>)methodDeclaration.parameters()) {
Type type = singleVariableDeclaration.getType();
if (type.isPrimitiveType()) {
FieldMetadata primitiveFieldMetadata = processVariableDeclaration(singleVariableDeclaration, type);
methodMetadata.getParameters().add(primitiveFieldMetadata);
}
if (type.isParameterizedType()) {
FieldMetadata parameterizedTypeFieldMetadata = processVariableDeclaration(singleVariableDeclaration, type);
methodMetadata.getParameters().add(parameterizedTypeFieldMetadata);
}
if (type.isQualifiedType()) {
// TODO
}
if (type.isSimpleType()) {
FieldMetadata simpleTypeFieldMetadata = processVariableDeclaration(singleVariableDeclaration, type);
methodMetadata.getParameters().add(simpleTypeFieldMetadata);
}
if (type.isArrayType()) {
FieldMetadata arrayTypeFieldMetadata = processVariableDeclaration(singleVariableDeclaration, type);
methodMetadata.getParameters().add(arrayTypeFieldMetadata);
}
if (type.isWildcardType()) {
// TODO
}
}
}
/**
* Process a {@link SingleVariableDeclaration} of a {@link MethodDeclaration}.
*
* @param singleVariableDeclaration
* @param type
* @return a field meta data.
*/
@SuppressWarnings( "unchecked" )
private FieldMetadata processVariableDeclaration( SingleVariableDeclaration singleVariableDeclaration,
Type type ) {
Variable variable;
if (type.isPrimitiveType()) {
FieldMetadata primitiveFieldMetadata = FieldMetadata.primitiveType(((PrimitiveType)type).getPrimitiveTypeCode().toString());
variable = new Variable();
variable.setName(JavaMetadataUtil.getName(singleVariableDeclaration.getName()));
primitiveFieldMetadata.setName(variable.getName());
primitiveFieldMetadata.getVariables().add(variable);
for (IExtendedModifier extendedModifier : (List<IExtendedModifier>)singleVariableDeclaration.modifiers()) {
if (extendedModifier.isAnnotation()) {
primitiveFieldMetadata.getAnnotations().add(createAnnotationMetadataFor((Annotation)extendedModifier));
} else {
Modifier modifier = (Modifier)extendedModifier;
primitiveFieldMetadata.getModifiers().add(new ModifierMetadata(modifier.getKeyword().toString()));
}
}
return primitiveFieldMetadata;
}
if (type.isSimpleType()) {
SimpleType simpleType = (SimpleType)type;
FieldMetadata simpleTypeFieldMetadata = FieldMetadata.simpleType(JavaMetadataUtil.getName(simpleType.getName()));
variable = new Variable();
variable.setName(JavaMetadataUtil.getName(singleVariableDeclaration.getName()));
simpleTypeFieldMetadata.setName(variable.getName());
simpleTypeFieldMetadata.getVariables().add(variable);
for (IExtendedModifier simpleTypeExtendedModifier : (List<IExtendedModifier>)singleVariableDeclaration.modifiers()) {
if (simpleTypeExtendedModifier.isAnnotation()) {
simpleTypeFieldMetadata.getAnnotations().add(createAnnotationMetadataFor((Annotation)simpleTypeExtendedModifier));
} else {
Modifier modifier = (Modifier)simpleTypeExtendedModifier;
simpleTypeFieldMetadata.getModifiers().add(new ModifierMetadata(modifier.getKeyword().toString()));
}
}
return simpleTypeFieldMetadata;
}
if (type.isParameterizedType()) {
ParameterizedType parameterizedType = (ParameterizedType)type;
FieldMetadata parameterizedTypeFieldMetadata = FieldMetadata.parametrizedType(getTypeName(parameterizedType));
variable = new Variable();
variable.setName(JavaMetadataUtil.getName(singleVariableDeclaration.getName()));
parameterizedTypeFieldMetadata.setName(variable.getName());
parameterizedTypeFieldMetadata.getVariables().add(variable);
for (IExtendedModifier parameterizedExtendedModifier : (List<IExtendedModifier>)singleVariableDeclaration.modifiers()) {
if (parameterizedExtendedModifier.isAnnotation()) {
parameterizedTypeFieldMetadata.getAnnotations().add(createAnnotationMetadataFor((Annotation)parameterizedExtendedModifier));
} else {
Modifier modifier = (Modifier)parameterizedExtendedModifier;
parameterizedTypeFieldMetadata.getModifiers().add(new ModifierMetadata(modifier.getKeyword().toString()));
}
}
return parameterizedTypeFieldMetadata;
}
if (type.isArrayType()) {
ArrayType arrayType = (ArrayType)type;
FieldMetadata arrayTypeFieldMetadata = FieldMetadata.arrayType(getTypeName(arrayType));
variable = new Variable();
variable.setName(JavaMetadataUtil.getName(singleVariableDeclaration.getName()));
arrayTypeFieldMetadata.setName(variable.getName());
arrayTypeFieldMetadata.getVariables().add(variable);
for (IExtendedModifier arrayTypeExtendedModifier : (List<IExtendedModifier>)singleVariableDeclaration.modifiers()) {
if (arrayTypeExtendedModifier.isAnnotation()) {
arrayTypeFieldMetadata.getAnnotations().add(createAnnotationMetadataFor((Annotation)arrayTypeExtendedModifier));
} else {
Modifier modifier = (Modifier)arrayTypeExtendedModifier;
arrayTypeFieldMetadata.getModifiers().add(new ModifierMetadata(modifier.getKeyword().toString()));
}
}
return arrayTypeFieldMetadata;
}
return null;
}
/**
* Extract the type name
*
* @param type - the type to be processed. This can be primitive, simple, parameterized ...
* @return the name of a type.
* @throws IllegalArgumentException if type is null.
*/
private String getTypeName( Type type ) {
CheckArg.isNotNull(type, "type");
if (type.isPrimitiveType()) {
PrimitiveType primitiveType = (PrimitiveType)type;
return primitiveType.getPrimitiveTypeCode().toString();
}
if (type.isSimpleType()) {
SimpleType simpleType = (SimpleType)type;
return JavaMetadataUtil.getName(simpleType.getName());
}
if (type.isParameterizedType()) {
ParameterizedType parameterizedType = (ParameterizedType)type;
return getTypeName(parameterizedType.getType());
}
if (type.isArrayType()) {
ArrayType arrayType = (ArrayType)type;
// the element type is never an array type
Type elementType = arrayType.getElementType();
if (elementType.isPrimitiveType()) {
return ((PrimitiveType)elementType).getPrimitiveTypeCode().toString();
}
// can't be an array type
if (elementType.isSimpleType()) {
return JavaMetadataUtil.getName(((SimpleType)elementType).getName());
}
}
return null;
}
/**
* Get {@link org.modeshape.sequencer.javafile.metadata.MethodMetadata}
*
* @param methodDeclaration
* @return constructorMetadata
*/
protected MethodMetadata getConstructorMetadataFrom( MethodDeclaration methodDeclaration ) {
MethodMetadata constructorMetadata = MethodMetadata.constructorType(JavaMetadataUtil.getName(methodDeclaration.getName()));
// modifiers
processModifiersOfMethodDeclaration(methodDeclaration, constructorMetadata);
processParametersOfMethodDeclaration(methodDeclaration, constructorMetadata);
// arguments list
return constructorMetadata;
}
/**
* Gets a field meta data from {@link FieldDeclaration}.
*
* @param fieldDeclaration - the declaration.
* @return fieldMetadata - meta data.
*/
protected FieldMetadata getFieldMetadataFrom( FieldDeclaration fieldDeclaration ) {
if (fieldDeclaration != null && fieldDeclaration.getType() != null && (!fieldDeclaration.fragments().isEmpty())) {
// type
Type type = fieldDeclaration.getType();
// Primitive type
if (type.isPrimitiveType()) {
return processPrimitiveType(fieldDeclaration);
}
// ParameterizedType
if (type.isParameterizedType()) {
return processParameterizedType(fieldDeclaration);
}
// SimpleType
if (type.isSimpleType()) {
return processSimpleType(fieldDeclaration);
}
// ArrayType
if (type.isArrayType()) {
return processArrayTypeFrom(fieldDeclaration);
}
// QualifiedType
if (type.isQualifiedType()) {
// TODO
}
// WildcardType
if (type.isWildcardType()) {
// TODO
}
}
return null;
}
/**
* Process a {@link FieldDeclaration} to win information for an array type.
*
* @param fieldDeclaration - field declaration
* @return an ArrayTypeFieldMetadata, that contains information about an array type.
*/
protected FieldMetadata processArrayTypeFrom( FieldDeclaration fieldDeclaration ) {
ArrayType arrayType = (ArrayType)fieldDeclaration.getType();
FieldMetadata arrayTypeFieldMetadata = null;
// the element type is never an array type
Type type = arrayType.getElementType();
if (type.isPrimitiveType()) {
PrimitiveType primitiveType = (PrimitiveType)type;
arrayTypeFieldMetadata = FieldMetadata.arrayType(primitiveType.getPrimitiveTypeCode().toString());
processModifiersAndVariablesOfFieldDeclaration(fieldDeclaration, arrayTypeFieldMetadata);
arrayTypeFieldMetadata.setName(getFieldName(fieldDeclaration));
return arrayTypeFieldMetadata;
}
// can't be an array type
if (type.isSimpleType()) {
SimpleType simpleType = (SimpleType)type;
arrayTypeFieldMetadata = FieldMetadata.arrayType(JavaMetadataUtil.getName(simpleType.getName()));
processModifiersAndVariablesOfFieldDeclaration(fieldDeclaration, arrayTypeFieldMetadata);
arrayTypeFieldMetadata.setName(getFieldName(fieldDeclaration));
return arrayTypeFieldMetadata;
}
return null;
}
/**
* Process together modifiers and variables of a {@link FieldDeclaration}.
*
* @param fieldDeclaration - the field declaration instance.
* @param arrayTypeFieldMetadata - the meta data.
*/
private void processModifiersAndVariablesOfFieldDeclaration( FieldDeclaration fieldDeclaration,
FieldMetadata arrayTypeFieldMetadata ) {
processModifiersOfFieldDeclaration(fieldDeclaration, arrayTypeFieldMetadata);
processVariablesOfVariableDeclarationFragment(fieldDeclaration, arrayTypeFieldMetadata);
}
/**
* Process the simple type of a {@link FieldDeclaration}.
*
* @param fieldDeclaration - the field declaration.
* @return SimpleTypeFieldMetadata.
*/
protected FieldMetadata processSimpleType( FieldDeclaration fieldDeclaration ) {
SimpleType simpleType = (SimpleType)fieldDeclaration.getType();
FieldMetadata simpleTypeFieldMetadata = FieldMetadata.simpleType(JavaMetadataUtil.getName(simpleType.getName()));
// modifiers
processModifiersOfFieldDeclaration(fieldDeclaration, simpleTypeFieldMetadata);
processVariablesOfVariableDeclarationFragment(fieldDeclaration, simpleTypeFieldMetadata);
simpleTypeFieldMetadata.setName(getFieldName(fieldDeclaration));
return simpleTypeFieldMetadata;
}
/**
* Process the parameterized type of a {@link FieldDeclaration}.
*
* @param fieldDeclaration - the field declaration.
* @return ParameterizedTypeFieldMetadata.
*/
protected FieldMetadata processParameterizedType( FieldDeclaration fieldDeclaration ) {
ParameterizedType parameterizedType = (ParameterizedType)fieldDeclaration.getType();
Type typeOfParameterizedType = parameterizedType.getType(); // type may be a simple type or a qualified type.
FieldMetadata referenceFieldMetadata = createParameterizedFieldMetadataFrom(typeOfParameterizedType);
// modifiers
processModifiersOfFieldDeclaration(fieldDeclaration, referenceFieldMetadata);
// variables
referenceFieldMetadata.setName(getFieldName(fieldDeclaration));
processVariablesOfVariableDeclarationFragment(fieldDeclaration, referenceFieldMetadata);
return referenceFieldMetadata;
}
protected String getFieldName( FieldDeclaration fieldDeclaration ) {
FieldVisitor visitor = new FieldVisitor();
fieldDeclaration.accept(visitor);
return visitor.name;
}
/**
* Process the primitive type of a {@link FieldDeclaration}.
*
* @param fieldDeclaration - the field declaration.
* @return PrimitiveFieldMetadata.
*/
protected FieldMetadata processPrimitiveType( FieldDeclaration fieldDeclaration ) {
PrimitiveType primitiveType = (PrimitiveType)fieldDeclaration.getType();
FieldMetadata primitiveFieldMetadata = FieldMetadata.primitiveType(primitiveType.getPrimitiveTypeCode().toString());
primitiveFieldMetadata.setName(getFieldName(fieldDeclaration));
// modifiers
processModifiersOfFieldDeclaration(fieldDeclaration, primitiveFieldMetadata);
// variables
processVariablesOfVariableDeclarationFragment(fieldDeclaration, primitiveFieldMetadata);
return primitiveFieldMetadata;
}
/**
* Process modifiers of a {@link FieldDeclaration}
*
* @param fieldDeclaration
* @param fieldMetadata
*/
@SuppressWarnings( "unchecked" )
protected void processModifiersOfFieldDeclaration( FieldDeclaration fieldDeclaration,
FieldMetadata fieldMetadata ) {
List<IExtendedModifier> extendedModifiers = fieldDeclaration.modifiers();
for (IExtendedModifier extendedModifier : extendedModifiers) {
if (extendedModifier.isAnnotation()) {
Annotation annotation = (Annotation)extendedModifier;
fieldMetadata.getAnnotations().add(createAnnotationMetadataFor(annotation));
} else {
Modifier modifier = (Modifier)extendedModifier;
ModifierMetadata modifierMetadata = new ModifierMetadata(modifier.getKeyword().toString());
fieldMetadata.getModifiers().add(modifierMetadata);
}
}
}
/**
* Process modifiers of a {@link MethodDeclaration}.
*
* @param methodDeclaration
* @param methodMetadata
*/
@SuppressWarnings( "unchecked" )
protected void processModifiersOfMethodDeclaration( MethodDeclaration methodDeclaration,
MethodMetadata methodMetadata ) {
List<IExtendedModifier> extendedModifiers = methodDeclaration.modifiers();
for (IExtendedModifier extendedModifier : extendedModifiers) {
if (extendedModifier.isAnnotation()) {
Annotation annotation = (Annotation)extendedModifier;
methodMetadata.getAnnotations().add(createAnnotationMetadataFor(annotation));
} else {
Modifier modifier = (Modifier)extendedModifier;
methodMetadata.getModifiers().add(new ModifierMetadata(modifier.getKeyword().toString()));
}
}
}
/**
* Create a <code>FieldMetadata</code> from a {@link Type} instance.
*
* @param type - The {@link Type}
* @return the specific type of <code>FieldMetadata</code>
*/
protected FieldMetadata createParameterizedFieldMetadataFrom( Type type ) {
FieldMetadata parameterizedTypeFieldMetadata = null;
if (type.isSimpleType()) {
SimpleType simpleType = (SimpleType)type;
parameterizedTypeFieldMetadata = FieldMetadata.parametrizedType(JavaMetadataUtil.getName(simpleType.getName()));
}
// TODO also process QualifiedType
return parameterizedTypeFieldMetadata;
}
/**
* Process variables of a {@link VariableDeclarationFragment}.
*
* @param fieldDeclaration - the {@link FieldDeclaration}
* @param fieldMetadata - where to transfer the meta data.
*/
@SuppressWarnings( "unchecked" )
protected void processVariablesOfVariableDeclarationFragment( FieldDeclaration fieldDeclaration,
FieldMetadata fieldMetadata ) {
List<VariableDeclarationFragment> fragments = fieldDeclaration.fragments();
for (VariableDeclarationFragment fragment : fragments) {
fieldMetadata.getVariables().add(new Variable(JavaMetadataUtil.getName(fragment.getName())));
}
}
class FieldVisitor extends ASTVisitor {
String name;
@Override
public boolean visit( VariableDeclarationFragment node ) {
this.name = node.getName().getFullyQualifiedName();
return super.visit(node);
}
}
}