1 /*
   2  * Copyright (c) 2004, 2007, 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  */
  23 
  24 
  25 import com.sun.mirror.apt.*;
  26 import com.sun.mirror.declaration.*;
  27 import com.sun.mirror.type.*;
  28 import com.sun.mirror.util.*;
  29 
  30 import java.util.Collection;
  31 import java.util.Set;
  32 import java.util.Map;
  33 import java.util.Arrays;
  34 import java.util.Collections;
  35 
  36 
  37 public class Scanner implements AnnotationProcessorFactory {
  38     static class ScannerProc implements AnnotationProcessor {
  39         AnnotationProcessorEnvironment env;
  40         ScannerProc(AnnotationProcessorEnvironment env) {
  41             this.env = env;
  42         }
  43 
  44         static class CountingVisitor extends SimpleDeclarationVisitor {
  45             int count;
  46             CountingVisitor() {
  47                 count = 0;
  48             }
  49 
  50             public void visitDeclaration(Declaration d) {
  51                 count++;
  52 
  53                 Collection<AnnotationMirror> ams = d.getAnnotationMirrors();
  54                 if (ams == null)
  55                     throw new RuntimeException("Declaration " + d +
  56                                                " not annotated with visit order.");
  57                 else {
  58                     if (ams.size() != 1)
  59                         throw new RuntimeException("Declaration " + d +
  60                                                    " has wrong number of declarations.");
  61                     else {
  62                         for(AnnotationMirror am: ams) {
  63                             Map<AnnotationTypeElementDeclaration,AnnotationValue> elementValues = am.getElementValues();
  64                             for(AnnotationTypeElementDeclaration atmd: elementValues.keySet()) {
  65                                 if (!atmd.getDeclaringType().toString().equals("VisitOrder"))
  66                                     throw new RuntimeException("Annotation " + atmd +
  67                                                                " is the wrong type.");
  68                                 else {
  69                                     AnnotationValue av =
  70                                         elementValues.get(atmd);
  71                                     Integer value = (Integer) av.getValue();
  72                                     if (value.intValue() != count)
  73                                         throw new RuntimeException("Expected declaration " + d +
  74                                                                    " to be in position " + count +
  75                                                                    " instead of " + value.intValue());
  76 
  77                                     System.out.println("Declaration " + d +
  78                                                        ": visit order " + value.intValue());
  79                                 }
  80                             }
  81 
  82                         }
  83                     }
  84                 }
  85 
  86             }
  87         }
  88 
  89         public void process() {
  90             for(TypeDeclaration td: env.getSpecifiedTypeDeclarations() ) {
  91                 td.accept(DeclarationVisitors.getSourceOrderDeclarationScanner(new CountingVisitor(),
  92                                                                                DeclarationVisitors.NO_OP));
  93             }
  94         }
  95     }
  96 
  97 
  98     static Collection<String> supportedTypes;
  99     static {
 100         String types[] = {"*"};
 101         supportedTypes = Collections.unmodifiableCollection(Arrays.asList(types));
 102     }
 103 
 104     static Collection<String> supportedOptions;
 105     static {
 106         String options[] = {""};
 107         supportedOptions = Collections.unmodifiableCollection(Arrays.asList(options));
 108     }
 109 
 110     public Collection<String> supportedOptions() {
 111         return supportedOptions;
 112     }
 113 
 114     public Collection<String> supportedAnnotationTypes() {
 115         return supportedTypes;
 116     }
 117 
 118     public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> atds,
 119                                         AnnotationProcessorEnvironment env) {
 120         return new ScannerProc(env);
 121     }
 122 
 123 }