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:
042: package org.netbeans.modules.visualweb.websvcmgr.codegen;
043:
044: import com.sun.tools.ws.processor.model.java.JavaParameter;
045: import java.util.List;
046: import org.netbeans.modules.visualweb.websvcmgr.util.Util;
047:
048: import java.io.Writer;
049: import java.util.Date;
050: import java.util.HashSet;
051: import java.util.Iterator;
052: import java.util.Set;
053: import org.netbeans.modules.websvc.manager.util.ManagerUtil;
054:
055: /**
056: * Creates the DataProvider Java source code for the given method
057: * @author cao
058: */
059: public class DataProviderWriter extends java.io.PrintWriter {
060:
061: private static String[] PRIMITIVE_TYPES = { "char", "byte",
062: "short", "int", "long", "float", "double", "boolean" };
063:
064: private static String[] PRIMITIVE_WRAPPERS = { "Character", "Byte",
065: "Short", "Integer", "Long", "Float", "Double", "Boolean" };
066:
067: private DataProviderInfo dataProviderInfo;
068: private Set imports = new HashSet();
069: private boolean isJ2EE_15;
070: private ClassLoader classLoader;
071:
072: public DataProviderWriter(Writer writer,
073: DataProviderInfo dataProviderInfo, boolean isJ2EE_15) {
074: super (writer);
075: this .dataProviderInfo = dataProviderInfo;
076: this .isJ2EE_15 = isJ2EE_15;
077: }
078:
079: public void addImport(String importLine) {
080: imports.add(importLine);
081: }
082:
083: public void setClassLoader(ClassLoader loader) {
084: this .classLoader = loader;
085: }
086:
087: public void writeClass() {
088: boolean isPrimitiveReturnType = Util
089: .isPrimitiveType(dataProviderInfo.getMethod()
090: .getMethodReturnType());
091:
092: // package
093: println("package " + dataProviderInfo.getPackageName() + ";");
094:
095: // comments
096: println("/**");
097: println(" * Source code created on " + new Date());
098: println(" */");
099: println();
100:
101: // Import
102: if (!imports.isEmpty()) {
103: Iterator iter = imports.iterator();
104: while (iter.hasNext()) {
105: println("import " + iter.next() + ";");
106: }
107: println();
108: }
109: println("import com.sun.data.provider.*;");
110: println("import com.sun.data.provider.impl.*;");
111: println("import java.lang.reflect.Method;");
112: if (isJ2EE_15) {
113: println("import java.lang.reflect.ParameterizedType;");
114: println("import java.lang.reflect.Type;");
115: }
116: println("import java.beans.*;");
117: println("import java.util.ArrayList;");
118: println();
119:
120: // start of class
121: // Always extends from "MethodResultTableDataProvider
122: String dpSuperClassName = "MethodResultTableDataProvider";
123:
124: String className = dataProviderInfo.getClassName();
125: println("public class " + className + " extends "
126: + dpSuperClassName + " {");
127: println();
128:
129: // Memeber variables
130: String clientWrapperClassName = dataProviderInfo
131: .getClientWrapperClassName();
132: String clientWrapperClassVar = ManagerUtil
133: .makeValidJavaBeanName(ManagerUtil
134: .decapitalize(clientWrapperClassName));
135:
136: println(" protected " + clientWrapperClassName + " "
137: + clientWrapperClassVar + ";");
138: println(" // Properties. One per method parameter.");
139:
140: for (DataProviderParameter parameter : dataProviderInfo
141: .getMethod().getParameters()) {
142: println(" protected " + parameter.getType() + " "
143: + parameter.getName() + ";");
144: }
145: println();
146:
147: // Default Constructor
148: println(" public " + className + "() {");
149: println(" }");
150: println();
151:
152: // Getter and setter for the client wrapper class
153: println(" public " + clientWrapperClassName + " get"
154: + clientWrapperClassName + "() {");
155: println(" return this." + clientWrapperClassVar + ";");
156: println(" }");
157: println();
158:
159: println(" public void set" + clientWrapperClassName + "( "
160: + clientWrapperClassName + " " + clientWrapperClassVar
161: + " ) { ");
162: println(" this." + clientWrapperClassVar + " = "
163: + clientWrapperClassVar + ";");
164:
165: // Call super.setDataMethod() - need to the method name and parameter class types
166: println(" try { ");
167: println(" setDataProviderProperties(); ");
168:
169: // Call super.setCollectionElementType(Class) - needed to generate correct FieldKeys for List<T> return types (only for JAX-WS)
170: if (isJ2EE_15) {
171: println(" Method dataMethod = super.getDataMethod(); ");
172: println(" Class returnClass = dataMethod.getReturnType();");
173: println(" if (java.util.Collection.class.isAssignableFrom(returnClass)) {");
174: println(" Type returnType = dataMethod.getGenericReturnType();");
175: println(" if (returnType instanceof ParameterizedType) { ");
176: println(" ParameterizedType paramType = (ParameterizedType)returnType;");
177: println(" Type[] actualTypes = paramType.getActualTypeArguments();");
178: println(" if (actualTypes.length == 1 && actualTypes[0] instanceof Class) { ");
179: println(" super.setCollectionElementType((Class)actualTypes[0]);");
180: println(" }");
181: println(" }");
182: println(" }");
183: }
184:
185: println(" } catch( java.lang.NoSuchMethodException ne ) { ");
186: println(" ne.printStackTrace();");
187: println(" }");
188: println(" }");
189: println();
190:
191: // Methods for get/set of the properties/method parameters
192:
193: for (DataProviderParameter param : dataProviderInfo.getMethod()
194: .getParameters()) {
195: // Getter
196: println(" public " + param.getType() + " get"
197: + ManagerUtil.upperCaseFirstChar(param.getName())
198: + "() {");
199: println(" return " + param.getName() + ";");
200: println(" }");
201: println();
202:
203: // Setter
204: println(" public void set"
205: + ManagerUtil.upperCaseFirstChar(param.getName())
206: + "( " + param.getType() + " " + param.getName()
207: + " ) { ");
208: println(" this." + param.getName() + " = "
209: + param.getName() + ";");
210: println(" }");
211: println();
212: }
213: println();
214:
215: // Implement abstract method from super class - getDataMethodArguments()
216: if (!isPrimitiveReturnType
217: && dataProviderInfo.getOutputHolderIndex() < 0
218: && dataProviderInfo.getWrappedProperty() == null) {
219: println(" public Object[] getDataMethodArguments() {");
220: } else {
221: println(" private Object[] getOriginalDataMethodArguments() {");
222: }
223:
224: int methodArgSize = dataProviderInfo.getMethod()
225: .getParameters().size();
226:
227: println(" try { ");
228: println(" Object[] values = new Object["
229: + methodArgSize + "];");
230: println();
231:
232: for (int i = 0; i < methodArgSize; i++) {
233: DataProviderParameter field = dataProviderInfo.getMethod()
234: .getParameters().get(i);
235: println(" values["
236: + i
237: + "] = "
238: + convertPrimitiveType(field.getName(), field
239: .getType()) + ";");
240: }
241:
242: println(" return values;");
243: println(" } catch( Exception e ) { ");
244: println(" e.printStackTrace();");
245: println(" return null; ");
246: println(" }");
247:
248: println();
249: println(" }");
250: println();
251:
252: // Override getFieldKeys() method to filter out the class field
253: println(" public FieldKey[] getFieldKeys() throws DataProviderException {");
254: println(" FieldKey[] fieldKeys = super.getFieldKeys(); ");
255: println(" ArrayList finalKeys = new ArrayList(); ");
256: println(" for( int i = 0; i < fieldKeys.length; i ++ ) { ");
257: println(" if( !fieldKeys[i].getFieldId().equals( \"class\" ) )");
258: println(" finalKeys.add( fieldKeys[i] ); ");
259: println(" } ");
260: println(" return (FieldKey[])finalKeys.toArray( new FieldKey[0] ); ");
261: println(" } ");
262:
263: int outputHolderIndex = dataProviderInfo.getOutputHolderIndex();
264:
265: if (dataProviderInfo.getWrappedProperty() != null) {
266: println(" private void setDataProviderProperties() throws NoSuchMethodException { ");
267: println(" super.setDataClassInstance( this );");
268: println(" originalDataMethod = "
269: + clientWrapperClassName + ".class.getMethod(");
270: println(" \""
271: + dataProviderInfo.getMethod().getMethodName()
272: + "\", new Class[] {" + getMethodParamTypes()
273: + "} );");
274: println(" super.setDataMethod( getWrapperMethod() ); ");
275: println(" }");
276: writeUnwrapMethod(clientWrapperClassVar, dataProviderInfo
277: .getMethod().getMethodReturnType(),
278: dataProviderInfo.getWrappedProperty().getName(),
279: dataProviderInfo.getWrappedProperty().getType());
280: } else if (outputHolderIndex >= 0) {
281: List<JavaParameter> args = ((DataProviderModelMethod) dataProviderInfo
282: .getMethod()).getJavaMethod().getParametersList();
283: String holderValueType = args.get(outputHolderIndex)
284: .getType().getRealName();
285:
286: println(" private void setDataProviderProperties() throws NoSuchMethodException { ");
287: for (DataProviderParameter param : dataProviderInfo
288: .getMethod().getParameters()) {
289: if (param.getType().startsWith("javax.xml.ws.Holder")) {
290: String paramName = param.getName();
291: String paramType = param.getType();
292: println(" " + paramName + " = new "
293: + paramType + "();");
294: }
295: }
296: println(" super.setDataClassInstance( this );");
297: println(" originalDataMethod = "
298: + clientWrapperClassName + ".class.getMethod(");
299: println(" \""
300: + dataProviderInfo.getMethod().getMethodName()
301: + "\", new Class[] {" + getMethodParamTypes()
302: + "} );");
303: println(" super.setDataMethod( getWrapperMethod() ); ");
304: println(" }");
305:
306: writeOutputHolderMethodWrapper(clientWrapperClassVar,
307: holderValueType);
308: } else if (!isPrimitiveReturnType) {
309: println(" private void setDataProviderProperties() throws NoSuchMethodException { ");
310: println(" super.setDataClassInstance( "
311: + clientWrapperClassVar + ");");
312: println(" java.lang.reflect.Method dataMethod = "
313: + clientWrapperClassName + ".class.getMethod(");
314: println(" \""
315: + dataProviderInfo.getMethod().getMethodName()
316: + "\", new Class[] {" + getMethodParamTypes()
317: + "} );");
318: println(" super.setDataMethod( dataMethod );");
319: println(" }");
320: } else {
321: println(" private void setDataProviderProperties() throws NoSuchMethodException { ");
322: println(" super.setDataClassInstance( this );");
323: println(" originalDataMethod = "
324: + clientWrapperClassName + ".class.getMethod(");
325: println(" \""
326: + dataProviderInfo.getMethod().getMethodName()
327: + "\", new Class[] {" + getMethodParamTypes()
328: + "} );");
329: println(" super.setDataMethod( getWrapperMethod() ); ");
330: println(" }");
331: writePrimitiveMethodWrapper(clientWrapperClassVar);
332: }
333:
334: // End of client bean class
335: println("}");
336: }
337:
338: private void writeOutputHolderMethodWrapper(String clientVar,
339: String holderValueType) {
340: int outputHolderIndex = dataProviderInfo.getOutputHolderIndex();
341: String getter = "get"
342: + ManagerUtil.upperCaseFirstChar(dataProviderInfo
343: .getMethod().getParameters().get(
344: outputHolderIndex).getName()) + "()";
345:
346: String exceptionReturnValue = "null";
347:
348: if (ManagerUtil.isJavaPrimitive(holderValueType)) {
349: exceptionReturnValue = getDefaultPrimitiveRepresentation(holderValueType);
350: }
351:
352: println("");
353: println(" private Method originalDataMethod; ");
354: println("");
355: println(" public " + holderValueType + " invokeMethod() {");
356: println(" try { ");
357: println(" originalDataMethod.invoke(" + clientVar
358: + ", getOriginalDataMethodArguments()); ");
359: println(" " + holderValueType
360: + " methodResult = this." + getter + ".value;");
361: println(" return methodResult; ");
362: println(" }catch (Exception ex) { ");
363: println(" ex.printStackTrace(); ");
364: println(" return " + exceptionReturnValue + "; ");
365: println(" }");
366: println(" } ");
367: println("");
368: println(" private Method getWrapperMethod() throws NoSuchMethodException {");
369: println(" return this.getClass().getMethod(\"invokeMethod\", new Class[0]); ");
370: println(" } ");
371: println("");
372: }
373:
374: private void writeUnwrapMethod(String clientVar,
375: String wrappedType, String propertyName, String propertyType) {
376: java.lang.reflect.Method getMethod = Util.getPropertyGetter(
377: wrappedType, propertyName, classLoader);
378: String getter = getMethod.getName() + "()";
379: String exceptionReturnValue = "null";
380:
381: if (Util.isJavaPrimitive(propertyType)) {
382: exceptionReturnValue = getDefaultPrimitiveRepresentation(propertyType);
383: }
384:
385: println("");
386: println(" private Method originalDataMethod; ");
387: println("");
388: println(" public " + propertyType + " invokeMethod() {");
389: println(" try { ");
390: println(" " + wrappedType + " result = ("
391: + wrappedType + ") originalDataMethod.invoke("
392: + clientVar + ", getOriginalDataMethodArguments()); ");
393: println(" " + propertyType
394: + " methodResult = result." + getter + ";");
395: println(" return methodResult; ");
396: println(" }catch (Exception ex) { ");
397: println(" ex.printStackTrace(); ");
398: println(" return " + exceptionReturnValue + "; ");
399: println(" }");
400: println(" } ");
401: println("");
402: println(" private Method getWrapperMethod() throws NoSuchMethodException {");
403: println(" return this.getClass().getMethod(\"invokeMethod\", new Class[0]); ");
404: println(" } ");
405: println("");
406: }
407:
408: private void writePrimitiveMethodWrapper(String clientVar) {
409: String mrt = dataProviderInfo.getMethod().getMethodReturnType();
410: if (Util.isJavaPrimitive(mrt)) {
411: mrt = Util.getWrapperForPrimitive(mrt);
412: }
413:
414: println("");
415: println(" private Method originalDataMethod; ");
416: println("");
417: println(" public ResultBean invokeMethod() {");
418: println(" try { ");
419: println(" " + mrt + " result = (" + mrt
420: + ")originalDataMethod.invoke(" + clientVar
421: + ", getOriginalDataMethodArguments()); ");
422: println(" ResultBean methodResult = new ResultBean(); ");
423: println(" methodResult.setMethodResult(result); ");
424: println(" return methodResult; ");
425: println(" }catch (Exception ex) { ");
426: println(" ex.printStackTrace(); ");
427: println(" return null; ");
428: println(" }");
429: println(" } ");
430: println("");
431: println(" private Method getWrapperMethod() throws NoSuchMethodException {");
432: println(" return this.getClass().getMethod(\"invokeMethod\", new Class[0]); ");
433: println(" } ");
434: println("");
435: println(" public static final class ResultBean { ");
436: println(" private " + mrt + " methodResult; ");
437: println("");
438: println(" public ResultBean() { ");
439: println(" } ");
440: println("");
441: println(" public " + mrt + " getMethodResult() { ");
442: println(" return this.methodResult; ");
443: println(" }");
444: println("");
445: println(" public void setMethodResult(" + mrt
446: + " result) { ");
447: println(" this.methodResult = result; ");
448: println(" } ");
449: println(" } ");
450: }
451:
452: private String convertPrimitiveType(String name, String type) {
453: for (int i = 0; i < PRIMITIVE_TYPES.length; i++) {
454: String typeName = PRIMITIVE_TYPES[i];
455: if (type != null && typeName.equals(type.trim())) {
456: return PRIMITIVE_WRAPPERS[i] + ".valueOf(this." + name
457: + ")";
458: }
459: }
460:
461: return "this." + name;
462: }
463:
464: private String getMethodParamTypes() {
465: StringBuffer buf = new StringBuffer();
466: boolean first = true;
467:
468: for (DataProviderParameter param : dataProviderInfo.getMethod()
469: .getParameters()) {
470: if (first) {
471: first = false;
472: } else {
473: buf.append(", ");
474: }
475:
476: int len = separateGenericType(param.getType());
477: String typeClass = param.getType().substring(0, len);
478:
479: buf.append(typeClass);
480: buf.append(".class"); // NOI18N
481: }
482: return buf.toString();
483: }
484:
485: // TODO - merge this with ReflectionHelper.separateGenericType
486: private int separateGenericType(String typeName) {
487: int length = typeName.length();
488:
489: if (length < 2 || typeName.charAt(length - 1) != '>') { // NOI18N
490: return length;
491: } else {
492: int depth = 1;
493: for (int i = length - 2; i >= 0; i--) {
494: if (typeName.charAt(i) == '>') {
495: depth += 1;
496: } else if (typeName.charAt(i) == '<') {
497: depth -= 1;
498: }
499:
500: if (depth == 0) {
501: return i;
502: }
503: }
504:
505: return length;
506: }
507: }
508:
509: private String getDefaultPrimitiveRepresentation(String typeName) {
510: if (typeName.equals("boolean")) {
511: return "false";
512: } else {
513: return "0";
514: }
515: }
516:
517: }
|