package com.farata.cdb.annotations.processor; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import java.util.Set; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.xml.sax.SAXException; import clear.cdb.extjs.annotations.JSJPQLMethod; import com.farata.cdb.annotations.helper.HQLCompiler; import com.farata.cdb.annotations.helper.HQLHelper; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.apt.AnnotationProcessorFactory; import com.sun.mirror.apt.Messager; import com.sun.mirror.declaration.AnnotationMirror; import com.sun.mirror.declaration.AnnotationTypeDeclaration; import com.sun.mirror.declaration.AnnotationTypeElementDeclaration; import com.sun.mirror.declaration.AnnotationValue; import com.sun.mirror.declaration.Declaration; import com.sun.mirror.declaration.MethodDeclaration; public class CDBHQLAnnotationProcessor implements AnnotationProcessor, AnnotationProcessorFactory { public static final String OPTION_CDB_CONFIGURATION_FILE = "-Acom.faratasystems.cdb.configuration.file"; public static final String OPTION_CDB_ENTITIES_CLASSPATH = "-Acom.faratasystems.cdb.entities.classpath"; private AnnotationProcessorEnvironment _env; private HQLCompiler hqlCompiler; @Override public void process() { Messager messager = _env.getMessager(); // obtain the declaration of the annotation we want to process AnnotationTypeDeclaration annoDecl = (AnnotationTypeDeclaration) _env .getTypeDeclaration(JSJPQLMethod.class.getName()); // get the annotated types Collection<Declaration> annotatedTypes = _env .getDeclarationsAnnotatedWith(annoDecl); for (Declaration decl : annotatedTypes) { Collection<AnnotationMirror> mirrors = decl.getAnnotationMirrors(); // for each annotation found, get a map of element name/value pairs for (AnnotationMirror mirror : mirrors) { if (!"JSJPQLMethod".equals(mirror.getAnnotationType() .getDeclaration().getSimpleName())) { continue; } Map<AnnotationTypeElementDeclaration, AnnotationValue> valueMap = mirror .getElementValues(); Set<Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue>> valueSet = valueMap .entrySet(); for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> annoKeyValue : valueSet) { if (annoKeyValue.getKey().getSimpleName().equals( "query")) { String query = (String) annoKeyValue.getValue().getValue(); try { if (hqlCompiler == null) { Document doc = parseConfiguration(); loadClasses(); hqlCompiler = new HQLCompiler(doc); } hqlCompiler.compileQuery(query); } catch (Throwable e) { messager.printError(annoKeyValue.getValue().getPosition(), e.getMessage()); } break; } } } } } private void loadClasses() throws MalformedURLException { String classpathOption = getOption(OPTION_CDB_ENTITIES_CLASSPATH); String[] cps = {}; if (classpathOption != null) { cps = classpathOption.split(";"); } ArrayList<String> cpEntries = new ArrayList<String>(); for (String cp : cps) { if (cp != null) { String resolved = resolveFile(cp.trim()); if (resolved != null) { cpEntries.add(resolved); } File f = new File(resolved); if (f.isDirectory()) { for (File ch : f.listFiles()) { if (ch.getName().endsWith(".jar")) { cpEntries.add(ch.getAbsolutePath()); } } } } } loadClasspaths(cpEntries.toArray(new String[cpEntries.size()])); } @SuppressWarnings("deprecation") private void loadClasspaths(String cps[]) throws MalformedURLException { ArrayList<URL> urls = new ArrayList<URL>(); for (String cp : cps) { URL url = new File(cp).toURL(); urls.add(url); } if (urls.size() > 0) { URLClassLoader clazzLoader = new URLClassLoader(urls .toArray(new URL[urls.size()]), getClass().getClassLoader()); Thread.currentThread().setContextClassLoader(clazzLoader); } } private Document parseConfiguration() throws FileNotFoundException, SAXException, IOException, ParserConfigurationException { String configurationFile = resolveFile(getOption(OPTION_CDB_CONFIGURATION_FILE)); return HQLHelper.parseConfiguration(configurationFile); } public static String resolveFile(String option) { File _output = new File(option); if (!_output.isAbsolute()) { try { File root = org.eclipse.core.resources.ResourcesPlugin .getWorkspace().getRoot().getLocation().toFile(); _output = new File(root, option); } catch (Throwable th) { // System.out.println("WARNING: " + th); } } return _output.getAbsolutePath(); } protected String getOption(String name) { for (String option : _env.getOptions().keySet()) { if (option.contains(name)) { String[] ret = option.split("="); if (ret.length > 1) { return ret[1]; } else { return _env.getOptions().get(option); } } } return null; } @Override public AnnotationProcessor getProcessorFor( Set<AnnotationTypeDeclaration> annotationTypeDeclarations, AnnotationProcessorEnvironment annotationProcessorEnvironment) { if (_env != annotationProcessorEnvironment) { _env = annotationProcessorEnvironment; hqlCompiler = null; } return this; } @Override public Collection<String> supportedAnnotationTypes() { ArrayList<String> result = new ArrayList<String>(); result.add(JSJPQLMethod.class.getCanonicalName()); return result; } @Override public Collection<String> supportedOptions() { return null; } }