/*
* Copyright (c) 2012. The Genome Analysis Centre, Norwich, UK
* MISO project contacts: Robert Davey, Mario Caccamo @ TGAC
* *********************************************************************
*
* This file is part of MISO.
*
* MISO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MISO 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with MISO. If not, see <http://www.gnu.org/licenses/>.
*
* *********************************************************************
*/
package uk.ac.bbsrc.tgac.miso.core.plugin.annotation;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementVisitor;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.SimpleElementVisitor6;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* A processor for MISO annotations. You should use this processor
* when compiling MISO tools, as it extracts metadata encapsulated in
* annotations to tool configuration files which can then be read by consumers
* of these tools.
*
* @author Tony Burdett
* @author Rob Davey
* @date 20-Jul-2010
* @since 0.0.2
*/
public class MisoAnnotationProcessor extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> typeElements,
RoundEnvironment roundEnv) {
PrintWriter writer = null;
try {
// collection of captured classes
final Set<TypeElement> misoElements =
new HashSet<TypeElement>();
// check everything annotated with @MisoParameter annotations -
// we can only really apply this to String params
for (Element element : roundEnv.getElementsAnnotatedWith(
MisoParameter.class)) {
if (!(element.asType().toString().equals(String.class.getName()))) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR,
"@MisoParameter annotations can only be applied to " +
String.class.getName() + " arguments (not " +
element.asType().toString() + " '" +
element.getSimpleName() + "')",
element);
}
}
// check all elements annotated with @MisoPlugin
for (Element element : roundEnv
.getElementsAnnotatedWith(MisoPlugin.class)) {
ElementVisitor<Void, Void> visitor =
new SimpleElementVisitor6<Void, Void>() {
public Void visitType(TypeElement element, Void aVoid) {
// check this type is a class
if (element.getKind().isClass()) {
// this class is annotated with @MisoPlugin, write out an entry
misoElements.add(element);
}
return super.visitType(element, aVoid);
}
};
element.accept(visitor, null);
}
// now, iterate over all classes annotated with @MisoPlugin, and write to file
if (misoElements.size() > 0) {
// printwriter for writing list of MISO plugins
processingEnv.getMessager().printMessage(
Diagnostic.Kind.NOTE,
"Generating services for MISO plugins");
FileObject fo = processingEnv.getFiler().createResource(
StandardLocation.CLASS_OUTPUT,
"",
"META-INF/miso/plugins");
Writer w = fo.openWriter();
writer = new PrintWriter(w);
for (TypeElement misoElement : misoElements) {
writer.println(misoElement.getQualifiedName());
}
}
return true;
}
catch (IOException e) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR,
"Problem creating META-INF/miso/plugins file");
return false;
}
finally {
if (writer != null) {
writer.close();
}
}
}
public Set<String> getSupportedAnnotationTypes() {
Set<String> result = new HashSet<String>();
result.add(MisoPlugin.class.getName());
return result;
}
public Set<String> getSupportedOptions() {
// no supported options
return Collections.emptySet();
}
}