/**
* Copyright (c) 2009 Farata Systems http://www.faratasystems.com
*
* Licensed under The MIT License
* Re-distributions of files must retain the above copyright notice.
*
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*
*/
package com.farata.dto2extjs.asap;
import java.util.Collection;
import java.util.Set;
import java.util.Map;
import java.util.HashSet;
import java.util.WeakHashMap;
import java.util.Arrays;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.apt.AnnotationProcessorFactory;
import com.sun.mirror.apt.AnnotationProcessorListener;
import com.sun.mirror.apt.AnnotationProcessors;
import com.sun.mirror.apt.RoundCompleteEvent;
import com.sun.mirror.apt.RoundCompleteListener;
import com.sun.mirror.apt.RoundState;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
import com.farata.dto2extjs.annotations.JSClass;
import com.farata.dto2extjs.asap.env.AptEnvironmentInspector;
import com.farata.dto2extjs.asap.env.IEnvironmentInspector;
public class JSAnnotationProcessorFactory implements AnnotationProcessorFactory {
public Collection<String> supportedOptions() {
return JSAnnotationProcessorOptions.SUPPORTED_OPTIONS;
}
public Collection<String> supportedAnnotationTypes() {
return SUPPORTED_ANNOTATIONS;
}
final private AnnotationProcessorListener _listener = new RoundCompleteListener() {
public void roundComplete(final RoundCompleteEvent e) {
final RoundState state = e.getRoundState();
/*
System.out.println("EVENT:" +
" errors = " + state.errorRaised() +
", newClasses = " + state.classFilesCreated() +
", newSources = " + state.sourceFilesCreated() +
", final = " + state.finalRound()
);
*/
boolean anyRoundComplete = true;
if ( anyRoundComplete || state.finalRound() ) {
final AnnotationProcessorEnvironment env = e.getSource();
final Set<TypeDeclaration> visited = _envs.remove( env );
if (null != visited)
visited.clear();
env.removeListener(this);
}
}
};
final private Map<AnnotationProcessorEnvironment, Set<TypeDeclaration>> _envs = new WeakHashMap<AnnotationProcessorEnvironment, Set<TypeDeclaration>>();
public AnnotationProcessor getProcessorFor(final Set<AnnotationTypeDeclaration> atds, final AnnotationProcessorEnvironment env) {
final JSAnnotationProcessorOptions options = new JSAnnotationProcessorOptions(env, INSPECTOR);
if ( !options.parse() )
return AnnotationProcessors.NO_OP;
if ( INSPECTOR.isReconciliation(env) ) {
/*
System.out.println("RECONCILE: " + env.getSpecifiedTypeDeclarations());
*/
if ( !options.reconcile() )
return AnnotationProcessors.NO_OP;
}
final Collection<TypeDeclaration> targets = env.getSpecifiedTypeDeclarations();
Set<TypeDeclaration> visited = _envs.get(env);
final boolean firstCall = null == visited;
if (firstCall) {
/*
System.out.println(System.identityHashCode(env) + " -- ROUND START");
*/
env.addListener(_listener);
}
if ( firstCall || !visited.containsAll(targets) ) {
/*
System.out.println(System.identityHashCode(env) + ": NEW TARGET: " + targets + ", " + visited);
*/
if (firstCall)
_envs.put(env, visited = new HashSet<TypeDeclaration>(targets));
else
visited.addAll( targets );
return new JSAnnotationProcessor(env, options, INSPECTOR);
} else {
/*
System.out.println("IGNORED DUPLICATE: " + env.getSpecifiedTypeDeclarations());
*/
return AnnotationProcessors.NO_OP;
}
}
static IEnvironmentInspector INSPECTOR = AptEnvironmentInspector.INSTANCE;
final private static Collection<String> SUPPORTED_ANNOTATIONS
= Arrays.asList( JSClass.class.getName() );
}