/* * Copyright 2011 Blazebit */ package com.blazebit.apt.service; import com.blazebit.apt.AnnotationProcessingUtils; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic; import javax.tools.FileObject; import javax.tools.StandardLocation; /** * Constraint Validator classes must be available in compiled form! * * @author Christian Beikov * @since 0.1.2 */ @SupportedAnnotationTypes("com.blazebit.apt.service.ServiceProvider") @SupportedSourceVersion(SourceVersion.RELEASE_6) public class ServiceProviderAnnotationProcessor extends AbstractProcessor { @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (annotations.isEmpty()) { return true; } Map<String, List<String>> serviceProviders = new HashMap<String, List<String>>(); for (Element e : roundEnv .getElementsAnnotatedWith(ServiceProvider.class)) { TypeElement typeElement = (TypeElement) e; AnnotationMirror annotation = AnnotationProcessingUtils .findAnnotationMirror(processingEnv, typeElement, ServiceProvider.class); if (annotation == null) { // Workaround a strange bug... continue; } String service = AnnotationProcessingUtils .getAnnotationElementValue(processingEnv, annotation, "value").getValue().toString(); List<String> providers = serviceProviders.get(service); if (providers == null) { providers = new ArrayList<String>(); serviceProviders.put(service, providers); } providers.add(typeElement.getQualifiedName().toString()); } String serviceFile = null; try { for (Map.Entry<String, List<String>> entry : serviceProviders .entrySet()) { serviceFile = entry.getKey(); FileObject providerFileObject = processingEnv.getFiler() .createResource(StandardLocation.SOURCE_OUTPUT, "", "META-INF/services/" + serviceFile); List<String> services = entry.getValue(); BufferedWriter writer = null; try { writer = new BufferedWriter(providerFileObject.openWriter()); for (int i = 0; i < services.size(); i++) { writer.append(services.get(i)).append('\n'); } } finally { if (writer != null) { writer.close(); } } } } catch (Exception ex) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ex.printStackTrace(new PrintStream(baos)); processingEnv.getMessager().printMessage( Diagnostic.Kind.ERROR, "Could not create service file '" + serviceFile + "'\n" + baos.toString()); return false; } return true; } }