1 11 package org.eclipse.jdt.internal.compiler.apt.dispatch; 12 13 import java.util.ArrayList ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 import java.util.ServiceConfigurationError ; 17 import java.util.ServiceLoader ; 18 19 import javax.annotation.processing.Processor; 20 import javax.tools.StandardLocation; 21 22 import org.eclipse.jdt.internal.compiler.batch.Main; 23 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; 24 25 30 public class BatchAnnotationProcessorManager extends BaseAnnotationProcessorManager 31 { 32 33 36 private List <Processor> _setProcessors = null; 37 private Iterator <Processor> _setProcessorIter = null; 38 39 42 private List <String > _commandLineProcessors; 43 private Iterator <String > _commandLineProcessorIter = null; 44 45 private ServiceLoader <Processor> _serviceLoader = null; 46 private Iterator <Processor> _serviceLoaderIter; 47 48 private ClassLoader _procLoader; 49 50 private final static boolean VERBOSE_PROCESSOR_DISCOVERY = true; 52 private boolean _printProcessorDiscovery = false; 53 54 59 public BatchAnnotationProcessorManager() 60 { 61 } 62 63 @Override 64 public void configure(Object batchCompiler, String [] commandLineArguments) { 65 if (null != _processingEnv) { 66 throw new IllegalStateException ( 67 "Calling configure() more than once on an AnnotationProcessorManager is not supported"); } 69 BatchProcessingEnvImpl processingEnv = new BatchProcessingEnvImpl(this, (Main) batchCompiler, commandLineArguments); 70 _processingEnv = processingEnv; 71 _procLoader = processingEnv.getFileManager().getClassLoader(StandardLocation.ANNOTATION_PROCESSOR_PATH); 72 parseCommandLine(commandLineArguments); 73 _round = 0; 74 } 75 76 82 private void parseCommandLine(String [] commandLineArguments) { 83 List <String > commandLineProcessors = null; 84 for (int i = 0; i < commandLineArguments.length; ++i) { 85 String option = commandLineArguments[i]; 86 if ("-XprintProcessorInfo".equals(option)) { _printProcessorInfo = true; 88 _printProcessorDiscovery = VERBOSE_PROCESSOR_DISCOVERY; 89 } 90 else if ("-XprintRounds".equals(option)) { _printRounds = true; 92 } 93 else if ("-processor".equals(option)) { commandLineProcessors = new ArrayList <String >(); 95 String procs = commandLineArguments[++i]; 96 for (String proc : procs.split(",")) { commandLineProcessors.add(proc); 98 } 99 break; 100 } 101 } 102 _commandLineProcessors = commandLineProcessors; 103 if (null != _commandLineProcessors) { 104 _commandLineProcessorIter = _commandLineProcessors.iterator(); 105 } 106 } 107 108 @Override 109 public ProcessorInfo discoverNextProcessor() { 110 if (null != _setProcessors) { 111 if (_setProcessorIter.hasNext()) { 113 Processor p = _setProcessorIter.next(); 114 p.init(_processingEnv); 115 ProcessorInfo pi = new ProcessorInfo(p); 116 _processors.add(pi); 117 if (_printProcessorDiscovery && null != _out) { 118 _out.println("API specified processor: " + pi); } 120 return pi; 121 } 122 return null; 123 } 124 125 if (null != _commandLineProcessors) { 126 if (_commandLineProcessorIter.hasNext()) { 129 String proc = _commandLineProcessorIter.next(); 130 try { 131 Class <?> clazz = _procLoader.loadClass(proc); 132 Object o = clazz.newInstance(); 133 Processor p = (Processor) o; 134 p.init(_processingEnv); 135 ProcessorInfo pi = new ProcessorInfo(p); 136 _processors.add(pi); 137 if (_printProcessorDiscovery && null != _out) { 138 _out.println("Command line specified processor: " + pi); } 140 return pi; 141 } catch (Exception e) { 142 throw new AbortCompilation(null, e); 144 } 145 } 146 return null; 147 } 148 149 if (null == _serviceLoader ) { 152 _serviceLoader = ServiceLoader.load(Processor.class, _procLoader); 153 _serviceLoaderIter = _serviceLoader.iterator(); 154 } 155 try { 156 if (_serviceLoaderIter.hasNext()) { 157 Processor p = _serviceLoaderIter.next(); 158 p.init(_processingEnv); 159 ProcessorInfo pi = new ProcessorInfo(p); 160 _processors.add(pi); 161 if (_printProcessorDiscovery && null != _out) { 162 StringBuilder sb = new StringBuilder (); 163 sb.append("Discovered processor service "); sb.append(pi); 165 sb.append("\n supporting "); sb.append(pi.getSupportedAnnotationTypesAsString()); 167 sb.append("\n in "); sb.append(getProcessorLocation(p)); 169 _out.println(sb.toString()); 170 } 171 return pi; 172 } 173 } catch (ServiceConfigurationError e) { 174 throw new AbortCompilation(null, e); 176 } 177 return null; 178 } 179 180 185 private String getProcessorLocation(Processor p) { 186 boolean isMember = false; 189 Class <?> outerClass = p.getClass(); 190 StringBuilder innerName = new StringBuilder (); 191 while (outerClass.isMemberClass()) { 192 innerName.insert(0, outerClass.getSimpleName()); 193 innerName.insert(0, '$'); 194 isMember = true; 195 outerClass = outerClass.getEnclosingClass(); 196 } 197 String path = outerClass.getName(); 198 path = path.replace('.', '/'); 199 if (isMember) { 200 path = path + innerName; 201 } 202 path = path + ".class"; 204 String location = _procLoader.getResource(path).toString(); 206 if (location.endsWith(path)) { 207 location = location.substring(0, location.length() - path.length()); 208 } 209 return location; 210 } 211 212 @Override 213 public void reportProcessorException(Processor p, Exception e) { 214 throw new AbortCompilation(null, e); 216 } 217 218 @Override 219 public void setProcessors(Object [] processors) { 220 if (!_isFirstRound) { 221 throw new IllegalStateException ("setProcessors() cannot be called after processing has begun"); } 223 _setProcessors = new ArrayList <Processor>(processors.length); 226 for (Object o : processors) { 227 Processor p = (Processor)o; 228 _setProcessors.add(p); 229 } 230 _setProcessorIter = _setProcessors.iterator(); 231 232 _commandLineProcessors = null; 234 _commandLineProcessorIter = null; 235 } 236 237 } 238 | Popular Tags |