test/tools/javac/processing/model/element/repeatingAnnotations/ElementRepAnnoTester.java

Thu, 25 Jul 2013 11:02:27 +0200

author
jfranck
date
Thu, 25 Jul 2013 11:02:27 +0200
changeset 1918
a218f7befd55
parent 1564
aeadaf905d78
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8007961: javax.lang.model tests for repeating annotations fail in getAnnotationsByType
Reviewed-by: jjg

     1 /*
     2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  */
    24 import java.lang.annotation.Annotation;
    25 import java.util.Arrays;
    26 import java.util.EnumSet;
    27 import java.util.List;
    28 import java.util.Set;
    29 import javax.annotation.processing.*;
    30 import javax.lang.model.element.*;
    31 import javax.lang.model.type.MirroredTypeException;
    32 import javax.lang.model.type.TypeMirror;
    33 import javax.lang.model.util.Elements;
    35 public class ElementRepAnnoTester extends JavacTestingAbstractProcessor {
    36     // All methods to test.
    37     final EnumSet<TestMethod> ALL_TEST_METHODS = EnumSet.allOf(TestMethod.class);
    38     int count = 0;
    39     int error = 0;
    41     public boolean process(Set<? extends TypeElement> annotations,
    42             RoundEnvironment roundEnv) {
    43         if (!roundEnv.processingOver()) {
    44             List<String> superClass = Arrays.asList("A", "B", "C", "D", "E",
    45                     "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P");
    46             // Go through all test classes
    47             for (Element element : roundEnv.getRootElements()) {
    48                 // For now, no testing super classes (TODO)
    49                 if (element.getKind() == ElementKind.CLASS
    50                         && !superClass.contains(element.getSimpleName().toString())) {
    51                     // Compare expected and actual values from methods.
    52                     checkAnnoValues(element, ALL_TEST_METHODS);
    53                     // Now, look for enclosed elements in test classes.
    54                     for (Element elements : element.getEnclosedElements()) {
    55                         // Look for Methods annotations.
    56                         if (elements.getKind() == ElementKind.METHOD
    57                                 && elements.getSimpleName().toString().equals("testMethod")) {
    58                             checkAnnoValues(elements, ALL_TEST_METHODS);
    59                         }
    60                         // Look for Field annotations.
    61                         if (elements.getKind() == ElementKind.FIELD
    62                                 && elements.getSimpleName().toString().equals("testField")) {
    63                             checkAnnoValues(elements, ALL_TEST_METHODS);
    64                         }
    65                     }
    66                 }
    67             }
    69             if (error != 0) {
    70                 System.out.println("Total tests : " + count);
    71                 System.out.println("Total test failures : " + error);
    72                 throw new RuntimeException();
    73             } else {
    74                 System.out.println("ALL TESTS PASSED. " + count);
    75             }
    76         }
    77         return true;
    78     }
    80     enum TestMethod {
    81         getAnnotation,
    82         getAnnotationsByType,
    83         getAllAnnotationMirrors,
    84         getAnnotationMirrors
    85     }
    87     protected void checkAnnoValues(Element element, EnumSet<TestMethod> testMethods) {
    88         boolean baseAnnoPresent = false;
    89         boolean conAnnoPresent = false;
    90         ExpectedBase eb = null;
    91         ExpectedContainer ec = null;
    92         // Getting the expected values to compare with.
    93         eb = element.getAnnotation(ExpectedBase.class);
    94         ec = element.getAnnotation(ExpectedContainer.class);
    96         if (eb == null) {
    97             System.out.println("Did not find ExpectedBase Annotation in  "
    98                     + element.getSimpleName().toString() + ", Test will exit");
    99             throw new RuntimeException();
   100         }
   101         if (ec == null) {
   102             System.out.println("Did not find ExpectedContainer Annotation in "
   103                     + element.getSimpleName().toString() + " Test will exit");
   104             throw new RuntimeException();
   105         }
   106         // Look if all test cases have ExpectedBase and ExpectedContainer values().
   107         TypeMirror valueBase = null;
   108         TypeMirror valueCon = null;
   110         try {
   111             eb.value();
   112         } catch (MirroredTypeException mte) {
   113             valueBase = mte.getTypeMirror();
   114         }
   116         try {
   117             ec.value();
   118         } catch (MirroredTypeException mte1) {
   119             valueCon = mte1.getTypeMirror();
   120         }
   122         String expectedBaseAnno = valueBase.toString();
   123         String expectedConAnno = valueCon.toString();
   125         if (!expectedBaseAnno.equals("java.lang.annotation.Annotation")) {
   126             baseAnnoPresent = true;
   127         }
   128         if (!expectedConAnno.equalsIgnoreCase("java.lang.annotation.Annotation")) {
   129             conAnnoPresent = true;
   130         }
   132         // Look into TestMethod and compare method's output with expected values.
   133         for (TestMethod testMethod : testMethods) {
   134             boolean isBasePass = true;
   135             boolean isConPass = true;
   137             switch (testMethod) {
   138                 case getAnnotation:
   139                     if (baseAnnoPresent) {
   140                         count++;
   141                         Annotation actualAnno = getAnnotationBase(element);
   142                         String expectedAnno = eb.getAnnotation();
   143                         isBasePass = compareAnnotation(actualAnno, expectedAnno);
   144                     }
   145                     if (conAnnoPresent) {
   146                         count++;
   147                         Annotation actualAnno = getAnnotationContainer(element);
   148                         String expectedAnno = ec.getAnnotation();
   149                         isConPass = compareAnnotation(actualAnno, expectedAnno);
   150                     }
   151                     if (!isBasePass || !isConPass) {
   152                         System.out.println("FAIL in " + element.getSimpleName()
   153                                 + "-" + element.getKind()
   154                                 + " method: getAnnotation(class <T>)");
   155                         error++;
   156                     }
   157                     break;
   159                 case getAnnotationMirrors:
   160                     if (baseAnnoPresent) {
   161                         count++;
   162                         List<? extends AnnotationMirror> actualDeclAnnos =
   163                                 element.getAnnotationMirrors();
   164                         String[] expectedAnnos = eb.getAnnotationMirrors();
   165                         isBasePass = compareArrVals(actualDeclAnnos, expectedAnnos);
   166                     }
   167                     if (conAnnoPresent) {
   168                         isConPass = true;
   169                     }
   170                     if (!isBasePass || !isConPass) {
   171                         System.out.println("FAIL in " + element.getSimpleName()
   172                                 + "-" + element.getKind()
   173                                 + " method: getAnnotationMirrors()");
   174                         error++;
   175                     }
   176                     break;
   178                 case getAnnotationsByType:
   179                     if (baseAnnoPresent) {
   180                         count++;
   181                         Annotation[] actualAnnosArgs = getAnnotationsBase(element);
   182                         String[] expectedAnnos = eb.getAnnotationsByType();
   183                         isBasePass = compareArrVals(actualAnnosArgs, expectedAnnos);
   184                     }
   185                     if (conAnnoPresent) {
   186                         count++;
   187                         Annotation[] actualAnnosArgs = getAnnotationsContainer(element);
   188                         String[] expectedAnnos = ec.getAnnotationsByType();
   189                         isConPass = compareArrVals(actualAnnosArgs, expectedAnnos);
   190                     }
   191                     if (!isBasePass || !isConPass) {
   192                         System.out.println("FAIL in " + element.getSimpleName()
   193                                 + "-" + element.getKind()
   194                                 + " method: getAnnotationsByType(class <T>)");
   195                         error++;
   196                     }
   197                     break;
   199                 case getAllAnnotationMirrors:
   200                     if (baseAnnoPresent) {
   201                         count++;
   202                         Elements elements = processingEnv.getElementUtils();
   203                         List<? extends AnnotationMirror> actualAnnosMirrors =
   204                                 elements.getAllAnnotationMirrors(element);
   205                         String[] expectedAnnos = eb.getAllAnnotationMirrors();
   206                         isBasePass = compareArrVals(actualAnnosMirrors, expectedAnnos);
   207                     }
   208                     if (conAnnoPresent) {
   209                         isConPass = true;
   210                     }
   211                     if (!isBasePass || !isConPass) {
   212                         System.out.println("FAIL in " + element.getSimpleName()
   213                                 + "-" + element.getKind()
   214                                 + " method: getAllAnnotationMirrors(e)");
   215                         error++;
   216                     }
   217                     break;
   218             }
   219         }
   220     }
   221     // Sort tests to be run with different anno processors.
   222     final List<String> singularAnno = Arrays.asList(
   223             "SingularBasicTest"
   224             );
   225     final List<String> singularInheritedAnno = Arrays.asList(
   226             "SingularInheritedATest"
   227             );
   228     final List<String> repeatableAnno = Arrays.asList(
   229             "RepeatableBasicTest",
   230             "MixRepeatableAndOfficialContainerBasicTest",
   231             "OfficialContainerBasicTest",
   232             "RepeatableOfficialContainerBasicTest"
   233             );
   234     final List<String> repeatableInheritedAnno = Arrays.asList(
   235             "RepeatableInheritedTest",
   236             "RepeatableOverrideATest",
   237             "RepeatableOverrideBTest",
   238             "OfficialContainerInheritedTest",
   239             "MixRepeatableAndOfficialContainerInheritedA1Test",
   240             "MixRepeatableAndOfficialContainerInheritedB1Test",
   241             "MixRepeatableAndOfficialContainerInheritedA2Test",
   242             "MixRepeatableAndOfficialContainerInheritedB2Test"
   243             );
   244     final List<String> repeatableContainerInheritedAnno = Arrays.asList(
   245             "RepeatableOfficialContainerInheritedTest"
   246             );
   247     final List<String> unofficialAnno = Arrays.asList(
   248             "UnofficialContainerBasicTest",
   249             "MixSingularAndUnofficialContainerBasicTest"
   250             );
   251     final List<String> unofficialInheritedAnno = Arrays.asList(
   252             "UnofficialContainerInheritedTest",
   253             "SingularInheritedBTest",
   254             "MixSingularAndUnofficialContainerInheritedA1Test",
   255             "MixSingularAndUnofficialContainerInheritedB1Test",
   256             "MixSingularAndUnofficialContainerInheritedA2Test",
   257             "MixSingularAndUnofficialContainerInheritedB2Test"
   258             );
   259     // Respective container annotation for the different test cases to test.
   260     final List<String> repeatableAnnoContainer = repeatableAnno;
   261     final List<String> repeatableInheritedAnnoContainer = repeatableInheritedAnno;
   262     final List<String> repeatableContainerInheritedAnnoContainer =
   263             repeatableContainerInheritedAnno;
   264     final List<String> unofficialAnnoContainer = unofficialAnno;
   265     final List<String> unofficialInheritedAnnoContainer = unofficialInheritedAnno;
   267     // Variables to verify if all test cases have been run.
   268     private Annotation specialAnno = new Annotation() {
   269        @Override
   270         public Class annotationType() {
   271             return null;
   272         }
   273     };
   274     private Annotation[] specialAnnoArray = new Annotation[1];
   275     private List<AnnotationMirror> specialAnnoMirrors =
   276             new java.util.ArrayList<AnnotationMirror>(2);
   278     private Annotation getAnnotationBase(Element e) {
   279         Annotation actualAnno = specialAnno;
   281         if (singularAnno.contains(
   282                 e.getEnclosingElement().toString())
   283                 || singularAnno.contains(
   284                 e.getSimpleName().toString())
   285                 || unofficialAnno.contains(
   286                 e.getEnclosingElement().toString())
   287                 || unofficialAnno.contains(
   288                 e.getSimpleName().toString())) {
   289             actualAnno = e.getAnnotation(Foo.class);
   290         }
   291         if (singularInheritedAnno.contains(
   292                 e.getEnclosingElement().toString())
   293                 || singularInheritedAnno.contains(
   294                 e.getSimpleName().toString())
   295                 || unofficialInheritedAnno.contains(
   296                 e.getEnclosingElement().toString())
   297                 || unofficialInheritedAnno.contains(
   298                 e.getSimpleName().toString())) {
   299             actualAnno = e.getAnnotation(FooInherited.class);
   300         }
   301         if (repeatableAnno.contains(
   302                 e.getEnclosingElement().toString())
   303                 || repeatableAnno.contains(
   304                 e.getSimpleName().toString())) {
   305             actualAnno = e.getAnnotation(Bar.class);
   306         }
   307         if (repeatableInheritedAnno.contains(
   308                 e.getEnclosingElement().toString())
   309                 || repeatableInheritedAnno.contains(
   310                 e.getSimpleName().toString())) {
   311             actualAnno = e.getAnnotation(BarInherited.class);
   312         }
   313         if (repeatableContainerInheritedAnno.contains(
   314                 e.getEnclosingElement().toString())
   315                 || repeatableContainerInheritedAnno.contains(
   316                 e.getSimpleName().toString())) {
   317             actualAnno = e.getAnnotation(BarInheritedContainer.class);
   318         }
   319         return actualAnno;
   320     }
   322     private Annotation getAnnotationContainer(Element e) {
   323         Annotation actualAnno = specialAnno;
   325         if (repeatableAnnoContainer.contains(
   326                 e.getEnclosingElement().toString())
   327                 || repeatableAnnoContainer.contains(
   328                 e.getSimpleName().toString())) {
   329             actualAnno = e.getAnnotation(BarContainer.class);
   330         }
   331         if (repeatableInheritedAnnoContainer.contains(
   332                 e.getEnclosingElement().toString())
   333                 || repeatableInheritedAnnoContainer.contains(
   334                 e.getSimpleName().toString())) {
   335             actualAnno = e.getAnnotation(BarInheritedContainer.class);
   336         }
   337         if (repeatableContainerInheritedAnnoContainer.contains(
   338                 e.getEnclosingElement().toString())
   339                 || repeatableContainerInheritedAnnoContainer.contains(
   340                 e.getSimpleName().toString())) {
   341             actualAnno = e.getAnnotation(BarInheritedContainerContainer.class);
   342         }
   343         if (unofficialAnnoContainer.contains(
   344                 e.getEnclosingElement().toString())
   345                 || unofficialAnnoContainer.contains(
   346                 e.getSimpleName().toString())) {
   347             actualAnno = e.getAnnotation(UnofficialContainer.class);
   348         }
   349         if (unofficialInheritedAnnoContainer.contains(
   350                 e.getEnclosingElement().toString())
   351                 || unofficialInheritedAnnoContainer.contains(
   352                 e.getSimpleName().toString())) {
   353             actualAnno = e.getAnnotation(UnofficialInheritedContainer.class);
   354         }
   355         return actualAnno;
   356     }
   358     private Annotation[] getAnnotationsBase(Element e) {
   359         Annotation[] actualAnnosArgs = specialAnnoArray;
   361         if (singularAnno.contains(
   362                 e.getEnclosingElement().toString())
   363                 || singularAnno.contains(
   364                 e.getSimpleName().toString())
   365                 || unofficialAnno.contains(
   366                 e.getEnclosingElement().toString())
   367                 || unofficialAnno.contains(
   368                 e.getSimpleName().toString())) {
   369             actualAnnosArgs = e.getAnnotationsByType(Foo.class);
   370         }
   371         if (singularInheritedAnno.contains(
   372                 e.getEnclosingElement().toString())
   373                 || singularInheritedAnno.contains(
   374                 e.getSimpleName().toString())
   375                 || unofficialInheritedAnno.contains(
   376                 e.getEnclosingElement().toString())
   377                 || unofficialInheritedAnno.contains(
   378                 e.getSimpleName().toString())) {
   379             actualAnnosArgs = e.getAnnotationsByType(FooInherited.class);
   380         }
   381         if (repeatableAnno.contains(
   382                 e.getEnclosingElement().toString())
   383                 || repeatableAnno.contains(
   384                 e.getSimpleName().toString())) {
   385             actualAnnosArgs = e.getAnnotationsByType(Bar.class);
   386         }
   387         if (repeatableInheritedAnno.contains(
   388                 e.getEnclosingElement().toString())
   389                 || repeatableInheritedAnno.contains(
   390                 e.getSimpleName().toString())) {
   391             actualAnnosArgs = e.getAnnotationsByType(BarInherited.class);
   392         }
   393         if (repeatableContainerInheritedAnno.contains(
   394                 e.getEnclosingElement().toString())
   395                 || repeatableContainerInheritedAnno.contains(
   396                 e.getSimpleName().toString())) {
   397             actualAnnosArgs = e.getAnnotationsByType(BarInheritedContainer.class);
   398         }
   399         return actualAnnosArgs;
   400     }
   402     private Annotation[] getAnnotationsContainer(Element e) {
   403         Annotation[] actualAnnosArgs = specialAnnoArray;
   405         if (repeatableAnnoContainer.contains(
   406                 e.getEnclosingElement().toString())
   407                 || repeatableAnnoContainer.contains(
   408                 e.getSimpleName().toString())) {
   409             actualAnnosArgs = e.getAnnotationsByType(BarContainer.class);
   410         }
   411         if (repeatableInheritedAnnoContainer.contains(
   412                 e.getEnclosingElement().toString())
   413                 || repeatableInheritedAnnoContainer.contains(
   414                 e.getSimpleName().toString())) {
   415             actualAnnosArgs = e.getAnnotationsByType(BarInheritedContainer.class);
   416         }
   417         if (repeatableContainerInheritedAnnoContainer.contains(
   418                 e.getEnclosingElement().toString())
   419                 || repeatableContainerInheritedAnnoContainer.contains(
   420                 e.getSimpleName().toString())) {
   421             actualAnnosArgs = e.getAnnotationsByType(BarInheritedContainerContainer.class);
   422         }
   423         if (unofficialAnnoContainer.contains(
   424                 e.getEnclosingElement().toString())
   425                 || unofficialAnnoContainer.contains(
   426                 e.getSimpleName().toString())) {
   427             actualAnnosArgs = e.getAnnotationsByType(UnofficialContainer.class);
   428         }
   429         if (unofficialInheritedAnnoContainer.contains(
   430                 e.getEnclosingElement().toString())
   431                 || unofficialInheritedAnnoContainer.contains(
   432                 e.getSimpleName().toString())) {
   433             actualAnnosArgs = e.getAnnotationsByType(UnofficialInheritedContainer.class);
   434         }
   435         return actualAnnosArgs;
   436     }
   438     // Array comparison: Length should be same and all expected values
   439     // should be present in actualAnnos[].
   440     private boolean compareArrVals(Annotation[] actualAnnos, String[] expectedAnnos) {
   441         // Look if test case was run.
   442         if (actualAnnos == specialAnnoArray) {
   443             return false; // no testcase matches
   444         }
   445         if (actualAnnos.length != expectedAnnos.length) {
   446             System.out.println("Length not same. "
   447                     + " actualAnnos length = " + actualAnnos.length
   448                     + " expectedAnnos length = " + expectedAnnos.length);
   449             printArrContents(actualAnnos);
   450             printArrContents(expectedAnnos);
   451             return false;
   452         } else {
   453             int i = 0;
   454             String[] actualArr = new String[actualAnnos.length];
   455             for (Annotation a : actualAnnos) {
   456                 actualArr[i++] = a.toString();
   457             }
   458             List<String> actualList = Arrays.asList(actualArr);
   459             List<String> expectedList = Arrays.asList(expectedAnnos);
   461             if (!actualList.containsAll(expectedList)) {
   462                 System.out.println("Array values are not same");
   463                 printArrContents(actualAnnos);
   464                 printArrContents(expectedAnnos);
   465                 return false;
   466             }
   467         }
   468         return true;
   469     }
   471     // Array comparison: Length should be same and all expected values
   472     // should be present in actualAnnos List<?>.
   473     private boolean compareArrVals(List<? extends AnnotationMirror> actualAnnos,
   474             String[] expectedAnnos) {
   475         // Look if test case was run.
   476         if (actualAnnos == specialAnnoMirrors) {
   477             return false; //no testcase run
   478         }
   479         if (actualAnnos.size() != expectedAnnos.length) {
   480             System.out.println("Length not same. "
   481                     + " actualAnnos length = " + actualAnnos.size()
   482                     + " expectedAnnos length = " + expectedAnnos.length);
   483             printArrContents(actualAnnos);
   484             printArrContents(expectedAnnos);
   485             return false;
   486         } else {
   487             int i = 0;
   488             String[] actualArr = new String[actualAnnos.size()];
   489             String annoTypeName = "";
   490             for (AnnotationMirror annotationMirror : actualAnnos) {
   491                 if (annotationMirror.getAnnotationType().toString().contains("Expected")) {
   492                     annoTypeName = annotationMirror.getAnnotationType().toString();
   493                 } else {
   494                      annoTypeName = annotationMirror.toString();
   495                 }
   496                 actualArr[i++] = annoTypeName;
   497             }
   498             List<String> actualList = Arrays.asList(actualArr);
   499             List<String> expectedList = Arrays.asList(expectedAnnos);
   501             if (!actualList.containsAll(expectedList)) {
   502                 System.out.println("Array values are not same");
   503                 printArrContents(actualAnnos);
   504                 printArrContents(expectedAnnos);
   505                 return false;
   506             }
   507         }
   508         return true;
   509     }
   511     private void printArrContents(Annotation[] actualAnnos) {
   512         for (Annotation a : actualAnnos) {
   513             System.out.println("actualAnnos values = " + a);
   514         }
   515     }
   517     private void printArrContents(String[] expectedAnnos) {
   518         for (String s : expectedAnnos) {
   519             System.out.println("expectedAnnos values =  " + s);
   520         }
   521     }
   523     private void printArrContents(List<? extends AnnotationMirror> actualAnnos) {
   524         for (AnnotationMirror annotationMirror : actualAnnos) {
   525             System.out.println("actualAnnos values = " + annotationMirror);
   526         }
   527     }
   529     private boolean compareAnnotation(Annotation actualAnno, String expectedAnno) {
   530         //String actualAnnoName = "";
   531         boolean isSame = true;
   532         // Look if test case was run.
   533         if (actualAnno == specialAnno) {
   534             return false; //no testcase run
   535         }
   536         if (actualAnno != null) {
   537             if (!actualAnno.toString().equalsIgnoreCase(expectedAnno)) {
   538                 System.out.println("Anno did not match. "
   539                         + " expectedAnno = " + expectedAnno
   540                         + " actualAnno = " + actualAnno);
   541                 isSame = false;
   542             } else {
   543                 isSame = true;
   544             }
   545         } else {
   546             if (expectedAnno.compareToIgnoreCase("null") == 0) {
   547                 isSame = true;
   548             } else {
   549                 System.out.println("Actual anno is null");
   550                 isSame = false;
   551             }
   552         }
   553         return isSame;
   554     }
   555 }

mercurial