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 static com.sun.codemodel.ClassType.CLASS;
039: import com.sun.codemodel.*;
040: import com.sun.codemodel.writer.ProgressCodeWriter;
041: import com.sun.mirror.declaration.*;
042: import com.sun.mirror.type.ClassType;
043: import com.sun.mirror.type.*;
044: import com.sun.tools.ws.processor.generator.GeneratorBase;
045: import com.sun.tools.ws.processor.generator.GeneratorConstants;
046: import com.sun.tools.ws.processor.generator.Names;
047: import com.sun.tools.ws.processor.modeler.ModelerException;
048: import com.sun.tools.ws.processor.util.DirectoryUtil;
049: import com.sun.tools.ws.resources.WebserviceapMessages;
050: import com.sun.tools.ws.util.ClassNameInfo;
051: import com.sun.tools.ws.wscompile.FilerCodeWriter;
052: import com.sun.tools.ws.wscompile.WsgenOptions;
053: import com.sun.tools.ws.wsdl.document.soap.SOAPStyle;
054: import com.sun.xml.ws.util.StringUtils;
055: import com.sun.xml.bind.api.JAXBRIContext;
056: import com.sun.xml.bind.api.impl.NameConverter;
057:
058: import javax.jws.*;
059: import javax.xml.bind.annotation.*;
060: import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
061: import javax.xml.namespace.QName;
062: import javax.xml.ws.RequestWrapper;
063: import javax.xml.ws.ResponseWrapper;
064: import javax.xml.ws.WebFault;
065: import java.io.File;
066: import java.io.IOException;
067: import java.util.*;
068: import java.lang.annotation.Annotation;
069:
070: /**
071: * This class generates the request/response and Exception Beans
072: * used by the JAX-WS runtime.
073: *
074: * @author WS Development Team
075: */
076: public class WebServiceWrapperGenerator extends WebServiceVisitor {
077: protected Set<String> wrapperNames;
078: protected Set<String> processedExceptions;
079: protected JCodeModel cm;
080: protected MakeSafeTypeVisitor makeSafeVisitor;
081:
082: public WebServiceWrapperGenerator(ModelBuilder builder,
083: AnnotationProcessorContext context) {
084: super (builder, context);
085: makeSafeVisitor = new MakeSafeTypeVisitor(builder.getAPEnv());
086: }
087:
088: protected void processWebService(WebService webService,
089: TypeDeclaration d) {
090: cm = new JCodeModel();
091: wrapperNames = new HashSet<String>();
092: processedExceptions = new HashSet<String>();
093: }
094:
095: protected void postProcessWebService(WebService webService,
096: InterfaceDeclaration d) {
097: super .postProcessWebService(webService, d);
098: doPostProcessWebService(webService, d);
099: }
100:
101: protected void postProcessWebService(WebService webService,
102: ClassDeclaration d) {
103: super .postProcessWebService(webService, d);
104: doPostProcessWebService(webService, d);
105: }
106:
107: protected void doPostProcessWebService(WebService webService,
108: TypeDeclaration d) {
109: if (cm != null) {
110: File sourceDir = builder.getSourceDir();
111: assert (sourceDir != null);
112: WsgenOptions options = builder.getOptions();
113: try {
114: CodeWriter cw = new FilerCodeWriter(sourceDir, options);
115: if (options.verbose)
116: cw = new ProgressCodeWriter(cw, System.out);
117: cm.build(cw);
118: } catch (IOException e) {
119: e.printStackTrace();
120: }
121: }
122: }
123:
124: protected void processMethod(MethodDeclaration method,
125: WebMethod webMethod) {
126: builder.log("WrapperGen - method: " + method);
127: builder.log("method.getDeclaringType(): "
128: + method.getDeclaringType());
129: boolean generatedWrapper = false;
130: if (wrapped && soapStyle.equals(SOAPStyle.DOCUMENT)) {
131: generatedWrapper = generateWrappers(method, webMethod);
132: }
133: generatedWrapper = generateExceptionBeans(method)
134: || generatedWrapper;
135: if (generatedWrapper) {
136: // Theres not going to be a second round
137: builder.setWrapperGenerated(generatedWrapper);
138: }
139: }
140:
141: private boolean generateExceptionBeans(MethodDeclaration method) {
142: String beanPackage = packageName + PD_JAXWS_PACKAGE_PD;
143: if (packageName.length() == 0)
144: beanPackage = JAXWS_PACKAGE_PD;
145: boolean beanGenerated = false;
146: for (ReferenceType thrownType : method.getThrownTypes()) {
147: ClassDeclaration typeDecl = ((ClassType) thrownType)
148: .getDeclaration();
149: if (typeDecl == null) {
150: builder.onError(WebserviceapMessages
151: .WEBSERVICEAP_COULD_NOT_FIND_TYPEDECL(
152: thrownType.toString(), context
153: .getRound()));
154: return false;
155: }
156: boolean tmp = generateExceptionBean(typeDecl, beanPackage);
157: beanGenerated = beanGenerated || tmp;
158: }
159: return beanGenerated;
160: }
161:
162: private boolean duplicateName(String name) {
163: for (String str : wrapperNames) {
164: if (str.equalsIgnoreCase(name))
165: return true;
166: }
167: wrapperNames.add(name);
168: return false;
169: }
170:
171: private boolean generateWrappers(MethodDeclaration method,
172: WebMethod webMethod) {
173: boolean isOneway = method.getAnnotation(Oneway.class) != null;
174: String beanPackage = packageName + PD_JAXWS_PACKAGE_PD;
175: if (packageName.length() == 0)
176: beanPackage = JAXWS_PACKAGE_PD;
177: String methodName = method.getSimpleName();
178: String operationName = builder.getOperationName(methodName);
179: operationName = webMethod != null
180: && webMethod.operationName().length() > 0 ? webMethod
181: .operationName() : operationName;
182: String reqName = operationName;
183: String resName = operationName + RESPONSE;
184: String reqNamespace = typeNamespace;
185: String resNamespace = typeNamespace;
186:
187: String requestClassName = beanPackage
188: + StringUtils.capitalize(method.getSimpleName());
189: RequestWrapper reqWrapper = method
190: .getAnnotation(RequestWrapper.class);
191: if (reqWrapper != null) {
192: if (reqWrapper.className().length() > 0)
193: requestClassName = reqWrapper.className();
194: if (reqWrapper.localName().length() > 0)
195: reqName = reqWrapper.localName();
196: if (reqWrapper.targetNamespace().length() > 0)
197: reqNamespace = reqWrapper.targetNamespace();
198: }
199: builder.log("requestWrapper: " + requestClassName);
200: ///// fix for wsgen CR 6442344
201: File file = new File(DirectoryUtil.getOutputDirectoryFor(
202: requestClassName, builder.getSourceDir()), Names
203: .stripQualifier(requestClassName)
204: + GeneratorConstants.JAVA_SRC_SUFFIX);
205: builder.getOptions().addGeneratedFile(file);
206: //////////
207: boolean canOverwriteRequest = builder
208: .canOverWriteClass(requestClassName);
209: if (!canOverwriteRequest) {
210: builder.log("Class " + requestClassName
211: + " exists. Not overwriting.");
212: }
213: if (duplicateName(requestClassName) && canOverwriteRequest) {
214: builder
215: .onError(WebserviceapMessages
216: .WEBSERVICEAP_METHOD_REQUEST_WRAPPER_BEAN_NAME_NOT_UNIQUE(
217: typeDecl.getQualifiedName(), method
218: .toString()));
219: }
220:
221: String responseClassName = null;
222: boolean canOverwriteResponse = canOverwriteRequest;
223: if (!isOneway) {
224: responseClassName = beanPackage
225: + StringUtils.capitalize(method.getSimpleName())
226: + RESPONSE;
227: ResponseWrapper resWrapper = method
228: .getAnnotation(ResponseWrapper.class);
229: if (resWrapper != null) {
230: if (resWrapper.className().length() > 0)
231: responseClassName = resWrapper.className();
232: if (resWrapper.localName().length() > 0)
233: resName = resWrapper.localName();
234: if (resWrapper.targetNamespace().length() > 0)
235: resNamespace = resWrapper.targetNamespace();
236: }
237: canOverwriteResponse = builder
238: .canOverWriteClass(requestClassName);
239: if (!canOverwriteResponse) {
240: builder.log("Class " + responseClassName
241: + " exists. Not overwriting.");
242: }
243: if (duplicateName(responseClassName)
244: && canOverwriteResponse) {
245: builder
246: .onError(WebserviceapMessages
247: .WEBSERVICEAP_METHOD_RESPONSE_WRAPPER_BEAN_NAME_NOT_UNIQUE(
248: typeDecl.getQualifiedName(),
249: method.toString()));
250: }
251: file = new File(DirectoryUtil.getOutputDirectoryFor(
252: responseClassName, builder.getSourceDir()), Names
253: .stripQualifier(responseClassName)
254: + GeneratorConstants.JAVA_SRC_SUFFIX);
255: builder.getOptions().addGeneratedFile(file);
256: }
257: ArrayList<MemberInfo> reqMembers = new ArrayList<MemberInfo>();
258: ArrayList<MemberInfo> resMembers = new ArrayList<MemberInfo>();
259: WrapperInfo reqWrapperInfo = new WrapperInfo(requestClassName);
260: reqWrapperInfo.setMembers(reqMembers);
261: WrapperInfo resWrapperInfo = null;
262: if (!isOneway) {
263: resWrapperInfo = new WrapperInfo(responseClassName);
264: resWrapperInfo.setMembers(resMembers);
265: }
266: seiContext.setReqWrapperOperation(method, reqWrapperInfo);
267: if (!isOneway)
268: seiContext.setResWrapperOperation(method, resWrapperInfo);
269: try {
270: if (!canOverwriteRequest && !canOverwriteResponse) {
271: return false;
272: }
273:
274: JDefinedClass reqCls = null;
275: if (canOverwriteRequest) {
276: reqCls = getCMClass(requestClassName, CLASS);
277: }
278:
279: JDefinedClass resCls = null;
280: if (!isOneway && canOverwriteResponse) {
281: resCls = getCMClass(responseClassName, CLASS);
282: }
283:
284: // XMLElement Declarations
285: writeXmlElementDeclaration(reqCls, reqName, reqNamespace);
286: writeXmlElementDeclaration(resCls, resName, resNamespace);
287:
288: collectMembers(method, reqMembers, resMembers);
289:
290: // XmlType
291: writeXmlTypeDeclaration(reqCls, reqName, reqNamespace,
292: reqMembers);
293: writeXmlTypeDeclaration(resCls, resName, resNamespace,
294: resMembers);
295:
296: // class members
297: writeMembers(reqCls, reqMembers);
298: writeMembers(resCls, resMembers);
299:
300: } catch (Exception e) {
301: throw new ModelerException("modeler.nestedGeneratorError",
302: e);
303: }
304: return true;
305: }
306:
307: private void collectMembers(MethodDeclaration method,
308: ArrayList<MemberInfo> requestMembers,
309: ArrayList<MemberInfo> responseMembers) {
310:
311: WebResult webResult = method.getAnnotation(WebResult.class);
312: List<Annotation> jaxbRespAnnotations = collectJAXBAnnotations(method);
313: String responseElementName = RETURN;
314: String responseName = RETURN_VALUE;
315: String responseNamespace = wrapped ? EMTPY_NAMESPACE_ID
316: : typeNamespace;
317: boolean isResultHeader = false;
318: if (webResult != null) {
319: if (webResult.name().length() > 0) {
320: responseElementName = webResult.name();
321: responseName = JAXBRIContext
322: .mangleNameToVariableName(webResult.name());
323:
324: //We wont have to do this if JAXBRIContext.mangleNameToVariableName() takes
325: //care of mangling java identifiers
326: responseName = Names
327: .getJavaReserverVarialbeName(responseName);
328: }
329: responseNamespace = webResult.targetNamespace().length() > 1 ? webResult
330: .targetNamespace()
331: : responseNamespace;
332: isResultHeader = webResult.header();
333: }
334:
335: // class members
336: WebParam webParam;
337: TypeMirror paramType;
338: String paramName;
339:
340: String paramNamespace;
341: TypeMirror holderType;
342: int paramIndex = -1;
343: TypeMirror typeMirror = getSafeType(method.getReturnType());
344:
345: if (!(method.getReturnType() instanceof VoidType)
346: && !isResultHeader) {
347: responseMembers.add(new MemberInfo(typeMirror,
348: responseName, new QName(responseNamespace,
349: responseElementName), method,
350: jaxbRespAnnotations
351: .toArray(new Annotation[jaxbRespAnnotations
352: .size()])));
353: }
354:
355: for (ParameterDeclaration param : method.getParameters()) {
356: List<Annotation> jaxbAnnotation = collectJAXBAnnotations(param);
357: WebParam.Mode mode = null;
358: paramIndex++;
359: holderType = builder.getHolderValueType(param.getType());
360: webParam = param.getAnnotation(WebParam.class);
361: typeMirror = getSafeType(param.getType());
362: paramType = typeMirror;
363: paramNamespace = wrapped ? EMTPY_NAMESPACE_ID
364: : typeNamespace;
365: if (holderType != null) {
366: paramType = holderType;
367: }
368: paramName = "arg" + paramIndex;
369: if (webParam != null && webParam.header()) {
370: continue;
371: }
372: if (webParam != null) {
373: mode = webParam.mode();
374: if (webParam.name().length() > 0)
375: paramName = webParam.name();
376: if (webParam.targetNamespace().length() > 0)
377: paramNamespace = webParam.targetNamespace();
378: }
379:
380: String propertyName = JAXBRIContext
381: .mangleNameToVariableName(paramName);
382: //We wont have to do this if JAXBRIContext.mangleNameToVariableName() takes
383: //care of mangling java identifiers
384: propertyName = Names
385: .getJavaReserverVarialbeName(propertyName);
386:
387: MemberInfo memInfo = new MemberInfo(paramType,
388: propertyName, new QName(paramNamespace, paramName),
389: param, jaxbAnnotation
390: .toArray(new Annotation[jaxbAnnotation
391: .size()]));
392: if (holderType != null) {
393: if (mode == null || mode.equals(WebParam.Mode.INOUT)) {
394: requestMembers.add(memInfo);
395: }
396: responseMembers.add(memInfo);
397: } else {
398: requestMembers.add(memInfo);
399: }
400: }
401: }
402:
403: private List<Annotation> collectJAXBAnnotations(
404: ParameterDeclaration param) {
405: List<Annotation> jaxbAnnotation = new ArrayList<Annotation>();
406: Annotation ann = param.getAnnotation(XmlAttachmentRef.class);
407: if (ann != null)
408: jaxbAnnotation.add(ann);
409:
410: ann = param.getAnnotation(XmlMimeType.class);
411: if (ann != null)
412: jaxbAnnotation.add(ann);
413:
414: ann = param.getAnnotation(XmlJavaTypeAdapter.class);
415: if (ann != null)
416: jaxbAnnotation.add(ann);
417:
418: ann = param.getAnnotation(XmlList.class);
419: if (ann != null)
420: jaxbAnnotation.add(ann);
421: return jaxbAnnotation;
422: }
423:
424: private List<Annotation> collectJAXBAnnotations(
425: MethodDeclaration method) {
426: List<Annotation> jaxbAnnotation = new ArrayList<Annotation>();
427: Annotation ann = method.getAnnotation(XmlAttachmentRef.class);
428: if (ann != null)
429: jaxbAnnotation.add(ann);
430:
431: ann = method.getAnnotation(XmlMimeType.class);
432: if (ann != null)
433: jaxbAnnotation.add(ann);
434:
435: ann = method.getAnnotation(XmlJavaTypeAdapter.class);
436: if (ann != null)
437: jaxbAnnotation.add(ann);
438:
439: ann = method.getAnnotation(XmlList.class);
440: if (ann != null)
441: jaxbAnnotation.add(ann);
442: return jaxbAnnotation;
443: }
444:
445: private TypeMirror getSafeType(TypeMirror type) {
446: return makeSafeVisitor.apply(type, builder.getAPEnv()
447: .getTypeUtils());
448: }
449:
450: private JType getType(TypeMirror typeMirror) {
451: String type = typeMirror.toString();
452: try {
453: // System.out.println("typeName: "+typeName);
454: return cm.parseType(type);
455: // System.out.println("type: "+type);
456: } catch (ClassNotFoundException e) {
457: return cm.ref(type);
458: }
459: }
460:
461: private ArrayList<MemberInfo> sortMembers(
462: ArrayList<MemberInfo> members) {
463: Map<String, MemberInfo> sortedMap = new java.util.TreeMap<String, MemberInfo>();
464: for (MemberInfo member : members) {
465: sortedMap.put(member.getParamName(), member);
466: }
467: ArrayList<MemberInfo> sortedMembers = new ArrayList<MemberInfo>();
468: sortedMembers.addAll(sortedMap.values());
469: return sortedMembers;
470: }
471:
472: private void writeMembers(JDefinedClass cls,
473: ArrayList<MemberInfo> members) {
474: if (cls == null)
475: return;
476: for (MemberInfo memInfo : members) {
477: JType type = getType(memInfo.getParamType());
478: JFieldVar field = cls.field(JMod.PRIVATE, type, memInfo
479: .getParamName());
480: QName elementName = memInfo.getElementName();
481: if (elementName != null) {
482: if (soapStyle.equals(SOAPStyle.RPC) || wrapped) {
483: JAnnotationUse xmlElementAnn = field
484: .annotate(XmlElement.class);
485: xmlElementAnn.param("name", elementName
486: .getLocalPart());
487: xmlElementAnn.param("namespace", elementName
488: .getNamespaceURI());
489: if (memInfo.getParamType() instanceof ArrayType) {
490: xmlElementAnn.param("nillable", true);
491: }
492: } else {
493: field.annotate(XmlValue.class);
494: }
495: annotateParameterWithJAXBAnnotations(field, memInfo
496: .getJaxbAnnotations());
497: }
498:
499: // copy adapter if needed
500: XmlJavaTypeAdapter xjta = memInfo.getDecl().getAnnotation(
501: XmlJavaTypeAdapter.class);
502: if (xjta != null) {
503: JAnnotationUse xjtaA = field
504: .annotate(XmlJavaTypeAdapter.class);
505: try {
506: xjta.value();
507: throw new AssertionError();
508: } catch (MirroredTypeException e) {
509: xjtaA.param("value", getType(e.getTypeMirror()));
510: }
511: // XmlJavaTypeAdapter.type() is for package only. No need to copy.
512: }
513: }
514: for (MemberInfo memInfo : members) {
515: writeMember(cls, memInfo.getParamType(), memInfo
516: .getParamName());
517: }
518: }
519:
520: private void annotateParameterWithJAXBAnnotations(JFieldVar field,
521: Annotation[] jaxbAnnotations) {
522: for (Annotation ann : jaxbAnnotations) {
523: if (ann instanceof XmlMimeType) {
524: JAnnotationUse jaxbAnn = field
525: .annotate(XmlMimeType.class);
526: jaxbAnn.param("value", ((XmlMimeType) ann).value());
527: } else if (ann instanceof XmlJavaTypeAdapter) {
528: JAnnotationUse jaxbAnn = field
529: .annotate(XmlJavaTypeAdapter.class);
530: XmlJavaTypeAdapter ja = (XmlJavaTypeAdapter) ann;
531: jaxbAnn.param("value", ja.value());
532: jaxbAnn.param("type", ja.type());
533: } else if (ann instanceof XmlAttachmentRef) {
534: field.annotate(XmlAttachmentRef.class);
535: } else if (ann instanceof XmlList) {
536: field.annotate(XmlList.class);
537: }
538: }
539: }
540:
541: protected JDefinedClass getCMClass(String className,
542: com.sun.codemodel.ClassType type) {
543: JDefinedClass cls;
544: try {
545: cls = cm._class(className, type);
546: } catch (com.sun.codemodel.JClassAlreadyExistsException e) {
547: cls = cm._getClass(className);
548: }
549: return cls;
550: }
551:
552: private boolean generateExceptionBean(ClassDeclaration thrownDecl,
553: String beanPackage) {
554: if (builder.isRemoteException(thrownDecl))
555: return false;
556:
557: String exceptionName = ClassNameInfo.getName(thrownDecl
558: .getQualifiedName());
559: if (processedExceptions.contains(exceptionName))
560: return false;
561: processedExceptions.add(exceptionName);
562: WebFault webFault = thrownDecl.getAnnotation(WebFault.class);
563: String className = beanPackage + exceptionName + BEAN;
564:
565: TreeMap<String, MethodDeclaration> propertyToTypeMap = new TreeMap<String, MethodDeclaration>();
566:
567: TypeModeler.collectExceptionProperties(thrownDecl,
568: propertyToTypeMap);
569:
570: boolean isWSDLException = isWSDLException(propertyToTypeMap,
571: thrownDecl);
572: String namespace = typeNamespace;
573: String name = exceptionName;
574: FaultInfo faultInfo;
575: if (isWSDLException) {
576: TypeMirror beanType = getSafeType(propertyToTypeMap.get(
577: FAULT_INFO).getReturnType());
578: faultInfo = new FaultInfo(TypeMonikerFactory
579: .getTypeMoniker(beanType), true);
580: namespace = webFault.targetNamespace().length() > 0 ? webFault
581: .targetNamespace()
582: : namespace;
583: name = webFault.name().length() > 0 ? webFault.name()
584: : name;
585: faultInfo.setElementName(new QName(namespace, name));
586: seiContext.addExceptionBeanEntry(thrownDecl
587: .getQualifiedName(), faultInfo, builder);
588: return false;
589: }
590: if (webFault != null) {
591: namespace = webFault.targetNamespace().length() > 0 ? webFault
592: .targetNamespace()
593: : namespace;
594: name = webFault.name().length() > 0 ? webFault.name()
595: : name;
596: className = webFault.faultBean().length() > 0 ? webFault
597: .faultBean() : className;
598:
599: }
600: JDefinedClass cls = getCMClass(className, CLASS);
601: faultInfo = new FaultInfo(className, false);
602:
603: if (duplicateName(className)) {
604: builder
605: .onError(WebserviceapMessages
606: .WEBSERVICEAP_METHOD_EXCEPTION_BEAN_NAME_NOT_UNIQUE(
607: typeDecl.getQualifiedName(),
608: thrownDecl.getQualifiedName()));
609: }
610:
611: ArrayList<MemberInfo> members = new ArrayList<MemberInfo>();
612: for (String key : propertyToTypeMap.keySet()) {
613: MethodDeclaration method = propertyToTypeMap.get(key);
614: TypeMirror erasureType = getSafeType(method.getReturnType());
615: MemberInfo member = new MemberInfo(erasureType, key, null,
616: method);
617: members.add(member);
618: }
619: faultInfo.setMembers(members);
620:
621: boolean canOverWriteBean = builder.canOverWriteClass(className);
622: if (!canOverWriteBean) {
623: builder.log("Class " + className
624: + " exists. Not overwriting.");
625: seiContext.addExceptionBeanEntry(thrownDecl
626: .getQualifiedName(), faultInfo, builder);
627: return false;
628: }
629: if (seiContext.getExceptionBeanName(thrownDecl
630: .getQualifiedName()) != null)
631: return false;
632:
633: //write class comment - JAXWS warning
634: JDocComment comment = cls.javadoc();
635: for (String doc : GeneratorBase.getJAXWSClassComment(builder
636: .getSourceVersion())) {
637: comment.add(doc);
638: }
639:
640: // XmlElement Declarations
641: writeXmlElementDeclaration(cls, name, namespace);
642:
643: // XmlType Declaration
644: members = sortMembers(members);
645: writeXmlTypeDeclaration(cls, exceptionName, typeNamespace,
646: members);
647:
648: writeMembers(cls, members);
649:
650: seiContext.addExceptionBeanEntry(thrownDecl.getQualifiedName(),
651: faultInfo, builder);
652: return true;
653: }
654:
655: protected boolean isWSDLException(
656: Map<String, MethodDeclaration> map,
657: ClassDeclaration thrownDecl) {
658: WebFault webFault = thrownDecl.getAnnotation(WebFault.class);
659: if (webFault == null)
660: return false;
661: return !(map.size() != 2 || map.get(FAULT_INFO) == null);
662: }
663:
664: private void writeXmlElementDeclaration(JDefinedClass cls,
665: String elementName, String namespaceUri) {
666:
667: if (cls == null)
668: return;
669: JAnnotationUse xmlRootElementAnn = cls
670: .annotate(XmlRootElement.class);
671: xmlRootElementAnn.param("name", elementName);
672: if (namespaceUri.length() > 0) {
673: xmlRootElementAnn.param("namespace", namespaceUri);
674: }
675: JAnnotationUse xmlAccessorTypeAnn = cls.annotate(cm
676: .ref(XmlAccessorType.class));
677: xmlAccessorTypeAnn.param("value", XmlAccessType.FIELD);
678: }
679:
680: private void writeXmlTypeDeclaration(JDefinedClass cls,
681: String typeName, String namespaceUri,
682: ArrayList<MemberInfo> members) {
683: if (cls == null)
684: return;
685: JAnnotationUse xmlTypeAnn = cls.annotate(cm.ref(XmlType.class));
686: xmlTypeAnn.param("name", typeName);
687: xmlTypeAnn.param("namespace", namespaceUri);
688: if (members.size() > 1) {
689: JAnnotationArrayMember paramArray = xmlTypeAnn
690: .paramArray("propOrder");
691: for (MemberInfo memInfo : members) {
692: paramArray.param(memInfo.getParamName());
693: }
694: }
695: }
696:
697: private void writeMember(JDefinedClass cls, TypeMirror paramType,
698: String paramName) {
699:
700: if (cls == null)
701: return;
702:
703: String accessorName = JAXBRIContext
704: .mangleNameToPropertyName(paramName);
705: String getterPrefix = paramType.toString().equals("boolean") ? "is"
706: : "get";
707: JType propType = getType(paramType);
708: JMethod m = cls.method(JMod.PUBLIC, propType, getterPrefix
709: + accessorName);
710: JDocComment methodDoc = m.javadoc();
711: JCommentPart ret = methodDoc.addReturn();
712: ret.add("returns " + propType.name());
713: JBlock body = m.body();
714: body._return(JExpr._this ().ref(paramName));
715:
716: m = cls.method(JMod.PUBLIC, cm.VOID, "set" + accessorName);
717: JVar param = m.param(propType, paramName);
718: methodDoc = m.javadoc();
719: JCommentPart part = methodDoc.addParam(paramName);
720: part.add("the value for the " + paramName + " property");
721: body = m.body();
722: body.assign(JExpr._this().ref(paramName), param);
723: }
724: }
|