0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package org.netbeans.modules.websvc.core.jaxws.actions;
0042:
0043: import com.sun.source.tree.AnnotationTree;
0044: import com.sun.source.tree.ClassTree;
0045: import com.sun.source.tree.CompilationUnitTree;
0046: import com.sun.source.tree.ExpressionTree;
0047: import com.sun.source.tree.ImportTree;
0048: import com.sun.source.tree.ModifiersTree;
0049: import com.sun.source.tree.Tree;
0050: import com.sun.source.tree.VariableTree;
0051: import com.sun.source.tree.VariableTree;
0052: import com.sun.source.util.TreePath;
0053: import java.io.IOException;
0054: import java.io.StringWriter;
0055: import java.io.Writer;
0056: import java.text.MessageFormat;
0057: import java.util.Arrays;
0058: import java.util.Collections;
0059: import java.util.HashSet;
0060: import java.util.List;
0061: import java.util.Set;
0062: import java.util.StringTokenizer;
0063: import javax.lang.model.element.ElementKind;
0064: import javax.lang.model.element.ExecutableElement;
0065: import javax.lang.model.element.Modifier;
0066: import javax.lang.model.element.TypeElement;
0067: import javax.lang.model.util.ElementFilter;
0068: import javax.swing.JEditorPane;
0069: import javax.swing.text.BadLocationException;
0070: import javax.swing.text.Document;
0071: import javax.swing.text.StyledDocument;
0072: import org.netbeans.api.java.source.CancellableTask;
0073: import org.netbeans.api.java.source.CompilationController;
0074: import org.netbeans.api.java.source.JavaSource;
0075: import org.netbeans.api.java.source.TreeMaker;
0076: import org.netbeans.modules.j2ee.api.ejbjar.Car;
0077: import org.netbeans.modules.websvc.api.support.java.SourceUtils;
0078: import org.netbeans.modules.websvc.core.InvokeOperationCookie;
0079: import static org.netbeans.api.java.source.JavaSource.Phase;
0080: import static com.sun.source.tree.Tree.Kind.*;
0081: import org.netbeans.api.java.source.WorkingCopy;
0082: import org.netbeans.api.project.FileOwnerQuery;
0083: import org.netbeans.api.project.Project;
0084:
0085: import org.netbeans.modules.editor.NbEditorUtilities;
0086: import org.netbeans.modules.j2ee.common.queries.api.InjectionTargetQuery;
0087: import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
0088: import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
0089: import org.netbeans.modules.websvc.api.jaxws.project.config.Client;
0090: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlOperation;
0091: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlParameter;
0092: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlPort;
0093: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlService;
0094: import org.netbeans.modules.websvc.core.JaxWsUtils;
0095: import org.netbeans.modules.websvc.core.jaxws.nodes.OperationNode;
0096: import org.openide.DialogDisplayer;
0097: import org.openide.ErrorManager;
0098: import org.openide.NotifyDescriptor;
0099: import org.openide.cookies.EditorCookie;
0100: import org.openide.filesystems.FileObject;
0101: import org.openide.loaders.DataObject;
0102: import org.openide.nodes.Node;
0103: import org.openide.text.IndentEngine;
0104: import org.openide.text.NbDocument;
0105: import org.openide.util.Exceptions;
0106: import org.openide.util.NbBundle;
0107:
0108: /** JaxWsCodeGenerator.java
0109: *
0110: * Created on March 2, 2006
0111: *
0112: * @author mkuchtiak
0113: */
0114: public class JaxWsCodeGenerator {
0115:
0116: private static final List IMPLICIT_JSP_OBJECTS = Arrays
0117: .asList(new String[] { "request", "response", "session",
0118: "out", "page", "config", "application",
0119: "pageContext" //NOI18N
0120: });
0121: private static final String HINT_INIT_ARGUMENTS = " // TODO initialize WS operation arguments here\n"; //NOI18N
0122: // {0} = service java name (as variable, e.g. "AddNumbersService")
0123: // {1} = port java name (e.g. "AddNumbersPort")
0124: // {2} = port getter method (e.g. "getAddNumbersPort")
0125: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
0126: // {4} = java result type (e.g. "int")
0127: // {5} = operation java method name (e.g. "add")
0128: // {6} = java method arguments (e.g. "int x, int y")
0129: // {7} = service field name
0130: private static final String JAVA_TRY = "\ntry '{' // Call Web Service Operation\n"; //NOI18N
0131: private static final String JAVA_SERVICE_DEF = " {0} {7} = new {0}();\n"; //NOI18N
0132: private static final String JAVA_PORT_DEF = " {1} port = {7}.{2}();\n"; //NOI18N
0133: private static final String JAVA_RESULT = " {3}" + //NOI18N
0134: " // TODO process result here\n" + //NOI18N
0135: " {4} result = port.{5}({6});\n"; //NOI18N
0136: private static final String JAVA_VOID = " {3}" + //NOI18N
0137: " port.{5}({6});\n"; //NOI18N
0138: private static final String JAVA_OUT = " {8}.println(\"Result = \"+result);\n"; //NOI18N
0139: private static final String JAVA_CATCH = "'}' catch (Exception ex) '{'\n"
0140: + //NOI18N
0141: " // TODO handle custom exceptions here\n" + //NOI18N
0142: "'}'\n"; //NOI18N
0143: // {0} = service java name (as variable, e.g. "AddNumbersService")
0144: // {1} = port java name (e.g. "AddNumbersPort")
0145: // {2} = port getter method (e.g. "getAddNumbersPort")
0146: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
0147: // {4} = java result type (e.g. "int")
0148: // {5} = operation java method name (e.g. "add")
0149: // {6} = java method arguments (e.g. "int x, int y")
0150: private static final String JAVA_STATIC_STUB_ASYNC_POLLING = "\ntry '{' // Call Web Service Operation(async. polling)\n"
0151: + //NOI18N
0152: " {0} service = new {0}();\n" + //NOI18N
0153: " {1} port = service.{2}();\n" + //NOI18N
0154: " {3}" + //NOI18N
0155: " // TODO process asynchronous response here\n" + //NOI18N
0156: " {4} resp = port.{5}({6});\n" + //NOI18N
0157: " while(!resp.isDone()) '{'\n" + //NOI18N
0158: " // do something\n" + //NOI18N
0159: " Thread.sleep(100);\n" + //NOI18N
0160: " '}'\n" + //NOI18N
0161: " System.out.println(\"Result = \"+resp.get());\n" + //NOI18N
0162: "'}' catch (Exception ex) '{'\n" + //NOI18N
0163: " // TODO handle custom exceptions here\n" + //NOI18N
0164: "'}'\n"; //NOI18N
0165: // {0} = service java name (as variable, e.g. "AddNumbersService")
0166: // {1} = port java name (e.g. "AddNumbersPort")
0167: // {2} = port getter method (e.g. "getAddNumbersPort")
0168: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
0169: // {4} = java result type (e.g. "int")
0170: // {5} = operation java method name (e.g. "add")
0171: // {6} = java method arguments (e.g. "int x, int y")
0172: // {7} = response type (e.g. FooResponse)
0173: private static final String JAVA_STATIC_STUB_ASYNC_CALLBACK = "\ntry '{' // Call Web Service Operation(async. callback)\n"
0174: + //NOI18N
0175: " {0} service = new {0}();\n"
0176: + //NOI18N
0177: " {1} port = service.{2}();\n"
0178: + //NOI18N
0179: " {3}"
0180: + //NOI18N
0181: " public void handleResponse(javax.xml.ws.Response<{7}> response) '{'\n"
0182: + //NOI18N
0183: " try '{'\n"
0184: + //NOI18N
0185: " // TODO process asynchronous response here\n"
0186: + //NOI18N
0187: " System.out.println(\"Result = \"+ response.get());\n"
0188: + //NOI18N
0189: " '}' catch(Exception ex) '{'\n" + //NOI18N
0190: " // TODO handle exception\n" + //NOI18N
0191: " '}'\n" + //NOI18N
0192: " '}'\n" + //NOI18N
0193: " '}';\n" + //NOI18N
0194: " {4} result = port.{5}({6});\n" + //NOI18N
0195: " while(!result.isDone()) '{'\n" + //NOI18N
0196: " // do something\n" + //NOI18N
0197: " Thread.sleep(100);\n" + //NOI18N
0198: " '}'\n" + //NOI18N
0199: "'}' catch (Exception ex) '{'\n" + //NOI18N
0200: " // TODO handle custom exceptions here\n" + //NOI18N
0201: "'}'\n"; //NOI18N
0202: // {0} = service java name (as variable, e.g. "AddNumbersService")
0203: // {1} = port java name (e.g. "AddNumbersPort")
0204: // {2} = port getter method (e.g. "getAddNumbersPort")
0205: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
0206: // {4} = java result type (e.g. "int")
0207: // {5} = operation java method name (e.g. "add")
0208: // {6} = java method arguments (e.g. "int x, int y")
0209: private static final String JSP_STATIC_STUB = " <%-- start web service invocation --%><hr/>\n"
0210: + //NOI18N
0211: " <%\n" + //NOI18N
0212: " try '{'\n" + //NOI18N
0213: "\t{0} service = new {0}();\n" + //NOI18N
0214: "\t{1} port = service.{2}();\n" + //NOI18N
0215: "{3}" + //NOI18N
0216: "\t// TODO process result here\n" + //NOI18N
0217: "\t{4} result = port.{5}({6});\n" + //NOI18N
0218: "\tout.println(\"Result = \"+result);\n" + //NOI18N
0219: " '}' catch (Exception ex) '{'\n" + //NOI18N
0220: "\t// TODO handle custom exceptions here\n" + //NOI18N
0221: " '}'\n" + //NOI18N
0222: " %>\n" + //NOI18N
0223: " <%-- end web service invocation --%><hr/>\n"; //NOI18N
0224: // {0} = service java name (as variable, e.g. "AddNumbersService")
0225: // {1} = port java name (e.g. "AddNumbersPort")
0226: // {2} = port getter method (e.g. "getAddNumbersPort")
0227: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
0228: // {5} = operation java method name (e.g. "add")
0229: // {6} = java method arguments (e.g. "int x, int y")
0230: private static final String JSP_STATIC_STUB_VOID = " <%-- start web service invocation --%><hr/>\n"
0231: + //NOI18N
0232: " <%\n" + //NOI18N
0233: " try '{'\n" + //NOI18N
0234: "\t{0} service = new {0}();\n" + //NOI18N
0235: "\t{1} port = service.{2}();\n" + //NOI18N
0236: "{3}" + //NOI18N
0237: "\tport.{5}({6});\n" + //NOI18N
0238: " '}' catch (Exception ex) '{'\n" + //NOI18N
0239: "\t// TODO handle custom exceptions here\n" + //NOI18N
0240: " '}'\n" + //NOI18N
0241: " %>\n" + //NOI18N
0242: " <%-- end web service invocation --%><hr/>\n"; //NOI18N
0243: // {0} = service java name (as variable, e.g. "AddNumbersService")
0244: // {1} = port java name (e.g. "AddNumbersPort")
0245: // {2} = port getter method (e.g. "getAddNumbersPort")
0246: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
0247: // {4} = java result type (e.g. "int")
0248: // {5} = operation java method name (e.g. "add")
0249: // {6} = java method arguments (e.g. "int x, int y")
0250: private static final String JSP_STATIC_STUB_ASYNC_POLLING = " <%-- start web service invocation(async. polling) --%><hr/>\n"
0251: + //NOI18N
0252: " <%\n" + //NOI18N
0253: " try '{'\n" + //NOI18N
0254: "\t{0} service = new {0}();\n" + //NOI18N
0255: "\t{1} port = service.{2}();\n" + //NOI18N
0256: "{3}" + //NOI18N
0257: "\t// TODO process asynchronous response here\n" + //NOI18N
0258: "\t{4} resp = port.{5}({6});\n" + //NOI18N
0259: "\twhile(!resp.isDone()) '{'\n" + //NOI18N
0260: "\t\t// do something\n" + //NOI18N
0261: "\t\tThread.sleep(100);\n" + //NOI18N
0262: "\t'}'\n" + //NOI18N
0263: "\tout.println(\"Result = \"+resp.get());\n" + //NOI18N
0264: " '}' catch (Exception ex) '{'\n" + //NOI18N
0265: "\t// TODO handle custom exceptions here\n" + //NOI18N
0266: " '}'\n" + //NOI18N
0267: " %>\n" + //NOI18N
0268: " <%-- end web service invocation(async. polling) --%><hr/>\n"; //NOI18N
0269: // {0} = service java name (as variable, e.g. "AddNumbersService")
0270: // {1} = port java name (e.g. "AddNumbersPort")
0271: // {2} = port getter method (e.g. "getAddNumbersPort")
0272: // {3} = argument initialization part (e.g. "int x=0; int y=0;")
0273: // {4} = java result type (e.g. "int")
0274: // {5} = operation java method name (e.g. "add")
0275: // {6} = java method arguments (e.g. "int x, int y")
0276: private static final String JSP_STATIC_STUB_ASYNC_CALLBACK = " <%-- start web service invocation(async. callback) --%><hr/>\n"
0277: + //NOI18N
0278: " <%\n"
0279: + //NOI18N
0280: " try '{'\n"
0281: + //NOI18N
0282: "\t{0} service = new {0}();\n"
0283: + //NOI18N
0284: "\t{1} port = service.{2}();\n"
0285: + //NOI18N
0286: "{3}"
0287: + //NOI18N
0288: "\t// TODO process asynchronous response here\n"
0289: + //NOI18N
0290: "\t{4} result = port.{5}({6});\n"
0291: + //NOI18N
0292: "\twhile(!result.isDone()) '{'\n"
0293: + //NOI18N
0294: "\t\t// do something\n"
0295: + //NOI18N
0296: "\t\tThread.sleep(100);\n"
0297: + //NOI18N
0298: "\t'}'\n"
0299: + //NOI18N
0300: "\tout.println(\"Result = \"+asyncHandler.getResponse());\n"
0301: + //NOI18N
0302: " '}' catch (Exception ex) '{'\n" + //NOI18N
0303: "\t// TODO handle custom exceptions here\n" + //NOI18N
0304: " '}'\n" + //NOI18N
0305: " %>\n" + //NOI18N
0306: " <%-- end web service invocation(async. callback) --%><hr/>\n"; //NOI18N
0307: // {0} = handler name (as type, e.g. "FooCallbackHandler")
0308: // {1} = response type (e.g. FooResponse)
0309: private static final String JSP_CALLBACK_HANDLER = "<%!\n"
0310: + //NOI18N
0311: "class {0} implements javax.xml.ws.AsyncHandler<{1}> '{'\n"
0312: + //NOI18N
0313: " private {1} output;\n"
0314: + //NOI18N
0315: "\n"
0316: + //NOI18N
0317: " public void handleResponse(javax.xml.ws.Response<{1}> response) '{'\n"
0318: + //NOI18N
0319: " try '{'\n" + //NOI18N
0320: " output = response.get();\n" + //NOI18N
0321: " '}' catch(Exception ex) '{'\n" + //NOI18N
0322: " // TODO handle exception\n" + //NOI18N
0323: " '}'\n" + //NOI18N
0324: " '}'\n" + //NOI18N
0325: "\n" + //NOI18N
0326: " {1} getResponse() '{'\n" + //NOI18N
0327: " return output;\n" + //NOI18N
0328: " '}'\n" + //NOI18N
0329: "'}'\n" + //NOI18N
0330: "%>\n"; //NOI18N
0331: private static final String QNAME = "\nQName portQName = new QName(\"{0}\" , \"{1}\"); ";
0332: // {0} = service java name (as variable, e.g. "AddNumbersService")
0333: // {1} =namespace URI of port
0334: // {2} = java port name
0335: // {3} = XML message string
0336: private static final String JSP_DISPATCH = " <%-- start web service invocation --%><hr/>\n"
0337: + //NOI18N
0338: " <%\n"
0339: + //NOI18N
0340: " try '{'\n"
0341: + //NOI18N
0342: "\t{0} service = new {0}();\n"
0343: + //NOI18N
0344: "javax.xml.namespace.QName portQName = new javax.xml.namespace.QName(\"{1}\", \"{2}\");\n"
0345: + "String req = \"{3}\";\n"
0346: + "javax.xml.ws.Dispatch<javax.xml.transform.Source> sourceDispatch = null;\n"
0347: + "sourceDispatch = service.createDispatch(portQName, javax.xml.transform.Source.class, javax.xml.ws.Service.Mode.PAYLOAD);\n"
0348: + "javax.xml.transform.Source result = sourceDispatch.invoke(new javax.xml.transform.stream.StreamSource(new java.io.StringReader(req)));\n"
0349: + " '}' catch (Exception ex) '{'\n" + //NOI18N
0350: "\t// TODO handle custom exceptions here\n" + //NOI18N
0351: " '}'\n" + //NOI18N
0352: " %>\n" + //NOI18N
0353: " <%-- end web service invocation --%><hr/>\n"; //NOI18N
0354:
0355: public static void insertMethodCall(int targetSourceType,
0356: DataObject dataObj, Node sourceNode, Node operationNode) {
0357: EditorCookie cookie = sourceNode.getCookie(EditorCookie.class);
0358: OperationNode opNode = operationNode.getLookup().lookup(
0359: OperationNode.class);
0360: boolean inJsp = InvokeOperationCookie.TARGET_SOURCE_JSP == targetSourceType;
0361: Node portNode = operationNode.getParentNode();
0362: Node serviceNode = portNode.getParentNode();
0363: addProjectReference(serviceNode, sourceNode);
0364: final Document document;
0365: int position = -1;
0366: if (inJsp) {
0367: //TODO:
0368: //this should be handled differently, see issue 60609
0369: document = cookie.getDocument();
0370: try {
0371: String content = document.getText(0, document
0372: .getLength());
0373: position = content.lastIndexOf("</body>"); //NOI18N
0374: if (position < 0) {
0375: position = content.lastIndexOf("</html>"); //NOI18N
0376: }
0377: if (position >= 0) { //find where line begins
0378: while (position > 0
0379: && content.charAt(position - 1) != '\n'
0380: && content.charAt(position - 1) != '\r') {
0381: position--;
0382: }
0383: } else {
0384: position = document.getLength();
0385: }
0386: } catch (BadLocationException ble) {
0387: Exceptions.printStackTrace(ble);
0388: }
0389: } else {
0390: EditorCookie ec = dataObj.getCookie(EditorCookie.class);
0391: JEditorPane pane = ec.getOpenedPanes()[0];
0392: document = pane.getDocument();
0393: position = pane.getCaretPosition();
0394: }
0395: final int pos = position;
0396: insertMethod(document, pos, opNode);
0397: }
0398:
0399: private static void addProjectReference(Node serviceNode,
0400: Node sourceNode) {
0401: Node clientNode = serviceNode.getParentNode();
0402: FileObject srcRoot = clientNode.getLookup().lookup(
0403: FileObject.class);
0404: Project clientProject = FileOwnerQuery.getOwner(srcRoot);
0405: DataObject dObj = sourceNode.getCookie(DataObject.class);
0406: if (dObj != null) {
0407: FileObject targetFo = dObj.getPrimaryFile();
0408: JaxWsUtils.addProjectReference(clientProject, targetFo);
0409: }
0410: }
0411:
0412: /**
0413: * Determines the initialization value of a variable of type "type"
0414: * @param type Type of the variable
0415: * @param targetFile FileObject containing the class that declares the type
0416: */
0417: private static String resolveInitValue(final String type,
0418: FileObject targetFile) {
0419: if ("int".equals(type)) { //NOI18N
0420: return "0;"; //NOI18N
0421: } else if ("long".equals(type)) { //NOI18N
0422: return "0L;"; //NOI18N
0423: } else if ("float".equals(type)) { //NOI18N
0424: return "0.0f;"; //NOI18N
0425: } else if ("double".equals(type)) { //NOI18N
0426: return "0.0d;"; //NOI18N
0427: } else if ("short".equals(type)) { //NOI18N
0428: return "(short)0;"; //NOI18N
0429: } else if ("byte".equals(type)) { //NOI18N
0430: return "(byte)0;"; //NOI18N
0431: } else if ("boolean".equals(type)) { //NOI18N
0432: return "false;"; //NOI18N
0433: } else if ("java.lang.String".equals(type)) { //NOI18N
0434: return "\"\";"; //NOI18N
0435: } else if ("java.lang.Integer".equals(type)) { //NOI18N
0436: return "Integer.valueOf(0);"; //NOI18N
0437: } else if ("java.lang.Long".equals(type)) { //NOI18N
0438: return "Long.valueOf(0L);"; //NOI18N
0439: } else if ("java.lang.Float".equals(type)) { //NOI18N
0440: return "Float.valueOf(0.0f);"; //NOI18N
0441: } else if ("java.lang.Double".equals(type)) { //NOI18N
0442: return "Double.valueOf(0.0d);"; //NOI18N
0443: } else if ("java.lang.Short".equals(type)) { //NOI18N
0444: return "Short.valueOf((short)0);"; //NOI18N
0445: } else if ("java.lang.Byte".equals(type)) { //NOI18N
0446: return "Byte.valueOf((byte)0);"; //NOI18N
0447: } else if ("java.lang.Boolean".equals(type)) { //NOI18N
0448: return "Boolean.FALSE;"; //NOI18N
0449: } else if (type.endsWith("CallbackHandler")) { //NOI18N
0450: return "new " + type + "();"; //NOI18N
0451: } else if (type.startsWith("javax.xml.ws.AsyncHandler")) { //NOI18N
0452: return "new " + type + "() {"; //NOI18N
0453: }
0454:
0455: ResultHolder<String> result = new ResultHolder<String>("");
0456: getInitValue(type, targetFile, result);
0457: String returnText = result.getResult();
0458: if (!returnText.equals("")) {
0459: return returnText;
0460: }
0461:
0462: return "null;"; //NOI18N
0463: }
0464:
0465: private static void getInitValue(final String type,
0466: FileObject targetFile, final ResultHolder<String> result) {
0467: if (targetFile == null) {
0468: return;
0469: }
0470: JavaSource targetSource = JavaSource.forFileObject(targetFile);
0471: CancellableTask<CompilationController> task = new CancellableTask<CompilationController>() {
0472:
0473: public void run(CompilationController controller)
0474: throws IOException {
0475: controller.toPhase(Phase.ELEMENTS_RESOLVED);
0476: if (!isEnum(controller, type)) {
0477: if (hasNoArgConstructor(controller, type)) {
0478: result.setResult("new " + type + "();");//NOI18N
0479: }
0480: }
0481: }
0482:
0483: public void cancel() {
0484: }
0485: };
0486: try {
0487: targetSource.runUserActionTask(task, true);
0488: } catch (IOException e) {
0489: ErrorManager.getDefault().notify(e);
0490: }
0491: }
0492:
0493: private static boolean isEnum(CompilationController controller,
0494: String type) {
0495: TypeElement classEl = controller.getElements().getTypeElement(
0496: getCanonicalClassName(type));
0497: if (classEl != null) {
0498: return classEl.getKind() == ElementKind.ENUM;
0499: }
0500: return false;
0501: }
0502:
0503: private static boolean hasNoArgConstructor(
0504: CompilationController controller, String type) {
0505: TypeElement classEl = controller.getElements().getTypeElement(
0506: getCanonicalClassName(type));
0507: if (classEl != null) {
0508: List<ExecutableElement> constructors = ElementFilter
0509: .constructorsIn(classEl.getEnclosedElements());
0510: for (ExecutableElement c : constructors) {
0511: if (c.getParameters().size() == 0) {
0512: return true;
0513: }
0514: }
0515: }
0516: return false;
0517: }
0518:
0519: /** Holder class for result
0520: */
0521: private static class ResultHolder<E> {
0522:
0523: private E result;
0524:
0525: public ResultHolder(E result) {
0526: this .result = result;
0527: }
0528:
0529: public E getResult() {
0530: return result;
0531: }
0532:
0533: public void setResult(E result) {
0534: this .result = result;
0535: }
0536: }
0537:
0538: private static String getCanonicalClassName(String genericClassName) {
0539: int index = genericClassName.indexOf("<");
0540: if (index != -1) {
0541: return genericClassName.substring(0, index);
0542: }
0543: return genericClassName;
0544: }
0545:
0546: private static String resolveResponseType(String argumentType) {
0547: int start = argumentType.indexOf("<");
0548: int end = argumentType.indexOf(">");
0549: if (start > 0 && end > 0 && start < end) {
0550: return argumentType.substring(start + 1, end);
0551: } else {
0552: return "javax.xml.ws.Response";
0553: } //NOI18N
0554: }
0555:
0556: private static String pureJavaName(String javaNameWithPackage) {
0557: int index = javaNameWithPackage.lastIndexOf(".");
0558: return index >= 0 ? javaNameWithPackage.substring(index + 1)
0559: : javaNameWithPackage;
0560: }
0561:
0562: public static void insertMethod(final Document document,
0563: final int pos, OperationNode operationNode) {
0564: Node portNode = operationNode.getParentNode();
0565: Node serviceNode = portNode.getParentNode();
0566: Node wsdlNode = serviceNode.getParentNode();
0567: WsdlOperation operation = operationNode.getLookup().lookup(
0568: WsdlOperation.class);
0569: WsdlPort port = portNode.getLookup().lookup(WsdlPort.class);
0570: WsdlService service = serviceNode.getLookup().lookup(
0571: WsdlService.class);
0572: Client client = wsdlNode.getLookup().lookup(Client.class);
0573:
0574: String wsdlUrl = client.getWsdlUrl();
0575: if (wsdlUrl.startsWith("file:")) //NOI18N
0576: {
0577: wsdlUrl = findWsdlLocation(client, NbEditorUtilities
0578: .getFileObject(document));
0579: }
0580:
0581: if (client.getUseDispatch()) {
0582: insertDispatchMethod(document, pos, service, port,
0583: operation, wsdlUrl);
0584: } else {
0585: insertMethod(document, pos, service, port, operation,
0586: wsdlUrl);
0587: }
0588: }
0589:
0590: public static void insertMethod(final Document document,
0591: final int pos, WsdlService service, WsdlPort port,
0592: WsdlOperation operation, String wsdlUrl) {
0593:
0594: boolean inJsp = "text/x-jsp".equals(document
0595: .getProperty("mimeType")); //NOI18N
0596: // First, collect name of method, port, and service:
0597:
0598: final String serviceJavaName;
0599: String serviceFieldName;
0600: String portJavaName, portGetterMethod, operationJavaName, returnTypeName;
0601: String responseType = "Object"; //NOI18N
0602: String callbackHandlerName = "javax.xml.ws.AsyncHandler"; //NOI18N
0603: String argumentInitializationPart, argumentDeclarationPart;
0604:
0605: try {
0606: serviceFieldName = "service"; //NOI18N
0607: operationJavaName = operation.getJavaName();
0608: portJavaName = port.getJavaName();
0609: portGetterMethod = port.getPortGetter();
0610: serviceJavaName = service.getJavaName();
0611: List arguments = operation.getParameters();
0612: returnTypeName = operation.getReturnTypeName();
0613: StringBuffer argumentBuffer1 = new StringBuffer();
0614: StringBuffer argumentBuffer2 = new StringBuffer();
0615: for (int i = 0; i < arguments.size(); i++) {
0616: String argumentTypeName = ((WsdlParameter) arguments
0617: .get(i)).getTypeName();
0618: if (argumentTypeName
0619: .startsWith("javax.xml.ws.AsyncHandler")) { //NOI18N
0620: responseType = resolveResponseType(argumentTypeName);
0621: if (inJsp) {
0622: argumentTypeName = pureJavaName(portJavaName)
0623: + "CallbackHandler";
0624: } //NOI18N
0625: callbackHandlerName = argumentTypeName;
0626: }
0627: String argumentName = ((WsdlParameter) arguments.get(i))
0628: .getName();
0629: if (inJsp
0630: && IMPLICIT_JSP_OBJECTS.contains(argumentName)) {
0631: argumentName = argumentName + "_1"; //NOI18N
0632: }
0633: argumentBuffer1.append("\t"
0634: + argumentTypeName
0635: + " "
0636: + argumentName
0637: + " = "
0638: + resolveInitValue(argumentTypeName,
0639: NbEditorUtilities
0640: .getFileObject(document))
0641: + "\n"); //NOI18N
0642: argumentBuffer2.append(i > 0 ? ", " + argumentName
0643: : argumentName); //NOI18N
0644: }
0645: argumentInitializationPart = (argumentBuffer1.length() > 0 ? "\t"
0646: + HINT_INIT_ARGUMENTS + argumentBuffer1.toString()
0647: : "");
0648: argumentDeclarationPart = argumentBuffer2.toString();
0649:
0650: } catch (NullPointerException npe) {
0651: // !PW notify failure to extract service information.
0652: npe.printStackTrace();
0653: String message = NbBundle.getMessage(
0654: JaxWsCodeGenerator.class,
0655: "ERR_FailedUnexpectedWebServiceDescriptionPattern"); // NOI18N
0656: NotifyDescriptor desc = new NotifyDescriptor.Message(
0657: message, NotifyDescriptor.Message.ERROR_MESSAGE);
0658: DialogDisplayer.getDefault().notify(desc);
0659: return;
0660: }
0661:
0662: // including code to JSP
0663: if (inJsp) {
0664: // invocation
0665: Object[] args = new Object[] { serviceJavaName,
0666: portJavaName, portGetterMethod,
0667: argumentInitializationPart, returnTypeName,
0668: operationJavaName, argumentDeclarationPart };
0669: final String invocationBody = getJSPInvocationBody(
0670: operation, args);
0671: try {
0672: if (WsdlOperation.TYPE_ASYNC_CALLBACK == operation
0673: .getOperationType()) {
0674: Object[] args1 = new Object[] {
0675: callbackHandlerName, responseType };
0676: final String methodBody = MessageFormat.format(
0677: JSP_CALLBACK_HANDLER, args1);
0678: // insert 2 parts in one atomic action
0679: NbDocument.runAtomic((StyledDocument) document,
0680: new Runnable() {
0681:
0682: public void run() {
0683: try {
0684: document.insertString(document
0685: .getLength(),
0686: methodBody, null);
0687: document.insertString(pos,
0688: invocationBody, null);
0689: } catch (javax.swing.text.BadLocationException ex) {
0690: }
0691: }
0692: });
0693: } else {
0694: document.insertString(pos, invocationBody, null);
0695: }
0696:
0697: } catch (javax.swing.text.BadLocationException ex) {
0698: }
0699:
0700: return;
0701: }
0702:
0703: // including code to java class
0704: final FileObject targetFo = NbEditorUtilities
0705: .getFileObject(document);
0706:
0707: JavaSource targetSource = JavaSource.forFileObject(targetFo);
0708: String respType = responseType;
0709: final String[] argumentInitPart = { argumentInitializationPart };
0710: final String[] argumentDeclPart = { argumentDeclarationPart };
0711: final String[] serviceFName = { serviceFieldName };
0712:
0713: try {
0714: CompilerTask task = new CompilerTask(serviceJavaName,
0715: serviceFName, argumentDeclPart, argumentInitPart);
0716: targetSource.runUserActionTask(task, true);
0717:
0718: // create & format inserted text
0719: IndentEngine eng = IndentEngine.find(document);
0720: StringWriter textWriter = new StringWriter();
0721: Writer indentWriter = eng.createWriter(document, pos,
0722: textWriter);
0723:
0724: // create the inserted text
0725: String invocationBody = task.getJavaInvocationBody(
0726: operation, portJavaName, portGetterMethod,
0727: returnTypeName, operationJavaName, respType);
0728:
0729: indentWriter.write(invocationBody);
0730: indentWriter.close();
0731: String textToInsert = textWriter.toString();
0732:
0733: try {
0734: document.insertString(pos, textToInsert, null);
0735: } catch (BadLocationException badLoc) {
0736: document.insertString(pos + 1, textToInsert, null);
0737: }
0738:
0739: // @insert WebServiceRef injection
0740: if (!task.containsWsRefInjection()) {
0741: InsertTask modificationTask = new InsertTask(
0742: serviceJavaName, serviceFieldName, wsdlUrl);
0743: targetSource.runModificationTask(modificationTask)
0744: .commit();
0745: }
0746: } catch (BadLocationException badLoc) {
0747: ErrorManager.getDefault().notify(
0748: ErrorManager.INFORMATIONAL, badLoc);
0749: } catch (IOException ioe) {
0750: ErrorManager.getDefault().notify(
0751: ErrorManager.INFORMATIONAL, ioe);
0752: }
0753: }
0754:
0755: private static String findWsdlLocation(Client client,
0756: FileObject targetFo) {
0757: Project targetProject = FileOwnerQuery.getOwner(targetFo);
0758: J2eeModuleProvider moduleProvider = targetProject.getLookup()
0759: .lookup(J2eeModuleProvider.class);
0760: if (moduleProvider != null
0761: && J2eeModule.WAR.equals(moduleProvider.getJ2eeModule()
0762: .getModuleType())) {
0763: return "WEB-INF/wsdl/client/" + client.getName() + "/"
0764: + client.getLocalWsdlFile(); //NOI18N
0765: } else {
0766: return "META-INF/wsdl/client/" + client.getName() + "/"
0767: + client.getLocalWsdlFile(); //NOI18N
0768: }
0769: }
0770:
0771: private static String getJSPInvocationBody(WsdlOperation operation,
0772: Object[] args) {
0773: String invocationBody = "";
0774: switch (operation.getOperationType()) {
0775: case WsdlOperation.TYPE_NORMAL: {
0776: if ("void".equals(args[4])) {
0777: invocationBody = MessageFormat.format(
0778: JSP_STATIC_STUB_VOID, args);
0779: } else {
0780: invocationBody = MessageFormat.format(JSP_STATIC_STUB,
0781: args);
0782: }
0783: break;
0784: }
0785: case WsdlOperation.TYPE_ASYNC_POLLING: {
0786: invocationBody = MessageFormat.format(
0787: JSP_STATIC_STUB_ASYNC_POLLING, args);
0788: break;
0789: }
0790: case WsdlOperation.TYPE_ASYNC_CALLBACK: {
0791: invocationBody = MessageFormat.format(
0792: JSP_STATIC_STUB_ASYNC_CALLBACK, args);
0793: break;
0794: }
0795: }
0796: return invocationBody;
0797: }
0798:
0799: static final class CompilerTask implements
0800: CancellableTask<CompilationController> {
0801:
0802: private final boolean[] insertServiceDef = { true };
0803: private final boolean[] generateWsRefInjection = { false };
0804: private final String[] printerName = { "System.out" }; // NOI18N
0805: private final String serviceJavaName;
0806: private final String[] serviceFName;
0807: private final String[] argumentDeclPart;
0808: private final String[] argumentInitPart;
0809:
0810: public CompilerTask(String serviceJavaName,
0811: String[] serviceFName, String[] argumentDeclPart,
0812: String[] argumentInitPart) {
0813: this .serviceJavaName = serviceJavaName;
0814: this .argumentInitPart = argumentInitPart;
0815: this .argumentDeclPart = argumentDeclPart;
0816: this .serviceFName = serviceFName;
0817: }
0818:
0819: public void run(CompilationController controller)
0820: throws IOException {
0821: controller.toPhase(Phase.ELEMENTS_RESOLVED);
0822: CompilationUnitTree cut = controller.getCompilationUnit();
0823:
0824: TypeElement this TypeEl = SourceUtils
0825: .getPublicTopLevelElement(controller);
0826: if (this TypeEl != null) {
0827: ClassTree javaClass = controller.getTrees().getTree(
0828: this TypeEl);
0829: // find if class is Injection Target
0830: generateWsRefInjection[0] = InjectionTargetQuery
0831: .isInjectionTarget(controller, this TypeEl);
0832: if (generateWsRefInjection[0]) {
0833: // issue 126014 : check if J2EE Container supports EJBs (e.g. Tomcat 6 doesn't)
0834: Project project = FileOwnerQuery
0835: .getOwner(controller.getFileObject());
0836: generateWsRefInjection[0] = JaxWsUtils
0837: .isEjbSupported(project);
0838: }
0839:
0840: insertServiceDef[0] = !generateWsRefInjection[0];
0841: if (isServletClass(controller, this TypeEl)) {
0842: // PENDING Need to compute pronter name from the method
0843: printerName[0] = "out"; //NOI18N
0844: argumentInitPart[0] = fixNamesInInitializationPart(argumentInitPart[0]);
0845: argumentDeclPart[0] = fixNamesInDeclarationPart(argumentDeclPart[0]);
0846: }
0847: // compute the service field name
0848: if (generateWsRefInjection[0]) {
0849: Set<String> serviceFieldNames = new HashSet<String>();
0850: boolean injectionExists = false;
0851: int memberOrder = 0;
0852: for (Tree member : javaClass.getMembers()) {
0853: // for the first inner class in top level
0854: ++memberOrder;
0855: if (VARIABLE == member.getKind()) {
0856: // get variable type
0857: VariableTree var = (VariableTree) member;
0858: Tree typeTree = var.getType();
0859: TreePath typeTreePath = controller
0860: .getTrees().getPath(cut, typeTree);
0861: TypeElement typeEl = (TypeElement) controller
0862: .getTrees()
0863: .getElement(typeTreePath);
0864: if (typeEl != null) {
0865: String variableType = typeEl
0866: .getQualifiedName().toString();
0867: if (serviceJavaName
0868: .equals(variableType)) {
0869: serviceFName[0] = var.getName()
0870: .toString();
0871: generateWsRefInjection[0] = false;
0872: injectionExists = true;
0873: break;
0874: }
0875: }
0876: serviceFieldNames.add(var.getName()
0877: .toString());
0878: }
0879: }
0880: if (!injectionExists) {
0881: serviceFName[0] = findProperServiceFieldName(serviceFieldNames);
0882: }
0883: }
0884: }
0885: }
0886:
0887: public void cancel() {
0888: }
0889:
0890: public String getJavaInvocationBody(WsdlOperation operation,
0891: String portJavaName, String portGetterMethod,
0892: String returnTypeName, String operationJavaName,
0893: String responseType) {
0894: String invocationBody = "";
0895: Object[] args = new Object[] { serviceJavaName,
0896: portJavaName, portGetterMethod,
0897: argumentInitPart[0], returnTypeName,
0898: operationJavaName, argumentDeclPart[0],
0899: serviceFName[0], printerName[0] };
0900: switch (operation.getOperationType()) {
0901: case WsdlOperation.TYPE_NORMAL: {
0902: if ("void".equals(returnTypeName)) { //NOI18N
0903: String body = JAVA_TRY
0904: + (insertServiceDef[0] ? JAVA_SERVICE_DEF
0905: : "") + JAVA_PORT_DEF + JAVA_VOID
0906: + JAVA_CATCH;
0907: invocationBody = MessageFormat.format(body, args);
0908: } else {
0909: String body = JAVA_TRY
0910: + (insertServiceDef[0] ? JAVA_SERVICE_DEF
0911: : "") + JAVA_PORT_DEF + JAVA_RESULT
0912: + JAVA_OUT + JAVA_CATCH;
0913: invocationBody = MessageFormat.format(body, args);
0914: }
0915: break;
0916: }
0917: case WsdlOperation.TYPE_ASYNC_POLLING: {
0918: invocationBody = MessageFormat.format(
0919: JAVA_STATIC_STUB_ASYNC_POLLING, args);
0920: break;
0921: }
0922: case WsdlOperation.TYPE_ASYNC_CALLBACK: {
0923: args[7] = responseType;
0924: invocationBody = MessageFormat.format(
0925: JAVA_STATIC_STUB_ASYNC_CALLBACK, args);
0926: break;
0927: }
0928: }
0929: return invocationBody;
0930: }
0931:
0932: public boolean containsWsRefInjection() {
0933: return !generateWsRefInjection[0];
0934: }
0935:
0936: private static boolean isServletClass(
0937: CompilationController controller,
0938: TypeElement typeElement) {
0939: return SourceUtils.isSubtype(controller, typeElement,
0940: "javax.servlet.http.HttpServlet"); // NOI18N
0941: }
0942:
0943: private static String fixNamesInInitializationPart(
0944: String argumentInitializationPart) {
0945: return argumentInitializationPart.replaceFirst(" request ", //NOI18N
0946: " request_1 ").replaceFirst(" response ", //NOI18N
0947: " response_1 ").replaceFirst(" out ", " out_1 "); //NOI18N
0948: }
0949:
0950: private static String fixNamesInDeclarationPart(
0951: String argumentDeclarationPart) {
0952: StringTokenizer tok = new StringTokenizer(
0953: argumentDeclarationPart, " ,"); //NOI18N
0954: StringBuffer buf = new StringBuffer();
0955: int i = 0;
0956: while (tok.hasMoreTokens()) {
0957: String token = tok.nextToken();
0958: String newName = null;
0959: if ("request".equals(token)) { //NOI18N
0960: newName = "request_1"; //NOI18N
0961: } else if ("response".equals(token)) { //NOI18N
0962: newName = "response_1"; //NOI18N
0963: } else if ("out".equals(token)) { //NOI18N
0964: newName = "out_1"; //NOI18N
0965: } else {
0966: newName = token;
0967: }
0968: buf.append(i > 0 ? ", " + newName : newName); //NOI18N
0969: i++;
0970: }
0971: return buf.toString();
0972: }
0973:
0974: private static String findProperServiceFieldName(
0975: Set serviceFieldNames) {
0976: String name = "service"; //NOI18N
0977: int i = 0;
0978: while (serviceFieldNames.contains(name)) {
0979: name = "service_" + String.valueOf(++i); //NOI18N
0980: }
0981: return name;
0982: }
0983: }
0984:
0985: static class InsertTask implements CancellableTask<WorkingCopy> {
0986:
0987: private final String serviceJavaName;
0988: private final String serviceFName;
0989: private final String wsdlUrl;
0990:
0991: public InsertTask(String serviceJavaName, String serviceFName,
0992: String wsdlUrl) {
0993: this .serviceJavaName = serviceJavaName;
0994: this .serviceFName = serviceFName;
0995: this .wsdlUrl = wsdlUrl;
0996: }
0997:
0998: public void run(WorkingCopy workingCopy) throws IOException {
0999: workingCopy.toPhase(Phase.RESOLVED);
1000: TreeMaker make = workingCopy.getTreeMaker();
1001: ClassTree javaClass = SourceUtils
1002: .getPublicTopLevelTree(workingCopy);
1003: if (javaClass != null) {
1004: TypeElement wsRefElement = workingCopy.getElements()
1005: .getTypeElement("javax.xml.ws.WebServiceRef"); //NOI18N
1006: AnnotationTree wsRefAnnotation = make.Annotation(make
1007: .QualIdent(wsRefElement), Collections
1008: .<ExpressionTree> singletonList(make
1009: .Assignment(make
1010: .Identifier("wsdlLocation"),
1011: make.Literal(wsdlUrl)))); //NOI18N
1012: // create field modifier: private(static) with @WebServiceRef annotation
1013: FileObject targetFo = workingCopy.getFileObject();
1014: Set<Modifier> modifiers = new HashSet<Modifier>();
1015: if (Car.getCar(targetFo) != null) {
1016: modifiers.add(Modifier.STATIC);
1017: }
1018: modifiers.add(Modifier.PRIVATE);
1019: ModifiersTree methodModifiers = make
1020: .Modifiers(
1021: modifiers,
1022: Collections
1023: .<AnnotationTree> singletonList(wsRefAnnotation));
1024: TypeElement typeElement = workingCopy.getElements()
1025: .getTypeElement(serviceJavaName);
1026:
1027: // THIS is a workaround for issue 101395
1028: // after it is fixed, use the code commented code
1029: /*
1030: VariableTree serviceRefInjection = make.Variable(
1031: methodModifiers,
1032: fieldName,
1033: make.Type(typeElement.asType()),
1034: null);
1035: */
1036: //to be removed after 101395
1037: VariableTree var = make.Variable(methodModifiers,
1038: serviceFName, make.Type(typeElement.asType()),
1039: null);
1040: VariableTree serviceRefInjection = make
1041: .Variable(make.Modifiers(var.getModifiers()
1042: .getFlags(), var.getModifiers()
1043: .getAnnotations()), var.getName(), var
1044: .getType(), var.getInitializer());
1045: //end - to be removed after 101395
1046: ClassTree modifiedClass = make.insertClassMember(
1047: javaClass, 0, serviceRefInjection);
1048: workingCopy.rewrite(javaClass, modifiedClass);
1049: }
1050: }
1051:
1052: public void cancel() {
1053: }
1054: }
1055:
1056: static boolean foundImport(String importStatement,
1057: CompilationUnitTree tree) {
1058: List<? extends ImportTree> imports = tree.getImports();
1059: for (ImportTree imp : imports) {
1060: if (importStatement.equals(imp.getQualifiedIdentifier()
1061: .toString())) {
1062: return true;
1063: }
1064: }
1065: return false;
1066: }
1067:
1068: static final class DispatchCompilerTask implements
1069: CancellableTask<WorkingCopy> {
1070:
1071: public void run(WorkingCopy workingCopy) throws Exception {
1072: boolean changed = false;
1073: workingCopy.toPhase(Phase.RESOLVED);
1074: ClassTree javaClass = SourceUtils
1075: .getPublicTopLevelTree(workingCopy);
1076: TreeMaker make = workingCopy.getTreeMaker();
1077: CompilationUnitTree cut = workingCopy.getCompilationUnit();
1078: CompilationUnitTree copy = cut;
1079: if (!foundImport("javax.xml.namespace.QName", copy)) {
1080: copy = make
1081: .addCompUnitImport(
1082: copy,
1083: make
1084: .Import(
1085: make
1086: .Identifier("javax.xml.namespace.QName"),
1087: false));
1088: changed = true;
1089: }
1090: if (!foundImport("javax.xml.transform.Source", copy)) {
1091: copy = make.addCompUnitImport(copy, make.Import(make
1092: .Identifier("javax.xml.transform.Source"),
1093: false));
1094: changed = true;
1095: }
1096: if (!foundImport("javax.xml.ws.Dispatch", copy)) {
1097: copy = make.addCompUnitImport(copy, make.Import(make
1098: .Identifier("javax.xml.ws.Dispatch"), false));
1099: changed = true;
1100: }
1101: if (!foundImport("javax.xml.transform.stream.StreamSource",
1102: copy)) {
1103: copy = make
1104: .addCompUnitImport(
1105: copy,
1106: make
1107: .Import(
1108: make
1109: .Identifier("javax.xml.transform.stream.StreamSource"),
1110: false));
1111: changed = true;
1112: }
1113: if (!foundImport("javax.xml.ws.Service", copy)) {
1114: copy = make.addCompUnitImport(copy, make.Import(make
1115: .Identifier("javax.xml.ws.Service"), false));
1116: changed = true;
1117: }
1118: if (!foundImport("java.io.StringReader", copy)) {
1119: copy = make.addCompUnitImport(copy, make.Import(make
1120: .Identifier("java.io.StringReader"), false));
1121: changed = true;
1122: }
1123: if (changed) {
1124: workingCopy.rewrite(cut, copy);
1125: }
1126: }
1127:
1128: public void cancel() {
1129: }
1130: }
1131:
1132: public static String generateXMLMessage(WsdlPort port,
1133: WsdlOperation operation) {
1134: StringBuffer message = new StringBuffer("");
1135:
1136: String operationName = operation.getOperationName();
1137: String namespace = port.getNamespaceURI();
1138: message.append("<");
1139: message.append(operationName);
1140: message.append(" xmlns=\\\"");
1141: message.append(namespace);
1142: message.append("\\\">");
1143: List<WsdlParameter> parameters = operation.getParameters();
1144: for (WsdlParameter parameter : parameters) {
1145: String name = parameter.getName();
1146: message.append("<");
1147: message.append(name);
1148: message.append(">");
1149: message.append("ENTER VALUE");
1150: message.append("</");
1151: message.append(name);
1152: message.append(">");
1153: }
1154: message.append("</");
1155: message.append(operationName);
1156: message.append(">");
1157: return message.toString();
1158: }
1159:
1160: private static String getDispatchInvocationMethod(WsdlPort port,
1161: WsdlOperation operation) {
1162: StringBuffer invoke = new StringBuffer("");
1163: invoke.append(MessageFormat.format(QNAME, new Object[] {
1164: port.getNamespaceURI(), port.getName() }));
1165: invoke.append("\n");
1166: invoke.append("String req = ");
1167: invoke.append("\"");
1168: invoke.append(generateXMLMessage(port, operation));
1169: invoke.append("\";\n");
1170: invoke.append(MessageFormat.format(JAVA_TRY, new Object[] {}));
1171: invoke.append("\n");
1172: invoke.append("Dispatch<Source> sourceDispatch = null;\n");
1173: invoke
1174: .append("sourceDispatch = service.createDispatch(portQName, Source.class, Service.Mode.PAYLOAD);\n");
1175: invoke
1176: .append("Source result = sourceDispatch.invoke(new StreamSource(new StringReader(req)));\n");
1177: invoke
1178: .append(MessageFormat.format(JAVA_CATCH,
1179: new Object[] {}));
1180: invoke.append("\n");
1181: return invoke.toString();
1182: }
1183:
1184: private static String getJSPDispatchBody(Object[] args) {
1185: return MessageFormat.format(JSP_DISPATCH, args);
1186: }
1187:
1188: public static void insertDispatchMethod(final Document document,
1189: final int pos, WsdlService service, WsdlPort port,
1190: WsdlOperation operation, String wsdlUrl) {
1191: boolean inJsp = "text/x-jsp".equals(document
1192: .getProperty("mimeType")); //NOI18N
1193: if (inJsp) {
1194: Object[] args = new Object[] { service.getJavaName(),
1195: port.getNamespaceURI(), port.getJavaName(),
1196: generateXMLMessage(port, operation) };
1197: final String invocationBody = getJSPDispatchBody(args);
1198: try {
1199:
1200: document.insertString(pos, invocationBody, null);
1201: } catch (javax.swing.text.BadLocationException ex) {
1202: }
1203: return;
1204: }
1205: try {
1206:
1207: final FileObject targetFo = NbEditorUtilities
1208: .getFileObject(document);
1209: JavaSource targetSource = JavaSource
1210: .forFileObject(targetFo);
1211:
1212: String serviceJavaName = service.getJavaName();
1213: String[] serviceFName = new String[] { "service" };
1214: String[] argumentDeclPart = new String[] { "" };
1215: String[] argumentInitPart = new String[] { "" };
1216: CompilerTask compilerTask = new CompilerTask(
1217: serviceJavaName, serviceFName, argumentDeclPart,
1218: argumentInitPart);
1219: targetSource.runUserActionTask(compilerTask, true);
1220:
1221: IndentEngine eng = IndentEngine.find(document);
1222: StringWriter textWriter = new StringWriter();
1223: Writer indentWriter = eng.createWriter(document, pos,
1224: textWriter);
1225:
1226: if (compilerTask.containsWsRefInjection()) { //if in J2SE
1227: Object[] args = new Object[] { service.getJavaName(),
1228: null, null, null, null, null, null, "service" }; //TODO: compute proper var name
1229: String serviceDeclForJava = MessageFormat.format(
1230: JAVA_SERVICE_DEF, args);
1231: indentWriter.write(serviceDeclForJava);
1232: }
1233: // create the inserted text
1234: String invocationBody = getDispatchInvocationMethod(port,
1235: operation);
1236: indentWriter.write(invocationBody);
1237: indentWriter.close();
1238: String textToInsert = textWriter.toString();
1239:
1240: try {
1241: document.insertString(pos, textToInsert, null);
1242: } catch (BadLocationException badLoc) {
1243: try {
1244: document.insertString(pos + 1, textToInsert, null);
1245: } catch (BadLocationException ex) {
1246: ErrorManager.getDefault().notify(ex);
1247: }
1248: }
1249:
1250: // @insert WebServiceRef injection
1251: if (!compilerTask.containsWsRefInjection()) {
1252: InsertTask modificationTask = new InsertTask(
1253: serviceJavaName, serviceFName[0], wsdlUrl);
1254: targetSource.runModificationTask(modificationTask)
1255: .commit();
1256: }
1257:
1258: DispatchCompilerTask task = new DispatchCompilerTask();
1259: targetSource.runModificationTask(task).commit();
1260:
1261: } catch (IOException ex) {
1262: Exceptions.printStackTrace(ex);
1263: }
1264: }
1265: }
|