1 /* 2 * Copyright (c) 1997, 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 23 * questions. 24 */ 25 26 package com.sun.tools.internal.ws.processor.modeler.annotation; 27 28 import com.sun.codemodel.internal.CodeWriter; 29 import com.sun.codemodel.internal.JAnnotationArrayMember; 30 import com.sun.codemodel.internal.JAnnotationUse; 31 import com.sun.codemodel.internal.JBlock; 32 import com.sun.codemodel.internal.JCodeModel; 33 import com.sun.codemodel.internal.JCommentPart; 34 import com.sun.codemodel.internal.JDefinedClass; 35 import com.sun.codemodel.internal.JDocComment; 36 import com.sun.codemodel.internal.JExpr; 37 import com.sun.codemodel.internal.JFieldVar; 38 import com.sun.codemodel.internal.JMethod; 39 import com.sun.codemodel.internal.JMod; 40 import com.sun.codemodel.internal.JType; 41 import com.sun.codemodel.internal.JVar; 42 import com.sun.codemodel.internal.writer.ProgressCodeWriter; 43 import com.sun.tools.internal.jxc.ap.InlineAnnotationReaderImpl; 44 import com.sun.tools.internal.jxc.model.nav.ApNavigator; 45 import com.sun.tools.internal.ws.ToolVersion; 46 import com.sun.tools.internal.ws.processor.generator.GeneratorBase; 47 import com.sun.tools.internal.ws.processor.generator.GeneratorConstants; 48 import com.sun.tools.internal.ws.processor.generator.Names; 49 import com.sun.tools.internal.ws.processor.modeler.ModelerException; 50 import com.sun.tools.internal.ws.processor.util.DirectoryUtil; 51 import com.sun.tools.internal.ws.resources.WebserviceapMessages; 52 import com.sun.tools.internal.ws.util.ClassNameInfo; 53 import com.sun.tools.internal.ws.wscompile.FilerCodeWriter; 54 import com.sun.tools.internal.ws.wscompile.WsgenOptions; 55 import com.sun.tools.internal.ws.wsdl.document.soap.SOAPStyle; 56 import com.sun.xml.internal.bind.v2.model.annotation.AnnotationReader; 57 import com.sun.xml.internal.bind.v2.model.nav.Navigator; 58 import com.sun.xml.internal.ws.model.AbstractWrapperBeanGenerator; 59 import com.sun.xml.internal.ws.spi.db.BindingHelper; 60 import com.sun.xml.internal.ws.util.StringUtils; 61 62 import javax.jws.Oneway; 63 import javax.jws.WebMethod; 64 import javax.jws.WebService; 65 import javax.lang.model.element.ExecutableElement; 66 import javax.lang.model.element.Name; 67 import javax.lang.model.element.TypeElement; 68 import javax.lang.model.type.DeclaredType; 69 import javax.lang.model.type.MirroredTypeException; 70 import javax.lang.model.type.TypeKind; 71 import javax.lang.model.type.TypeMirror; 72 import javax.xml.bind.annotation.XmlAccessType; 73 import javax.xml.bind.annotation.XmlAccessorType; 74 import javax.xml.bind.annotation.XmlAttachmentRef; 75 import javax.xml.bind.annotation.XmlElement; 76 import javax.xml.bind.annotation.XmlList; 77 import javax.xml.bind.annotation.XmlMimeType; 78 import javax.xml.bind.annotation.XmlRootElement; 79 import javax.xml.bind.annotation.XmlType; 80 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 81 import javax.xml.namespace.QName; 82 import javax.xml.ws.RequestWrapper; 83 import javax.xml.ws.ResponseWrapper; 84 import javax.xml.ws.WebFault; 85 import javax.xml.ws.WebServiceException; 86 import java.io.File; 87 import java.io.IOException; 88 import java.lang.annotation.Annotation; 89 import java.util.Collection; 90 import java.util.HashSet; 91 import java.util.List; 92 import java.util.Set; 93 94 import static com.sun.codemodel.internal.ClassType.CLASS; 95 import static com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceConstants.BEAN; 96 import static com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceConstants.FAULT_INFO; 97 import static com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceConstants.JAXWS_PACKAGE_PD; 98 import static com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceConstants.PD_JAXWS_PACKAGE_PD; 99 import static com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceConstants.RESPONSE; 100 101 /** 102 * This class generates the request/response and Exception Beans 103 * used by the JAX-WS runtime. 104 * 105 * @author WS Development Team 106 */ 107 public class WebServiceWrapperGenerator extends WebServiceVisitor { 108 private Set<String> wrapperNames; 109 private Set<String> processedExceptions; 110 private JCodeModel cm; 111 private final MakeSafeTypeVisitor makeSafeVisitor; 112 113 private static final FieldFactory FIELD_FACTORY = new FieldFactory(); 114 115 private final AbstractWrapperBeanGenerator ap_generator = 116 new ApWrapperBeanGenerator(InlineAnnotationReaderImpl.theInstance, 117 new ApNavigator(builder.getProcessingEnvironment()), FIELD_FACTORY); 118 119 private final class ApWrapperBeanGenerator extends AbstractWrapperBeanGenerator<TypeMirror, TypeElement, ExecutableElement, MemberInfo> { 120 121 protected ApWrapperBeanGenerator( 122 AnnotationReader<TypeMirror, TypeElement, ?, ExecutableElement> annReader, 123 Navigator<TypeMirror, TypeElement, ?, ExecutableElement> nav, BeanMemberFactory<TypeMirror, MemberInfo> beanMemberFactory) { 124 super(annReader, nav, beanMemberFactory); 125 } 126 127 @Override 128 protected TypeMirror getSafeType(TypeMirror type) { 129 return WebServiceWrapperGenerator.this.getSafeType(type); 130 } 131 132 @Override 133 protected TypeMirror getHolderValueType(TypeMirror paramType) { 134 return builder.getHolderValueType(paramType); 135 } 136 137 @Override 138 protected boolean isVoidType(TypeMirror type) { 139 return type != null && type.getKind().equals(TypeKind.VOID); 140 } 141 142 } 143 144 private static final class FieldFactory implements AbstractWrapperBeanGenerator.BeanMemberFactory<TypeMirror, MemberInfo> { 145 146 @Override 147 public MemberInfo createWrapperBeanMember(TypeMirror paramType, 148 String paramName, List<Annotation> jaxb) { 149 return new MemberInfo(paramType, paramName, jaxb); 150 } 151 } 152 153 public WebServiceWrapperGenerator(ModelBuilder builder, AnnotationProcessorContext context) { 154 super(builder, context); 155 makeSafeVisitor = new MakeSafeTypeVisitor(builder.getProcessingEnvironment()); 156 } 157 158 @Override 159 protected void processWebService(WebService webService, TypeElement d) { 160 cm = new JCodeModel(); 161 wrapperNames = new HashSet<String>(); 162 processedExceptions = new HashSet<String>(); 163 } 164 165 @Override 166 protected void postProcessWebService(WebService webService, TypeElement d) { 167 super.postProcessWebService(webService, d); 168 doPostProcessWebService(webService, d); 169 } 170 171 @SuppressWarnings("CallToThreadDumpStack") 172 protected void doPostProcessWebService(WebService webService, TypeElement d) { 173 if (cm != null) { 174 WsgenOptions options = builder.getOptions(); 175 assert options.filer != null; 176 try { 177 CodeWriter cw = new FilerCodeWriter(options); 178 if(options.verbose) 179 cw = new ProgressCodeWriter(cw, System.out); 180 cm.build(cw); 181 } catch (IOException e) { 182 e.printStackTrace(); 183 } 184 } 185 } 186 187 @Override 188 protected void processMethod(ExecutableElement method, WebMethod webMethod) { 189 builder.log("WrapperGen - method: "+method); 190 builder.log("method.getDeclaringType(): " + method.asType()); 191 if (wrapped && soapStyle.equals(SOAPStyle.DOCUMENT)) { 192 generateWrappers(method, webMethod); 193 } 194 generateExceptionBeans(method); 195 } 196 197 private boolean generateExceptionBeans(ExecutableElement method) { 198 String beanPackage = packageName + PD_JAXWS_PACKAGE_PD.getValue(); 199 if (packageName.length() == 0) 200 beanPackage = JAXWS_PACKAGE_PD.getValue(); 201 boolean beanGenerated = false; 202 for (TypeMirror thrownType : method.getThrownTypes()) { 203 TypeElement typeDecl = (TypeElement) ((DeclaredType) thrownType).asElement(); 204 if (typeDecl == null) { 205 builder.processError(WebserviceapMessages.WEBSERVICEAP_COULD_NOT_FIND_TYPEDECL( 206 thrownType.toString(), context.getRound())); 207 return false; 208 } 209 boolean tmp = generateExceptionBean(typeDecl, beanPackage); 210 beanGenerated = beanGenerated || tmp; 211 } 212 return beanGenerated; 213 } 214 215 private boolean duplicateName(String name) { 216 for (String str : wrapperNames) { 217 if (str.equalsIgnoreCase(name)) 218 return true; 219 } 220 wrapperNames.add(name); 221 return false; 222 } 223 224 private boolean generateWrappers(ExecutableElement method, WebMethod webMethod) { 225 boolean isOneway = method.getAnnotation(Oneway.class) != null; 226 String beanPackage = packageName + PD_JAXWS_PACKAGE_PD.getValue(); 227 if (packageName.length() == 0) 228 beanPackage = JAXWS_PACKAGE_PD.getValue(); 229 Name methodName = method.getSimpleName(); 230 String operationName = builder.getOperationName(methodName); 231 operationName = webMethod != null && webMethod.operationName().length() > 0 ? 232 webMethod.operationName() : operationName; 233 String reqName = operationName; 234 String resName = operationName + WebServiceConstants.RESPONSE.getValue(); 235 String reqNamespace = typeNamespace; 236 String resNamespace = typeNamespace; 237 238 String requestClassName = beanPackage + StringUtils.capitalize(method.getSimpleName().toString()); 239 RequestWrapper reqWrapper = method.getAnnotation(RequestWrapper.class); 240 if (reqWrapper != null) { 241 if (reqWrapper.className().length() > 0) 242 requestClassName = reqWrapper.className(); 243 if (reqWrapper.localName().length() > 0) 244 reqName = reqWrapper.localName(); 245 if (reqWrapper.targetNamespace().length() > 0) 246 reqNamespace = reqWrapper.targetNamespace(); 247 } 248 builder.log("requestWrapper: "+requestClassName); 249 ///// fix for wsgen CR 6442344 250 addGeneratedFile(requestClassName); 251 ////////// 252 boolean canOverwriteRequest = builder.canOverWriteClass(requestClassName); 253 if (!canOverwriteRequest) { 254 builder.log("Class " + requestClassName + " exists. Not overwriting."); 255 } 256 if (duplicateName(requestClassName) && canOverwriteRequest) { 257 builder.processError(WebserviceapMessages.WEBSERVICEAP_METHOD_REQUEST_WRAPPER_BEAN_NAME_NOT_UNIQUE( 258 typeElement.getQualifiedName(), method.toString())); 259 } 260 261 String responseClassName = null; 262 boolean canOverwriteResponse = canOverwriteRequest; 263 if (!isOneway) { 264 responseClassName = beanPackage+StringUtils.capitalize(method.getSimpleName().toString())+RESPONSE.getValue(); 265 ResponseWrapper resWrapper = method.getAnnotation(ResponseWrapper.class); 266 if(resWrapper != null) { 267 if (resWrapper.className().length() > 0) 268 responseClassName = resWrapper.className(); 269 if (resWrapper.localName().length() > 0) 270 resName = resWrapper.localName(); 271 if (resWrapper.targetNamespace().length() > 0) 272 resNamespace = resWrapper.targetNamespace(); 273 } 274 canOverwriteResponse = builder.canOverWriteClass(responseClassName); 275 if (!canOverwriteResponse) { 276 builder.log("Class " + responseClassName + " exists. Not overwriting."); 277 } 278 if (duplicateName(responseClassName) && canOverwriteResponse) { 279 builder.processError(WebserviceapMessages.WEBSERVICEAP_METHOD_RESPONSE_WRAPPER_BEAN_NAME_NOT_UNIQUE( 280 typeElement.getQualifiedName(), method.toString())); 281 } 282 addGeneratedFile(responseClassName); 283 } 284 //ArrayList<MemberInfo> reqMembers = new ArrayList<MemberInfo>(); 285 //ArrayList<MemberInfo> resMembers = new ArrayList<MemberInfo>(); 286 WrapperInfo reqWrapperInfo = new WrapperInfo(requestClassName); 287 //reqWrapperInfo.setMembers(reqMembers); 288 WrapperInfo resWrapperInfo = null; 289 if (!isOneway) { 290 resWrapperInfo = new WrapperInfo(responseClassName); 291 //resWrapperInfo.setMembers(resMembers); 292 } 293 seiContext.setReqWrapperOperation(method, reqWrapperInfo); 294 if (!isOneway) 295 seiContext.setResWrapperOperation(method, resWrapperInfo); 296 try { 297 if (!canOverwriteRequest && !canOverwriteResponse) { 298 return false; 299 } 300 301 JDefinedClass reqCls = null; 302 if (canOverwriteRequest) { 303 reqCls = getCMClass(requestClassName, CLASS); 304 } 305 306 JDefinedClass resCls = null; 307 if (!isOneway && canOverwriteResponse) { 308 resCls = getCMClass(responseClassName, CLASS); 309 } 310 311 // XMLElement Declarations 312 writeXmlElementDeclaration(reqCls, reqName,reqNamespace); 313 writeXmlElementDeclaration(resCls, resName, resNamespace); 314 315 List<MemberInfo> reqMembers = ap_generator.collectRequestBeanMembers(method); 316 List<MemberInfo> resMembers = ap_generator.collectResponseBeanMembers(method); 317 318 // XmlType 319 writeXmlTypeDeclaration(reqCls, reqName, reqNamespace, reqMembers); 320 writeXmlTypeDeclaration(resCls, resName, resNamespace, resMembers); 321 322 // class members 323 writeMembers(reqCls, reqMembers); 324 writeMembers(resCls, resMembers); 325 326 } catch (Exception e) { 327 throw new ModelerException("modeler.nestedGeneratorError",e); 328 } 329 return true; 330 } 331 332 private void addGeneratedFile(String requestClassName) { 333 File file = new File(DirectoryUtil.getOutputDirectoryFor(requestClassName, builder.getSourceDir()), 334 Names.stripQualifier(requestClassName) + GeneratorConstants.JAVA_SRC_SUFFIX.getValue()); 335 builder.getOptions().addGeneratedFile(file); 336 } 337 338 // private List<Annotation> collectJAXBAnnotations(Declaration decl) { 339 // List<Annotation> jaxbAnnotation = new ArrayList<Annotation>(); 340 // for(Class jaxbClass : jaxbAnns) { 341 // Annotation ann = decl.getAnnotation(jaxbClass); 342 // if (ann != null) { 343 // jaxbAnnotation.add(ann); 344 // } 345 // } 346 // return jaxbAnnotation; 347 // } 348 349 private TypeMirror getSafeType(TypeMirror type) { 350 return makeSafeVisitor.visit(type, builder.getProcessingEnvironment().getTypeUtils()); 351 } 352 353 private JType getType(TypeMirror typeMirror) { 354 String type = typeMirror.toString(); 355 try { 356 // System.out.println("typeName: "+typeName); 357 return cm.parseType(type); 358 // System.out.println("type: "+type); 359 } catch (ClassNotFoundException e) { 360 return cm.ref(type); 361 } 362 } 363 364 private void writeMembers(JDefinedClass cls, Collection<MemberInfo> members) { 365 if (cls == null) 366 return; 367 for (MemberInfo memInfo : members) { 368 JType type = getType(memInfo.getParamType()); 369 JFieldVar field = cls.field(JMod.PRIVATE, type, memInfo.getParamName()); 370 annotateParameterWithJaxbAnnotations(memInfo, field); 371 } 372 for (MemberInfo memInfo : members) { 373 writeMember(cls, memInfo.getParamType(), 374 memInfo.getParamName()); 375 } 376 } 377 378 private void annotateParameterWithJaxbAnnotations(MemberInfo memInfo, JFieldVar field) { 379 List<Annotation> jaxbAnnotations = memInfo.getJaxbAnnotations(); 380 for(Annotation ann : jaxbAnnotations) { 381 if (ann instanceof XmlMimeType) { 382 JAnnotationUse jaxbAnn = field.annotate(XmlMimeType.class); 383 jaxbAnn.param("value", ((XmlMimeType)ann).value()); 384 } else if (ann instanceof XmlJavaTypeAdapter) { 385 JAnnotationUse jaxbAnn = field.annotate(XmlJavaTypeAdapter.class); 386 XmlJavaTypeAdapter ja = (XmlJavaTypeAdapter) ann; 387 try { 388 ja.value(); 389 throw new AssertionError(); 390 } catch (MirroredTypeException e) { 391 jaxbAnn.param("value",getType(e.getTypeMirror())); 392 } 393 // XmlJavaTypeAdapter.type() is for package only. No need to copy. 394 } else if (ann instanceof XmlAttachmentRef) { 395 field.annotate(XmlAttachmentRef.class); 396 } else if (ann instanceof XmlList){ 397 field.annotate(XmlList.class); 398 } else if (ann instanceof XmlElement) { 399 XmlElement elemAnn = (XmlElement)ann; 400 JAnnotationUse jAnn = field.annotate(XmlElement.class); 401 jAnn.param("name", elemAnn.name()); 402 jAnn.param("namespace", elemAnn.namespace()); 403 if (elemAnn.nillable()) { 404 jAnn.param("nillable", true); 405 } 406 if (elemAnn.required()) { 407 jAnn.param("required", true); 408 } 409 } else { 410 throw new WebServiceException("SEI Parameter cannot have this JAXB annotation: " + ann); 411 } 412 } 413 } 414 415 protected JDefinedClass getCMClass(String className, com.sun.codemodel.internal.ClassType type) { 416 JDefinedClass cls; 417 try { 418 cls = cm._class(className, type); 419 } catch (com.sun.codemodel.internal.JClassAlreadyExistsException e){ 420 cls = cm._getClass(className); 421 } 422 return cls; 423 } 424 425 private boolean generateExceptionBean(TypeElement thrownDecl, String beanPackage) { 426 if (!builder.isServiceException(thrownDecl.asType())) 427 return false; 428 429 String exceptionName = ClassNameInfo.getName(thrownDecl.getQualifiedName().toString()); 430 if (processedExceptions.contains(exceptionName)) 431 return false; 432 processedExceptions.add(exceptionName); 433 WebFault webFault = thrownDecl.getAnnotation(WebFault.class); 434 String className = beanPackage+ exceptionName + BEAN.getValue(); 435 436 Collection<MemberInfo> members = ap_generator.collectExceptionBeanMembers(thrownDecl); 437 boolean isWSDLException = isWSDLException(members, thrownDecl); 438 String namespace = typeNamespace; 439 String name = exceptionName; 440 FaultInfo faultInfo; 441 if (isWSDLException) { 442 TypeMirror beanType = getFaultInfoMember(members).getParamType(); 443 faultInfo = new FaultInfo(TypeMonikerFactory.getTypeMoniker(beanType), true); 444 namespace = webFault.targetNamespace().length()>0 ? 445 webFault.targetNamespace() : namespace; 446 name = webFault.name().length()>0 ? 447 webFault.name() : name; 448 faultInfo.setElementName(new QName(namespace, name)); 449 seiContext.addExceptionBeanEntry(thrownDecl.getQualifiedName(), faultInfo, builder); 450 return false; 451 } 452 if (webFault != null) { 453 namespace = webFault.targetNamespace().length()>0 ? 454 webFault.targetNamespace() : namespace; 455 name = webFault.name().length()>0 ? 456 webFault.name() : name; 457 className = webFault.faultBean().length()>0 ? 458 webFault.faultBean() : className; 459 460 } 461 JDefinedClass cls = getCMClass(className, CLASS); 462 faultInfo = new FaultInfo(className, false); 463 464 if (duplicateName(className)) { 465 builder.processError(WebserviceapMessages.WEBSERVICEAP_METHOD_EXCEPTION_BEAN_NAME_NOT_UNIQUE( 466 typeElement.getQualifiedName(), thrownDecl.getQualifiedName())); 467 } 468 469 boolean canOverWriteBean = builder.canOverWriteClass(className); 470 if (!canOverWriteBean) { 471 builder.log("Class " + className + " exists. Not overwriting."); 472 seiContext.addExceptionBeanEntry(thrownDecl.getQualifiedName(), faultInfo, builder); 473 return false; 474 } 475 if (seiContext.getExceptionBeanName(thrownDecl.getQualifiedName()) != null) { 476 return false; 477 } 478 479 addGeneratedFile(className); 480 481 //write class comment - JAXWS warning 482 JDocComment comment = cls.javadoc(); 483 for (String doc : GeneratorBase.getJAXWSClassComment(ToolVersion.VERSION.MAJOR_VERSION)) { 484 comment.add(doc); 485 } 486 487 // XmlElement Declarations 488 writeXmlElementDeclaration(cls, name, namespace); 489 490 // XmlType Declaration 491 //members = sortMembers(members); 492 XmlType xmlType = thrownDecl.getAnnotation(XmlType.class); 493 String xmlTypeName = (xmlType != null && !xmlType.name().equals("##default")) ? xmlType.name() : exceptionName; 494 String xmlTypeNamespace = (xmlType != null && !xmlType.namespace().equals("##default")) ? xmlType.namespace() : typeNamespace; 495 writeXmlTypeDeclaration(cls, xmlTypeName, xmlTypeNamespace, members); 496 497 writeMembers(cls, members); 498 499 seiContext.addExceptionBeanEntry(thrownDecl.getQualifiedName(), faultInfo, builder); 500 return true; 501 } 502 503 protected boolean isWSDLException(Collection<MemberInfo> members, TypeElement thrownDecl) { 504 WebFault webFault = thrownDecl.getAnnotation(WebFault.class); 505 return webFault != null && members.size() == 2 && getFaultInfoMember(members) != null; 506 } 507 508 /* 509 * Returns the corresponding MemberInfo for getFaultInfo() 510 * method of an exception. Returns null, if that method is not there. 511 */ 512 private MemberInfo getFaultInfoMember(Collection<MemberInfo> members) { 513 for(MemberInfo member : members) { 514 if (member.getParamName().equals(FAULT_INFO.getValue())) { 515 return member; 516 } 517 } 518 return null; 519 } 520 521 private void writeXmlElementDeclaration(JDefinedClass cls, String elementName, String namespaceUri) { 522 523 if (cls == null) 524 return; 525 JAnnotationUse xmlRootElementAnn = cls.annotate(XmlRootElement.class); 526 xmlRootElementAnn.param("name", elementName); 527 if (namespaceUri.length() > 0) { 528 xmlRootElementAnn.param("namespace", namespaceUri); 529 } 530 JAnnotationUse xmlAccessorTypeAnn = cls.annotate(cm.ref(XmlAccessorType.class)); 531 xmlAccessorTypeAnn.param("value", XmlAccessType.FIELD); 532 } 533 534 private void writeXmlTypeDeclaration(JDefinedClass cls, String typeName, String namespaceUri, 535 Collection<MemberInfo> members) { 536 if (cls == null) 537 return; 538 JAnnotationUse xmlTypeAnn = cls.annotate(cm.ref(XmlType.class)); 539 xmlTypeAnn.param("name", typeName); 540 xmlTypeAnn.param("namespace", namespaceUri); 541 if (members.size() > 1) { 542 JAnnotationArrayMember paramArray = xmlTypeAnn.paramArray("propOrder"); 543 for (MemberInfo memInfo : members) { 544 paramArray.param(memInfo.getParamName()); 545 } 546 } 547 } 548 549 private void writeMember(JDefinedClass cls, TypeMirror paramType, 550 String paramName) { 551 552 if (cls == null) 553 return; 554 555 String accessorName =BindingHelper.mangleNameToPropertyName(paramName); 556 String getterPrefix = paramType.toString().equals("boolean")? "is" : "get"; 557 JType propType = getType(paramType); 558 JMethod m = cls.method(JMod.PUBLIC, propType, getterPrefix+ accessorName); 559 JDocComment methodDoc = m.javadoc(); 560 JCommentPart ret = methodDoc.addReturn(); 561 ret.add("returns "+propType.name()); 562 JBlock body = m.body(); 563 body._return( JExpr._this().ref(paramName) ); 564 565 m = cls.method(JMod.PUBLIC, cm.VOID, "set"+accessorName); 566 JVar param = m.param(propType, paramName); 567 methodDoc = m.javadoc(); 568 JCommentPart part = methodDoc.addParam(paramName); 569 part.add("the value for the "+ paramName+" property"); 570 body = m.body(); 571 body.assign( JExpr._this().ref(paramName), param ); 572 } 573 }