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-2006 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:
042: package org.netbeans.modules.websvc.registry.jaxrpc;
043:
044: import com.sun.xml.rpc.processor.model.java.JavaException;
045: import com.sun.xml.rpc.processor.model.java.JavaMethod;
046: import com.sun.xml.rpc.processor.model.java.JavaParameter;
047: import com.sun.xml.rpc.processor.model.Port;
048: import com.sun.xml.rpc.processor.model.Operation;
049:
050: import org.netbeans.modules.websvc.registry.util.Util;
051:
052: import java.io.PrintWriter;
053: import java.io.Writer;
054: import java.util.HashSet;
055: import java.util.Iterator;
056: import java.util.Set;
057:
058: /**
059: * A simple writer to write the Java Source.
060: * @author Winston Prakash
061: */
062: public class WrapperClientWriter extends java.io.PrintWriter {
063:
064: private String serviceName;
065: private String serviceVariable;
066:
067: private String className;
068: private String super ClassName;
069: private Set interfaces = new HashSet();
070: private String packageName;
071: private Set imports = new HashSet();
072: private Set ports = new HashSet();
073:
074: private Set constructorStatements = new HashSet();
075:
076: int indent = 0;
077:
078: /** Creates a new instance of JavaWriter */
079: public WrapperClientWriter(Writer writer) {
080: super (writer);
081: }
082:
083: public void setContainedClassInfo(String serviceName) {
084: this .serviceName = serviceName;
085: serviceVariable = serviceName.substring(serviceName
086: .lastIndexOf('.') + 1, serviceName.length());
087: serviceVariable = serviceVariable.toLowerCase() + "1";
088: }
089:
090: /** Set package name */
091: public void setPackage(String pkgName) {
092: packageName = pkgName;
093: }
094:
095: public void addImport(String importLine) {
096: imports.add(importLine);
097: }
098:
099: /** Set the name of the class */
100: public void setName(String name) {
101: className = name;
102: }
103:
104: /** Set the name of the super class this class would extends */
105: public void setSuperClass(String super Class) {
106: super ClassName = super Class;
107: }
108:
109: /** Set the name of the interfaces this class would extends */
110: public void addInterface(String interfaceName) {
111: interfaces.add(interfaceName);
112: }
113:
114: public void addConstructorStatements(String statement) {
115: constructorStatements.add(statement);
116: }
117:
118: public void addPort(Port inPort) {
119: ports.add(inPort);
120: }
121:
122: public void writeClass() {
123: /**
124: * Write the package statement
125: */
126: println("package " + packageName + ";");
127: println();
128:
129: /**
130: * Write the imports statement.
131: */
132: if (!imports.isEmpty()) {
133: Iterator iter = imports.iterator();
134: while (iter.hasNext()) {
135: println("import " + iter.next() + ";");
136: }
137: println();
138: }
139: println("import java.rmi.RemoteException;");
140: println("import javax.xml.rpc.ServiceException;");
141: println("import javax.xml.rpc.Stub;");
142: println();
143:
144: /**
145: * Write the class declaration
146: */
147: print("public class " + className);
148: if (super ClassName != null)
149: print("extends " + super ClassName + " ");
150: if (!interfaces.isEmpty()) {
151: println("implements ");
152: Iterator iter = interfaces.iterator();
153: while (iter.hasNext()) {
154: print((String) iter.next());
155: if (iter.hasNext())
156: print(",");
157: }
158: }
159: println(" {");
160: println();
161:
162: /**
163: * write the class instance variables.
164: */
165:
166: /**
167: * write a variable for the service implementation.
168: */
169: println(" private " + serviceName + " " + serviceVariable
170: + " = " + "new " + serviceName + "_Impl();");
171:
172: /**
173: * write a variable for each port in the serviee.
174: */
175: if (!ports.isEmpty()) {
176: Iterator portIterator = ports.iterator();
177: Port currentPort = null;
178: while (portIterator.hasNext()) {
179: currentPort = (Port) portIterator.next();
180: /**
181: * get the Java class name for the port.
182: */
183: String portImplName = Util
184: .getProperPortName(currentPort.getName()
185: .getLocalPart());
186: String portInterfaceName = currentPort
187: .getJavaInterface().getName();
188: /**
189: * Strip off the leading package qualification since we don't need it.
190: */
191: portInterfaceName = portInterfaceName.substring(
192: portInterfaceName.lastIndexOf('.') + 1,
193: portInterfaceName.length());
194: /**
195: * create the variable name for the port
196: * NOTE: - When we write out the methods, we'll need to use the same convention of naming the port that
197: * we do here.
198: */
199: String portInterfaceVariable = portInterfaceName
200: .substring(
201: portInterfaceName.lastIndexOf('.') + 1,
202: portInterfaceName.length());
203: String portInterfacePrefix = portInterfaceVariable
204: .toLowerCase();
205: portInterfaceVariable = portInterfaceVariable
206: .toLowerCase()
207: + "1";
208: /**
209: * Apparently, the compiletool uppercases the first letter of the port name to make it a proper getter so we need to do the same.
210: */
211: String modifiedPortName = Util
212: .upperCaseFirstChar(portInterfaceName);
213:
214: println(" private " + portInterfaceName + " "
215: + portInterfaceVariable + ";"); // " + portInterfaceVariable + " = " + serviceVariable + ".get" +portImplName +"();");
216: addConstructorStatements(portInterfaceVariable + " = "
217: + serviceVariable + ".get" + portImplName
218: + "()");
219: println(" private Stub " + portInterfacePrefix
220: + "Stub;"); // = (Stub)" + portInterfaceVariable + ";");
221: addConstructorStatements(portInterfacePrefix
222: + "Stub = (Stub)" + portInterfaceVariable);
223: }
224:
225: println();
226: // Write the constructor
227: println(" public " + className
228: + "() throws ServiceException {");
229: if (!constructorStatements.isEmpty()) {
230: Iterator iter = constructorStatements.iterator();
231: while (iter.hasNext()) {
232: println(" " + (String) iter.next() + ";");
233: }
234: }
235: println(" }");
236: println();
237:
238: printOperations(ports);
239: println("}");
240:
241: }
242: }
243:
244: private void printOperations(Set inPorts) {
245: Iterator portIterator = inPorts.iterator();
246: Port currentPort = null;
247: while (portIterator.hasNext()) {
248: currentPort = (Port) portIterator.next();
249: /**
250: * Get the name for the current port.
251: */
252: String lowercasePortName = Util.getProperPortName(
253: currentPort.getName().getLocalPart()).toLowerCase();
254: /**
255: * get the Java class name for the port.
256: */
257: String portInterfaceName = currentPort.getJavaInterface()
258: .getName();
259: /**
260: * Strip off the leading package qualification since we don't need it.
261: */
262: portInterfaceName = portInterfaceName.substring(
263: portInterfaceName.lastIndexOf('.') + 1,
264: portInterfaceName.length());
265: /**
266: * create the variable name for the port
267: * NOTE: -This variable name needs to be the same one written out for the class instance varables.
268: */
269: String portInterfaceVariable = portInterfaceName.substring(
270: portInterfaceName.lastIndexOf('.') + 1,
271: portInterfaceName.length());
272: String portInterfacePrefix = portInterfaceVariable
273: .toLowerCase();
274: portInterfaceVariable = portInterfaceVariable.toLowerCase()
275: + "1";
276: Iterator operationsIterator = currentPort.getOperations();
277: Operation currentOperation = null;
278: while (operationsIterator.hasNext()) {
279: currentOperation = (Operation) operationsIterator
280: .next();
281: if (null == currentOperation) {
282: continue;
283: }
284: JavaMethod method = currentOperation.getJavaMethod();
285: String modifiedMethodName = Util
286: .upperCaseFirstChar(method.getName());
287: println();
288: print(" public "
289: + method.getReturnType().getRealName() + " ");
290: print(lowercasePortName + modifiedMethodName + "(");
291: Iterator params = method.getParameters();
292: String parameterType = "";
293:
294: while (params.hasNext()) {
295: JavaParameter param = (JavaParameter) params.next();
296: /**
297: * Bug fix: 5059732
298: * If the parameter is a "Holder" we need the holder type and not the JavaType. This is
299: * typically the case when there is no return type and the parameter's meant to be mutable, pass-by-reference
300: * type parameters. I took the code below directly from the JAX-RPC class:
301: * "com.sun.xml.rpc.processor.generator.StubGenerator"
302: * - David Botterill 6/8/2004
303: */
304:
305: parameterType = Util.getParameterType(currentPort,
306: param);
307: /**
308: * end of bug fix: 5059732
309: */
310:
311: print(parameterType + " " + param.getName());
312: if (params.hasNext())
313: write(", ");
314: }
315: print(") ");
316: Iterator exceptions = method.getExceptions();
317: /**
318: * Bugid: 4970323 This area of code was not exercised before WSDLInfo was fixed. Hence this bug showed up as a result of
319: * fixing a bug.
320: *
321: */
322:
323: /**
324: * We need a "throws" at least for the RemoteException
325: *
326: */
327: print(" throws ");
328:
329: while (exceptions.hasNext()) {
330: /**
331: * Bugid: 4970323 - The return type of an exceptions is a String not a JavaException. This
332: * can only be know for sure by reading the current JavaException code since the "JavaMethod.getExceptions()"
333: * method returns an Iterator and the javadoc says nothing of it being a String.
334: *
335: * This area of code was not exercised before WSDLInfo was fixed. Hence this bug showed up as a result of
336: * fixing a bug.
337: */
338: /**
339: * Make sure we don't get back a null or an empty String. Check to make sure
340: * the Object is a string in case the API matures and JavaException turns back into a real object with
341: * a "getName" method.
342: */
343: Object currentException = exceptions.next();
344: if (null != currentException
345: && currentException instanceof String
346: && ((String) currentException).length() > 0) {
347: print((String) currentException);
348: /**
349: * always print a "," because we have the RemoteException following.
350: */
351: print(", ");
352: }
353: }
354: println(" RemoteException { ");
355:
356: if (!"void"
357: .equals(method.getReturnType().getRealName())) {
358: print(" return " + portInterfaceVariable
359: + "." + method.getName() + "(");
360: } else {
361: print(" " + portInterfaceVariable + "."
362: + method.getName() + "(");
363: }
364: params = method.getParameters();
365: while (params.hasNext()) {
366: JavaParameter param = (JavaParameter) params.next();
367: //if(param.isHolder()){
368: //print(param.getHolderName());
369: //}else {
370: print(param.getName());
371: //}
372: if (params.hasNext())
373: write(", ");
374: }
375: println(");");
376:
377: println(" }");
378: }
379:
380: /**
381: * Now print out the methods for setting the Stub properties.
382: */
383: println("public void " + lowercasePortName
384: + "SetUsername(String inUserName) {");
385: println(" "
386: + portInterfacePrefix
387: + "Stub._setProperty(Stub.USERNAME_PROPERTY, inUserName);");
388: println("}");
389: println();
390: println("public void " + lowercasePortName
391: + "SetPassword(String inPassword) {");
392: println(" "
393: + portInterfacePrefix
394: + "Stub._setProperty(Stub.PASSWORD_PROPERTY, inPassword);");
395: println("}");
396: println();
397: println("public void " + lowercasePortName
398: + "SetAddress(String inAddress) {");
399: println(" "
400: + portInterfacePrefix
401: + "Stub._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, inAddress);");
402: println("}");
403: println();
404: }
405:
406: }
407:
408: public class Method {
409: Set methodStatement = new HashSet();
410:
411: public Method(JavaMethod method) {
412: }
413:
414: public void addStatement(String statement) {
415: methodStatement.add(statement);
416: }
417:
418: public Set getStatements() {
419: return methodStatement;
420: }
421: }
422:
423: /**
424: * @param args the command line arguments
425: */
426: public static void main(String[] args) {
427: }
428:
429: }
|