1 /*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
34
35 import javax.annotation.processing.AbstractProcessor;
36 import javax.annotation.processing.ProcessingEnvironment;
37 import javax.annotation.processing.RoundEnvironment;
38 import javax.annotation.processing.SupportedAnnotationTypes;
39 import javax.annotation.processing.SupportedOptions;
40 import javax.jws.WebService;
41 import javax.lang.model.SourceVersion;
42 import javax.lang.model.element.Element;
43 import javax.lang.model.element.ElementKind;
44 import javax.lang.model.element.Name;
45 import javax.lang.model.element.TypeElement;
46 import javax.lang.model.type.TypeMirror;
47 import javax.lang.model.util.ElementFilter;
48 import javax.tools.Diagnostic;
49 import javax.xml.ws.Holder;
50 import javax.xml.ws.WebServiceProvider;
51 import java.io.ByteArrayOutputStream;
52 import java.io.File;
53 import java.io.PrintStream;
54 import java.lang.reflect.Method;
55 import java.rmi.Remote;
56 import java.rmi.RemoteException;
57 import java.util.ArrayList;
58 import java.util.Collection;
59 import java.util.HashSet;
60 import java.util.Scanner;
61 import java.util.Set;
62 import java.util.logging.Level;
63
64 /**
65 * WebServiceAp is a AnnotationProcessor for processing javax.jws.* and
66 * javax.xml.ws.* annotations. This class is used either by the WsGen (CompileTool) tool or
67 * indirectly when invoked by javac.
68 *
69 * @author WS Development Team
70 */
71 @SupportedAnnotationTypes({
72 "javax.jws.HandlerChain",
73 "javax.jws.Oneway",
74 "javax.jws.WebMethod",
75 "javax.jws.WebParam",
76 "javax.jws.WebResult",
77 "javax.jws.WebService",
78 "javax.jws.soap.InitParam",
79 "javax.jws.soap.SOAPBinding",
80 "javax.jws.soap.SOAPMessageHandler",
81 "javax.jws.soap.SOAPMessageHandlers",
82 "javax.xml.ws.BindingType",
83 "javax.xml.ws.RequestWrapper",
84 "javax.xml.ws.ResponseWrapper",
85 "javax.xml.ws.ServiceMode",
86 "javax.xml.ws.WebEndpoint",
87 "javax.xml.ws.WebFault",
88 "javax.xml.ws.WebServiceClient",
89 "javax.xml.ws.WebServiceProvider",
90 "javax.xml.ws.WebServiceRef"
91 })
92 @SupportedOptions({WebServiceAp.DO_NOT_OVERWRITE, WebServiceAp.IGNORE_NO_WEB_SERVICE_FOUND_WARNING})
93 public class WebServiceAp extends AbstractProcessor implements ModelBuilder {
94
95 private static final Logger LOGGER = Logger.getLogger(WebServiceAp.class);
96
97 public static final String DO_NOT_OVERWRITE = "doNotOverWrite";
98 public static final String IGNORE_NO_WEB_SERVICE_FOUND_WARNING = "ignoreNoWebServiceFoundWarning";
99
100 private WsgenOptions options;
101 protected AnnotationProcessorContext context;
102 private File sourceDir;
103 private boolean doNotOverWrite;
104 private boolean ignoreNoWebServiceFoundWarning = false;
105 private TypeElement remoteElement;
106 private TypeMirror remoteExceptionElement;
107 private TypeMirror exceptionElement;
108 private TypeMirror runtimeExceptionElement;
109 private TypeElement defHolderElement;
110 private boolean isCommandLineInvocation;
111 private PrintStream out;
112 private Collection<TypeElement> processedTypeElements = new HashSet<TypeElement>();
113
114 public WebServiceAp() {
115 this.context = new AnnotationProcessorContext();
116 }
117
118 public WebServiceAp(WsgenOptions options, PrintStream out) {
119 this.options = options;
120 this.sourceDir = (options != null) ? options.sourceDir : null;
121 this.doNotOverWrite = (options != null) && options.doNotOverWrite;
122 this.context = new AnnotationProcessorContext();
123 this.out = out;
124 }
125
126 @Override
127 public synchronized void init(ProcessingEnvironment processingEnv) {
128 super.init(processingEnv);
129 remoteElement = processingEnv.getElementUtils().getTypeElement(Remote.class.getName());
130 remoteExceptionElement = processingEnv.getElementUtils().getTypeElement(RemoteException.class.getName()).asType();
131 exceptionElement = processingEnv.getElementUtils().getTypeElement(Exception.class.getName()).asType();
132 runtimeExceptionElement = processingEnv.getElementUtils().getTypeElement(RuntimeException.class.getName()).asType();
133 defHolderElement = processingEnv.getElementUtils().getTypeElement(Holder.class.getName());
134 if (options == null) {
135 options = new WsgenOptions();
136
137 out = new PrintStream(new ByteArrayOutputStream());
138
139 doNotOverWrite = getOption(DO_NOT_OVERWRITE);
140 ignoreNoWebServiceFoundWarning = getOption(IGNORE_NO_WEB_SERVICE_FOUND_WARNING);
141
142 String classDir = parseArguments();
143 String property = System.getProperty("java.class.path");
144 options.classpath = classDir + File.pathSeparator + (property != null ? property : "");
145 isCommandLineInvocation = true;
146 }
147 options.filer = processingEnv.getFiler();
148 }
149
150 private String parseArguments() {
151 // let's try to parse JavacOptions
152
153 String classDir = null;
154 try {
155 ClassLoader cl = WebServiceAp.class.getClassLoader();
156 Class javacProcessingEnvironmentClass = Class.forName("com.sun.tools.javac.processing.JavacProcessingEnvironment", false, cl);
157 if (javacProcessingEnvironmentClass.isInstance(processingEnv)) {
158 Method getContextMethod = javacProcessingEnvironmentClass.getDeclaredMethod("getContext");
159 Object tmpContext = getContextMethod.invoke(processingEnv);
160 Class optionsClass = Class.forName("com.sun.tools.javac.util.Options", false, cl);
161 Class contextClass = Class.forName("com.sun.tools.javac.util.Context", false, cl);
162 Method instanceMethod = optionsClass.getDeclaredMethod("instance", new Class[]{contextClass});
163 Object tmpOptions = instanceMethod.invoke(null, tmpContext);
164 if (tmpOptions != null) {
165 Method getMethod = optionsClass.getDeclaredMethod("get", new Class[]{String.class});
166 Object result = getMethod.invoke(tmpOptions, "-s"); // todo: we have to check for -d also
167 if (result != null) {
168 classDir = (String) result;
169 }
170 this.options.verbose = getMethod.invoke(tmpOptions, "-verbose") != null;
171 }
172 }
173 } catch (Exception e) {
174 /// some Error was here - problems with reflection or security
175 processWarning(WebserviceapMessages.WEBSERVICEAP_PARSING_JAVAC_OPTIONS_ERROR());
176 report(e.getMessage());
177 }
178
179 if (classDir == null) { // some error within reflection block
180 String property = System.getProperty("sun.java.command");
181 if (property != null) {
182 Scanner scanner = new Scanner(property);
183 boolean sourceDirNext = false;
184 while (scanner.hasNext()) {
185 String token = scanner.next();
186 if (sourceDirNext) {
187 classDir = token;
188 sourceDirNext = false;
189 } else if ("-verbose".equals(token)) {
190 options.verbose = true;
191 } else if ("-s".equals(token)) {
192 sourceDirNext = true;
193 }
194 }
195 }
196 }
197 if (classDir != null) {
198 sourceDir = new File(classDir);
199 }
200 return classDir;
201 }
202
203 private boolean getOption(String key) {
204 String value = processingEnv.getOptions().get(key);
205 if (value != null) {
206 return Boolean.valueOf(value);
207 }
208 return false;
209 }
210
211 @Override
212 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
213 if (context.getRound() != 1) {
214 return true;
215 }
216 context.incrementRound();
217 WebService webService;
218 WebServiceProvider webServiceProvider;
219 WebServiceVisitor webServiceVisitor = new WebServiceWrapperGenerator(this, context);
220 boolean processedEndpoint = false;
221 Collection<TypeElement> classes = new ArrayList<TypeElement>();
222 filterClasses(classes, roundEnv.getRootElements());
292 public void processError(String message, Element element) {
293 if (isCommandLineInvocation) {
294 processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, element);
295 } else {
296 throw new ModelerException(message);
297 }
298 }
299
300 @Override
301 public boolean canOverWriteClass(String className) {
302 return !((doNotOverWrite && GeneratorUtil.classExists(options, className)));
303 }
304
305 @Override
306 public File getSourceDir() {
307 return sourceDir;
308 }
309
310 @Override
311 public boolean isRemote(TypeElement typeElement) {
312 return processingEnv.getTypeUtils().isSubtype(typeElement.asType(), remoteElement.asType());
313 }
314
315 @Override
316 public boolean isServiceException(TypeMirror typeMirror) {
317 return processingEnv.getTypeUtils().isSubtype(typeMirror, exceptionElement)
318 && !processingEnv.getTypeUtils().isSubtype(typeMirror, runtimeExceptionElement)
319 && !processingEnv.getTypeUtils().isSubtype(typeMirror, remoteExceptionElement);
320 }
321
322 @Override
323 public TypeMirror getHolderValueType(TypeMirror type) {
324 return TypeModeler.getHolderValueType(type, defHolderElement, processingEnv);
325 }
326
327 @Override
328 public boolean checkAndSetProcessed(TypeElement typeElement) {
329 if (!processedTypeElements.contains(typeElement)) {
330 processedTypeElements.add(typeElement);
331 return false;
332 }
333 return true;
334 }
335
336 @Override
337 public void log(String message) {
338 if (options != null && options.verbose) {
339 message = new StringBuilder().append('[').append(message).append(']').toString(); // "[%s]"
|
1 /*
2 * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
34
35 import javax.annotation.processing.AbstractProcessor;
36 import javax.annotation.processing.ProcessingEnvironment;
37 import javax.annotation.processing.RoundEnvironment;
38 import javax.annotation.processing.SupportedAnnotationTypes;
39 import javax.annotation.processing.SupportedOptions;
40 import javax.jws.WebService;
41 import javax.lang.model.SourceVersion;
42 import javax.lang.model.element.Element;
43 import javax.lang.model.element.ElementKind;
44 import javax.lang.model.element.Name;
45 import javax.lang.model.element.TypeElement;
46 import javax.lang.model.type.TypeMirror;
47 import javax.lang.model.util.ElementFilter;
48 import javax.tools.Diagnostic;
49 import javax.xml.ws.Holder;
50 import javax.xml.ws.WebServiceProvider;
51 import java.io.ByteArrayOutputStream;
52 import java.io.File;
53 import java.io.PrintStream;
54 import java.util.ArrayList;
55 import java.util.Collection;
56 import java.util.HashSet;
57 import java.util.Set;
58 import java.util.logging.Level;
59
60 /**
61 * WebServiceAp is a AnnotationProcessor for processing javax.jws.* and
62 * javax.xml.ws.* annotations. This class is used either by the WsGen (CompileTool) tool or
63 * indirectly when invoked by javac.
64 *
65 * @author WS Development Team
66 */
67 @SupportedAnnotationTypes({
68 "javax.jws.HandlerChain",
69 "javax.jws.Oneway",
70 "javax.jws.WebMethod",
71 "javax.jws.WebParam",
72 "javax.jws.WebResult",
73 "javax.jws.WebService",
74 "javax.jws.soap.InitParam",
75 "javax.jws.soap.SOAPBinding",
76 "javax.jws.soap.SOAPMessageHandler",
77 "javax.jws.soap.SOAPMessageHandlers",
78 "javax.xml.ws.BindingType",
79 "javax.xml.ws.RequestWrapper",
80 "javax.xml.ws.ResponseWrapper",
81 "javax.xml.ws.ServiceMode",
82 "javax.xml.ws.WebEndpoint",
83 "javax.xml.ws.WebFault",
84 "javax.xml.ws.WebServiceClient",
85 "javax.xml.ws.WebServiceProvider",
86 "javax.xml.ws.WebServiceRef"
87 })
88 @SupportedOptions({WebServiceAp.DO_NOT_OVERWRITE, WebServiceAp.IGNORE_NO_WEB_SERVICE_FOUND_WARNING, WebServiceAp.VERBOSE})
89 public class WebServiceAp extends AbstractProcessor implements ModelBuilder {
90
91 private static final Logger LOGGER = Logger.getLogger(WebServiceAp.class);
92
93 public static final String DO_NOT_OVERWRITE = "doNotOverWrite";
94 public static final String IGNORE_NO_WEB_SERVICE_FOUND_WARNING = "ignoreNoWebServiceFoundWarning";
95 public static final String VERBOSE = "verbose";
96
97 private WsgenOptions options;
98 protected AnnotationProcessorContext context;
99 private File sourceDir;
100 private boolean doNotOverWrite;
101 private boolean ignoreNoWebServiceFoundWarning = false;
102 private TypeMirror exceptionElement;
103 private TypeMirror runtimeExceptionElement;
104 private TypeElement defHolderElement;
105 private boolean isCommandLineInvocation;
106 private PrintStream out;
107 private Collection<TypeElement> processedTypeElements = new HashSet<TypeElement>();
108
109 public WebServiceAp() {
110 this.context = new AnnotationProcessorContext();
111 }
112
113 public WebServiceAp(WsgenOptions options, PrintStream out) {
114 this.options = options;
115 this.sourceDir = (options != null) ? options.sourceDir : null;
116 this.doNotOverWrite = (options != null) && options.doNotOverWrite;
117 this.context = new AnnotationProcessorContext();
118 this.out = out;
119 }
120
121 @Override
122 public synchronized void init(ProcessingEnvironment processingEnv) {
123 super.init(processingEnv);
124 exceptionElement = processingEnv.getElementUtils().getTypeElement(Exception.class.getName()).asType();
125 runtimeExceptionElement = processingEnv.getElementUtils().getTypeElement(RuntimeException.class.getName()).asType();
126 defHolderElement = processingEnv.getElementUtils().getTypeElement(Holder.class.getName());
127 if (options == null) {
128 options = new WsgenOptions();
129
130 out = new PrintStream(new ByteArrayOutputStream());
131 doNotOverWrite = getOption(DO_NOT_OVERWRITE);
132 ignoreNoWebServiceFoundWarning = getOption(IGNORE_NO_WEB_SERVICE_FOUND_WARNING);
133 options.verbose = getOption(VERBOSE);
134 isCommandLineInvocation = true;
135 }
136 options.filer = processingEnv.getFiler();
137 }
138
139 private boolean getOption(String key) {
140 String value = processingEnv.getOptions().get(key);
141 if (value != null) {
142 return Boolean.valueOf(value);
143 }
144 return false;
145 }
146
147 @Override
148 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
149 if (context.getRound() != 1) {
150 return true;
151 }
152 context.incrementRound();
153 WebService webService;
154 WebServiceProvider webServiceProvider;
155 WebServiceVisitor webServiceVisitor = new WebServiceWrapperGenerator(this, context);
156 boolean processedEndpoint = false;
157 Collection<TypeElement> classes = new ArrayList<TypeElement>();
158 filterClasses(classes, roundEnv.getRootElements());
228 public void processError(String message, Element element) {
229 if (isCommandLineInvocation) {
230 processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, element);
231 } else {
232 throw new ModelerException(message);
233 }
234 }
235
236 @Override
237 public boolean canOverWriteClass(String className) {
238 return !((doNotOverWrite && GeneratorUtil.classExists(options, className)));
239 }
240
241 @Override
242 public File getSourceDir() {
243 return sourceDir;
244 }
245
246 @Override
247 public boolean isRemote(TypeElement typeElement) {
248 return TypeModeler.isRemote(typeElement);
249 }
250
251 @Override
252 public boolean isServiceException(TypeMirror typeMirror) {
253 return processingEnv.getTypeUtils().isSubtype(typeMirror, exceptionElement)
254 && !processingEnv.getTypeUtils().isSubtype(typeMirror, runtimeExceptionElement)
255 && !TypeModeler.isRemoteException(processingEnv, typeMirror);
256 }
257
258 @Override
259 public TypeMirror getHolderValueType(TypeMirror type) {
260 return TypeModeler.getHolderValueType(type, defHolderElement, processingEnv);
261 }
262
263 @Override
264 public boolean checkAndSetProcessed(TypeElement typeElement) {
265 if (!processedTypeElements.contains(typeElement)) {
266 processedTypeElements.add(typeElement);
267 return false;
268 }
269 return true;
270 }
271
272 @Override
273 public void log(String message) {
274 if (options != null && options.verbose) {
275 message = new StringBuilder().append('[').append(message).append(']').toString(); // "[%s]"
|