src/share/jaxws_classes/com/sun/tools/internal/ws/processor/generator/ServiceGenerator.java

changeset 0
373ffda63c9a
child 637
9c07ef4934dd
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
1 /*
2 * Copyright (c) 1997, 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
23 * questions.
24 */
25
26 package com.sun.tools.internal.ws.processor.generator;
27
28 import com.sun.codemodel.internal.ClassType;
29 import com.sun.codemodel.internal.JAnnotationUse;
30 import com.sun.codemodel.internal.JBlock;
31 import com.sun.codemodel.internal.JCatchBlock;
32 import com.sun.codemodel.internal.JClass;
33 import com.sun.codemodel.internal.JClassAlreadyExistsException;
34 import com.sun.codemodel.internal.JCommentPart;
35 import com.sun.codemodel.internal.JConditional;
36 import com.sun.codemodel.internal.JDefinedClass;
37 import com.sun.codemodel.internal.JDocComment;
38 import com.sun.codemodel.internal.JExpr;
39 import com.sun.codemodel.internal.JFieldVar;
40 import com.sun.codemodel.internal.JInvocation;
41 import com.sun.codemodel.internal.JMethod;
42 import com.sun.codemodel.internal.JMod;
43 import com.sun.codemodel.internal.JTryBlock;
44 import com.sun.codemodel.internal.JType;
45 import com.sun.codemodel.internal.JVar;
46 import com.sun.tools.internal.ws.processor.model.Model;
47 import com.sun.tools.internal.ws.processor.model.ModelProperties;
48 import com.sun.tools.internal.ws.processor.model.Port;
49 import com.sun.tools.internal.ws.processor.model.Service;
50 import com.sun.tools.internal.ws.processor.model.java.JavaInterface;
51 import com.sun.tools.internal.ws.resources.GeneratorMessages;
52 import com.sun.tools.internal.ws.wscompile.ErrorReceiver;
53 import com.sun.tools.internal.ws.wscompile.Options;
54 import com.sun.tools.internal.ws.wscompile.WsimportOptions;
55 import com.sun.tools.internal.ws.wsdl.document.PortType;
56 import com.sun.xml.internal.ws.spi.db.BindingHelper;
57
58 import org.xml.sax.Locator;
59
60 import javax.xml.namespace.QName;
61 import javax.xml.ws.WebEndpoint;
62 import javax.xml.ws.WebServiceClient;
63 import javax.xml.ws.WebServiceFeature;
64 import javax.xml.ws.WebServiceException;
65 import java.net.MalformedURLException;
66 import java.net.URL;
67
68 import com.sun.xml.internal.ws.util.ServiceFinder;
69 import java.util.Locale;
70
71 /**
72 * @author WS Development Team
73 * @author Jitendra Kotamraju
74 */
75 public class ServiceGenerator extends GeneratorBase {
76
77 public static void generate(Model model, WsimportOptions options, ErrorReceiver receiver) {
78 ServiceGenerator serviceGenerator = new ServiceGenerator(model, options, receiver);
79 serviceGenerator.doGeneration();
80 }
81
82 private ServiceGenerator(Model model, WsimportOptions options, ErrorReceiver receiver) {
83 init(model, options, receiver);
84 }
85
86 @Override
87 public void visit(Service service) {
88 JavaInterface intf = service.getJavaInterface();
89 String className = Names.customJavaTypeClassName(intf);
90 if (donotOverride && GeneratorUtil.classExists(options, className)) {
91 log("Class " + className + " exists. Not overriding.");
92 return;
93 }
94
95 JDefinedClass cls;
96 try {
97 cls = getClass(className, ClassType.CLASS);
98 } catch (JClassAlreadyExistsException e) {
99 receiver.error(service.getLocator(), GeneratorMessages.GENERATOR_SERVICE_CLASS_ALREADY_EXIST(className, service.getName()));
100 return;
101 }
102
103 cls._extends(javax.xml.ws.Service.class);
104 String serviceFieldName = BindingHelper.mangleNameToClassName(service.getName().getLocalPart()).toUpperCase(Locale.ENGLISH);
105 String wsdlLocationName = serviceFieldName + "_WSDL_LOCATION";
106 JFieldVar urlField = cls.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, URL.class, wsdlLocationName);
107
108 JFieldVar exField = cls.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, WebServiceException.class, serviceFieldName+"_EXCEPTION");
109
110
111 String serviceName = serviceFieldName + "_QNAME";
112 cls.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, QName.class, serviceName,
113 JExpr._new(cm.ref(QName.class)).arg(service.getName().getNamespaceURI()).arg(service.getName().getLocalPart()));
114
115 JClass qNameCls = cm.ref(QName.class);
116 JInvocation inv;
117 inv = JExpr._new(qNameCls);
118 inv.arg("namespace");
119 inv.arg("localpart");
120
121 if (options.useBaseResourceAndURLToLoadWSDL) {
122 writeClassLoaderBaseResourceWSDLLocation(className, cls, urlField, exField);
123 } else if (wsdlLocation.startsWith("http://") || wsdlLocation.startsWith("https://") || wsdlLocation.startsWith("file:/")) {
124 writeAbsWSDLLocation(cls, urlField, exField);
125 } else if (wsdlLocation.startsWith("META-INF/")) {
126 writeClassLoaderResourceWSDLLocation(className, cls, urlField, exField);
127 } else {
128 writeResourceWSDLLocation(className, cls, urlField, exField);
129 }
130
131 //write class comment - JAXWS warning
132 JDocComment comment = cls.javadoc();
133
134 if (service.getJavaDoc() != null) {
135 comment.add(service.getJavaDoc());
136 comment.add("\n\n");
137 }
138
139 for (String doc : getJAXWSClassComment()) {
140 comment.add(doc);
141 }
142
143 // Generating constructor
144 // for e.g: public ExampleService()
145 JMethod constructor1 = cls.constructor(JMod.PUBLIC);
146 String constructor1Str = String.format("super(__getWsdlLocation(), %s);", serviceName);
147 constructor1.body().directStatement(constructor1Str);
148
149 // Generating constructor
150 // for e.g: public ExampleService(WebServiceFeature ... features)
151 if (options.target.isLaterThan(Options.Target.V2_2)) {
152 JMethod constructor2 = cls.constructor(JMod.PUBLIC);
153 constructor2.varParam(WebServiceFeature.class, "features");
154 String constructor2Str = String.format("super(__getWsdlLocation(), %s, features);", serviceName);
155 constructor2.body().directStatement(constructor2Str);
156 }
157
158 // Generating constructor
159 // for e.g: public ExampleService(URL wsdlLocation)
160 if (options.target.isLaterThan(Options.Target.V2_2)) {
161 JMethod constructor3 = cls.constructor(JMod.PUBLIC);
162 constructor3.param(URL.class, "wsdlLocation");
163 String constructor3Str = String.format("super(wsdlLocation, %s);", serviceName);
164 constructor3.body().directStatement(constructor3Str);
165 }
166
167 // Generating constructor
168 // for e.g: public ExampleService(URL wsdlLocation, WebServiceFeature ... features)
169 if (options.target.isLaterThan(Options.Target.V2_2)) {
170 JMethod constructor4 = cls.constructor(JMod.PUBLIC);
171 constructor4.param(URL.class, "wsdlLocation");
172 constructor4.varParam(WebServiceFeature.class, "features");
173 String constructor4Str = String.format("super(wsdlLocation, %s, features);", serviceName);
174 constructor4.body().directStatement(constructor4Str);
175 }
176
177 // Generating constructor
178 // for e.g: public ExampleService(URL wsdlLocation, QName serviceName)
179 JMethod constructor5 = cls.constructor(JMod.PUBLIC);
180 constructor5.param(URL.class, "wsdlLocation");
181 constructor5.param(QName.class, "serviceName");
182 constructor5.body().directStatement("super(wsdlLocation, serviceName);");
183
184 // Generating constructor
185 // for e.g: public ExampleService(URL, QName, WebServiceFeature ...)
186 if (options.target.isLaterThan(Options.Target.V2_2)) {
187 JMethod constructor6 = cls.constructor(JMod.PUBLIC);
188 constructor6.param(URL.class, "wsdlLocation");
189 constructor6.param(QName.class, "serviceName");
190 constructor6.varParam(WebServiceFeature.class, "features");
191 constructor6.body().directStatement("super(wsdlLocation, serviceName, features);");
192 }
193
194 //@WebService
195 JAnnotationUse webServiceClientAnn = cls.annotate(cm.ref(WebServiceClient.class));
196 writeWebServiceClientAnnotation(service, webServiceClientAnn);
197
198 // additional annotations
199 for (GeneratorExtension f:ServiceFinder.find(GeneratorExtension.class)) {
200 f.writeWebServiceClientAnnotation(options, cm, cls);
201 }
202
203
204 //@HandlerChain
205 writeHandlerConfig(Names.customJavaTypeClassName(service.getJavaInterface()), cls, options);
206
207 for (Port port : service.getPorts()) {
208 if (port.isProvider()) {
209 continue; // No getXYZPort() for porvider based endpoint
210 }
211
212 //Get the SEI class
213 JType retType;
214 try {
215 retType = getClass(port.getJavaInterface().getName(), ClassType.INTERFACE);
216 } catch (JClassAlreadyExistsException e) {
217 QName portTypeName =
218 (QName) port.getProperty(
219 ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME);
220 Locator loc = null;
221 if (portTypeName != null) {
222 PortType pt = port.portTypes.get(portTypeName);
223 if (pt != null) {
224 loc = pt.getLocator();
225 }
226 }
227 receiver.error(loc, GeneratorMessages.GENERATOR_SEI_CLASS_ALREADY_EXIST(port.getJavaInterface().getName(), portTypeName));
228 return;
229 }
230
231 //write getXyzPort()
232 writeDefaultGetPort(port, retType, cls);
233
234 //write getXyzPort(WebServicesFeature...)
235 if (options.target.isLaterThan(Options.Target.V2_1)) {
236 writeGetPort(port, retType, cls);
237 }
238 }
239
240 writeGetWsdlLocation(cm.ref(URL.class), cls, urlField, exField);
241 }
242
243 private void writeGetPort(Port port, JType retType, JDefinedClass cls) {
244 JMethod m = cls.method(JMod.PUBLIC, retType, port.getPortGetter());
245 JDocComment methodDoc = m.javadoc();
246 if (port.getJavaDoc() != null) {
247 methodDoc.add(port.getJavaDoc());
248 }
249 JCommentPart ret = methodDoc.addReturn();
250 JCommentPart paramDoc = methodDoc.addParam("features");
251 paramDoc.append("A list of ");
252 paramDoc.append("{@link " + WebServiceFeature.class.getName() + "}");
253 paramDoc.append("to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.");
254 ret.add("returns " + retType.name());
255 m.varParam(WebServiceFeature.class, "features");
256 JBlock body = m.body();
257 StringBuilder statement = new StringBuilder("return ");
258 statement.append("super.getPort(new QName(\"").append(port.getName().getNamespaceURI()).append("\", \"").append(port.getName().getLocalPart()).append("\"), ");
259 statement.append(retType.name());
260 statement.append(".class, features);");
261 body.directStatement(statement.toString());
262 writeWebEndpoint(port, m);
263 }
264
265
266 /*
267 Generates the code to create URL for absolute WSDL location
268
269 for e.g.:
270 static {
271 URL url = null;
272 WebServiceException e = null;
273 try {
274 url = new URL("http://ExampleService.wsdl");
275 } catch (MalformedURLException ex) {
276 e = new WebServiceException(ex);
277 }
278 EXAMPLESERVICE_WSDL_LOCATION = url;
279 EXAMPLESERVICE_EXCEPTION = e;
280 }
281 */
282 private void writeAbsWSDLLocation(JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
283 JBlock staticBlock = cls.init();
284 JVar urlVar = staticBlock.decl(cm.ref(URL.class), "url", JExpr._null());
285 JVar exVar = staticBlock.decl(cm.ref(WebServiceException.class), "e", JExpr._null());
286
287 JTryBlock tryBlock = staticBlock._try();
288 tryBlock.body().assign(urlVar, JExpr._new(cm.ref(URL.class)).arg(wsdlLocation));
289 JCatchBlock catchBlock = tryBlock._catch(cm.ref(MalformedURLException.class));
290 catchBlock.param("ex");
291 catchBlock.body().assign(exVar, JExpr._new(cm.ref(WebServiceException.class)).arg(JExpr.ref("ex")));
292
293 staticBlock.assign(urlField, urlVar);
294 staticBlock.assign(exField, exVar);
295 }
296
297 /*
298 Generates the code to create URL for WSDL location as resource
299
300 for e.g.:
301 static {
302 EXAMPLESERVICE_WSDL_LOCATION = ExampleService.class.getResource(...);
303 Exception e = null;
304 if (EXAMPLESERVICE_WSDL_LOCATION == null) {
305 e = new WebServiceException("...");
306 }
307 EXAMPLESERVICE_EXCEPTION = e;
308 }
309 */
310 private void writeResourceWSDLLocation(String className, JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
311 JBlock staticBlock = cls.init();
312 staticBlock.assign(urlField, JExpr.dotclass(cm.ref(className)).invoke("getResource").arg(wsdlLocation));
313 JVar exVar = staticBlock.decl(cm.ref(WebServiceException.class), "e", JExpr._null());
314 JConditional ifBlock = staticBlock._if(urlField.eq(JExpr._null()));
315 ifBlock._then().assign(exVar, JExpr._new(cm.ref(WebServiceException.class)).arg(
316 "Cannot find "+JExpr.quotify('\'', wsdlLocation)+" wsdl. Place the resource correctly in the classpath."));
317 staticBlock.assign(exField, exVar);
318 }
319
320 /*
321 Generates the code to create URL for WSDL location as classloader resource
322
323 for e.g.:
324 static {
325 EXAMPLESERVICE_WSDL_LOCATION = ExampleService.class.getClassLoader().getResource(...);
326 Exception e = null;
327 if (EXAMPLESERVICE_WSDL_LOCATION == null) {
328 e = new WebServiceException("...");
329 }
330 EXAMPLESERVICE_EXCEPTION = e;
331 }
332 */
333 private void writeClassLoaderResourceWSDLLocation(String className, JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
334 JBlock staticBlock = cls.init();
335 staticBlock.assign(urlField, JExpr.dotclass(cm.ref(className)).invoke("getClassLoader").invoke("getResource").arg(wsdlLocation));
336 JVar exVar = staticBlock.decl(cm.ref(WebServiceException.class), "e", JExpr._null());
337 JConditional ifBlock = staticBlock._if(urlField.eq(JExpr._null()));
338 ifBlock._then().assign(exVar, JExpr._new(cm.ref(WebServiceException.class)).arg(
339 "Cannot find "+JExpr.quotify('\'', wsdlLocation)+" wsdl. Place the resource correctly in the classpath."));
340 staticBlock.assign(exField, exVar);
341 }
342
343 /*
344 Generates the code to create URL for WSDL location from classloader base resource
345
346 for e.g.:
347 static {
348 Exception e = null;
349 URL url = null;
350 try {
351 url = new URL(ExampleService.class.getClassLoader().getResource("."), ...);
352 } catch (MalformedURLException murl) {
353 e = new WebServiceException(murl);
354 }
355 EXAMPLESERVICE_WSDL_LOCATION = url;
356 EXAMPLESERVICE_EXCEPTION = e;
357 }
358 */
359 private void writeClassLoaderBaseResourceWSDLLocation(String className, JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
360 JBlock staticBlock = cls.init();
361 JVar exVar = staticBlock.decl(cm.ref(WebServiceException.class), "e", JExpr._null());
362 JVar urlVar = staticBlock.decl(cm.ref(URL.class), "url", JExpr._null());
363 JTryBlock tryBlock = staticBlock._try();
364 tryBlock.body().assign(urlVar, JExpr._new(cm.ref(URL.class)).arg(JExpr.dotclass(cm.ref(className)).invoke("getResource").arg(".")).arg(wsdlLocation));
365 JCatchBlock catchBlock = tryBlock._catch(cm.ref(MalformedURLException.class));
366 JVar murlVar = catchBlock.param("murl");
367 catchBlock.body().assign(exVar, JExpr._new(cm.ref(WebServiceException.class)).arg(murlVar));
368 staticBlock.assign(urlField, urlVar);
369 staticBlock.assign(exField, exVar);
370 }
371
372 /*
373 Generates code that gives wsdl URL. If there is an exception in
374 creating the URL, it throws an exception.
375
376 for example:
377
378 private URL __getWsdlLocation() {
379 if (EXAMPLESERVICE_EXCEPTION != null) {
380 throw EXAMPLESERVICE_EXCEPTION;
381 }
382 return EXAMPLESERVICE_WSDL_LOCATION;
383 }
384 */
385 private void writeGetWsdlLocation(JType retType, JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
386 JMethod m = cls.method(JMod.PRIVATE|JMod.STATIC , retType, "__getWsdlLocation");
387 JConditional ifBlock = m.body()._if(exField.ne(JExpr._null()));
388 ifBlock._then()._throw(exField);
389 m.body()._return(urlField);
390 }
391
392 private void writeDefaultGetPort(Port port, JType retType, JDefinedClass cls) {
393 String portGetter = port.getPortGetter();
394 JMethod m = cls.method(JMod.PUBLIC, retType, portGetter);
395 JDocComment methodDoc = m.javadoc();
396 if (port.getJavaDoc() != null) {
397 methodDoc.add(port.getJavaDoc());
398 }
399 JCommentPart ret = methodDoc.addReturn();
400 ret.add("returns " + retType.name());
401 JBlock body = m.body();
402 StringBuilder statement = new StringBuilder("return ");
403 statement.append("super.getPort(new QName(\"").append(port.getName().getNamespaceURI()).append("\", \"").append(port.getName().getLocalPart()).append("\"), ");
404 statement.append(retType.name());
405 statement.append(".class);");
406 body.directStatement(statement.toString());
407 writeWebEndpoint(port, m);
408 }
409
410 private void writeWebServiceClientAnnotation(Service service, JAnnotationUse wsa) {
411 String serviceName = service.getName().getLocalPart();
412 String serviceNS = service.getName().getNamespaceURI();
413 wsa.param("name", serviceName);
414 wsa.param("targetNamespace", serviceNS);
415 wsa.param("wsdlLocation", wsdlLocation);
416 }
417
418 private void writeWebEndpoint(Port port, JMethod m) {
419 JAnnotationUse webEndpointAnn = m.annotate(cm.ref(WebEndpoint.class));
420 webEndpointAnn.param("name", port.getName().getLocalPart());
421 }
422 }

mercurial