/*
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.apt.mirror.apt;
import com.sun.mirror.declaration.*;
import com.sun.mirror.util.*;
import com.sun.mirror.apt.*;
import com.sun.tools.apt.mirror.apt.*;
import com.sun.tools.apt.mirror.declaration.DeclarationMaker;
import com.sun.tools.apt.mirror.util.*;
import com.sun.tools.apt.util.Bark;
import com.sun.tools.javac.util.Context;
import com.sun.tools.apt.mirror.apt.FilerImpl;
import com.sun.tools.apt.mirror.apt.MessagerImpl;
import com.sun.tools.apt.mirror.apt.RoundStateImpl;
import com.sun.tools.apt.mirror.apt.RoundCompleteEventImpl;
import com.sun.tools.javac.util.Context;
import java.util.*;
import static com.sun.mirror.util.DeclarationVisitors.*;
/*
* Annotation Processor Environment implementation.
*/
public class AnnotationProcessorEnvironmentImpl implements AnnotationProcessorEnvironment {
Collection<TypeDeclaration> spectypedecls;
Collection<TypeDeclaration> typedecls;
Map<String, String> origOptions;
DeclarationMaker declMaker;
Declarations declUtils;
Types typeUtils;
Messager messager;
FilerImpl filer;
Bark bark;
Set<RoundCompleteListener> roundCompleteListeners;
public AnnotationProcessorEnvironmentImpl(Collection<TypeDeclaration> spectypedecls,
Collection<TypeDeclaration> typedecls,
Map<String, String> origOptions,
Context context) {
// Safer to copy collections before applying unmodifiable
// wrapper.
this.spectypedecls = Collections.unmodifiableCollection(spectypedecls);
this.typedecls = Collections.unmodifiableCollection(typedecls);
this.origOptions = Collections.unmodifiableMap(origOptions);
declMaker = DeclarationMaker.instance(context);
declUtils = DeclarationsImpl.instance(context);
typeUtils = TypesImpl.instance(context);
messager = MessagerImpl.instance(context);
filer = FilerImpl.instance(context);
bark = Bark.instance(context);
roundCompleteListeners = new LinkedHashSet<RoundCompleteListener>();
}
public Map<String,String> getOptions() {
return origOptions;
}
public Messager getMessager() {
return messager;
}
public Filer getFiler() {
return filer;
}
public Collection<TypeDeclaration> getSpecifiedTypeDeclarations() {
return spectypedecls;
}
public PackageDeclaration getPackage(String name) {
return declMaker.getPackageDeclaration(name);
}
public TypeDeclaration getTypeDeclaration(String name) {
return declMaker.getTypeDeclaration(name);
}
public Collection<TypeDeclaration> getTypeDeclarations() {
return typedecls;
}
public Collection<Declaration> getDeclarationsAnnotatedWith(
AnnotationTypeDeclaration a) {
/*
* create collection of Declarations annotated with a given
* annotation.
*/
CollectingAP proc = new CollectingAP(this, a);
proc.process();
return proc.decls;
}
private static class CollectingAP implements AnnotationProcessor {
AnnotationProcessorEnvironment env;
Collection<Declaration> decls;
AnnotationTypeDeclaration atd;
CollectingAP(AnnotationProcessorEnvironment env,
AnnotationTypeDeclaration atd) {
this.env = env;
this.atd = atd;
decls = new HashSet<Declaration>();
}
private class CollectingVisitor extends SimpleDeclarationVisitor {
public void visitDeclaration(Declaration d) {
for(AnnotationMirror am: d.getAnnotationMirrors()) {
if (am.getAnnotationType().getDeclaration().equals(CollectingAP.this.atd))
CollectingAP.this.decls.add(d);
}
}
}
public void process() {
for(TypeDeclaration d: env.getSpecifiedTypeDeclarations())
d.accept(getSourceOrderDeclarationScanner(new CollectingVisitor(),
NO_OP));
}
}
public Declarations getDeclarationUtils() {
return declUtils;
}
public Types getTypeUtils() {
return typeUtils;
}
public void addListener(AnnotationProcessorListener listener) {
if (listener == null)
throw new NullPointerException();
else {
if (listener instanceof RoundCompleteListener)
roundCompleteListeners.add((RoundCompleteListener)listener);
}
}
public void removeListener(AnnotationProcessorListener listener) {
if (listener == null)
throw new NullPointerException();
else
roundCompleteListeners.remove(listener);
}
public void roundComplete() {
RoundState roundState = new RoundStateImpl(bark.nerrors > 0,
filer.getSourceFileNames().size() > 0,
filer.getClassFileNames().size() > 0,
origOptions);
RoundCompleteEvent roundCompleteEvent = new RoundCompleteEventImpl(this, roundState);
filer.roundOver();
for(RoundCompleteListener rcl: roundCompleteListeners)
rcl.roundComplete(roundCompleteEvent);
}
}