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
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.websvc.rest.codegen;
042:
043: import com.sun.source.tree.AnnotationTree;
044: import com.sun.source.tree.ClassTree;
045: import com.sun.source.tree.CompilationUnitTree;
046: import com.sun.source.tree.ExpressionTree;
047: import com.sun.source.tree.ModifiersTree;
048: import com.sun.source.tree.Tree;
049: import com.sun.source.tree.VariableTree;
050: import com.sun.source.util.TreePath;
051: import java.io.IOException;
052: import java.text.MessageFormat;
053: import java.util.Collections;
054: import java.util.HashSet;
055: import java.util.List;
056: import java.util.Set;
057: import javax.lang.model.element.Modifier;
058: import javax.lang.model.element.TypeElement;
059: import org.netbeans.api.java.source.CancellableTask;
060: import org.netbeans.api.java.source.CompilationController;
061: import org.netbeans.api.java.source.JavaSource;
062: import org.netbeans.api.java.source.JavaSource.Phase;
063: import org.netbeans.api.java.source.ModificationResult;
064: import org.netbeans.api.java.source.TreeMaker;
065: import org.netbeans.api.java.source.WorkingCopy;
066: import org.netbeans.api.project.FileOwnerQuery;
067: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlOperation;
068: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlParameter;
069: import org.netbeans.modules.websvc.rest.codegen.model.WsdlComponentBean;
070: import org.netbeans.modules.websvc.rest.codegen.model.JaxwsOperationInfo;
071: import org.netbeans.modules.websvc.rest.codegen.model.ParameterInfo;
072: import org.netbeans.modules.websvc.rest.component.palette.RestComponentData;
073: import org.netbeans.modules.websvc.rest.support.AbstractTask;
074: import org.netbeans.modules.websvc.rest.support.JavaSourceHelper;
075: import org.netbeans.modules.websvc.rest.support.SourceGroupSupport;
076: import org.openide.DialogDisplayer;
077: import org.openide.NotifyDescriptor;
078: import org.openide.filesystems.FileObject;
079: import org.openide.util.NbBundle;
080: import static com.sun.source.tree.Tree.Kind.*;
081:
082: /**
083: * Code generator for REST services wrapping WSDL-based web service.
084: *
085: * @author nam
086: */
087: public class WsdlComponentGenerator extends RestComponentGenerator {
088:
089: public static final String SET_HEADER_PARAMS = "setHeaderParameters";
090:
091: public WsdlComponentGenerator(FileObject targetFile,
092: RestComponentData data) {
093: super (targetFile, new WsdlComponentBean(data, FileOwnerQuery
094: .getOwner(targetFile)));
095: }
096:
097: @Override
098: public WsdlComponentBean getBean() {
099: return (WsdlComponentBean) bean;
100: }
101:
102: public static final String QNAME = "javax.xml.namespace.QName";
103: public static final String WS_BINDING_PROVIDER = "com.sun.xml.ws.developer.WSBindingProvider";
104: public static final String HEADERS = "com.sun.xml.ws.api.message.Headers";
105:
106: @Override
107: public void addSupportingMethods() throws IOException {
108: if (getBean().getHeaderParameters().isEmpty()) {
109: return;
110: }
111: ModificationResult result = wrapperResourceJS
112: .runModificationTask(new AbstractTask<WorkingCopy>() {
113: public void run(WorkingCopy copy)
114: throws IOException {
115: copy.toPhase(JavaSource.Phase.RESOLVED);
116: JavaSourceHelper.addImports(copy, new String[] {
117: QNAME, WS_BINDING_PROVIDER, HEADERS });
118: ClassTree initial = JavaSourceHelper
119: .getTopLevelClassTree(copy);
120: ClassTree tree = addSetHeaderParamsMethod(copy,
121: initial, getBean().lastOperationInfo()
122: .getPort().getJavaName());
123: copy.rewrite(initial, tree);
124: }
125: });
126: result.commit();
127: }
128:
129: protected String getCustomMethodBody() throws IOException {
130: String methodBody = "try { ";
131: String converterName = getConverterName();
132: if (converterName != null) {
133: methodBody += "$CONVERTER$ representation = new $CONVERTER$(); "
134: .replace("$CONVERTER$", getConverterName());
135: }
136: JaxwsOperationInfo[] operations = ((WsdlComponentBean) bean)
137: .getOperationInfos();
138: for (JaxwsOperationInfo info : operations) {
139: methodBody += getWSInvocationCode(info);
140: }
141:
142: if (getBean().needsHtmlRepresentation()) {
143: methodBody += "return result;"; //NOI18N
144: } else {
145: methodBody += "return representation;"; //NOI18N
146: }
147: methodBody += "} catch(Exception ex) { //TODO handle \n throw new WebApplicationException(ex); }";
148: return methodBody;
149: }
150:
151: private static final String HINT_INIT_ARGUMENTS = " // TODO initialize WS operation arguments here\n"; //NOI18N
152: // {0} = service java name (as variable, e.g. "AddNumbersService")
153: // {1} = port java name (e.g. "AddNumbersPort")
154: // {2} = port getter method (e.g. "getAddNumbersPort")
155: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
156: // {4} = java result type (e.g. "int")
157: // {5} = operation java method name (e.g. "add")
158: // {6} = java method arguments (e.g. "int x, int y")
159: // {7} = service field name
160: private static final String JAVA_SERVICE_DEF = " {0} {7} = new {0}();\n"; //NOI18N
161: private static final String JAVA_PORT_DEF = " {1} port = {7}.{2}();\n"; //NOI18N
162: private static final String JAVA_RESULT = " {3}"
163: + " // TODO process result here\n"
164: + " {4} result = port.{5}({6});\n"; //NOI18N
165: private static final String JAVA_VOID = " {3}"
166: + " port.{5}({6});\n"; //NOI18N
167: private static final String JAVA_OUT = " {8}.println(\"Result = \"+result);\n"; //NOI18N
168: // {0} = service java name (as variable, e.g. "AddNumbersService")
169: // {1} = port java name (e.g. "AddNumbersPort")
170: // {2} = port getter method (e.g. "getAddNumbersPort")
171: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
172: // {4} = java result type (e.g. "int")
173: // {5} = operation java method name (e.g. "add")
174: // {6} = java method arguments (e.g. "int x, int y")
175: private static final String JAVA_STATIC_STUB_ASYNC_POLLING = "\ntry '{' // Call Web Service Operation(async. polling)\n"
176: + " {0} service = new {0}();\n"
177: + " {1} port = service.{2}();\n"
178: + " {3}"
179: + " // TODO process asynchronous response here\n"
180: + " {4} resp = port.{5}({6});\n"
181: + " while(!resp.isDone()) '{'\n"
182: + " // do something\n"
183: + " Thread.sleep(100);\n"
184: + " '}'\n"
185: + " System.out.println(\"Result = \"+resp.get());\n"
186: + "'}' catch (Exception ex) '{'\n"
187: + " // TODO handle custom exceptions here\n" + "'}'\n"; //NOI18N
188: // {0} = service java name (as variable, e.g. "AddNumbersService")
189: // {1} = port java name (e.g. "AddNumbersPort")
190: // {2} = port getter method (e.g. "getAddNumbersPort")
191: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
192: // {4} = java result type (e.g. "int")
193: // {5} = operation java method name (e.g. "add")
194: // {6} = java method arguments (e.g. "int x, int y")
195: // {7} = response type (e.g. FooResponse)
196: private static final String JAVA_STATIC_STUB_ASYNC_CALLBACK = "\ntry '{' // Call Web Service Operation(async. callback)\n"
197: + " {0} service = new {0}();\n"
198: + " {1} port = service.{2}();\n"
199: + " {3}"
200: + " public void handleResponse(javax.xml.ws.Response<{7}> response) '{'\n"
201: + " try '{'\n"
202: + " // TODO process asynchronous response here\n"
203: + " System.out.println(\"Result = \"+ response.get());\n"
204: + " '}' catch(Exception ex) '{'\n"
205: + " // TODO handle exception\n"
206: + " '}'\n"
207: + " '}'\n"
208: + " '}';\n"
209: + " {4} result = port.{5}({6});\n"
210: + " while(!result.isDone()) '{'\n"
211: + " // do something\n"
212: + " Thread.sleep(100);\n"
213: + " '}'\n"
214: + "'}' catch (Exception ex) '{'\n"
215: + " // TODO handle custom exceptions here\n" + "'}'\n"; //NOI18N
216:
217: /**
218: * Add JAXWS client code for invoking the given operation at current position.
219: */
220: private String getWSInvocationCode(JaxwsOperationInfo info)
221: throws IOException {
222: //Collect java names for invocation code
223: String wsdlUrl = info.getWsdlURL();
224: final String serviceJavaName = info.getService().getJavaName();
225: String portJavaName = info.getPort().getJavaName();
226: String operationJavaName = info.getOperation().getJavaName();
227: String portGetterMethod = info.getPort().getPortGetter();
228: String serviceFieldName = "service"; //NOI18N
229: String returnTypeName = info.getOperation().getReturnTypeName();
230: List<WsdlParameter> outArguments = info.getOutputParameters();
231: String responseType = "Object"; //NOI18N
232: String callbackHandlerName = "javax.xml.ws.AsyncHandler"; //NOI18N
233: String argumentInitializationPart = "";
234: String argumentDeclarationPart = "";
235: try {
236: StringBuffer argumentBuffer1 = new StringBuffer();
237: StringBuffer argumentBuffer2 = new StringBuffer();
238: for (int i = 0; i < outArguments.size(); i++) {
239: String argumentTypeName = outArguments.get(i)
240: .getTypeName();
241: if (argumentTypeName
242: .startsWith("javax.xml.ws.AsyncHandler")) {
243: //NOI18N
244: responseType = resolveResponseType(argumentTypeName);
245: callbackHandlerName = argumentTypeName;
246: }
247: String argumentName = outArguments.get(i).getName();
248: argumentBuffer1.append("\t" + argumentTypeName + " "
249: + argumentName + " = "
250: + resolveInitValue(argumentTypeName) + "\n"); //NOI18N
251: }
252:
253: List<WsdlParameter> parameters = info.getOperation()
254: .getParameters();
255: for (int i = 0; i < parameters.size(); i++) {
256: String argument = parameters.get(i).getName();
257: argumentBuffer2.append(i > 0 ? ", " + argument
258: : argument); //NOI18N
259: }
260: argumentInitializationPart = (argumentBuffer1.length() > 0 ? "\t"
261: + HINT_INIT_ARGUMENTS + argumentBuffer1.toString()
262: : "");
263: argumentDeclarationPart = argumentBuffer2.toString();
264: } catch (NullPointerException npe) {
265: // !PW notify failure to extract service information.
266: npe.printStackTrace();
267: String message = NbBundle.getMessage(
268: WsdlComponentGenerator.class,
269: "ERR_FailedUnexpectedWebServiceDescriptionPattern"); // NOI18N
270: NotifyDescriptor desc = new NotifyDescriptor.Message(
271: message, NotifyDescriptor.Message.ERROR_MESSAGE);
272: DialogDisplayer.getDefault().notify(desc);
273: }
274:
275: boolean success = false;
276:
277: final boolean[] insertServiceDef = { true };
278: final String[] printerName = { "System.out" }; // NOI18N
279: final String[] argumentInitPart = { argumentInitializationPart };
280: final String[] argumentDeclPart = { argumentDeclarationPart };
281: final String[] serviceFName = { serviceFieldName };
282: final boolean[] generateWsRefInjection = { false };
283: CancellableTask<CompilationController> task = new CancellableTask<CompilationController>() {
284:
285: public void run(CompilationController controller)
286: throws IOException {
287: controller.toPhase(Phase.ELEMENTS_RESOLVED);
288: CompilationUnitTree cut = controller
289: .getCompilationUnit();
290: ClassTree classTree = JavaSourceHelper
291: .findPublicTopLevelClass(controller);
292: generateWsRefInjection[0] = JavaSourceHelper
293: .isInjectionTarget(controller);
294: insertServiceDef[0] = !generateWsRefInjection[0];
295:
296: // compute the service field name
297: if (generateWsRefInjection[0]) {
298: Set<String> serviceFieldNames = new HashSet<String>();
299: boolean injectionExists = false;
300: int memberOrder = 0;
301: for (Tree member : classTree.getMembers()) {
302: // for the first inner class in top level
303: ++memberOrder;
304: if (VARIABLE == member.getKind()) {
305: // get variable type
306: VariableTree var = (VariableTree) member;
307: Tree typeTree = var.getType();
308: TreePath typeTreePath = controller
309: .getTrees().getPath(cut, typeTree);
310: TypeElement typeEl = JavaSourceHelper
311: .getTypeElement(controller,
312: typeTreePath);
313: if (typeEl != null) {
314: String variableType = typeEl
315: .getQualifiedName().toString();
316: if (serviceJavaName
317: .equals(variableType)) {
318: serviceFName[0] = var.getName()
319: .toString();
320: generateWsRefInjection[0] = false;
321: injectionExists = true;
322: break;
323: }
324: }
325: serviceFieldNames.add(var.getName()
326: .toString());
327: }
328: }
329: if (!injectionExists) {
330: serviceFName[0] = findProperServiceFieldName(serviceFieldNames);
331: }
332: }
333: }
334:
335: public void cancel() {
336: }
337: };
338:
339: // create the inserted text
340: wrapperResourceJS.runUserActionTask(task, true);
341:
342: String invocationBody = getJavaInvocationBody(info
343: .getOperation(), insertServiceDef[0], serviceJavaName,
344: portJavaName, portGetterMethod, argumentInitPart[0],
345: returnTypeName, operationJavaName, argumentDeclPart[0],
346: serviceFName[0], printerName[0], responseType);
347:
348: if (!getBean().needsHtmlRepresentation()) {
349: List<WsdlParameter> outParams = info.getOutputParameters();
350: String outputClassName = SourceGroupSupport
351: .getClassName(info.getOutputType());
352: invocationBody += "representation.set" + outputClassName
353: + "(";
354: if (Constants.VOID.equals(returnTypeName)
355: && outParams.size() > 0) {
356: invocationBody += outParams.get(0).getName()
357: + ".value);";
358: } else if (!Constants.VOID.equals(returnTypeName)) {
359: invocationBody += "result);";
360: } else {
361: throw new IllegalArgumentException(
362: "Unsupported return type " + returnTypeName);
363: }
364: }
365:
366: if (generateWsRefInjection[0]) {
367: insertServiceRef(wrapperResourceJS, info, serviceFieldName);
368: }
369: return invocationBody;
370: }
371:
372: private void insertServiceRef(JavaSource targetJS,
373: JaxwsOperationInfo info, final String serviceFieldName)
374: throws IOException {
375: final String serviceJavaName = info.getService().getJavaName();
376: String wsdlUrl = info.getWsdlURL();
377:
378: if (wsdlUrl.startsWith("file:")) {
379: //NOI18N
380: wsdlUrl = info.getWsdlLocation();
381: }
382: final String localWsdlUrl = wsdlUrl;
383: CancellableTask<WorkingCopy> modificationTask = new CancellableTask<WorkingCopy>() {
384:
385: public void run(WorkingCopy workingCopy) throws IOException {
386: workingCopy.toPhase(Phase.RESOLVED);
387: TreeMaker make = workingCopy.getTreeMaker();
388: TypeElement typeElement = JavaSourceHelper
389: .getTopLevelClassElement(workingCopy);
390: ClassTree javaClass = JavaSourceHelper.getClassTree(
391: workingCopy, typeElement);
392: VariableTree serviceRefInjection = generateServiceRefInjection(
393: workingCopy, make, serviceFieldName,
394: serviceJavaName, localWsdlUrl);
395: ClassTree modifiedClass = make.insertClassMember(
396: javaClass, 0, serviceRefInjection);
397: workingCopy.rewrite(javaClass, modifiedClass);
398: }
399:
400: public void cancel() {
401: }
402: };
403: targetJS.runModificationTask(modificationTask).commit();
404: }
405:
406: /**
407: * Determines the initialization value of a variable of type "type"
408: * @param type Type of the variable
409: * @param targetFile FileObject containing the class that declares the type
410: */
411: private static String resolveInitValue(String type) {
412: if (type.startsWith("javax.xml.ws.Holder")) {
413: //NOI18N
414: return "new " + type + "();";
415: }
416: if ("int".equals(type) || "long".equals(type)
417: || "short".equals(type) || "byte".equals(type)) {
418: //NOI18N
419: return "0;"; //NOI18N
420: }
421: if ("boolean".equals(type)) {
422: //NOI18N
423: return "false;"; //NOI18N
424: }
425: if ("float".equals(type) || "double".equals(type)) {
426: //NOI18N
427: return "0.0;"; //NOI18N
428: }
429: if ("java.lang.String".equals(type)) {
430: //NOI18N
431: return "\"\";"; //NOI18N
432: }
433: if (type.endsWith("CallbackHandler")) {
434: //NOI18N
435: return "new " + type + "();"; //NOI18N
436: }
437: if (type.startsWith("javax.xml.ws.AsyncHandler")) {
438: //NOI18N
439: return "new " + type + "() {"; //NOI18N
440: }
441:
442: return "null;"; //NOI18N
443: }
444:
445: private static String resolveResponseType(String argumentType) {
446: int start = argumentType.indexOf("<");
447: int end = argumentType.indexOf(">");
448: if (start > 0 && end > 0 && start < end) {
449: return argumentType.substring(start + 1, end);
450: } else {
451: return "javax.xml.ws.Response"; //NOI18N
452: }
453: }
454:
455: public static final String SET_HEADER_PARAMS_CALL = SET_HEADER_PARAMS
456: + "(port); \n";
457:
458: private String getJavaInvocationBody(WsdlOperation operation,
459: boolean insertServiceDef, String serviceJavaName,
460: String portJavaName, String portGetterMethod,
461: String argumentInitializationPart, String returnTypeName,
462: String operationJavaName, String argumentDeclarationPart,
463: String serviceFieldName, String printerName,
464: String responseType) {
465:
466: String invocationBody = "";
467: String setHeaderParams = getBean().getHeaderParameters().size() > 0 ? SET_HEADER_PARAMS_CALL
468: : "";
469: Object[] args = new Object[] { serviceJavaName, portJavaName,
470: portGetterMethod, argumentInitializationPart,
471: returnTypeName, operationJavaName,
472: argumentDeclarationPart, serviceFieldName, printerName };
473: switch (operation.getOperationType()) {
474: case WsdlOperation.TYPE_NORMAL: {
475: if ("void".equals(returnTypeName)) {
476: //NOI18N
477: String body = (insertServiceDef ? JAVA_SERVICE_DEF : "")
478: + setHeaderParams + JAVA_PORT_DEF + JAVA_VOID;
479: invocationBody += MessageFormat.format(body, args);
480: } else {
481: String body = (insertServiceDef ? JAVA_SERVICE_DEF : "")
482: + JAVA_PORT_DEF
483: + setHeaderParams
484: + JAVA_RESULT
485: + JAVA_OUT;
486: invocationBody += MessageFormat.format(body, args);
487: }
488: break;
489: }
490: case WsdlOperation.TYPE_ASYNC_POLLING: {
491: invocationBody += MessageFormat.format(
492: JAVA_STATIC_STUB_ASYNC_POLLING, args);
493: break;
494: }
495: case WsdlOperation.TYPE_ASYNC_CALLBACK: {
496: args[7] = responseType;
497: invocationBody += MessageFormat.format(
498: JAVA_STATIC_STUB_ASYNC_CALLBACK, args);
499: break;
500: }
501: }
502: return invocationBody;
503: }
504:
505: private static VariableTree generateServiceRefInjection(
506: WorkingCopy workingCopy, TreeMaker make, String fieldName,
507: String fieldType, String wsdlUrl) {
508: TypeElement wsRefElement = workingCopy.getElements()
509: .getTypeElement("javax.xml.ws.WebServiceRef"); //NOI18N
510: AnnotationTree wsRefAnnotation = make.Annotation(make
511: .QualIdent(wsRefElement), Collections
512: .<ExpressionTree> singletonList(make.Assignment(make
513: .Identifier("wsdlLocation"), make
514: .Literal(wsdlUrl))));
515: // create method modifier: public and no annotation
516: ModifiersTree methodModifiers = make.Modifiers(Collections
517: .<Modifier> singleton(Modifier.PUBLIC), Collections
518: .<AnnotationTree> singletonList(wsRefAnnotation));
519: TypeElement typeElement = workingCopy.getElements()
520: .getTypeElement(fieldType);
521:
522: VariableTree var = make.Variable(methodModifiers, fieldName,
523: make.Type(typeElement.asType()), null);
524: return make.Variable(make.Modifiers(var.getModifiers()
525: .getFlags(), var.getModifiers().getAnnotations()), var
526: .getName(), var.getType(), var.getInitializer());
527: }
528:
529: private static String findProperServiceFieldName(
530: Set serviceFieldNames) {
531: String name = "service";
532: int i = 0;
533: while (serviceFieldNames.contains(name)) {
534: name = "service_" + String.valueOf(++i);
535: }
536: return name; //NOI18N
537: }
538:
539: private ClassTree addSetHeaderParamsMethod(WorkingCopy copy,
540: ClassTree tree, String portJavaType) {
541: Modifier[] modifiers = Constants.PRIVATE;
542: String[] annotations = new String[0];
543: Object[] annotationAttrs = new Object[0];
544: Object returnType = Constants.VOID;
545: String bodyText = "{ WSBindingProvider bp = (WSBindingProvider)port;";
546: bodyText += "bp.setOutboundHeaders(";
547: boolean first = true;
548: for (ParameterInfo pinfo : getBean().getHeaderParameters()) {
549: if (pinfo.getDefaultValue() == null) {
550: continue;
551: }
552: if (first) {
553: first = false;
554: } else {
555: bodyText += ", \n ";
556: }
557: String namespaceUri = pinfo.getQName().getNamespaceURI();
558: bodyText += "Headers.create(new QName(";
559: if (namespaceUri != null) {
560: bodyText += "\"" + namespaceUri + "\",";
561: }
562: bodyText += "\"" + pinfo.getName() + "\"), \""
563: + pinfo.getDefaultValue() + "\")";
564: }
565: bodyText += ");";
566: String[] parameters = new String[] { "port" };
567: Object[] paramTypes = new Object[] { portJavaType };
568: String[] paramAnnotations = new String[0];
569: Object[] paramAnnotationAttrs = new String[0];
570: String comment = null;
571:
572: return JavaSourceHelper.addMethod(copy, tree, modifiers,
573: annotations, annotationAttrs, SET_HEADER_PARAMS,
574: returnType, parameters,
575: paramTypes, //NOI18N
576: paramAnnotations, paramAnnotationAttrs, bodyText,
577: comment); //NOI18N
578: }
579:
580: @Override
581: protected FileObject generateJaxbOutputWrapper() throws IOException {
582: if (getBean().needsHtmlRepresentation()) {
583: return null;
584: }
585: return super.generateJaxbOutputWrapper();
586: }
587: }
|