2323import java .util .Stack ;
2424import java .util .regex .Pattern ;
2525
26+ import javax .xml .bind .annotation .XmlElement ;
27+
2628import org .eclipse .jdt .core .IJavaProject ;
2729import org .eclipse .jdt .core .IType ;
2830import org .eclipse .jdt .core .dom .ASTNode ;
6567import org .eclipse .jdt .core .dom .FieldDeclaration ;
6668import org .eclipse .jdt .core .dom .ForStatement ;
6769import org .eclipse .jdt .core .dom .IBinding ;
70+ import org .eclipse .jdt .core .dom .IMemberValuePairBinding ;
6871import org .eclipse .jdt .core .dom .IMethodBinding ;
6972import org .eclipse .jdt .core .dom .ITypeBinding ;
7073import org .eclipse .jdt .core .dom .IVariableBinding ;
@@ -223,6 +226,7 @@ public class Java2ScriptVisitor extends ASTVisitor {
223226 final static int JAXB_TYPE_FIELD = 1 ;
224227 final static int JAXB_TYPE_PUBLIC_MEMBER = 2 ;
225228 final static int JAXB_TYPE_PROPERTY = 3 ;
229+ static final int JAXB_TYPE_ENUM = 4 ;
226230
227231
228232 private IJavaProject global_project ;
@@ -1946,12 +1950,13 @@ private void addClassOrInterface(ASTNode node, ITypeBinding binding, List<?> bod
19461950 }
19471951 }
19481952 }
1953+ List <EnumConstantDeclaration > enums = (isEnum ? new ArrayList <>(): null );
19491954 if (lstStatic .size () > 0 || hasDependents ) {
19501955 int pt = buffer .length ();
19511956 buffer .append ("\r \n C$.$clinit$ = function() {Clazz.load(C$, 1);\r \n " );
19521957 boolean haveDeclarations = isEnum ;
19531958 if (isEnum )
1954- addEnumConstants ((EnumDeclaration ) node );
1959+ addEnumConstants ((EnumDeclaration ) node , enums );
19551960 for (int i = lstStatic .size (); --i >= 0 ;) {
19561961 BodyDeclaration element = lstStatic .remove (0 );
19571962 if (element instanceof Initializer ) {
@@ -2085,7 +2090,7 @@ && checkAnnotations(element, CHECK_J2S_IGNORE_AND_ANNOTATIONS)) {
20852090 // and Enum constants
20862091
20872092 if (class_jaxbAccessorType != JAXB_TYPE_UNKNOWN ) {
2088- ClassAnnotation .addClassAnnotations (class_jaxbAccessorType , class_annotations , fields , methods , trailingBuffer );
2093+ ClassAnnotation .addClassAnnotations (class_jaxbAccessorType , class_annotations , enums , fields , methods , trailingBuffer );
20892094 class_annotations = null ;
20902095 class_jaxbAccessorType = JAXB_TYPE_UNKNOWN ;
20912096 }
@@ -2121,22 +2126,22 @@ && checkAnnotations(element, CHECK_J2S_IGNORE_AND_ANNOTATIONS)) {
21212126 }
21222127 }
21232128
2124- private boolean checkDeclarationType (BodyDeclaration element , int type ) {
2125- switch (class_jaxbAccessorType ) {
2126- case JAXB_TYPE_FIELD :
2127- case JAXB_TYPE_PROPERTY :
2128- return (type == class_jaxbAccessorType );
2129- case JAXB_TYPE_NONE :
2130- case JAXB_TYPE_PUBLIC_MEMBER :
2131- return true ;
2132- // can't check here, because if just one of set or get is annotated,
2133- // then it doesn't matter if either is public or not
2134- // return Modifier.isPublic(element.getModifiers());
2135- default :
2136- case JAXB_TYPE_UNKNOWN :
2137- return false ;
2138- }
2139- }
2129+ // private boolean checkDeclarationType(BodyDeclaration element, int type) {
2130+ // switch (class_jaxbAccessorType) {
2131+ // case JAXB_TYPE_FIELD:
2132+ // case JAXB_TYPE_PROPERTY:
2133+ // return (type == class_jaxbAccessorType);
2134+ // case JAXB_TYPE_NONE:
2135+ // case JAXB_TYPE_PUBLIC_MEMBER:
2136+ // return true;
2137+ // // can't check here, because if just one of set or get is annotated,
2138+ // // then it doesn't matter if either is public or not
2139+ //// return Modifier.isPublic(element.getModifiers());
2140+ // default:
2141+ // case JAXB_TYPE_UNKNOWN:
2142+ // return false;
2143+ // }
2144+ // }
21402145
21412146 /**
21422147 * Collect all names of all functional interface abstract methods that this
@@ -2186,11 +2191,12 @@ private void addDefaultConstructor() {
21862191 * @param constants
21872192 */
21882193
2189- private void addEnumConstants (EnumDeclaration e ) {
2194+ private void addEnumConstants (EnumDeclaration e , List < EnumConstantDeclaration > enums ) {
21902195 List <?> constants = e .enumConstants ();
21912196 buffer .append ("$vals=Clazz.array(C$,[0]);\r \n " );
21922197 for (int i = 0 ; i < constants .size (); i ++) {
21932198 EnumConstantDeclaration enumConst = (EnumConstantDeclaration ) constants .get (i );
2199+ enums .add (enumConst );
21942200 checkAnnotations (enumConst , CHECK_ANNOTATIONS_ONLY ); // for JAXB only
21952201 IMethodBinding binding = enumConst .resolveConstructorBinding ();
21962202 AnonymousClassDeclaration anonDeclare = enumConst .getAnonymousClassDeclaration ();
@@ -5413,7 +5419,8 @@ private boolean addAnnotation(Annotation annotation, ASTNode node, int mode) {
54135419 : s .contains ("PUBLIC" ) ? JAXB_TYPE_PUBLIC_MEMBER
54145420 : s .contains ("PROPERTY" ) ? JAXB_TYPE_PROPERTY
54155421 : JAXB_TYPE_NONE );
5416- }
5422+ } else if (qName .startsWith ("XmlEnum" ))
5423+ class_jaxbAccessorType = JAXB_TYPE_ENUM ;
54175424 }
54185425 return true ;
54195426 }
@@ -5539,7 +5546,7 @@ public List<String> getElementList() {
55395546 private void addDummyClassForPackageOnlyFile () {
55405547 appendElementKey ("_$" );
55415548 buffer .append ("var C$=Clazz.newClass(\" _$\" );\n C$.$clinit$ = function() {Clazz.load(C$, 1)};\n " );
5542- ClassAnnotation .addClassAnnotations (class_jaxbAccessorType , class_annotations , null , null , trailingBuffer );
5549+ ClassAnnotation .addClassAnnotations (class_jaxbAccessorType , class_annotations , null , null , null , trailingBuffer );
55435550 buffer .append (trailingBuffer );
55445551 addDefaultConstructor ();
55455552 }
@@ -6205,7 +6212,7 @@ protected ClassAnnotation(String qName, Annotation annotation, ASTNode node) {
62056212 }
62066213
62076214 @ SuppressWarnings ("unchecked" )
6208- public static void addClassAnnotations (int accessType , List <ClassAnnotation > class_annotations , List <FieldDeclaration > fields ,
6215+ public static void addClassAnnotations (int accessType , List <ClassAnnotation > class_annotations , List <EnumConstantDeclaration > enums , List < FieldDeclaration > fields ,
62096216 List <IMethodBinding > methods , TrailingBuffer trailingBuffer ) {
62106217
62116218 int pt = 0 , ptBuf = 0 ;
@@ -6215,10 +6222,22 @@ public static void addClassAnnotations(int accessType, List<ClassAnnotation> cla
62156222 for (int i = 0 ; i < class_annotations .size (); i ++) {
62166223 ClassAnnotation a = class_annotations .get (i );
62176224 String str = a .annotation .toString ();
6218- if (a .annotation instanceof SingleMemberAnnotation ) {
6219- // resolve classes
6225+ //System.out.println(">>>str " + str);
6226+ //System.out.println(">>>ann " + a.annotation.getClass().getName());
6227+ if (a .annotation instanceof NormalAnnotation ) {
6228+ // @XmlElement(name="test",type=Integer.class)
6229+ // remove commas, add quotes
6230+ NormalAnnotation na = (NormalAnnotation ) a .annotation ;
6231+ IMemberValuePairBinding [] pairs = na .resolveAnnotationBinding ().getDeclaredMemberValuePairs ();
6232+ str = str .substring (0 , str .indexOf ("(" ) + 1 );
6233+ for (int j = 0 ; j < pairs .length ; j ++)
6234+ str += annotationNameValue (pairs [j ].getName (), pairs [j ].getValue ());
6235+ str += ")" ;
6236+ } else if (a .annotation instanceof SingleMemberAnnotation ) {
6237+ // add quotes
62206238 List <ASTNode > expressions = null ;
62216239 Expression e = ((SingleMemberAnnotation ) a .annotation ).getValue ();
6240+ //System.out.println(">>>e " + e.getClass().getName());
62226241 if (e instanceof TypeLiteral ) {
62236242 expressions = new ArrayList <ASTNode >();
62246243 expressions .add (e );
@@ -6230,13 +6249,7 @@ public static void addClassAnnotations(int accessType, List<ClassAnnotation> cla
62306249 int n = expressions .size ();
62316250 String sep = (n > 1 ? "{" : "" );
62326251 for (int j = 0 ; j < n ; j ++) {
6233- str += sep ;
6234- e = (Expression ) expressions .get (j );
6235- if (e instanceof TypeLiteral ) {
6236- str += "\" " +((TypeLiteral ) e ).getType ().resolveBinding ().getQualifiedName () + ".class\" " ;
6237- } else {
6238- str += e .toString ();
6239- }
6252+ str += sep + annotationNameValue (null , expressions .get (j ));
62406253 sep = "," ;
62416254 }
62426255 str += (n > 1 ? "})" : ")" );
@@ -6275,6 +6288,7 @@ public static void addClassAnnotations(int accessType, List<ClassAnnotation> cla
62756288 type = var .getReturnType ();
62766289 } else if (a .node instanceof EnumConstantDeclaration ) {
62776290 EnumConstantDeclaration con = (EnumConstantDeclaration ) a .node ;
6291+ enums .remove (con );
62786292 IVariableBinding var = con .resolveVariable ();
62796293 varName = var .getName ();
62806294 type = var .getType ();
@@ -6297,11 +6311,31 @@ public static void addClassAnnotations(int accessType, List<ClassAnnotation> cla
62976311 }
62986312 if (pt > 0 ) {
62996313 addTrailingFragments (fragments , trailingBuffer , ptBuf );
6300- addImplicitJAXBFieldsAndMethods (accessType , trailingBuffer , fields , methods , propOrder );
6314+ addImplicitJAXBFieldsAndMethods (accessType , trailingBuffer , enums , fields , methods , propOrder );
63016315 trailingBuffer .append ("]]];\n " );
63026316 }
63036317 }
63046318
6319+ private static String annotationNameValue (String name , Object value ) {
6320+ String str = (name == null ? "" : name + "=" );
6321+ if (value instanceof TypeLiteral ) {
6322+ str += "\" " + ((TypeLiteral ) value ).getType ().resolveBinding ().getQualifiedName () + ".class\" " ;
6323+ } else if (value instanceof ITypeBinding ) {
6324+ str += "\" " + ((ITypeBinding ) value ).getQualifiedName () + ".class\" " ;
6325+ } else if (value instanceof Object []){
6326+ // propOrder
6327+ Object [] o = (Object [])value ;
6328+ str += "{" ;
6329+ for (int i = 0 ; i < o .length ; i ++)
6330+ str += annotationNameValue (null , o [i ]) + " " ;
6331+ str += "}" ;
6332+ } else {
6333+ str += "\" " + value .toString () + "\" " ;
6334+ }
6335+ str += " " ;
6336+ return str ;
6337+ }
6338+
63056339 private static IMethodBinding getJAXBGetMethod (IMethodBinding var , List <IMethodBinding > methods , boolean returnVar2 ) {
63066340 String varName = var .getName ();
63076341 // check for matching get/is and set
@@ -6314,7 +6348,17 @@ private static IMethodBinding getJAXBGetMethod(IMethodBinding var, List<IMethodB
63146348 }
63156349
63166350 private static void addImplicitJAXBFieldsAndMethods (int accessType , TrailingBuffer trailingBuffer ,
6317- List <FieldDeclaration > fields , List <IMethodBinding > methods , String propOrder ) {
6351+ List <EnumConstantDeclaration > enums , List <FieldDeclaration > fields , List <IMethodBinding > methods , String propOrder ) {
6352+ if (accessType == JAXB_TYPE_ENUM ) {
6353+ for (int j = 0 ; j < enums .size (); j ++) {
6354+ EnumConstantDeclaration con = enums .get (j );
6355+ IVariableBinding var = con .resolveVariable ();
6356+ String varName = var .getName ();
6357+ ITypeBinding type = var .getType ();
6358+ addAnnotation (type , varName , "@XmlEnumValue" , trailingBuffer );
6359+ }
6360+ return ;
6361+ }
63186362 if (accessType == JAXB_TYPE_NONE || fields == null )
63196363 return ;
63206364 boolean publicOnly = (accessType == JAXB_TYPE_PUBLIC_MEMBER );
0 commit comments