1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/tools/internal/ws/processor/generator/SeiGenerator.java Tue Mar 06 16:09:35 2012 -0800 1.3 @@ -0,0 +1,471 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.internal.ws.processor.generator; 1.30 + 1.31 +import com.sun.codemodel.internal.*; 1.32 +import com.sun.tools.internal.ws.api.TJavaGeneratorExtension; 1.33 +import com.sun.tools.internal.ws.processor.model.*; 1.34 +import com.sun.tools.internal.ws.processor.model.java.JavaInterface; 1.35 +import com.sun.tools.internal.ws.processor.model.java.JavaMethod; 1.36 +import com.sun.tools.internal.ws.processor.model.java.JavaParameter; 1.37 +import com.sun.tools.internal.ws.processor.model.jaxb.JAXBType; 1.38 +import com.sun.tools.internal.ws.processor.model.jaxb.JAXBTypeAndAnnotation; 1.39 +import com.sun.tools.internal.ws.wscompile.ErrorReceiver; 1.40 +import com.sun.tools.internal.ws.wscompile.Options; 1.41 +import com.sun.tools.internal.ws.wscompile.WsimportOptions; 1.42 +import com.sun.tools.internal.ws.wscompile.AbortException; 1.43 +import com.sun.tools.internal.ws.wsdl.document.soap.SOAPStyle; 1.44 +import com.sun.tools.internal.ws.wsdl.document.PortType; 1.45 +import com.sun.tools.internal.ws.wsdl.document.Kinds; 1.46 +import com.sun.tools.internal.ws.resources.GeneratorMessages; 1.47 + 1.48 +import javax.jws.WebMethod; 1.49 +import javax.jws.WebParam; 1.50 +import javax.jws.WebService; 1.51 +import javax.jws.soap.SOAPBinding; 1.52 +import javax.xml.bind.annotation.XmlSeeAlso; 1.53 +import javax.xml.namespace.QName; 1.54 +import javax.xml.ws.Holder; 1.55 +import java.util.ArrayList; 1.56 +import java.util.List; 1.57 + 1.58 +import org.xml.sax.Locator; 1.59 + 1.60 +public class SeiGenerator extends GeneratorBase { 1.61 + private String serviceNS; 1.62 + private TJavaGeneratorExtension extension; 1.63 + private List<TJavaGeneratorExtension> extensionHandlers; 1.64 + 1.65 + public static void generate(Model model, WsimportOptions options, ErrorReceiver receiver, TJavaGeneratorExtension... extensions){ 1.66 + SeiGenerator seiGenerator = new SeiGenerator(); 1.67 + seiGenerator.init(model, options, receiver, extensions); 1.68 + seiGenerator.doGeneration(); 1.69 + } 1.70 + 1.71 + public void init(Model model, WsimportOptions options, ErrorReceiver receiver, TJavaGeneratorExtension... extensions) { 1.72 + init(model, options, receiver); 1.73 + extensionHandlers = new ArrayList<TJavaGeneratorExtension>(); 1.74 + 1.75 + // register handlers for default extensions 1.76 + 1.77 + // 2.2 Spec requires generation of @Action when wsam:Action is explicitly stated in wsdl 1.78 + if (options.target.isLaterThan(Options.Target.V2_2)) { 1.79 + register(new W3CAddressingJavaGeneratorExtension()); 1.80 + } 1.81 + 1.82 + for (TJavaGeneratorExtension j : extensions) 1.83 + register(j); 1.84 + 1.85 + this.extension = new JavaGeneratorExtensionFacade(extensionHandlers.toArray(new TJavaGeneratorExtension[0])); 1.86 + } 1.87 + 1.88 + private void write(Port port) { 1.89 + JavaInterface intf = port.getJavaInterface(); 1.90 + String className = Names.customJavaTypeClassName(intf); 1.91 + 1.92 + if (donotOverride && GeneratorUtil.classExists(options, className)) { 1.93 + log("Class " + className + " exists. Not overriding."); 1.94 + return; 1.95 + } 1.96 + 1.97 + 1.98 + JDefinedClass cls = null; 1.99 + try { 1.100 + cls = getClass(className, ClassType.INTERFACE); 1.101 + } catch (JClassAlreadyExistsException e) { 1.102 + QName portTypeName = 1.103 + (QName) port.getProperty( 1.104 + ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME); 1.105 + Locator loc = null; 1.106 + if(portTypeName != null){ 1.107 + PortType pt = port.portTypes.get(portTypeName); 1.108 + if(pt!=null) 1.109 + loc = pt.getLocator(); 1.110 + } 1.111 + receiver.error(loc, GeneratorMessages.GENERATOR_SEI_CLASS_ALREADY_EXIST(intf.getName(), portTypeName)); 1.112 + return; 1.113 + } 1.114 + // If the class has methods it has already been defined 1.115 + // so skip it. 1.116 + if (!cls.methods().isEmpty()) 1.117 + return; 1.118 + 1.119 + //write class comment - JAXWS warning 1.120 + JDocComment comment = cls.javadoc(); 1.121 + 1.122 + String ptDoc = intf.getJavaDoc(); 1.123 + if(ptDoc != null){ 1.124 + comment.add(ptDoc); 1.125 + comment.add("\n\n"); 1.126 + } 1.127 + 1.128 + for(String doc:getJAXWSClassComment()){ 1.129 + comment.add(doc); 1.130 + } 1.131 + 1.132 + 1.133 + //@WebService 1.134 + JAnnotationUse webServiceAnn = cls.annotate(cm.ref(WebService.class)); 1.135 + writeWebServiceAnnotation(port, webServiceAnn); 1.136 + 1.137 + //@HandlerChain 1.138 + writeHandlerConfig(Names.customJavaTypeClassName(port.getJavaInterface()), cls, options); 1.139 + 1.140 + //@SOAPBinding 1.141 + writeSOAPBinding(port, cls); 1.142 + 1.143 + //@XmlSeeAlso 1.144 + if(options.target.isLaterThan(Options.Target.V2_1)) 1.145 + writeXmlSeeAlso(cls); 1.146 + 1.147 + for (Operation operation: port.getOperations()) { 1.148 + JavaMethod method = operation.getJavaMethod(); 1.149 + 1.150 + //@WebMethod 1.151 + JMethod m; 1.152 + JDocComment methodDoc; 1.153 + String methodJavaDoc = operation.getJavaDoc(); 1.154 + if(method.getReturnType().getName().equals("void")){ 1.155 + m = cls.method(JMod.PUBLIC, void.class, method.getName()); 1.156 + methodDoc = m.javadoc(); 1.157 + }else { 1.158 + JAXBTypeAndAnnotation retType = method.getReturnType().getType(); 1.159 + m = cls.method(JMod.PUBLIC, retType.getType(), method.getName()); 1.160 + retType.annotate(m); 1.161 + methodDoc = m.javadoc(); 1.162 + JCommentPart ret = methodDoc.addReturn(); 1.163 + ret.add("returns "+retType.getName()); 1.164 + } 1.165 + if(methodJavaDoc != null) 1.166 + methodDoc.add(methodJavaDoc); 1.167 + 1.168 + writeWebMethod(operation, m); 1.169 + JClass holder = cm.ref(Holder.class); 1.170 + for (JavaParameter parameter: method.getParametersList()) { 1.171 + JVar var; 1.172 + JAXBTypeAndAnnotation paramType = parameter.getType().getType(); 1.173 + if (parameter.isHolder()) { 1.174 + var = m.param(holder.narrow(paramType.getType().boxify()), parameter.getName()); 1.175 + }else{ 1.176 + var = m.param(paramType.getType(), parameter.getName()); 1.177 + } 1.178 + 1.179 + //annotate parameter with JAXB annotations 1.180 + paramType.annotate(var); 1.181 + methodDoc.addParam(var); 1.182 + JAnnotationUse paramAnn = var.annotate(cm.ref(WebParam.class)); 1.183 + writeWebParam(operation, parameter, paramAnn); 1.184 + } 1.185 + com.sun.tools.internal.ws.wsdl.document.Operation wsdlOp = operation.getWSDLPortTypeOperation(); 1.186 + for(Fault fault:operation.getFaultsSet()){ 1.187 + m._throws(fault.getExceptionClass()); 1.188 + methodDoc.addThrows(fault.getExceptionClass()); 1.189 + wsdlOp.putFault(fault.getWsdlFaultName(), fault.getExceptionClass()); 1.190 + } 1.191 + 1.192 + //It should be the last thing to invoke after JMethod is built completely 1.193 + extension.writeMethodAnnotations(wsdlOp, m); 1.194 + } 1.195 + } 1.196 + 1.197 + private void writeXmlSeeAlso(JDefinedClass cls) { 1.198 + if (model.getJAXBModel().getS2JJAXBModel() != null) { 1.199 + List<JClass> objectFactories = model.getJAXBModel().getS2JJAXBModel().getAllObjectFactories(); 1.200 + 1.201 + //if there are no object facotires, dont generate @XmlSeeAlso 1.202 + if(objectFactories.size() == 0) 1.203 + return; 1.204 + 1.205 + JAnnotationUse xmlSeeAlso = cls.annotate(cm.ref(XmlSeeAlso.class)); 1.206 + JAnnotationArrayMember paramArray = xmlSeeAlso.paramArray("value"); 1.207 + for (JClass of : objectFactories) { 1.208 + paramArray = paramArray.param(of); 1.209 + } 1.210 + } 1.211 + 1.212 + } 1.213 + 1.214 + private void writeWebMethod(Operation operation, JMethod m) { 1.215 + Response response = operation.getResponse(); 1.216 + JAnnotationUse webMethodAnn = m.annotate(cm.ref(WebMethod.class)); 1.217 + String operationName = (operation instanceof AsyncOperation)? 1.218 + ((AsyncOperation)operation).getNormalOperation().getName().getLocalPart(): 1.219 + operation.getName().getLocalPart(); 1.220 + 1.221 + if(!m.name().equals(operationName)){ 1.222 + webMethodAnn.param("operationName", operationName); 1.223 + } 1.224 + 1.225 + if (operation.getSOAPAction() != null && operation.getSOAPAction().length() > 0){ 1.226 + webMethodAnn.param("action", operation.getSOAPAction()); 1.227 + } 1.228 + 1.229 + if (operation.getResponse() == null){ 1.230 + m.annotate(javax.jws.Oneway.class); 1.231 + }else if (!operation.getJavaMethod().getReturnType().getName().equals("void") && 1.232 + operation.getResponse().getParametersList().size() > 0){ 1.233 + Block block; 1.234 + String resultName = null; 1.235 + String nsURI = null; 1.236 + if (operation.getResponse().getBodyBlocks().hasNext()) { 1.237 + block = operation.getResponse().getBodyBlocks().next(); 1.238 + resultName = block.getName().getLocalPart(); 1.239 + if(isDocStyle || block.getLocation() == Block.HEADER){ 1.240 + nsURI = block.getName().getNamespaceURI(); 1.241 + } 1.242 + } 1.243 + 1.244 + for (Parameter parameter : operation.getResponse().getParametersList()) { 1.245 + if (parameter.getParameterIndex() == -1) { 1.246 + if(operation.isWrapped()||!isDocStyle){ 1.247 + if(parameter.getBlock().getLocation() == Block.HEADER){ 1.248 + resultName = parameter.getBlock().getName().getLocalPart(); 1.249 + }else{ 1.250 + resultName = parameter.getName(); 1.251 + } 1.252 + if (isDocStyle || (parameter.getBlock().getLocation() == Block.HEADER)) { 1.253 + nsURI = parameter.getType().getName().getNamespaceURI(); 1.254 + } 1.255 + }else if(isDocStyle){ 1.256 + JAXBType t = (JAXBType)parameter.getType(); 1.257 + resultName = t.getName().getLocalPart(); 1.258 + nsURI = t.getName().getNamespaceURI(); 1.259 + } 1.260 + if(!(operation instanceof AsyncOperation)){ 1.261 + JAnnotationUse wr = null; 1.262 + 1.263 + if(!resultName.equals("return")){ 1.264 + wr = m.annotate(javax.jws.WebResult.class); 1.265 + wr.param("name", resultName); 1.266 + } 1.267 + if((nsURI != null) && (!nsURI.equals(serviceNS) || (isDocStyle && operation.isWrapped()))){ 1.268 + if(wr == null) 1.269 + wr = m.annotate(javax.jws.WebResult.class); 1.270 + wr.param("targetNamespace", nsURI); 1.271 + } 1.272 + //doclit wrapped could have additional headers 1.273 + if(!(isDocStyle && operation.isWrapped()) || 1.274 + (parameter.getBlock().getLocation() == Block.HEADER)){ 1.275 + if(wr == null) 1.276 + wr = m.annotate(javax.jws.WebResult.class); 1.277 + wr.param("partName", parameter.getName()); 1.278 + } 1.279 + if(parameter.getBlock().getLocation() == Block.HEADER){ 1.280 + if(wr == null) 1.281 + wr = m.annotate(javax.jws.WebResult.class); 1.282 + wr.param("header",true); 1.283 + } 1.284 + } 1.285 + } 1.286 + 1.287 + } 1.288 + } 1.289 + 1.290 + //DOC/BARE 1.291 + if (!sameParamStyle) { 1.292 + if(!operation.isWrapped()) { 1.293 + JAnnotationUse sb = m.annotate(SOAPBinding.class); 1.294 + sb.param("parameterStyle", SOAPBinding.ParameterStyle.BARE); 1.295 + } 1.296 + } 1.297 + 1.298 + if (operation.isWrapped() && operation.getStyle().equals(SOAPStyle.DOCUMENT)) { 1.299 + Block reqBlock = operation.getRequest().getBodyBlocks().next(); 1.300 + JAnnotationUse reqW = m.annotate(javax.xml.ws.RequestWrapper.class); 1.301 + reqW.param("localName", reqBlock.getName().getLocalPart()); 1.302 + reqW.param("targetNamespace", reqBlock.getName().getNamespaceURI()); 1.303 + reqW.param("className", reqBlock.getType().getJavaType().getName()); 1.304 + 1.305 + if (response != null) { 1.306 + JAnnotationUse resW = m.annotate(javax.xml.ws.ResponseWrapper.class); 1.307 + Block resBlock = response.getBodyBlocks().next(); 1.308 + resW.param("localName", resBlock.getName().getLocalPart()); 1.309 + resW.param("targetNamespace", resBlock.getName().getNamespaceURI()); 1.310 + resW.param("className", resBlock.getType().getJavaType().getName()); 1.311 + } 1.312 + } 1.313 + } 1.314 + 1.315 + private boolean isMessageParam(Parameter param, Message message) { 1.316 + Block block = param.getBlock(); 1.317 + 1.318 + return (message.getBodyBlockCount() > 0 && block.equals(message.getBodyBlocks().next())) || 1.319 + (message.getHeaderBlockCount() > 0 && 1.320 + block.equals(message.getHeaderBlocks().next())); 1.321 + } 1.322 + 1.323 + private boolean isHeaderParam(Parameter param, Message message) { 1.324 + if (message.getHeaderBlockCount() == 0) 1.325 + return false; 1.326 + 1.327 + for (Block headerBlock : message.getHeaderBlocksMap().values()) 1.328 + if (param.getBlock().equals(headerBlock)) 1.329 + return true; 1.330 + 1.331 + return false; 1.332 + } 1.333 + 1.334 + private boolean isAttachmentParam(Parameter param, Message message){ 1.335 + if (message.getAttachmentBlockCount() == 0) 1.336 + return false; 1.337 + 1.338 + for (Block attBlock : message.getAttachmentBlocksMap().values()) 1.339 + if (param.getBlock().equals(attBlock)) 1.340 + return true; 1.341 + 1.342 + return false; 1.343 + } 1.344 + 1.345 + private boolean isUnboundParam(Parameter param, Message message){ 1.346 + if (message.getUnboundBlocksCount() == 0) 1.347 + return false; 1.348 + 1.349 + for (Block unboundBlock : message.getUnboundBlocksMap().values()) 1.350 + if (param.getBlock().equals(unboundBlock)) 1.351 + return true; 1.352 + 1.353 + return false; 1.354 + } 1.355 + 1.356 + private void writeWebParam(Operation operation, JavaParameter javaParameter, JAnnotationUse paramAnno) { 1.357 + Parameter param = javaParameter.getParameter(); 1.358 + Request req = operation.getRequest(); 1.359 + Response res = operation.getResponse(); 1.360 + 1.361 + boolean header = isHeaderParam(param, req) || 1.362 + (res != null && isHeaderParam(param, res)); 1.363 + 1.364 + String name; 1.365 + boolean isWrapped = operation.isWrapped(); 1.366 + 1.367 + if((param.getBlock().getLocation() == Block.HEADER) || (isDocStyle && !isWrapped)) 1.368 + name = param.getBlock().getName().getLocalPart(); 1.369 + else 1.370 + name = param.getName(); 1.371 + 1.372 + paramAnno.param("name", name); 1.373 + 1.374 + String ns= null; 1.375 + 1.376 + if (isDocStyle) { 1.377 + ns = param.getBlock().getName().getNamespaceURI(); // its bare nsuri 1.378 + if(isWrapped){ 1.379 + ns = param.getType().getName().getNamespaceURI(); 1.380 + } 1.381 + }else if(header){ 1.382 + ns = param.getBlock().getName().getNamespaceURI(); 1.383 + } 1.384 + 1.385 + if((ns != null) && (!ns.equals(serviceNS) || (isDocStyle && isWrapped))) 1.386 + paramAnno.param("targetNamespace", ns); 1.387 + 1.388 + if (header) { 1.389 + paramAnno.param("header", true); 1.390 + } 1.391 + 1.392 + if (param.isINOUT()){ 1.393 + paramAnno.param("mode", javax.jws.WebParam.Mode.INOUT); 1.394 + }else if ((res != null) && (isMessageParam(param, res) || isHeaderParam(param, res) || isAttachmentParam(param, res) || 1.395 + isUnboundParam(param,res) || param.isOUT())){ 1.396 + paramAnno.param("mode", javax.jws.WebParam.Mode.OUT); 1.397 + } 1.398 + 1.399 + //doclit wrapped could have additional headers 1.400 + if(!(isDocStyle && isWrapped) || header) 1.401 + paramAnno.param("partName", javaParameter.getParameter().getName()); 1.402 + } 1.403 + 1.404 + private boolean isDocStyle = true; 1.405 + private boolean sameParamStyle = true; 1.406 + private void writeSOAPBinding(Port port, JDefinedClass cls) { 1.407 + JAnnotationUse soapBindingAnn = null; 1.408 + isDocStyle = port.getStyle() == null || port.getStyle().equals(SOAPStyle.DOCUMENT); 1.409 + if(!isDocStyle){ 1.410 + soapBindingAnn = cls.annotate(SOAPBinding.class); 1.411 + soapBindingAnn.param("style", SOAPBinding.Style.RPC); 1.412 + port.setWrapped(true); 1.413 + } 1.414 + if(isDocStyle){ 1.415 + boolean first = true; 1.416 + boolean isWrapper = true; 1.417 + for(Operation operation:port.getOperations()){ 1.418 + if(first){ 1.419 + isWrapper = operation.isWrapped(); 1.420 + first = false; 1.421 + continue; 1.422 + } 1.423 + sameParamStyle = (isWrapper == operation.isWrapped()); 1.424 + if(!sameParamStyle) 1.425 + break; 1.426 + } 1.427 + if(sameParamStyle) 1.428 + port.setWrapped(isWrapper); 1.429 + } 1.430 + if(sameParamStyle && !port.isWrapped()){ 1.431 + if(soapBindingAnn == null) 1.432 + soapBindingAnn = cls.annotate(SOAPBinding.class); 1.433 + soapBindingAnn.param("parameterStyle", SOAPBinding.ParameterStyle.BARE); 1.434 + } 1.435 + } 1.436 + 1.437 + private void writeWebServiceAnnotation(Port port, JAnnotationUse wsa) { 1.438 + QName name = (QName) port.getProperty(ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME); 1.439 + wsa.param("name", name.getLocalPart()); 1.440 + wsa.param("targetNamespace", name.getNamespaceURI()); 1.441 + } 1.442 + 1.443 + 1.444 + 1.445 + 1.446 + public void visit(Model model) throws Exception { 1.447 + for(Service s:model.getServices()){ 1.448 + s.accept(this); 1.449 + } 1.450 + } 1.451 + 1.452 + public void visit(Service service) throws Exception { 1.453 + String jd = model.getJavaDoc(); 1.454 + if(jd != null){ 1.455 + JPackage pkg = cm._package(options.defaultPackage); 1.456 + pkg.javadoc().add(jd); 1.457 + } 1.458 + 1.459 + for(Port p:service.getPorts()){ 1.460 + visitPort(service, p); 1.461 + } 1.462 + } 1.463 + 1.464 + private void visitPort(Service service, Port port) { 1.465 + if (port.isProvider()) { 1.466 + return; // Not generating for Provider based endpoint 1.467 + } 1.468 + write(port); 1.469 + } 1.470 + 1.471 + private void register(TJavaGeneratorExtension h) { 1.472 + extensionHandlers.add(h); 1.473 + } 1.474 +}