Validate.notNull(
compilationUnit.getImports(),
"Compilation unit imports should be non-null when producing type '%s'",
cid.getName());
for (final ImportMetadata importType : cid.getRegisteredImports()) {
ImportDeclaration importDeclaration;
if (!importType.isAsterisk()) {
NameExpr typeToImportExpr;
if (importType.getImportType().getEnclosingType() == null) {
typeToImportExpr = new QualifiedNameExpr(new NameExpr(
importType.getImportType().getPackage()
.getFullyQualifiedPackageName()),
importType.getImportType().getSimpleTypeName());
}
else {
typeToImportExpr = new QualifiedNameExpr(new NameExpr(
importType.getImportType().getEnclosingType()
.getFullyQualifiedTypeName()), importType
.getImportType().getSimpleTypeName());
}
importDeclaration = new ImportDeclaration(typeToImportExpr,
importType.isStatic(), false);
}
else {
importDeclaration = new ImportDeclaration(new NameExpr(
importType.getImportPackage()
.getFullyQualifiedPackageName()),
importType.isStatic(), importType.isAsterisk());
}
JavaParserCommentMetadataBuilder.updateCommentsToJavaParser(
importDeclaration, importType.getCommentStructure());
compilationUnit.getImports().add(importDeclaration);
}
// Create a class or interface declaration to represent this actual type
final int javaParserModifier = JavaParserUtils
.getJavaParserModifier(cid.getModifier());
TypeDeclaration typeDeclaration;
ClassOrInterfaceDeclaration classOrInterfaceDeclaration;
// Implements handling
final List<ClassOrInterfaceType> implementsList = new ArrayList<ClassOrInterfaceType>();
for (final JavaType current : cid.getImplementsTypes()) {
implementsList.add(JavaParserUtils.getResolvedName(cid.getName(),
current, compilationUnit));
}
if (cid.getPhysicalTypeCategory() == PhysicalTypeCategory.INTERFACE
|| cid.getPhysicalTypeCategory() == PhysicalTypeCategory.CLASS) {
final boolean isInterface = cid.getPhysicalTypeCategory() == PhysicalTypeCategory.INTERFACE;
if (parent == null) {
// Top level type
typeDeclaration = new ClassOrInterfaceDeclaration(
javaParserModifier, isInterface, cid
.getName()
.getNameIncludingTypeParameters()
.replace(
cid.getName().getPackage()
.getFullyQualifiedPackageName()
+ ".", ""));
classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) typeDeclaration;
}
else {
// Inner type
typeDeclaration = new ClassOrInterfaceDeclaration(
javaParserModifier, isInterface, cid.getName()
.getSimpleTypeName());
classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration) typeDeclaration;
if (cid.getName().getParameters().size() > 0) {
classOrInterfaceDeclaration
.setTypeParameters(new ArrayList<TypeParameter>());
for (final JavaType param : cid.getName().getParameters()) {
NameExpr pNameExpr = JavaParserUtils
.importTypeIfRequired(cid.getName(),
compilationUnit.getImports(), param);
final String tempName = StringUtils.replace(
pNameExpr.toString(), param.getArgName()
+ " extends ", "", 1);
pNameExpr = new NameExpr(tempName);
final ClassOrInterfaceType pResolvedName = JavaParserUtils
.getClassOrInterfaceType(pNameExpr);
classOrInterfaceDeclaration.getTypeParameters().add(
new TypeParameter(param.getArgName()
.getSymbolName(), Collections
.singletonList(pResolvedName)));
}
}
}
// Superclass handling
final List<ClassOrInterfaceType> extendsList = new ArrayList<ClassOrInterfaceType>();
for (final JavaType current : cid.getExtendsTypes()) {
if (!OBJECT.equals(current)) {
extendsList.add(JavaParserUtils.getResolvedName(
cid.getName(), current, compilationUnit));
}
}
if (extendsList.size() > 0) {
classOrInterfaceDeclaration.setExtends(extendsList);
}
// Implements handling
if (implementsList.size() > 0) {
classOrInterfaceDeclaration.setImplements(implementsList);
}
}
else {
typeDeclaration = new EnumDeclaration(javaParserModifier, cid
.getName().getSimpleTypeName());
}
typeDeclaration.setMembers(new ArrayList<BodyDeclaration>());
Validate.notNull(typeDeclaration.getName(),
"Missing type declaration name for '%s'", cid.getName());
// If adding a new top-level type, must add it to the compilation unit
// types
Validate.notNull(
compilationUnit.getTypes(),
"Compilation unit types must not be null when attempting to add '%s'",
cid.getName());
if (parent == null) {
// Top-level class
compilationUnit.getTypes().add(typeDeclaration);
}
else {
// Inner class
parent.add(typeDeclaration);
}
// If the enclosing CompilationUnitServices was not provided a default
// CompilationUnitServices needs to be created
if (enclosingCompilationUnitServices == null) {
// Create a compilation unit so that we can use JavaType*Metadata
// static methods directly
enclosingCompilationUnitServices = new CompilationUnitServices() {
@Override
public JavaPackage getCompilationUnitPackage() {
return cid.getName().getPackage();
}
@Override
public JavaType getEnclosingTypeName() {
return cid.getName();
}
@Override
public List<ImportDeclaration> getImports() {
return compilationUnit.getImports();
}
@Override
public List<TypeDeclaration> getInnerTypes() {
return compilationUnit.getTypes();
}
@Override
public PhysicalTypeCategory getPhysicalTypeCategory() {
return cid.getPhysicalTypeCategory();
}
};
}
final CompilationUnitServices finalCompilationUnitServices = enclosingCompilationUnitServices;
// A hybrid CompilationUnitServices must be provided that references the
// enclosing types imports and package
final CompilationUnitServices compilationUnitServices = new CompilationUnitServices() {
@Override
public JavaPackage getCompilationUnitPackage() {
return finalCompilationUnitServices.getCompilationUnitPackage();
}
@Override
public JavaType getEnclosingTypeName() {
return cid.getName();
}
@Override
public List<ImportDeclaration> getImports() {
return finalCompilationUnitServices.getImports();
}
@Override
public List<TypeDeclaration> getInnerTypes() {
return compilationUnit.getTypes();
}
@Override
public PhysicalTypeCategory getPhysicalTypeCategory() {
return cid.getPhysicalTypeCategory();
}
};
// Add type annotations
final List<AnnotationExpr> annotations = new ArrayList<AnnotationExpr>();
typeDeclaration.setAnnotations(annotations);
for (final AnnotationMetadata candidate : cid.getAnnotations()) {
JavaParserAnnotationMetadataBuilder.addAnnotationToList(
compilationUnitServices, annotations, candidate);
}
// Add enum constants and interfaces
if (typeDeclaration instanceof EnumDeclaration
&& cid.getEnumConstants().size() > 0) {
final EnumDeclaration enumDeclaration = (EnumDeclaration) typeDeclaration;
final List<EnumConstantDeclaration> constants = new ArrayList<EnumConstantDeclaration>();
enumDeclaration.setEntries(constants);
for (final JavaSymbolName constant : cid.getEnumConstants()) {
addEnumConstant(constants, constant);
}
// Implements handling
if (implementsList.size() > 0) {
enumDeclaration.setImplements(implementsList);
}
}
// Add fields
for (final FieldMetadata candidate : cid.getDeclaredFields()) {
JavaParserFieldMetadataBuilder.addField(compilationUnitServices,
typeDeclaration.getMembers(), candidate);
}
// Add constructors
for (final ConstructorMetadata candidate : cid
.getDeclaredConstructors()) {
JavaParserConstructorMetadataBuilder.addConstructor(
compilationUnitServices, typeDeclaration.getMembers(),
candidate, null);
}
// Add methods
for (final MethodMetadata candidate : cid.getDeclaredMethods()) {
JavaParserMethodMetadataBuilder.addMethod(compilationUnitServices,
typeDeclaration.getMembers(), candidate, null);
}
// Add inner types
for (final ClassOrInterfaceTypeDetails candidate : cid
.getDeclaredInnerTypes()) {
updateOutput(compilationUnit, compilationUnitServices, candidate,
typeDeclaration.getMembers());
}
final HashSet<String> imported = new HashSet<String>();
final ArrayList<ImportDeclaration> imports = new ArrayList<ImportDeclaration>();
for (final ImportDeclaration importDeclaration : compilationUnit
.getImports()) {
JavaPackage importPackage = null;
JavaType importType = null;
if (importDeclaration.isAsterisk()) {
importPackage = new JavaPackage(importDeclaration.getName()
.toString());
}
else {
importType = new JavaType(importDeclaration.getName()
.toString());
importPackage = importType.getPackage();
}
if (importPackage.equals(cid.getName().getPackage())
&& importDeclaration.isAsterisk()) {
continue;
}
if (importPackage.equals(cid.getName().getPackage())
&& importType != null
&& importType.getEnclosingType() == null) {
continue;
}
if (importType != null && importType.equals(cid.getName())) {
continue;
}
if (!imported.contains(importDeclaration.getName().toString())) {
imports.add(importDeclaration);
imported.add(importDeclaration.getName().toString());
}
}
Collections.sort(imports, new Comparator<ImportDeclaration>() {
@Override
public int compare(final ImportDeclaration importDeclaration,
final ImportDeclaration importDeclaration1) {
return importDeclaration.getName().toString()
.compareTo(importDeclaration1.getName().toString());
}
});
compilationUnit.setImports(imports);