1 /* 2 * Copyright (c) 2004, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.apt.mirror.apt; 27 28 import com.sun.mirror.declaration.*; 29 import com.sun.mirror.util.*; 30 import com.sun.mirror.apt.*; 31 import com.sun.tools.apt.mirror.apt.*; 32 import com.sun.tools.apt.mirror.declaration.DeclarationMaker; 33 import com.sun.tools.apt.mirror.util.*; 34 import com.sun.tools.apt.util.Bark; 35 import com.sun.tools.javac.util.Context; 36 37 import com.sun.tools.apt.mirror.apt.FilerImpl; 38 import com.sun.tools.apt.mirror.apt.MessagerImpl; 39 import com.sun.tools.apt.mirror.apt.RoundStateImpl; 40 import com.sun.tools.apt.mirror.apt.RoundCompleteEventImpl; 41 42 import com.sun.tools.javac.util.Context; 43 44 import java.util.*; 45 import static com.sun.mirror.util.DeclarationVisitors.*; 46 47 /* 48 * Annotation Processor Environment implementation. 49 */ 50 @SuppressWarnings("deprecation") 51 public class AnnotationProcessorEnvironmentImpl implements AnnotationProcessorEnvironment { 52 53 Collection<TypeDeclaration> spectypedecls; 54 Collection<TypeDeclaration> typedecls; 55 Map<String, String> origOptions; 56 DeclarationMaker declMaker; 57 Declarations declUtils; 58 Types typeUtils; 59 Messager messager; 60 FilerImpl filer; 61 Bark bark; 62 Set<RoundCompleteListener> roundCompleteListeners; 63 64 public AnnotationProcessorEnvironmentImpl(Collection<TypeDeclaration> spectypedecls, 65 Collection<TypeDeclaration> typedecls, 66 Map<String, String> origOptions, 67 Context context) { 68 // Safer to copy collections before applying unmodifiable 69 // wrapper. 70 this.spectypedecls = Collections.unmodifiableCollection(spectypedecls); 71 this.typedecls = Collections.unmodifiableCollection(typedecls); 72 this.origOptions = Collections.unmodifiableMap(origOptions); 73 74 declMaker = DeclarationMaker.instance(context); 75 declUtils = DeclarationsImpl.instance(context); 76 typeUtils = TypesImpl.instance(context); 77 messager = MessagerImpl.instance(context); 78 filer = FilerImpl.instance(context); 79 bark = Bark.instance(context); 80 roundCompleteListeners = new LinkedHashSet<RoundCompleteListener>(); 81 } 82 83 public Map<String,String> getOptions() { 84 return origOptions; 85 } 86 87 public Messager getMessager() { 88 return messager; 89 } 90 91 public Filer getFiler() { 92 return filer; 93 } 94 95 public Collection<TypeDeclaration> getSpecifiedTypeDeclarations() { 96 return spectypedecls; 97 } 98 99 public PackageDeclaration getPackage(String name) { 100 return declMaker.getPackageDeclaration(name); 101 } 102 103 public TypeDeclaration getTypeDeclaration(String name) { 104 return declMaker.getTypeDeclaration(name); 105 } 106 107 public Collection<TypeDeclaration> getTypeDeclarations() { 108 return typedecls; 109 } 110 111 public Collection<Declaration> getDeclarationsAnnotatedWith( 112 AnnotationTypeDeclaration a) { 113 /* 114 * create collection of Declarations annotated with a given 115 * annotation. 116 */ 117 118 CollectingAP proc = new CollectingAP(this, a); 119 proc.process(); 120 return proc.decls; 121 } 122 123 private static class CollectingAP implements AnnotationProcessor { 124 AnnotationProcessorEnvironment env; 125 Collection<Declaration> decls; 126 AnnotationTypeDeclaration atd; 127 CollectingAP(AnnotationProcessorEnvironment env, 128 AnnotationTypeDeclaration atd) { 129 this.env = env; 130 this.atd = atd; 131 decls = new HashSet<Declaration>(); 132 } 133 134 private class CollectingVisitor extends SimpleDeclarationVisitor { 135 public void visitDeclaration(Declaration d) { 136 for(AnnotationMirror am: d.getAnnotationMirrors()) { 137 if (am.getAnnotationType().getDeclaration().equals(CollectingAP.this.atd)) 138 CollectingAP.this.decls.add(d); 139 } 140 } 141 } 142 143 public void process() { 144 for(TypeDeclaration d: env.getSpecifiedTypeDeclarations()) 145 d.accept(getSourceOrderDeclarationScanner(new CollectingVisitor(), 146 NO_OP)); 147 } 148 } 149 150 public Declarations getDeclarationUtils() { 151 return declUtils; 152 } 153 154 public Types getTypeUtils() { 155 return typeUtils; 156 } 157 158 public void addListener(AnnotationProcessorListener listener) { 159 if (listener == null) 160 throw new NullPointerException(); 161 else { 162 if (listener instanceof RoundCompleteListener) 163 roundCompleteListeners.add((RoundCompleteListener)listener); 164 } 165 } 166 167 public void removeListener(AnnotationProcessorListener listener) { 168 if (listener == null) 169 throw new NullPointerException(); 170 else 171 roundCompleteListeners.remove(listener); 172 } 173 174 public void roundComplete() { 175 RoundState roundState = new RoundStateImpl(bark.nerrors > 0, 176 filer.getSourceFileNames().size() > 0, 177 filer.getClassFileNames().size() > 0, 178 origOptions); 179 RoundCompleteEvent roundCompleteEvent = new RoundCompleteEventImpl(this, roundState); 180 181 filer.roundOver(); 182 for(RoundCompleteListener rcl: roundCompleteListeners) 183 rcl.roundComplete(roundCompleteEvent); 184 } 185 }