package org.jvnet.jaxb2_commons.plugin.inheritance.util; import japa.parser.ast.type.ClassOrInterfaceType; import japa.parser.ast.type.PrimitiveType; import japa.parser.ast.type.ReferenceType; import japa.parser.ast.type.Type; import japa.parser.ast.type.VoidType; import japa.parser.ast.type.WildcardType; import japa.parser.ast.visitor.GenericVisitorAdapter; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.lang3.Validate; import com.sun.codemodel.JClass; import com.sun.codemodel.JCodeModel; import com.sun.codemodel.JType; public class TypeToJTypeConvertingVisitor extends GenericVisitorAdapter<JType, JCodeModel> { private final Map<String, JClass> knownClasses; public TypeToJTypeConvertingVisitor(Map<String, JClass> knownClasses) { Validate.notNull(knownClasses); this.knownClasses = knownClasses; } @Override public JType visit(VoidType type, JCodeModel codeModel) { return codeModel.VOID; } @Override public JType visit(PrimitiveType type, JCodeModel codeModel) { switch (type.getType()) { case Boolean: return codeModel.BOOLEAN; case Char: return codeModel.CHAR; case Byte: return codeModel.BYTE; case Short: return codeModel.SHORT; case Int: return codeModel.INT; case Long: return codeModel.LONG; case Float: return codeModel.FLOAT; case Double: return codeModel.DOUBLE; default: throw new AssertionError("Unknown primitive type [" + type.getType() + "]"); } } @Override public JType visit(ReferenceType type, JCodeModel codeModel) { final JType referencedType = type.getType().accept(this, codeModel); JType referencedTypeArray = referencedType; for (int index = 0; index < type.getArrayCount(); index++) { referencedTypeArray = referencedTypeArray.array(); } return referencedTypeArray; } @Override public JType visit(WildcardType type, JCodeModel codeModel) { if (type.getExtends() != null) { final ReferenceType _extends = type.getExtends(); final JType boundType = _extends.accept(this, codeModel); if (!(boundType instanceof JClass)) { throw new IllegalArgumentException("Bound type [" + _extends + "]in the wildcard type must be class."); } final JClass boundClass = (JClass) boundType; return boundClass.wildcard(); } else if (type.getSuper() != null) { // TODO throw new IllegalArgumentException( "Wildcard types with super clause are not supported at the moment."); } else { throw new IllegalArgumentException( "Wildcard type must have either extends or super clause."); } } @Override public JType visit(ClassOrInterfaceType type, JCodeModel codeModel) { final String name = getName(type); final JClass knownClass = this.knownClasses.get(name); final JClass jclass = knownClass != null ? knownClass : codeModel .ref(name); final List<Type> typeArgs = type.getTypeArgs(); if (typeArgs == null || typeArgs.isEmpty()) { return jclass; } else { final List<JClass> jtypeArgs = new ArrayList<JClass>( typeArgs.size()); for (Type typeArg : typeArgs) { final JType jtype = typeArg.accept(this, codeModel); if (!(jtype instanceof JClass)) { throw new IllegalArgumentException("Type argument [" + typeArg.toString() + "] is not a class."); } else { jtypeArgs.add((JClass) jtype); } } return jclass.narrow(jtypeArgs); } } private String getName(ClassOrInterfaceType type) { final String name = type.getName(); final ClassOrInterfaceType scope = type.getScope(); if (scope == null) { return name; } else { return getName(scope) + "." + name; } } }