/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 *******************************************************************************/ package org.ebayopensource.turmeric.tools.codegen.external; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Level; import javax.wsdl.Binding; import javax.wsdl.BindingInput; import javax.wsdl.BindingOperation; import javax.wsdl.BindingOutput; import javax.wsdl.Definition; import javax.wsdl.Fault; import javax.wsdl.Input; import javax.wsdl.Message; import javax.wsdl.Operation; import javax.wsdl.Output; import javax.wsdl.Part; import javax.wsdl.Port; import javax.wsdl.PortType; import javax.wsdl.Service; import javax.wsdl.WSDLException; import javax.wsdl.extensions.ExtensibilityElement; import javax.wsdl.extensions.http.HTTPAddress; import javax.wsdl.extensions.schema.Schema; import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.extensions.soap.SOAPHeader; import javax.wsdl.extensions.soap12.SOAP12Address; import javax.wsdl.extensions.soap12.SOAP12Header; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLReader; import javax.xml.namespace.QName; import org.apache.axis2.util.JavaUtils; import org.ebayopensource.turmeric.runtime.codegen.common.PkgNSMappingType; import org.ebayopensource.turmeric.runtime.codegen.common.PkgToNSMappingList; import org.ebayopensource.turmeric.runtime.common.impl.utils.CallTrackingLogger; import org.ebayopensource.turmeric.runtime.common.impl.utils.LogManager; import org.ebayopensource.turmeric.tools.codegen.CodeGenContext; import org.ebayopensource.turmeric.tools.codegen.InputOptions; import org.ebayopensource.turmeric.tools.codegen.exception.PreProcessFailedException; import org.ebayopensource.turmeric.tools.codegen.external.wsdl.parser.AuthenticatingProxyWSDLLocatorImpl; import org.ebayopensource.turmeric.tools.codegen.external.wsdl.parser.WSDLParserException; import org.ebayopensource.turmeric.tools.codegen.external.wsdl.parser.WSDLParserFactory; import org.ebayopensource.turmeric.tools.codegen.external.wsdl.parser.schema.ElementType; import org.ebayopensource.turmeric.tools.codegen.external.wsdl.parser.schema.Parser; import org.ebayopensource.turmeric.tools.codegen.external.wsdl.parser.schema.SchemaType; import org.ebayopensource.turmeric.tools.codegen.util.CodeGenConstants; import org.ebayopensource.turmeric.tools.codegen.util.CodeGenUtil; import org.ebayopensource.turmeric.tools.library.TypeLibraryInputOptions; import org.ebayopensource.turmeric.tools.library.codegen.TypeLibraryCodeGenContext; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import com.sun.xml.bind.api.impl.NameConverter; public class WSDLUtil { private static Map<String,QName> elementQNameMap = new HashMap<String,QName>(); private static CallTrackingLogger s_logger = LogManager.getInstance(WSDLUtil.class); private static CallTrackingLogger getLogger() { return s_logger; } /** * This method is common interface for Parser.getAllSchemaTypes. * This method takes care of caching the parsed objects so that Parser.getAllSchemaTypes is called only once. * * The caller of the method should take care that codegencontext should have wsdl definition populated. * * @param wsdlLoc * @param codeGenContext * @param types * @throws WSDLException * @throws WSDLParserException */ public static void persistAndPopulateAllSchemaTypes( CodeGenContext codeGenContext, List<SchemaType> types, String wsdlLoc ) throws WSDLException, WSDLParserException { if( codeGenContext.getSchemaTypes() != null ){ types.addAll(codeGenContext.getSchemaTypes() ); }else{ Definition wsdlDef = codeGenContext.getWsdlDefinition(); AuthenticatingProxyWSDLLocatorImpl wsdlLocator = null; if( wsdlLoc != null){ wsdlLocator = new AuthenticatingProxyWSDLLocatorImpl(wsdlLoc, "", ""); } Parser.getAllSchemaTypes(wsdlDef, types, wsdlLocator); List<SchemaType> typesBackup = new ArrayList<SchemaType>(); typesBackup.addAll( types ); codeGenContext.setSchemaTypes(typesBackup); } } public static Map<String, WSDLOperationType> getWSDLOparations(String wsdlLoc,CodeGenContext codeGenContext) { Map<String, WSDLOperationType> wsdlOperations = new HashMap<String, WSDLOperationType>(); if (CodeGenUtil.isEmptyString(wsdlLoc)) { return wsdlOperations; } try { Definition wsdlDef = codeGenContext.getWsdlDefinition(); if(wsdlDef == null) wsdlDef = getWSDLDefinition(wsdlLoc); Map<String, String> element2SchemaTypeMap = getSchemaType2ElementMap(wsdlLoc, wsdlDef, codeGenContext); wsdlOperations = internalGetWSDLOperations(wsdlDef, element2SchemaTypeMap); } catch (Exception ex) { //NOPMD } return wsdlOperations; } public static Map<String, String> getSchemaType2ElementMap(String wsdlLoc, CodeGenContext codeGenContext) { Map<String, String> element2SchemaTypeMap = new HashMap<String, String>(); if (CodeGenUtil.isEmptyString(wsdlLoc)) { return element2SchemaTypeMap; } try { Definition wsdlDef = getWSDLDefinition(wsdlLoc); element2SchemaTypeMap = getSchemaType2ElementMap(wsdlLoc, wsdlDef, codeGenContext); } catch (Exception ex) { //NOPMD } return element2SchemaTypeMap; } private static Map<String, String> getSchemaType2ElementMap(String wsdlLoc, Definition wsdlDef, CodeGenContext codeGenContext) { Map<String, String> element2SchemaTypeMap = new HashMap<String, String>(); elementQNameMap.clear(); try { List<SchemaType> types = new ArrayList<SchemaType>(); persistAndPopulateAllSchemaTypes(codeGenContext, types, wsdlLoc); for (int i = 0; i < types.size(); i++) { Object obj = types.get(i); if (obj instanceof ElementType) { ElementType schemaElement = (ElementType) obj; QName typeQName = schemaElement.getElementType(); QName elementQName = schemaElement.getTypeName(); if (typeQName == null) { typeQName = elementQName; } if (typeQName != null && elementQName != null) { String elementLocalPart = elementQName.getLocalPart(); String typeLocalPart = typeQName.getLocalPart(); element2SchemaTypeMap.put( elementLocalPart, typeLocalPart); elementQNameMap.put(elementLocalPart, elementQName); elementQNameMap.put(typeLocalPart, typeQName); } } } } catch (Exception ex) { //NOPMD } return element2SchemaTypeMap; } private static Map<String, WSDLOperationType> internalGetWSDLOperations( Definition wsdlDef, Map<String, String> element2SchemaTypeMap) { Map portTypeMap = wsdlDef.getPortTypes(); Iterator mapValuesItr = portTypeMap.values().iterator(); Map<String, WSDLOperationType> wsdlOperations = new HashMap<String, WSDLOperationType>(); //get the Binding for the WSDL file Binding binding = getBindingForWSDL(wsdlDef); while (mapValuesItr.hasNext()) { PortType portType = (PortType) mapValuesItr.next(); List operations = portType.getOperations(); for (int i = 0; i < operations.size(); i++) { Operation operation = (Operation) operations.get(i); try{ WSDLOperationType wsdlOpType = new WSDLOperationType(); wsdlOpType.setOperationName(operation.getName()); if (operation.getInput() != null) { Input input = operation.getInput(); Message inputMsg = input.getMessage(); Part msgPart = getFirstPart(inputMsg.getParts().values()); WSDLMessageType wsdlMsg = getWSDLMsgType( inputMsg.getQName().getLocalPart(), msgPart, element2SchemaTypeMap); wsdlOpType.setInMessage(wsdlMsg); } if (operation.getOutput() != null) { Output output = operation.getOutput(); Message outputMsg = output.getMessage(); Part msgPart = getFirstPart(outputMsg.getParts().values()); WSDLMessageType wsdlMsg = getWSDLMsgType( outputMsg.getQName().getLocalPart(), msgPart, element2SchemaTypeMap); wsdlOpType.setOutMessage(wsdlMsg); } if(operation.getFaults() != null){ Map<String, Fault> map = new HashMap<String, Fault>(); map = operation.getFaults(); for(String faultName : map.keySet()){ Fault currFault = map.get(faultName); Message faultMessage = currFault.getMessage(); Part msgPart = getFirstPart(faultMessage.getParts().values()); WSDLMessageType wsdlMsg = new WSDLMessageType(); String faultElementName = msgPart.getElementName().getLocalPart(); String faultTypeName = element2SchemaTypeMap.get(faultElementName); QName faultTypeElement = elementQNameMap.get(faultTypeName); wsdlMsg.setName(faultTypeElement.getNamespaceURI()); wsdlMsg.setElementName(faultElementName); wsdlMsg.setElementQname(faultTypeElement); wsdlMsg.setSchemaTypeName(faultTypeName); wsdlOpType.getFaults().add(wsdlMsg); } } wsdlOperations.put(wsdlOpType.getOperationName(), wsdlOpType); //header-support { if(binding != null){ BindingOperation bindOper = binding.getBindingOperation(operation.getName(), null, null); if(bindOper != null){ //processing the BindingInput to get RequestHeader BindingInput bindIp = bindOper.getBindingInput(); for(Object obj : bindIp.getExtensibilityElements()){ if( obj instanceof SOAPHeader ) { SOAPHeader wsdlSoapReqHeader = null; WSDLMessageType wsdlMsg = new WSDLMessageType(); wsdlSoapReqHeader = (SOAPHeader) obj; QName headerRequestElementName = getHeaderElementName(wsdlDef,wsdlSoapReqHeader); String headerRequestType = element2SchemaTypeMap.get(headerRequestElementName.getLocalPart()); QName headerRequestTypeElement = elementQNameMap.get(headerRequestType); wsdlMsg.setName(headerRequestTypeElement.getNamespaceURI()); wsdlMsg.setElementName(headerRequestElementName.toString()); wsdlMsg.setSchemaTypeName(headerRequestType); wsdlOpType.getRequestHeader().add(wsdlMsg); } else if( obj instanceof SOAP12Header ) { SOAP12Header wsdlSoap12ReqHeader = null; WSDLMessageType wsdlMsg = new WSDLMessageType(); wsdlSoap12ReqHeader = (SOAP12Header) obj; QName headerRequestElementName = getHeaderElementName(wsdlDef,wsdlSoap12ReqHeader); String headerRequestType = element2SchemaTypeMap.get(headerRequestElementName.getLocalPart()); QName headerRequestTypeElement = elementQNameMap.get(headerRequestType); wsdlMsg.setName(headerRequestTypeElement.getNamespaceURI()); wsdlMsg.setElementName(headerRequestElementName.toString()); wsdlMsg.setSchemaTypeName(headerRequestType); wsdlOpType.getRequestHeader().add(wsdlMsg); } } //processing the BindingOutput to get ResponseHeader BindingOutput bindOp = bindOper.getBindingOutput(); for(Object obj : bindOp.getExtensibilityElements()){ if( obj instanceof SOAPHeader ) { SOAPHeader wsdlSoapResHeader = null; WSDLMessageType wsdlMsg = new WSDLMessageType(); wsdlSoapResHeader = (SOAPHeader) obj; QName headerResponseElementName = getHeaderElementName(wsdlDef,wsdlSoapResHeader); String headerResponseType = element2SchemaTypeMap.get(headerResponseElementName.getLocalPart()); QName headerResponseTypeElement = elementQNameMap.get(headerResponseType); wsdlMsg.setName(headerResponseTypeElement.getNamespaceURI()); wsdlMsg.setElementName(headerResponseElementName.toString()); wsdlMsg.setSchemaTypeName(headerResponseType); wsdlOpType.getResponseHeader().add(wsdlMsg); } else if( obj instanceof SOAP12Header ) { SOAP12Header wsdlSoap112ResHeader = null; WSDLMessageType wsdlMsg = new WSDLMessageType(); wsdlSoap112ResHeader = (SOAP12Header) obj; QName headerResponseElementName = getHeaderElementName(wsdlDef,wsdlSoap112ResHeader); String headerResponseType = element2SchemaTypeMap.get(headerResponseElementName.getLocalPart()); QName headerResponseTypeElement = elementQNameMap.get(headerResponseType); wsdlMsg.setName(headerResponseTypeElement.getNamespaceURI()); wsdlMsg.setElementName(headerResponseElementName.toString()); wsdlMsg.setSchemaTypeName(headerResponseType); wsdlOpType.getResponseHeader().add(wsdlMsg); } } } }//header-support } }catch(Exception e){ getLogger().log(Level.SEVERE, "Exception while parsing WSDL operation : " +operation.getName()); continue; } } } return wsdlOperations; } /** * returns the Element name of the SoapHeader * @param wsdlDef WSDL Definition * @param soapHeader SOAP Header (Request/Response) * @return XML Element name of the SoapHeader */ private static QName getHeaderElementName(Definition wsdlDef, SOAPHeader soapHeader) { Message message = wsdlDef.getMessage(soapHeader.getMessage()); Part part = message.getPart(soapHeader.getPart()); return part.getElementName(); } /** * returns the Element name of the Soap12Header instance * @param wsdlDef WSDL Definition * @param soap12Header SOAP12 Header (Request/Response) * @return XML Element name of the Soap12Header */ private static QName getHeaderElementName(Definition wsdlDef, SOAP12Header soap12Header) { Message message = wsdlDef.getMessage(soap12Header.getMessage()); Part part = message.getPart(soap12Header.getPart()); return part.getElementName(); } /** * gets the Type of the HeaderRequest and HeaderResponse , this method always assumes that the * <code>element</code> tag is a direct child of the <code>schema</code> tag * @param wsdlDef WSDL Defintion * @param soapHeader SOAPHeader representing the Header Request / Header Response * @return the type name of the input soapHeader */ private static String getHeaderType(Definition wsdlDef, SOAPHeader soapHeader ){ Message message = wsdlDef.getMessage(soapHeader.getMessage()); Part part = message.getPart(soapHeader.getPart()); String headerTypeName = part.getElementName().getLocalPart(); String headerType = null; Schema schema = null; /* * finding the <schema> element */ List exItems = wsdlDef.getTypes().getExtensibilityElements(); for (Object obj : exItems) { ExtensibilityElement exItem = (ExtensibilityElement)obj; if(! (exItem instanceof Schema )) continue; schema = (Schema)obj; } if(schema == null) return null; Element element = schema.getElement(); Node node = element.getFirstChild(); NamedNodeMap nameNode; /* * Scan the element nodes sequentially * * phase -1 logic (till the first continue statement) * 1. If its not an <element> node , move to the next sibling node * 2. If the node does not have any attributes, move to the next sibling node * * phase -2 logic (btw the first and the second "continue" statement) * 1. Move to the next sibling node If the current node's name attribute's value is different than the one which * we are looking for. * * phase -3 ( remainder of the while loop) * 1. Exit from the loop once we get the Header's Type. */ while((node = node.getNextSibling()) != null) { if( !("element".equals(node.getLocalName())) || !node.hasAttributes()) continue; nameNode = node.getAttributes(); String currHeaderTypeName = nameNode.getNamedItem("name").toString().trim(); currHeaderTypeName = currHeaderTypeName.substring(currHeaderTypeName.indexOf("\"")+1, currHeaderTypeName.length() - 1); if (!currHeaderTypeName.equalsIgnoreCase(headerTypeName)) continue; headerType = nameNode.getNamedItem("type").toString().trim(); headerType = headerType.substring(headerType.indexOf(":") +1 ,headerType.length() - 1 ); break; } return headerType; } /** * This procedure assumes that * 1. the input WSDL file will have only one service defined * 2. the service will be have only one port defined * 3. the port will have only one or zero binding defined */ private static Binding getBindingForWSDL(Definition wsdlDef) { Binding binding = null; QName serviceQName = null; String portName = null; Map servicesMap = wsdlDef.getServices(); //get the first service Iterator keySetItr = servicesMap.keySet().iterator(); while (keySetItr.hasNext()) { serviceQName = (QName) keySetItr.next(); break; } Service service = wsdlDef.getService(serviceQName); //get the first port of the service Map portsMap = service.getPorts(); keySetItr = portsMap.keySet().iterator(); while (keySetItr.hasNext()) { portName = (String) keySetItr.next(); break; } binding = service.getPort(portName).getBinding() ; return binding; } private static WSDLMessageType getWSDLMsgType( String msgName, Part msgPart, Map<String, String> element2SchemaTypeMap) { WSDLMessageType wsdlMsg = new WSDLMessageType(); wsdlMsg.setName(msgName); wsdlMsg.setElementName(msgPart.getElementName().getLocalPart()); wsdlMsg.setElementQname(msgPart.getElementName()); if (msgPart.getTypeName() != null) { wsdlMsg.setSchemaTypeQName(msgPart.getTypeName()); wsdlMsg.setSchemaTypeName(msgPart.getTypeName().getLocalPart()); } else { String typeName = element2SchemaTypeMap.get(msgPart.getElementName().getLocalPart()); wsdlMsg.setSchemaTypeName(typeName); wsdlMsg.setSchemaTypeQName( elementQNameMap.get(typeName) ); } return wsdlMsg; } private static Part getFirstPart(Collection<?> parts) { Part firstPart = null; Iterator<?> partsItr = parts.iterator(); while (partsItr.hasNext()) { firstPart = (Part) partsItr.next(); break; } return firstPart; } public static String getInterfaceName( String wsdlLoc, String pkgName) throws PreProcessFailedException { return getInterfaceName(wsdlLoc, pkgName, new HashMap<String, String>()); } public static String getInterfaceName( String wsdlLoc, String pkgName, Map<String, String> ns2PkgMap) throws PreProcessFailedException { return getInterfaceName(wsdlLoc, pkgName, new HashMap<String, String>(),null); } //The param codeGenContext can be NULL . So pls keep that in mind while making any changes public static String getInterfaceName( String wsdlLoc, String pkgName, Map<String, String> ns2PkgMap, CodeGenContext codeGenContext) throws PreProcessFailedException { String interfaceName = null; String serviceName = null; String targetNamespace = null; QName serviceQName = getFirstServiceQName(wsdlLoc,codeGenContext); serviceName = serviceQName.getLocalPart(); targetNamespace = serviceQName.getNamespaceURI(); if (CodeGenUtil.isEmptyString(pkgName)) { pkgName = ns2PkgMap.get(targetNamespace); if (CodeGenUtil.isEmptyString(pkgName)) { pkgName = getPackageFromNamespace(targetNamespace); } } interfaceName = CodeGenUtil.makeFirstLetterUpper(serviceName);// + "SkeletonInterface"; if (!CodeGenUtil.isEmptyString(pkgName)) { interfaceName = pkgName + "." + interfaceName; } return interfaceName; } public static Definition getWSDLDefinition(String wsdlLoc) throws WSDLException, PreProcessFailedException { WSDLFactory factory = WSDLParserFactory.getInstance(); WSDLReader wsdlReader = factory.newWSDLReader(); wsdlReader.setFeature("javax.wsdl.importDocuments", true); Definition wsdlDef = wsdlReader.readWSDL(wsdlLoc); return wsdlDef; } /** * Namespace 2 Package algorithm as defined by the JAXB Specification * * @param Namespace * @return String represeting Namespace */ public static String getPackageFromNamespace(String namespace) { //Using the method used by JAXB directly to avoid potential conflicts with JAXB generated code //Therefore commenting out the old code which is based on JAXB 2.0 spec return com.sun.tools.xjc.api.XJC.getDefaultPackageName(namespace); /* // The following steps correspond to steps described in the JAXB Specification boolean isURNProtocol = namespace.startsWith("urn:"); // Step 1: Scan off the host name String hostname = null; String path = null; try { URL url = new URL(namespace); hostname = url.getHost(); path = url.getPath(); } catch (MalformedURLException e) { // No FFDC code needed if (namespace.indexOf(":") > -1) { // Brain-dead code to skip over the protocol hostname = namespace.substring(namespace.indexOf(":") + 1); } else { hostname = namespace; } } //deriving the Host name and path for URI's starting with "urn" //Host name is the component which falls btw the first : and the second : (if second exists) if(isURNProtocol){ hostname = ""; path = ""; StringBuilder pathStr = new StringBuilder(); StringTokenizer urnTokens = new StringTokenizer(namespace,":"); if(urnTokens.countTokens() >= 2){ urnTokens.nextToken(); hostname = urnTokens.nextToken(); while(urnTokens.hasMoreTokens()){ pathStr.append(urnTokens.nextToken()); if(urnTokens.hasMoreTokens()) pathStr.append(":"); } path = pathStr.toString(); } } // Step 3: Tokenize the host name using ":" and "/" StringTokenizer st = new StringTokenizer(hostname, ":/"); ArrayList<String> wordList = new ArrayList<String>(); int hostNameTokenCount = st.countTokens(); //Read Hostname first. for (int i = 0; st != null && i < hostNameTokenCount; ++i) { wordList.add(st.nextToken()); } //Read rest Of the path now if (path != null) { StringTokenizer pathst = null; if(isURNProtocol) pathst = new StringTokenizer(path, ":"); else pathst = new StringTokenizer(path, "/"); while (pathst != null && pathst.hasMoreTokens()) { wordList.add(pathst.nextToken()); } } String[] words = wordList.toArray(new String[0]); // Now do step 2: Strip off the trailing "." (i.e. strip off .html) if (words.length > 1) { String lastWord = words[words.length - 1]; int index = lastWord.lastIndexOf('.'); if (index > 0) { words[words.length - 1] = lastWord.substring(0, index); } } // Step 4: Unescape each escape sequence // TODO I don't know what to do here. // Step 5: If protocol is urn, replace - with . in the first word if (isURNProtocol) { words[0] = replace(words[0], "-", "."); } // Step 6: Tokenize the first word with "." and reverse the order. (the www is also removed). // TODO This is not exactly equivalent to the JAXB Rule. StringTokenizer st2 = new StringTokenizer(words[0], "."); ArrayList<String> list = new ArrayList<String>(); while (st2.hasMoreTokens()) { // Add the strings so they are in reverse order list.add(0, st2.nextToken()); } // Remove www String last = list.get(list.size() - 1); if (last.equals("www")) { list.remove(list.size() - 1); } // Now each of words is represented by list for (int i = 1; i < words.length; i++) { list.add(words[i]); } // Step 7: lowercase each word for (int i = 0; i < list.size(); i++) { String word = list.remove(i); word = word.toLowerCase(); list.add(i, word); } // Step 8: make into and an appropriate java word for (int i = 0; i < list.size(); i++) { String word = list.get(i); // 8a: Convert special characters to underscore // Convert non-java words to underscore. // TODO: Need to do this for all chars..not just hyphens word = replace(word, "-", "_"); StringBuilder wordBuilder = new StringBuilder(word); // 8b: Append _ to java keywords if (JavaUtils.isJavaKeyword(word)) { wordBuilder.append("_"); } // 8c: prepend _ if first character cannot be the first character of a java identifier if (!Character.isJavaIdentifierPart(word.charAt(0))) { wordBuilder = new StringBuilder("_").append(wordBuilder); } list.set(i, wordBuilder.toString()); } // Step 9: Concatenate and return StringBuilder nameBuilder = new StringBuilder(); for (int i = 0; i < list.size(); i++) { if (i == 0) { nameBuilder.append(list.get(0)); } else { nameBuilder.append(".").append(list.get(i)); } } return nameBuilder.toString(); */ } /** * replace: Like String.replace except that the old new items are strings. * * @param name string * @param oldT old text to replace * @param newT new text to use * @return replacement string */ private static final String replace(String name, String oldT, String newT) { if (name == null) return ""; // Create a string buffer that is twice initial length. // This is a good starting point. StringBuffer sb = new StringBuffer(name.length() * 2); int len = oldT.length(); try { int start = 0; int i = name.indexOf(oldT, start); while (i >= 0) { sb.append(name.substring(start, i)); sb.append(newT); start = i + len; i = name.indexOf(oldT, start); } if (start < name.length()) sb.append(name.substring(start)); } catch (NullPointerException e) { // No FFDC code needed } return new String(sb); } private static String getFirstServiceName(Map servicesMap) { QName serviceQName = null; Iterator keySetItr = servicesMap.keySet().iterator(); while (keySetItr.hasNext()) { serviceQName = (QName) keySetItr.next(); break; } String firstSvcName = null; if (serviceQName != null) { firstSvcName = serviceQName.getLocalPart(); } else { firstSvcName = "Empty"; } return firstSvcName; } public static QName getFirstServiceQName(String wsdlLoc) throws PreProcessFailedException { try { Definition wsdlDef = getWSDLDefinition(wsdlLoc); return getFirstServiceQName(wsdlDef); } catch (WSDLException ex) { throw new PreProcessFailedException("Failed to parse WSDL", ex); } } public static QName getFirstServiceQName(String wsdlLoc,CodeGenContext codeGenContext) throws PreProcessFailedException { try { Definition wsdlDef = null; if(codeGenContext != null) wsdlDef = codeGenContext.getWsdlDefinition(); if(wsdlDef == null) wsdlDef = getWSDLDefinition(wsdlLoc); QName serviceQname = getFirstServiceQName(wsdlDef); //Adcommerce support.If serviceName option is set, this should be used for ServiceCreation. if( codeGenContext != null && ! CodeGenUtil.isEmptyString(codeGenContext.getServiceAdminName())){ serviceQname = new QName(serviceQname.getNamespaceURI(),codeGenContext.getServiceAdminName()); // if entry exists in service_metadata.properties for namespace, // it should be used. String namespace = (CodeGenUtil.isEmptyString(codeGenContext .getNamespace())) ? serviceQname.getNamespaceURI() : codeGenContext.getNamespace(); serviceQname = new QName(namespace, codeGenContext .getServiceAdminName()); } return serviceQname; } catch (WSDLException ex) { throw new PreProcessFailedException("Failed to parse WSDL", ex); } } public static QName getFirstServiceQName(Definition wsdlDef) throws PreProcessFailedException { Map servicesMap = wsdlDef.getServices(); if (servicesMap == null || servicesMap.isEmpty()) { throw new PreProcessFailedException("No services defined in WSDL."); } QName serviceQName = null; Iterator keySetItr = servicesMap.keySet().iterator(); while (keySetItr.hasNext()) { serviceQName = (QName) keySetItr.next(); break; } return serviceQName; } public static Map<String,String> getNS2PkgMappings(InputOptions inputOptions){ String ns2pkgValue = inputOptions.getNS2Pkg(); String nsPkgMapMasterStr="";// This is the master string, contents to this should be added based on the priority. // The priority now is -ns2pkg, -pkg2ns and others. // This ordering is required to determine the removal of multipe values of a single namespace with different packages PkgToNSMappingList pkgNsMapList = inputOptions.getPkgNSMappings(); String nsPkgMapStr = buildPkgNSMapString(pkgNsMapList, CodeGenConstants.WSDL_2_JAVA_NS_TO_PKG_PATTERN, ','); if(!CodeGenUtil.isEmptyString(ns2pkgValue) ) nsPkgMapMasterStr = ns2pkgValue; if(CodeGenUtil.isEmptyString(nsPkgMapMasterStr)) nsPkgMapMasterStr = nsPkgMapStr; else nsPkgMapMasterStr += "," + nsPkgMapStr; return processDuplicateNameSpaces(nsPkgMapMasterStr); } private static Map<String,String> processDuplicateNameSpaces(String nsPkgMapMasterStr){ //String derivedNS2PkgStr=""; Map<String, String> ns2PkgMap = new HashMap<String,String>(); String[] ns2PkgMappings = nsPkgMapMasterStr.split(","); for(String ns2Pkg:ns2PkgMappings){ ns2Pkg = ns2Pkg.trim(); String[] keyValue = ns2Pkg.split("="); if(keyValue == null || keyValue.length != 2) continue; String nameSpace = keyValue[0].trim(); String mappedPackage = keyValue[1].trim(); if(!ns2PkgMap.containsKey(nameSpace)){ ns2PkgMap.put(nameSpace, mappedPackage); //derivedNS2PkgStr += nameSpace + "=" + mappedPackage + ","; } } return ns2PkgMap; } private static String buildPkgNSMapString( PkgToNSMappingList pkgNsMapList, String pkgNSPatternStr, char seperator) { List<String> nsPkgMapList = buildPkgNSMapList(pkgNsMapList, pkgNSPatternStr); StringBuilder strBuilder = new StringBuilder(); if (!nsPkgMapList.isEmpty()) { for (String nsPkgMapEntry : nsPkgMapList) { strBuilder.append(nsPkgMapEntry).append(seperator); } // remove extra separator char at th end strBuilder.setLength(strBuilder.length()-1); } return strBuilder.toString(); } public static List<String> buildPkgNSMapList( PkgToNSMappingList pkgNsMapList, String pkgNSPatternStr) { String pkgNsMapStr = null; boolean isCommonTypesMapped = false; List<String> pkgNSMapList = new ArrayList<String>(2); if (pkgNsMapList != null && !pkgNsMapList.getPkgNsMap().isEmpty()) { for (PkgNSMappingType pkgNsMapType : pkgNsMapList.getPkgNsMap()) { pkgNsMapStr = pkgNSPatternStr.replace(CodeGenConstants.PKG_PARAM, pkgNsMapType.getPackage()); pkgNsMapStr = pkgNsMapStr.replace(CodeGenConstants.NAMESPACE_PARAM, pkgNsMapType.getNamespace()); pkgNSMapList.add(pkgNsMapStr); if (CodeGenConstants.SOA_COMMON_TYPES_PKG.equals(pkgNsMapType.getPackage())) { isCommonTypesMapped = true; } } } // If SOA common types pkg is NOT mapped to a namespace then // will do default mapping here, otherwise namespace mentioned in common types // schema will be used which is not we want if (isCommonTypesMapped == false) { pkgNsMapStr = pkgNSPatternStr.replaceAll(CodeGenConstants.PKG_PARAM, CodeGenConstants.SOA_COMMON_TYPES_PKG); pkgNsMapStr = pkgNsMapStr.replaceAll(CodeGenConstants.NAMESPACE_PARAM, CodeGenConstants.SOA_COMMON_TYPES_NS); pkgNSMapList.add(pkgNsMapStr); } return pkgNSMapList; } /** * * @param wsdlLocation * @throws WSDLException */ public static void populateCodegenCtxWithWSDLDetails(String wsdlLocation,CodeGenContext codeGenContext) throws PreProcessFailedException{ try{ Definition wsdlDef = codeGenContext.getWsdlDefinition(); if(wsdlDef == null){ wsdlDef = getWSDLDefinition(wsdlLocation); codeGenContext.setWsdlDefinition(wsdlDef); } populateCodegenCtxWithWSDLDetails(wsdlDef,codeGenContext); }catch (WSDLException e) { throw new PreProcessFailedException("Exception while preprocessing the WSDL",e); } } public static void populateCodegenCtxWithWSDLDetails(Definition wsdlDef,CodeGenContext codeGenContext) throws PreProcessFailedException{ if (wsdlDef == null) return; QName serviceQName = getFirstServiceQName(wsdlDef); if ( ! CodeGenUtil.isEmptyString(codeGenContext.getServiceAdminName())) { String namespace = serviceQName.getNamespaceURI(); serviceQName = new QName(namespace, codeGenContext.getServiceAdminName()); } codeGenContext.setServiceQName(serviceQName); List<String> operationNamesList = getWSDLOperationsName(wsdlDef); codeGenContext.getOperationNamesInWSDL().addAll(operationNamesList); Map<String, String> javaMethodNameOperationNameMap = getMethodNameOperationNameMapping(operationNamesList); codeGenContext.getJavaMethodOperationNameMap().putAll( javaMethodNameOperationNameMap); } public static void populateTypeLibraryCodegenCtxWithWSDLDetails(TypeLibraryCodeGenContext typeLibrarycodeGenCtx) throws PreProcessFailedException{ TypeLibraryInputOptions typeLibraryInputOptions = typeLibrarycodeGenCtx.getTypeLibraryInputOptions(); try{ Definition wsdlDef = getWSDLDefinition(typeLibraryInputOptions.getV4WsdlLocation()); populateTypeLibraryCodegenCtxWithWSDLDetails(wsdlDef, typeLibrarycodeGenCtx); }catch (WSDLException e) { throw new PreProcessFailedException("Exception while preprocessing the WSDL",e); } } public static void populateTypeLibraryCodegenCtxWithWSDLDetails(Definition wsdlDef,TypeLibraryCodeGenContext typeLibrarycodeGenCtx) throws PreProcessFailedException{ if(wsdlDef == null) return; QName serviceQName = getFirstServiceQName(wsdlDef); if(serviceQName != null) typeLibrarycodeGenCtx.setServiceName(serviceQName.getLocalPart()); typeLibrarycodeGenCtx.setServiceNamespace(wsdlDef.getTargetNamespace()); typeLibrarycodeGenCtx.setInterfacePkg(getPackageFromNamespace(wsdlDef.getTargetNamespace())); } private static Map<String, String> getMethodNameOperationNameMapping(List<String> operationNamesList) { Map<String,String> javaMethodNameOperationNameMap = new HashMap<String, String>(operationNamesList.size()); for(String currOperationName : operationNamesList){ String javaMethodName = JavaUtils.xmlNameToJavaIdentifier(currOperationName); javaMethodNameOperationNameMap.put(javaMethodName, currOperationName); } return javaMethodNameOperationNameMap; } /** * * @param wsdlLocation * @return * @throws PreProcessFailedException * @throws WSDLException */ public static List<String> getWSDLOperationsName(Definition wsdlDef) throws PreProcessFailedException { List<String> operationNamesList = new ArrayList<String>(); List<CodegenPortDetails> portDetailsInPriorityOrder = getWSDLPortsInPriority(wsdlDef); Port portWithHighestPriority = null; if(portDetailsInPriorityOrder.size() > 0){ portWithHighestPriority = portDetailsInPriorityOrder.get(0).getPort(); PortType portType = portWithHighestPriority.getBinding().getPortType(); List<Operation> operList = portType.getOperations(); for(Operation currOperation : operList) operationNamesList.add(currOperation.getName()); } if(operationNamesList.size() == 0) throw new PreProcessFailedException("There are no operations defined for the port type under the Port : " + portWithHighestPriority.getName()); return operationNamesList; } /** * * @param wsdlDefinition * @return list of ports in the WSDL in thee priority of * SOAP12 , SOAP11 and then HTTP ports. * @throws PreProcessFailedException */ public static List<CodegenPortDetails> getWSDLPortsInPriority(Definition wsdlDefinition) throws PreProcessFailedException{ List<CodegenPortDetails> soap12BindingPorts = new ArrayList<CodegenPortDetails>(); List<CodegenPortDetails> soap11BindingPorts = new ArrayList<CodegenPortDetails>(); List<CodegenPortDetails> httpBindingPorts = new ArrayList<CodegenPortDetails>(); List<CodegenPortDetails> allPortsInPriorityOrder = new ArrayList<CodegenPortDetails>(); QName serviceQName = getFirstServiceQName(wsdlDefinition); Service service = wsdlDefinition.getService(serviceQName); Port currPort =null; for(Object portObject :service.getPorts().keySet()){ currPort = (Port)service.getPorts().get(portObject); CodegenPortDetails currCodegenPortDetails = new CodegenPortDetails(); currCodegenPortDetails.setPort(currPort); List<ExtensibilityElement> listOfExten = currPort.getExtensibilityElements(); for(ExtensibilityElement extensibilityElement:listOfExten ){ if(extensibilityElement instanceof SOAP12Address){ currCodegenPortDetails.setSOAP12(true); soap12BindingPorts.add(currCodegenPortDetails); } else if(extensibilityElement instanceof SOAPAddress){ currCodegenPortDetails.setSOAP11(true); soap11BindingPorts.add(currCodegenPortDetails); } else if(extensibilityElement instanceof HTTPAddress){ currCodegenPortDetails.setHTTP(true); httpBindingPorts.add(currCodegenPortDetails); } } } allPortsInPriorityOrder.addAll(soap12BindingPorts); allPortsInPriorityOrder.addAll(soap11BindingPorts); allPortsInPriorityOrder.addAll(httpBindingPorts); return allPortsInPriorityOrder; } /** * * @param xmlIdentifierName Name of the XML identifier * @return The Java class name corresponding to the input XML identifier * @throws java.lang.IllegalArgumentException */ public static String getXMLIdentifiersClassName(String xmlIdentifierName) throws java.lang.IllegalArgumentException { if(CodeGenUtil.isEmptyString(xmlIdentifierName)) throw new IllegalArgumentException("The XML Identifier name passed is null/empty"); /* * XJC implementation of JAXB allows only an underscore or an alphabet to be the first character of the types name * xjc version "JAXB 2.1.3 in JDK 1.6" * JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB 2.1.3 in JDK 1.6) */ Character firstCharacter = xmlIdentifierName.charAt(0); if( !(Character.isLetter(firstCharacter) || firstCharacter.equals('_') ) ){ throw new IllegalArgumentException("The first character of an XML identifier's name should either be a character or an underscore"); } String derivedClassName = NameConverter.standard.toClassName(xmlIdentifierName); /* * refer to section D.2 in "The Java Architecture for XML Binding (JAXB) 2.0 Final Release April 19, 2006" for rules to convert an XML Identifier to a class name */ getLogger().log(Level.FINE, "XML Identifier Name : " + xmlIdentifierName); getLogger().log(Level.FINE, "JAVA class Name : " + derivedClassName); if(CodeGenUtil.isEmptyString(derivedClassName)) return xmlIdentifierName; else return derivedClassName; } }