001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036: package com.sun.tools.ws.processor.modeler.annotation;
037:
038: import com.sun.mirror.apt.AnnotationProcessor;
039: import com.sun.mirror.apt.AnnotationProcessorEnvironment;
040: import com.sun.mirror.apt.Messager;
041: import com.sun.mirror.declaration.*;
042: import com.sun.mirror.type.ClassType;
043: import com.sun.mirror.type.InterfaceType;
044: import com.sun.mirror.type.TypeMirror;
045: import com.sun.mirror.util.SourcePosition;
046: import com.sun.tools.ws.ToolVersion;
047: import com.sun.tools.ws.processor.generator.GeneratorUtil;
048: import com.sun.tools.ws.processor.generator.Names;
049: import com.sun.tools.ws.processor.model.Operation;
050: import com.sun.tools.ws.processor.model.Port;
051: import com.sun.tools.ws.processor.model.Service;
052: import com.sun.tools.ws.processor.modeler.ModelerException;
053: import com.sun.tools.ws.processor.modeler.wsdl.ConsoleErrorReporter;
054: import com.sun.tools.ws.resources.WebserviceapMessages;
055: import com.sun.tools.ws.wscompile.*;
056: import com.sun.xml.ws.util.localization.Localizable;
057: import com.sun.xml.ws.util.localization.Localizer;
058: import org.xml.sax.SAXParseException;
059:
060: import javax.jws.WebService;
061: import javax.xml.ws.WebServiceProvider;
062: import java.io.ByteArrayOutputStream;
063: import java.io.File;
064: import java.io.PrintStream;
065: import java.util.HashSet;
066: import java.util.Iterator;
067: import java.util.Map;
068: import java.util.Set;
069:
070: /**
071: * WebServiceAP is a APT AnnotationProcessor for processing javax.jws.* and
072: * javax.xml.ws.* annotations. This class is used either by the WsGen (CompileTool) tool or
073: * idirectly via the {@link com.sun.istack.ws.AnnotationProcessorFactoryImpl} when invoked by APT.
074: *
075: * @author WS Development Team
076: */
077: public class WebServiceAP implements AnnotationProcessor, ModelBuilder,
078: WebServiceConstants {
079:
080: protected AnnotationProcessorEnvironment apEnv;
081:
082: private File sourceDir;
083:
084: private TypeDeclaration remoteDecl;
085: private TypeDeclaration remoteExceptionDecl;
086: private TypeDeclaration exceptionDecl;
087: private TypeDeclaration defHolderDecl;
088: private Service service;
089: private Port port;
090: protected AnnotationProcessorContext context;
091: private Set<TypeDeclaration> processedTypeDecls = new HashSet<TypeDeclaration>();
092: protected Messager messager;
093: private boolean doNotOverWrite = false;
094: private WsgenOptions options;
095: private ErrorReceiver receiver;
096: private PrintStream out;
097:
098: /*
099: * Is this invocation from APT or JavaC?
100: */
101: private boolean isAPTInvocation = false;
102:
103: public void run() {
104: }
105:
106: protected boolean parseArguments(String[] args) {
107: return true;
108: }
109:
110: public WebServiceAP(WsgenOptions options,
111: AnnotationProcessorContext context, ErrorReceiver receiver,
112: PrintStream out) {
113: this .options = options;
114: this .sourceDir = (options != null) ? options.sourceDir : null;
115: this .doNotOverWrite = (options != null)
116: && options.doNotOverWrite;
117: this .receiver = receiver;
118: this .out = out;
119: this .context = context;
120: }
121:
122: public void init(AnnotationProcessorEnvironment apEnv) {
123: this .apEnv = apEnv;
124: remoteDecl = this .apEnv.getTypeDeclaration(REMOTE_CLASSNAME);
125: remoteExceptionDecl = this .apEnv
126: .getTypeDeclaration(REMOTE_EXCEPTION_CLASSNAME);
127: exceptionDecl = this .apEnv
128: .getTypeDeclaration(EXCEPTION_CLASSNAME);
129: defHolderDecl = this .apEnv.getTypeDeclaration(HOLDER_CLASSNAME);
130: if (options == null) {
131: options = new WsgenOptions();
132: out = new PrintStream(new ByteArrayOutputStream());
133: class Listener extends WsimportListener {
134: ConsoleErrorReporter cer = new ConsoleErrorReporter(out);
135:
136: @Override
137: public void generatedFile(String fileName) {
138: message(fileName);
139: }
140:
141: @Override
142: public void message(String msg) {
143: out.println(msg);
144: }
145:
146: @Override
147: public void error(SAXParseException exception) {
148: cer.error(exception);
149: }
150:
151: @Override
152: public void fatalError(SAXParseException exception) {
153: cer.fatalError(exception);
154: }
155:
156: @Override
157: public void warning(SAXParseException exception) {
158: cer.warning(exception);
159: }
160:
161: @Override
162: public void info(SAXParseException exception) {
163: cer.info(exception);
164: }
165: }
166:
167: final Listener listener = new Listener();
168: receiver = new ErrorReceiverFilter(new Listener()) {
169: public void info(SAXParseException exception) {
170: if (options.verbose)
171: super .info(exception);
172: }
173:
174: public void warning(SAXParseException exception) {
175: if (!options.quiet)
176: super .warning(exception);
177: }
178:
179: @Override
180: public void pollAbort() throws AbortException {
181: if (listener.isCanceled())
182: throw new AbortException();
183: }
184: };
185: Map<String, String> apOptions = apEnv.getOptions();
186: String classDir = apOptions.get("-d");
187: if (classDir == null)
188: classDir = ".";
189: if (apOptions.get("-s") != null)
190: sourceDir = new File(apOptions.get("-s"));
191: else
192: sourceDir = new File(classDir);
193: String cp = apOptions.get("-classpath");
194: String cpath = classDir + File.pathSeparator + cp
195: + File.pathSeparator
196: + System.getProperty("java.class.path");
197: options.classpath = cpath;
198: boolean setVerbose = false;
199: for (String key : apOptions.keySet()) {
200: if (key.equals("-verbose"))
201: setVerbose = true;
202: }
203: options.verbose = setVerbose;
204: messager = apEnv.getMessager();
205: isAPTInvocation = true;
206: }
207: options.filer = apEnv.getFiler();
208: // env.setFiler(apEnv.getFiler());
209: }
210:
211: public AnnotationProcessorEnvironment getAPEnv() {
212: return apEnv;
213: }
214:
215: public WsgenOptions getOptions() {
216: return options;
217: }
218:
219: public File getSourceDir() {
220: return sourceDir;
221: }
222:
223: public void onError(String message) {
224: if (messager != null) {
225: messager.printError(message);
226: throw new AbortException();
227: } else {
228: throw new ModelerException(message);
229: }
230: }
231:
232: private final static Localizer localizer = new Localizer();
233:
234: public void onError(SourcePosition pos, Localizable msg)
235: throws ModelerException {
236: if (messager != null) {
237: messager.printError(pos, localizer.localize(msg));
238: } else {
239: throw new ModelerException(msg);
240: }
241: }
242:
243: public void onWarning(String message) {
244: if (messager != null) {
245: messager.printWarning(message);
246: } else {
247: report(message);
248: }
249: }
250:
251: public void onInfo(String message) {
252: if (messager != null) {
253: messager.printNotice(message);
254: } else {
255: report(message);
256: }
257: }
258:
259: protected void report(String msg) {
260: PrintStream outstream = out instanceof PrintStream ? out
261: : new PrintStream(out, true);
262: outstream.println(msg);
263: outstream.flush();
264: }
265:
266: public void process() {
267: if (context.getRound() == 1) {
268: buildModel();
269: }
270: context.incrementRound();
271: }
272:
273: public boolean checkAndSetProcessed(TypeDeclaration typeDecl) {
274: if (!processedTypeDecls.contains(typeDecl)) {
275: processedTypeDecls.add(typeDecl);
276: return false;
277: }
278: return true;
279: }
280:
281: public void clearProcessed() {
282: processedTypeDecls.clear();
283: }
284:
285: public void setService(Service service) {
286: this .service = service;
287: }
288:
289: public void setPort(Port port) {
290: this .port = port;
291: service.addPort(port);
292: }
293:
294: public void addOperation(Operation operation) {
295: port.addOperation(operation);
296: }
297:
298: public void setWrapperGenerated(boolean wrapperGenerated) {
299: }
300:
301: public TypeDeclaration getTypeDeclaration(String typeName) {
302: return apEnv.getTypeDeclaration(typeName);
303: }
304:
305: public String getSourceVersion() {
306: return ToolVersion.VERSION.MAJOR_VERSION;
307: }
308:
309: private void buildModel() {
310: WebService webService;
311: WebServiceProvider webServiceProvider;
312: WebServiceVisitor wrapperGenerator = createWrapperGenerator();
313: boolean processedEndpoint = false;
314: for (TypeDeclaration typedecl : apEnv.getTypeDeclarations()) {
315: if (!(typedecl instanceof ClassDeclaration))
316: continue;
317: webServiceProvider = typedecl
318: .getAnnotation(WebServiceProvider.class);
319: webService = typedecl.getAnnotation(WebService.class);
320: if (webServiceProvider != null) {
321: if (webService != null) {
322: onError(WebserviceapMessages
323: .WEBSERVICEAP_WEBSERVICE_AND_WEBSERVICEPROVIDER(typedecl
324: .getQualifiedName()));
325: }
326: processedEndpoint = true;
327: }
328: if (!shouldProcessWebService(webService))
329: continue;
330: typedecl.accept(wrapperGenerator);
331: processedEndpoint = true;
332: }
333: if (!processedEndpoint) {
334: if (isAPTInvocation)
335: onWarning(WebserviceapMessages
336: .WEBSERVICEAP_NO_WEBSERVICE_ENDPOINT_FOUND());
337: else
338: onError(WebserviceapMessages
339: .WEBSERVICEAP_NO_WEBSERVICE_ENDPOINT_FOUND());
340: }
341: }
342:
343: protected WebServiceVisitor createWrapperGenerator() {
344: return new WebServiceWrapperGenerator(this , context);
345: }
346:
347: protected boolean shouldProcessWebService(WebService webService) {
348: return webService != null;
349: }
350:
351: public boolean isException(TypeDeclaration typeDecl) {
352: return isSubtype(typeDecl, exceptionDecl);
353: }
354:
355: public boolean isRemoteException(TypeDeclaration typeDecl) {
356: return isSubtype(typeDecl, remoteExceptionDecl);
357: }
358:
359: public boolean isRemote(TypeDeclaration typeDecl) {
360: return isSubtype(typeDecl, remoteDecl);
361: }
362:
363: public static boolean isSubtype(TypeDeclaration d1,
364: TypeDeclaration d2) {
365: if (d1.equals(d2))
366: return true;
367: ClassDeclaration super ClassDecl = null;
368: if (d1 instanceof ClassDeclaration) {
369: ClassType super Class = ((ClassDeclaration) d1)
370: .getSuperclass();
371: if (super Class != null) {
372: super ClassDecl = super Class.getDeclaration();
373: if (super ClassDecl.equals(d2))
374: return true;
375: }
376: }
377: InterfaceDeclaration super Intf = null;
378: for (InterfaceType interfaceType : d1.getSuperinterfaces()) {
379: super Intf = interfaceType.getDeclaration();
380: if (super Intf.equals(d2))
381: return true;
382: }
383: if (super Intf != null && isSubtype(super Intf, d2)) {
384: return true;
385: } else if (super ClassDecl != null
386: && isSubtype(super ClassDecl, d2)) {
387: return true;
388: }
389: return false;
390: }
391:
392: public static String getMethodSig(MethodDeclaration method) {
393: StringBuffer buf = new StringBuffer(method.getSimpleName()
394: + "(");
395: Iterator<TypeParameterDeclaration> params = method
396: .getFormalTypeParameters().iterator();
397: TypeParameterDeclaration param;
398: for (int i = 0; params.hasNext(); i++) {
399: if (i > 0)
400: buf.append(", ");
401: param = params.next();
402: buf.append(param.getSimpleName());
403: }
404: buf.append(")");
405: return buf.toString();
406: }
407:
408: public String getOperationName(String messageName) {
409: return messageName;
410: }
411:
412: public String getResponseName(String operationName) {
413: return Names.getResponseName(operationName);
414: }
415:
416: public TypeMirror getHolderValueType(TypeMirror type) {
417: return TypeModeler.getHolderValueType(type, defHolderDecl);
418: }
419:
420: public boolean canOverWriteClass(String className) {
421: return !((doNotOverWrite && GeneratorUtil.classExists(options,
422: className)));
423: }
424:
425: public void log(String msg) {
426: if (options != null && options.verbose) {
427: String message = "[" + msg + "]";
428: if (messager != null) {
429: messager.printNotice(message);
430: } else {
431: System.out.println(message);
432: }
433: }
434: }
435:
436: public String getXMLName(String javaName) {
437: return javaName;
438: }
439: }
|