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 Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,491 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2013, 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.wsdl.document.soap.SOAPStyle; 1.43 +import com.sun.tools.internal.ws.wsdl.document.PortType; 1.44 +import com.sun.tools.internal.ws.resources.GeneratorMessages; 1.45 + 1.46 +import javax.jws.WebMethod; 1.47 +import javax.jws.WebParam; 1.48 +import javax.jws.WebService; 1.49 +import javax.jws.soap.SOAPBinding; 1.50 +import javax.xml.bind.annotation.XmlSeeAlso; 1.51 +import javax.xml.namespace.QName; 1.52 +import javax.xml.ws.Holder; 1.53 +import java.util.ArrayList; 1.54 +import java.util.List; 1.55 + 1.56 +import org.xml.sax.Locator; 1.57 + 1.58 +public class SeiGenerator extends GeneratorBase { 1.59 + private TJavaGeneratorExtension extension; 1.60 + private List<TJavaGeneratorExtension> extensionHandlers; 1.61 + 1.62 + public static void generate(Model model, WsimportOptions options, ErrorReceiver receiver, TJavaGeneratorExtension... extensions){ 1.63 + SeiGenerator seiGenerator = new SeiGenerator(); 1.64 + seiGenerator.init(model, options, receiver, extensions); 1.65 + seiGenerator.doGeneration(); 1.66 + } 1.67 + 1.68 + public void init(Model model, WsimportOptions options, ErrorReceiver receiver, TJavaGeneratorExtension... extensions) { 1.69 + init(model, options, receiver); 1.70 + extensionHandlers = new ArrayList<TJavaGeneratorExtension>(); 1.71 + 1.72 + // register handlers for default extensions 1.73 + 1.74 + // 2.2 Spec requires generation of @Action when wsam:Action is explicitly stated in wsdl 1.75 + if (options.target.isLaterThan(Options.Target.V2_2)) { 1.76 + register(new W3CAddressingJavaGeneratorExtension()); 1.77 + } 1.78 + 1.79 + for (TJavaGeneratorExtension j : extensions) { 1.80 + register(j); 1.81 + } 1.82 + 1.83 + this.extension = new JavaGeneratorExtensionFacade(extensionHandlers.toArray(new TJavaGeneratorExtension[extensionHandlers.size()])); 1.84 + } 1.85 + 1.86 + private void write(Port port) { 1.87 + JavaInterface intf = port.getJavaInterface(); 1.88 + String className = Names.customJavaTypeClassName(intf); 1.89 + 1.90 + if (donotOverride && GeneratorUtil.classExists(options, className)) { 1.91 + log("Class " + className + " exists. Not overriding."); 1.92 + return; 1.93 + } 1.94 + 1.95 + 1.96 + JDefinedClass cls; 1.97 + try { 1.98 + cls = getClass(className, ClassType.INTERFACE); 1.99 + } catch (JClassAlreadyExistsException e) { 1.100 + QName portTypeName = 1.101 + (QName) port.getProperty( 1.102 + ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME); 1.103 + Locator loc = null; 1.104 + if(portTypeName != null){ 1.105 + PortType pt = port.portTypes.get(portTypeName); 1.106 + if (pt!=null) { 1.107 + loc = pt.getLocator(); 1.108 + } 1.109 + } 1.110 + receiver.error(loc, GeneratorMessages.GENERATOR_SEI_CLASS_ALREADY_EXIST(intf.getName(), portTypeName)); 1.111 + return; 1.112 + } 1.113 + // If the class has methods it has already been defined 1.114 + // so skip it. 1.115 + if (!cls.methods().isEmpty()) { 1.116 + return; 1.117 + } 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 + 1.148 + for (Operation operation: port.getOperations()) { 1.149 + JavaMethod method = operation.getJavaMethod(); 1.150 + 1.151 + //@WebMethod 1.152 + JMethod m; 1.153 + JDocComment methodDoc; 1.154 + String methodJavaDoc = operation.getJavaDoc(); 1.155 + if(method.getReturnType().getName().equals("void")){ 1.156 + m = cls.method(JMod.PUBLIC, void.class, method.getName()); 1.157 + methodDoc = m.javadoc(); 1.158 + }else { 1.159 + JAXBTypeAndAnnotation retType = method.getReturnType().getType(); 1.160 + m = cls.method(JMod.PUBLIC, retType.getType(), method.getName()); 1.161 + retType.annotate(m); 1.162 + methodDoc = m.javadoc(); 1.163 + JCommentPart ret = methodDoc.addReturn(); 1.164 + ret.add("returns "+retType.getName()); 1.165 + } 1.166 + if (methodJavaDoc != null) { 1.167 + methodDoc.add(methodJavaDoc); 1.168 + } 1.169 + 1.170 + writeWebMethod(operation, m); 1.171 + JClass holder = cm.ref(Holder.class); 1.172 + for (JavaParameter parameter: method.getParametersList()) { 1.173 + JVar var; 1.174 + JAXBTypeAndAnnotation paramType = parameter.getType().getType(); 1.175 + if (parameter.isHolder()) { 1.176 + var = m.param(holder.narrow(paramType.getType().boxify()), parameter.getName()); 1.177 + }else{ 1.178 + var = m.param(paramType.getType(), parameter.getName()); 1.179 + } 1.180 + 1.181 + //annotate parameter with JAXB annotations 1.182 + paramType.annotate(var); 1.183 + methodDoc.addParam(var); 1.184 + JAnnotationUse paramAnn = var.annotate(cm.ref(WebParam.class)); 1.185 + writeWebParam(operation, parameter, paramAnn); 1.186 + } 1.187 + com.sun.tools.internal.ws.wsdl.document.Operation wsdlOp = operation.getWSDLPortTypeOperation(); 1.188 + for(Fault fault:operation.getFaultsSet()){ 1.189 + m._throws(fault.getExceptionClass()); 1.190 + methodDoc.addThrows(fault.getExceptionClass()); 1.191 + wsdlOp.putFault(fault.getWsdlFaultName(), fault.getExceptionClass()); 1.192 + } 1.193 + 1.194 + //It should be the last thing to invoke after JMethod is built completely 1.195 + extension.writeMethodAnnotations(wsdlOp, m); 1.196 + } 1.197 + } 1.198 + 1.199 + private void writeXmlSeeAlso(JDefinedClass cls) { 1.200 + if (model.getJAXBModel().getS2JJAXBModel() != null) { 1.201 + List<JClass> objectFactories = model.getJAXBModel().getS2JJAXBModel().getAllObjectFactories(); 1.202 + 1.203 + //if there are no object facotires, dont generate @XmlSeeAlso 1.204 + if (objectFactories.isEmpty()) { 1.205 + return; 1.206 + } 1.207 + 1.208 + JAnnotationUse xmlSeeAlso = cls.annotate(cm.ref(XmlSeeAlso.class)); 1.209 + JAnnotationArrayMember paramArray = xmlSeeAlso.paramArray("value"); 1.210 + for (JClass of : objectFactories) { 1.211 + paramArray = paramArray.param(of); 1.212 + } 1.213 + } 1.214 + 1.215 + } 1.216 + 1.217 + private void writeWebMethod(Operation operation, JMethod m) { 1.218 + Response response = operation.getResponse(); 1.219 + JAnnotationUse webMethodAnn = m.annotate(cm.ref(WebMethod.class)); 1.220 + String operationName = (operation instanceof AsyncOperation)? 1.221 + ((AsyncOperation)operation).getNormalOperation().getName().getLocalPart(): 1.222 + operation.getName().getLocalPart(); 1.223 + 1.224 + if(!m.name().equals(operationName)){ 1.225 + webMethodAnn.param("operationName", operationName); 1.226 + } 1.227 + 1.228 + if (operation.getSOAPAction() != null && operation.getSOAPAction().length() > 0){ 1.229 + webMethodAnn.param("action", operation.getSOAPAction()); 1.230 + } 1.231 + 1.232 + if (operation.getResponse() == null){ 1.233 + m.annotate(javax.jws.Oneway.class); 1.234 + }else if (!operation.getJavaMethod().getReturnType().getName().equals("void") && 1.235 + operation.getResponse().getParametersList().size() > 0){ 1.236 + Block block; 1.237 + String resultName = null; 1.238 + String nsURI = null; 1.239 + if (operation.getResponse().getBodyBlocks().hasNext()) { 1.240 + block = operation.getResponse().getBodyBlocks().next(); 1.241 + resultName = block.getName().getLocalPart(); 1.242 + if(isDocStyle || block.getLocation() == Block.HEADER){ 1.243 + nsURI = block.getName().getNamespaceURI(); 1.244 + } 1.245 + } 1.246 + 1.247 + for (Parameter parameter : operation.getResponse().getParametersList()) { 1.248 + if (parameter.getParameterIndex() == -1) { 1.249 + if(operation.isWrapped()||!isDocStyle){ 1.250 + if(parameter.getBlock().getLocation() == Block.HEADER){ 1.251 + resultName = parameter.getBlock().getName().getLocalPart(); 1.252 + }else{ 1.253 + resultName = parameter.getName(); 1.254 + } 1.255 + if (isDocStyle || (parameter.getBlock().getLocation() == Block.HEADER)) { 1.256 + nsURI = parameter.getType().getName().getNamespaceURI(); 1.257 + } 1.258 + }else if(isDocStyle){ 1.259 + JAXBType t = (JAXBType)parameter.getType(); 1.260 + resultName = t.getName().getLocalPart(); 1.261 + nsURI = t.getName().getNamespaceURI(); 1.262 + } 1.263 + if(!(operation instanceof AsyncOperation)){ 1.264 + JAnnotationUse wr = null; 1.265 + 1.266 + if(!resultName.equals("return")){ 1.267 + wr = m.annotate(javax.jws.WebResult.class); 1.268 + wr.param("name", resultName); 1.269 + } 1.270 + if (nsURI != null || (isDocStyle && operation.isWrapped())) { 1.271 + if(wr == null) { 1.272 + wr = m.annotate(javax.jws.WebResult.class); 1.273 + } 1.274 + wr.param("targetNamespace", nsURI); 1.275 + } 1.276 + //doclit wrapped could have additional headers 1.277 + if(!(isDocStyle && operation.isWrapped()) || 1.278 + (parameter.getBlock().getLocation() == Block.HEADER)){ 1.279 + if (wr == null) { 1.280 + wr = m.annotate(javax.jws.WebResult.class); 1.281 + } 1.282 + wr.param("partName", parameter.getName()); 1.283 + } 1.284 + if(parameter.getBlock().getLocation() == Block.HEADER){ 1.285 + if (wr == null) { 1.286 + wr = m.annotate(javax.jws.WebResult.class); 1.287 + } 1.288 + wr.param("header",true); 1.289 + } 1.290 + } 1.291 + } 1.292 + 1.293 + } 1.294 + } 1.295 + 1.296 + //DOC/BARE 1.297 + if (!sameParamStyle) { 1.298 + if(!operation.isWrapped()) { 1.299 + JAnnotationUse sb = m.annotate(SOAPBinding.class); 1.300 + sb.param("parameterStyle", SOAPBinding.ParameterStyle.BARE); 1.301 + } 1.302 + } 1.303 + 1.304 + if (operation.isWrapped() && operation.getStyle().equals(SOAPStyle.DOCUMENT)) { 1.305 + Block reqBlock = operation.getRequest().getBodyBlocks().next(); 1.306 + JAnnotationUse reqW = m.annotate(javax.xml.ws.RequestWrapper.class); 1.307 + reqW.param("localName", reqBlock.getName().getLocalPart()); 1.308 + reqW.param("targetNamespace", reqBlock.getName().getNamespaceURI()); 1.309 + reqW.param("className", reqBlock.getType().getJavaType().getName()); 1.310 + 1.311 + if (response != null) { 1.312 + JAnnotationUse resW = m.annotate(javax.xml.ws.ResponseWrapper.class); 1.313 + Block resBlock = response.getBodyBlocks().next(); 1.314 + resW.param("localName", resBlock.getName().getLocalPart()); 1.315 + resW.param("targetNamespace", resBlock.getName().getNamespaceURI()); 1.316 + resW.param("className", resBlock.getType().getJavaType().getName()); 1.317 + } 1.318 + } 1.319 + } 1.320 + 1.321 + private boolean isMessageParam(Parameter param, Message message) { 1.322 + Block block = param.getBlock(); 1.323 + 1.324 + return (message.getBodyBlockCount() > 0 && block.equals(message.getBodyBlocks().next())) || 1.325 + (message.getHeaderBlockCount() > 0 && 1.326 + block.equals(message.getHeaderBlocks().next())); 1.327 + } 1.328 + 1.329 + private boolean isHeaderParam(Parameter param, Message message) { 1.330 + if (message.getHeaderBlockCount() == 0) { 1.331 + return false; 1.332 + } 1.333 + 1.334 + for (Block headerBlock : message.getHeaderBlocksMap().values()) { 1.335 + if (param.getBlock().equals(headerBlock)) { 1.336 + return true; 1.337 + } 1.338 + } 1.339 + 1.340 + return false; 1.341 + } 1.342 + 1.343 + private boolean isAttachmentParam(Parameter param, Message message){ 1.344 + if (message.getAttachmentBlockCount() == 0) { 1.345 + return false; 1.346 + } 1.347 + 1.348 + for (Block attBlock : message.getAttachmentBlocksMap().values()) { 1.349 + if (param.getBlock().equals(attBlock)) { 1.350 + return true; 1.351 + } 1.352 + } 1.353 + 1.354 + return false; 1.355 + } 1.356 + 1.357 + private boolean isUnboundParam(Parameter param, Message message){ 1.358 + if (message.getUnboundBlocksCount() == 0) { 1.359 + return false; 1.360 + } 1.361 + 1.362 + for (Block unboundBlock : message.getUnboundBlocksMap().values()) { 1.363 + if (param.getBlock().equals(unboundBlock)) { 1.364 + return true; 1.365 + } 1.366 + } 1.367 + 1.368 + return false; 1.369 + } 1.370 + 1.371 + private void writeWebParam(Operation operation, JavaParameter javaParameter, JAnnotationUse paramAnno) { 1.372 + Parameter param = javaParameter.getParameter(); 1.373 + Request req = operation.getRequest(); 1.374 + Response res = operation.getResponse(); 1.375 + 1.376 + boolean header = isHeaderParam(param, req) || 1.377 + (res != null && isHeaderParam(param, res)); 1.378 + 1.379 + String name; 1.380 + boolean isWrapped = operation.isWrapped(); 1.381 + 1.382 + if ((param.getBlock().getLocation() == Block.HEADER) || (isDocStyle && !isWrapped)) { 1.383 + name = param.getBlock().getName().getLocalPart(); 1.384 + } else { 1.385 + name = param.getName(); 1.386 + } 1.387 + 1.388 + paramAnno.param("name", name); 1.389 + 1.390 + String ns= null; 1.391 + 1.392 + if (isDocStyle) { 1.393 + ns = param.getBlock().getName().getNamespaceURI(); // its bare nsuri 1.394 + if(isWrapped){ 1.395 + ns = param.getType().getName().getNamespaceURI(); 1.396 + } 1.397 + }else if(header){ 1.398 + ns = param.getBlock().getName().getNamespaceURI(); 1.399 + } 1.400 + 1.401 + if (ns != null || (isDocStyle && isWrapped)) { 1.402 + paramAnno.param("targetNamespace", ns); 1.403 + } 1.404 + 1.405 + if (header) { 1.406 + paramAnno.param("header", true); 1.407 + } 1.408 + 1.409 + if (param.isINOUT()){ 1.410 + paramAnno.param("mode", javax.jws.WebParam.Mode.INOUT); 1.411 + }else if ((res != null) && (isMessageParam(param, res) || isHeaderParam(param, res) || isAttachmentParam(param, res) || 1.412 + isUnboundParam(param,res) || param.isOUT())){ 1.413 + paramAnno.param("mode", javax.jws.WebParam.Mode.OUT); 1.414 + } 1.415 + 1.416 + //doclit wrapped could have additional headers 1.417 + if (!(isDocStyle && isWrapped) || header) { 1.418 + paramAnno.param("partName", javaParameter.getParameter().getName()); 1.419 + } 1.420 + } 1.421 + 1.422 + private boolean isDocStyle = true; 1.423 + private boolean sameParamStyle = true; 1.424 + private void writeSOAPBinding(Port port, JDefinedClass cls) { 1.425 + JAnnotationUse soapBindingAnn = null; 1.426 + isDocStyle = port.getStyle() == null || port.getStyle().equals(SOAPStyle.DOCUMENT); 1.427 + if(!isDocStyle){ 1.428 + soapBindingAnn = cls.annotate(SOAPBinding.class); 1.429 + soapBindingAnn.param("style", SOAPBinding.Style.RPC); 1.430 + port.setWrapped(true); 1.431 + } 1.432 + if(isDocStyle){ 1.433 + boolean first = true; 1.434 + boolean isWrapper = true; 1.435 + for(Operation operation:port.getOperations()){ 1.436 + if(first){ 1.437 + isWrapper = operation.isWrapped(); 1.438 + first = false; 1.439 + continue; 1.440 + } 1.441 + sameParamStyle = (isWrapper == operation.isWrapped()); 1.442 + if (!sameParamStyle) { 1.443 + break; 1.444 + } 1.445 + } 1.446 + if (sameParamStyle) { 1.447 + port.setWrapped(isWrapper); 1.448 + } 1.449 + } 1.450 + if(sameParamStyle && !port.isWrapped()){ 1.451 + if (soapBindingAnn == null) { 1.452 + soapBindingAnn = cls.annotate(SOAPBinding.class); 1.453 + } 1.454 + soapBindingAnn.param("parameterStyle", SOAPBinding.ParameterStyle.BARE); 1.455 + } 1.456 + } 1.457 + 1.458 + private void writeWebServiceAnnotation(Port port, JAnnotationUse wsa) { 1.459 + QName name = (QName) port.getProperty(ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME); 1.460 + wsa.param("name", name.getLocalPart()); 1.461 + wsa.param("targetNamespace", name.getNamespaceURI()); 1.462 + } 1.463 + 1.464 + @Override 1.465 + public void visit(Model model) throws Exception { 1.466 + for(Service s:model.getServices()){ 1.467 + s.accept(this); 1.468 + } 1.469 + } 1.470 + 1.471 + @Override 1.472 + public void visit(Service service) throws Exception { 1.473 + String jd = model.getJavaDoc(); 1.474 + if(jd != null){ 1.475 + JPackage pkg = cm._package(options.defaultPackage); 1.476 + pkg.javadoc().add(jd); 1.477 + } 1.478 + 1.479 + for(Port p:service.getPorts()){ 1.480 + visitPort(service, p); 1.481 + } 1.482 + } 1.483 + 1.484 + private void visitPort(Service service, Port port) { 1.485 + if (port.isProvider()) { 1.486 + return; // Not generating for Provider based endpoint 1.487 + } 1.488 + write(port); 1.489 + } 1.490 + 1.491 + private void register(TJavaGeneratorExtension h) { 1.492 + extensionHandlers.add(h); 1.493 + } 1.494 +}