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.util;
043:
044: import com.sun.tools.ws.processor.model.java.JavaMethod;
045: import com.sun.tools.ws.processor.model.java.JavaParameter;
046: import com.sun.tools.ws.processor.model.java.JavaType;
047: import java.io.File;
048: import java.io.IOException;
049: import java.lang.reflect.GenericArrayType;
050: import java.lang.reflect.Method;
051: import java.lang.reflect.ParameterizedType;
052: import java.lang.reflect.Type;
053: import java.net.URL;
054: import java.net.URLClassLoader;
055: import java.util.ArrayList;
056: import java.util.HashMap;
057: import java.util.List;
058: import java.util.Map;
059: import org.netbeans.api.project.FileOwnerQuery;
060: import org.netbeans.api.project.Project;
061: import org.netbeans.api.project.libraries.Library;
062: import org.netbeans.api.project.libraries.LibraryManager;
063: import org.netbeans.modules.visualweb.api.designerapi.DesignerServiceHack;
064: import org.netbeans.modules.visualweb.websvcmgr.codegen.DataProviderMethod;
065: import org.netbeans.modules.visualweb.websvcmgr.codegen.DataProviderParameter;
066:
067: // BEGIN_NOI18N
068: import org.netbeans.modules.visualweb.websvcmgr.consumer.DesignerWebServiceExtData;
069: import org.netbeans.modules.visualweb.websvcmgr.consumer.DesignerWebServiceExtImpl;
070: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlPort;
071: import org.netbeans.modules.websvc.manager.api.WebServiceDescriptor;
072: import org.netbeans.modules.websvc.manager.model.WebServiceData;
073: import org.netbeans.modules.websvc.manager.util.ManagerUtil;
074: import org.openide.filesystems.FileObject;
075: import org.openide.modules.InstalledFileLocator;
076:
077: /**
078: * General utility methods for WSDL documents.
079: */
080: public class Util {
081: public static final String dataproviderJar = InstalledFileLocator
082: .getDefault().locate("modules/ext/dataprovider.jar", null,
083: false).getAbsolutePath(); // NOI18N
084: public static final String designTimeJar = InstalledFileLocator
085: .getDefault()
086: .locate(
087: "modules/org-netbeans-modules-visualweb-designtime.jar",
088: null, false).getAbsolutePath(); // NOI18N
089:
090: public static final int BUFFER_SIZE = 4096;
091: public static final String xsdNamespace = "xsd";
092: final static public String WSDL_FILE_EXTENSION = "wsdl";
093:
094: public static boolean isJAXRPCAvailable() {
095: return getWebServiceSupportLibDef(false) != null;
096: }
097:
098: /**
099: * @return The library definition containing the web service support jar files, null if it does not exist
100: */
101: public static Library getWebServiceSupportLibDef(boolean isJ2EE_15) {
102: String libraryName = (isJ2EE_15) ? "jaxws21" : "jaxrpc16";
103: Library libDef = LibraryManager.getDefault().getLibrary(
104: libraryName);
105:
106: return libDef;
107: }
108:
109: public static Method getPropertyGetter(String type,
110: String propName, ClassLoader loader) {
111: try {
112: Class typeClass = Class.forName(type, true, loader);
113:
114: char[] name = propName.toCharArray();
115: String propCaps = null;
116:
117: Method method = null;
118:
119: for (int i = 0; i < propName.length() && method == null; i++) {
120: name[i] = Character.toUpperCase(name[i]);
121: propCaps = new String(name);
122: try {
123: method = typeClass.getMethod("get" + propCaps,
124: new Class[0]); // NOI18N
125: } catch (NoSuchMethodException ex) {
126: try {
127: method = typeClass.getMethod("is" + propCaps,
128: new Class[0]); // NOI18N
129: } catch (NoSuchMethodException nsme) {
130: continue;
131: }
132: }
133: }
134:
135: return method;
136: } catch (Exception ex) {
137: return null;
138: }
139: }
140:
141: private static final String[] PRIMITIVE_WRAPPER_CLASSES = {
142: "java.lang.Boolean", "java.lang.Byte", "java.lang.Double",
143: "java.lang.Float", "java.lang.Integer", "java.lang.Long",
144: "java.lang.Short", "java.lang.Character",
145: "java.lang.String" };
146:
147: private static final String[] PRIMITIVE_TYPES = { "boolean",
148: "byte", "double", "float", "int", "long", "short", "char" };
149:
150: public static boolean isPrimitiveType(String typeName) {
151: for (int i = 0; i < PRIMITIVE_WRAPPER_CLASSES.length; i++) {
152: if (PRIMITIVE_WRAPPER_CLASSES[i].equals(typeName)) {
153: return true;
154: }
155: }
156:
157: return isJavaPrimitive(typeName);
158: }
159:
160: public static boolean isJavaPrimitive(String typeName) {
161: for (int i = 0; i < PRIMITIVE_TYPES.length; i++) {
162: if (PRIMITIVE_TYPES[i].equals(typeName)) {
163: return true;
164: }
165: }
166:
167: return false;
168: }
169:
170: public static String getWrapperForPrimitive(String javaPrimitive) {
171: for (int i = 0; i < PRIMITIVE_TYPES.length; i++) {
172: if (PRIMITIVE_TYPES[i].equals(javaPrimitive)) {
173: return PRIMITIVE_WRAPPER_CLASSES[i];
174: }
175: }
176:
177: return null;
178: }
179:
180: public static boolean hasOutput(JavaMethod m) {
181: JavaType type = m.getReturnType();
182:
183: if (!"void".equals(type.getRealName())) {
184: return true;
185: } else {
186: // check for output Holders
187: return getOutputHolderIndex(m) >= 0;
188: }
189: }
190:
191: public static int getOutputHolderIndex(JavaMethod m) {
192: List<JavaParameter> params = m.getParametersList();
193: if (params == null)
194: return -1;
195:
196: for (int i = 0; i < params.size(); i++) {
197: JavaParameter nextParam = params.get(i);
198: if (nextParam.isHolder()
199: && (nextParam.getParameter().isOUT() || nextParam
200: .getParameter().isINOUT())) {
201: return i;
202: }
203: }
204:
205: return -1;
206: }
207:
208: public static String typeToString(Type type) {
209: if (type instanceof ParameterizedType) {
210: ParameterizedType paramType = (ParameterizedType) type;
211: if (paramType.getOwnerType() != null)
212: return null;
213:
214: Type rawType = paramType.getRawType();
215: if (!(rawType instanceof Class)) {
216: return null;
217: }
218: Class rawClass = (Class) rawType;
219:
220: Type[] argTypes = paramType.getActualTypeArguments();
221: if (argTypes == null || argTypes.length == 0) {
222: return null;
223: }
224:
225: StringBuffer arguments = new StringBuffer();
226: for (int i = 0; i < argTypes.length; i++) {
227: String argument = typeToString(argTypes[0]);
228: if (argument == null) {
229: return null;
230: } else {
231: arguments.append(argument);
232: }
233:
234: if (i != argTypes.length - 1) {
235: arguments.append(',');
236: }
237: }
238:
239: return rawClass.getCanonicalName() + "<"
240: + arguments.toString() + ">";
241: } else if (type instanceof GenericArrayType) {
242: String component = typeToString(((GenericArrayType) type)
243: .getGenericComponentType());
244: if (component != null) {
245: return component + "[]";
246: }
247: } else if (type instanceof Class) {
248: return ((Class) type).getCanonicalName();
249: }
250:
251: return null;
252: }
253:
254: /*
255: * Removes any namespace prefix.
256: * eg: 'xsd:element' -> 'element'
257: */
258: public static String removeNamespace(String tagName) {
259: int pos = tagName.indexOf(':');
260: if (pos < 0)
261: return tagName;
262: return tagName.substring(pos + 1);
263: }
264:
265: public static String decapitalize(String name) {
266: if (name == null || name.length() == 0) {
267: return name;
268: }
269:
270: char chars[] = name.toCharArray();
271: chars[0] = Character.toLowerCase(chars[0]);
272: return new String(chars);
273: }
274:
275: /**
276: * Return the Project that is currently active according to the Designer.
277: *
278: * @return currently active project or null, if none.
279: */
280: public static Project getActiveProject() {
281: FileObject fileObject = DesignerServiceHack.getDefault()
282: .getCurrentFile();
283: if (fileObject == null) {
284: return null;
285: }
286: return FileOwnerQuery.getOwner(fileObject);
287: }
288:
289: /**
290: */
291: public static boolean isAcronyn(String name) {
292: // The name is consider as acronyn if it starts with two or more upper-case letters in a row
293: if (name == null || name.length() == 0) {
294: return false;
295: }
296:
297: char chars[] = name.toCharArray();
298: if (Character.isUpperCase(chars[0])
299: && Character.isUpperCase(chars[1]))
300: return true;
301: else
302: return false;
303: }
304:
305: /**
306: * Take an XML Schema data type and make a Java type out of it.
307: * eg: 'xsd:string' -> 'java.lang.String'
308: */
309: /*
310: public static String xmlSchemaType2JavaType(String typeName) {
311: if ((xsdNamespace+":string").equals(typeName))
312: return "java.lang.String";
313: if ("char_lb_rb".equals(typeName))
314: return "char[]";
315: if (typeName.startsWith(xsdNamespace+":"))
316: return typeName.substring(xsdNamespace.length()+1);
317: return typeName;
318: }
319: */
320: public static void insertSimpleTypes(Map typeMapping) {
321: typeMapping.put("java.lang.Integer", "java.lang.Integer");
322: typeMapping.put("java.lang.Short", "java.lang.Short");
323: typeMapping.put("java.lang.Long", "java.lang.Long");
324: typeMapping.put("java.lang.Double", "java.lang.Double");
325: typeMapping.put("java.lang.Boolean", "java.lang.Boolean");
326: typeMapping.put("java.lang.Character", "java.lang.Character");
327: typeMapping.put("java.lang.Float", "java.lang.Float");
328: typeMapping.put("java.lang.StringBuffer",
329: "java.lang.StringBuffer");
330: typeMapping.put("java.lang.Byte", "java.lang.Byte");
331: typeMapping.put("java.lang.String", "java.lang.String");
332: typeMapping.put("java.math.BigInteger", "java.math.BigInteger");
333: typeMapping.put("char_lb_rb", "char[]");
334: typeMapping.put("string", "java.lang.String");
335: typeMapping.put("int", "int");
336: typeMapping.put("short", "short");
337: typeMapping.put("long", "long");
338: typeMapping.put("double", "double");
339: typeMapping.put("boolean", "boolean");
340: typeMapping.put("char", "char");
341: typeMapping.put("float", "float");
342: typeMapping.put("byte", "byte");
343: typeMapping.put("decimal", "java.math.BigDecimal");
344: typeMapping.put("dateTime", "java.util.Date");
345: typeMapping.put((xsdNamespace + ":string").intern(),
346: "java.lang.String");
347: typeMapping.put((xsdNamespace + ":int").intern(), "int");
348: typeMapping.put((xsdNamespace + ":short").intern(), "short");
349: typeMapping.put((xsdNamespace + ":long").intern(), "long");
350: typeMapping.put((xsdNamespace + ":double").intern(), "double");
351: typeMapping
352: .put((xsdNamespace + ":boolean").intern(), "boolean");
353: typeMapping.put((xsdNamespace + ":char").intern(), "char");
354: typeMapping.put((xsdNamespace + ":float").intern(), "float");
355: typeMapping.put((xsdNamespace + ":byte").intern(), "byte");
356: typeMapping.put((xsdNamespace + ":decimal").intern(),
357: "java.math.BigDecimal");
358: typeMapping.put((xsdNamespace + ":dateTime").intern(),
359: "java.util.Date");
360: }
361:
362: private static Map baseTypes = null;
363:
364: public static boolean isSerializerNeeded(String type) {
365: if (baseTypes == null) {
366: baseTypes = new HashMap();
367: insertSimpleTypes(baseTypes);
368: }
369: return !baseTypes.containsKey(type);
370: }
371:
372: public static String getMethodSignatureAsString(
373: DataProviderMethod method) {
374: StringBuffer sig = new StringBuffer();
375: sig.append(method.getMethodName());
376: sig.append("(");
377:
378: // Parameters
379: boolean first = true;
380:
381: for (DataProviderParameter param : method.getParameters()) {
382: if (first)
383: first = false;
384: else
385: sig.append(",");
386:
387: // Only want the class name part
388: String paramTypeName = param.getType();
389:
390: sig.append(paramTypeName);
391: }
392:
393: sig.append(")");
394:
395: return sig.toString();
396: }
397:
398: public static Method getCorrespondingJaxRpcMethod(
399: JavaMethod modelMethod, String portName,
400: WebServiceData wsData) {
401: WebServiceDescriptor descriptor = wsData.getJaxRpcDescriptor();
402: if (descriptor == null) {
403: return null;
404: }
405: try {
406: List<URL> urlList = ManagerUtil.buildClasspath(null, false);
407: for (WebServiceDescriptor.JarEntry entry : descriptor
408: .getJars()) {
409: if (entry.getType().equals(
410: WebServiceDescriptor.JarEntry.PROXY_JAR_TYPE)) {
411: File jarFile = new File(descriptor
412: .getXmlDescriptorFile().getParent(), entry
413: .getName());
414: urlList.add(jarFile.toURI().toURL());
415: }
416: }
417:
418: ClassLoader urlClassLoader = new URLClassLoader(urlList
419: .toArray(new URL[urlList.size()]), Util.class
420: .getClassLoader());
421: WsdlPort port = wsData.getWsdlService().getPortByName(
422: portName);
423:
424: DesignerWebServiceExtData data = (DesignerWebServiceExtData) descriptor
425: .getConsumerData().get(
426: DesignerWebServiceExtImpl.CONSUMER_ID);
427: String beanClassName = data.getPortToProxyBeanNameMap()
428: .get(port.getName());
429:
430: Class beanClass = urlClassLoader.loadClass(beanClassName);
431:
432: Method[] methods = beanClass.getDeclaredMethods();
433: List<Method> candidateMethods = new ArrayList<Method>();
434:
435: for (int i = 0; i < methods.length; i++) {
436: if (isSimilarMethod(methods[i].getName(), modelMethod
437: .getName())) {
438: candidateMethods.add(methods[i]);
439: }
440: }
441:
442: if (candidateMethods.size() == 1) {
443: return candidateMethods.get(0);
444: }
445:
446: Method result = null;
447: int matchingParams = -1;
448: for (Method m : candidateMethods) {
449: int curMatchParams = getMatchingParametersCount(m,
450: modelMethod);
451: if (curMatchParams > matchingParams) {
452: result = m;
453: matchingParams = curMatchParams;
454: } else if (curMatchParams == matchingParams
455: && m.getParameterTypes().length == modelMethod
456: .getParametersList().size()) {
457: result = m;
458: }
459: }
460:
461: return result;
462: } catch (ClassNotFoundException ex) {
463: return null;
464: } catch (IOException ex) {
465: return null;
466: }
467: }
468:
469: private static boolean isSimilarMethod(String jaxRpcName,
470: String modelName) {
471: if (jaxRpcName.equalsIgnoreCase(modelName)) {
472: return true;
473: } else if (jaxRpcName.replace("_", "").equalsIgnoreCase(
474: modelName)) { // NOI18N
475: return true;
476: }
477:
478: return false;
479: }
480:
481: private static int getMatchingParametersCount(Method method,
482: JavaMethod model) {
483: List<JavaParameter> modelParams = model.getParametersList();
484: Type[] params = method.getGenericParameterTypes();
485: int matching = 0;
486:
487: for (int i = 0; i < params.length && i < modelParams.size(); i++) {
488: String paramRealName = ManagerUtil.typeToString(params[i]);
489: JavaParameter jParam = modelParams.get(i);
490:
491: if (!jParam.isHolder()
492: && jParam.getType().getRealName().startsWith(
493: paramRealName)) {
494: matching += 1;
495: }
496: }
497:
498: return matching;
499: }
500:
501: }
502: // END_NOI18N
|