Java tutorial
/* * Copyright 2001-2011 The Apache Software Foundation. * * 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 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.juddi.v3.client.mapping.wsdl; import org.apache.juddi.v3.client.mapping.Common2UDDI; import java.net.MalformedURLException; import java.net.URL; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.wsdl.Binding; import javax.wsdl.Definition; import javax.wsdl.Port; import javax.wsdl.PortType; import javax.wsdl.Service; import javax.wsdl.WSDLException; import javax.wsdl.extensions.http.HTTPAddress; import javax.wsdl.extensions.http.HTTPBinding; import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.extensions.soap.SOAPBinding; import javax.wsdl.extensions.soap12.SOAP12Address; import javax.wsdl.extensions.soap12.SOAP12Binding; import javax.xml.namespace.QName; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.juddi.api_v3.AccessPointType; import org.apache.juddi.jaxb.PrintUDDI; import org.apache.juddi.v3.client.config.Property; import org.apache.juddi.v3.client.config.UDDIClerk; import org.apache.juddi.v3.client.config.UDDIClient; import org.apache.juddi.v3.client.config.UDDIKeyConvention; import org.apache.juddi.v3.client.mapping.ServiceRegistrationResponse; import org.apache.juddi.v3.client.mapping.URLLocalizer; import org.apache.juddi.v3.client.mapping.wadl.WADL2UDDI; import org.apache.juddi.v3.client.transport.TransportException; import org.uddi.api_v3.AccessPoint; import org.uddi.api_v3.BindingTemplate; import org.uddi.api_v3.BindingTemplates; import org.uddi.api_v3.BusinessService; import org.uddi.api_v3.BusinessServices; import org.uddi.api_v3.CategoryBag; import org.uddi.api_v3.FindTModel; import org.uddi.api_v3.InstanceDetails; import org.uddi.api_v3.KeyedReference; import org.uddi.api_v3.Name; import org.uddi.api_v3.OverviewDoc; import org.uddi.api_v3.OverviewURL; import org.uddi.api_v3.TModel; import org.uddi.api_v3.TModelDetail; import org.uddi.api_v3.TModelInstanceDetails; import org.uddi.api_v3.TModelInstanceInfo; import org.w3c.dom.Element; /** * This class implements the OASIS <a * href="http://www.oasis-open.org/committees/uddi-spec/doc/tn/uddi-spec-tc-tn-wsdl-v202-20040631.htm"> * 'Using WSDL in a UDDI Registry, Version 2.0.2'</a> technote. This class * creates a detailed mapping of WSDL 1.1 artifacts to the UDDI V3 data model. * <ul> <th>Section 2.4 in the technote</th> <li>2.4.1 wsdl:portType -> * uddi:tModel - {@link #createWSDLPortTypeTModels(String, Map)}</li> <li>2.4.2 * wsdl:binding -> uddi:tModel - * {@link #createWSDLBindingTModels(String, Map)}</li> <li>TODO: 2.4.3 * wsdl:service -> uddi:businessService</li> <li>TODO: 2.4.4 wsdl:port -> * uddi:bindingTemplate</li> <li>TODO: 2.4.5 wsdl:port Address Extensions -> * uddi:bindingTemplate</li> </ul> * * @see WADL2UDDI * @see BPEL2UDDI * @author Kurt T Stam * @since 3.1.5 */ public class WSDL2UDDI { private static final Log log = LogFactory.getLog(WSDL2UDDI.class); private String keyDomainURI; private String businessKey; private String lang; private UDDIClerk clerk = null; private Properties properties = null; private URLLocalizer urlLocalizer; /** * Required Properties are: businessName, for example: 'Apache' * nodeName, for example: 'uddi.example.org_80' keyDomain, for example: * juddi.apache.org * * Optional Properties are: lang: for example: 'nl' * * @param clerk - can be null if register/unregister methods are not * used. * @param urlLocalizer - A reference to an custom * @param properties - required values keyDomain, businessKey, nodeName * @throws ConfigurationException */ public WSDL2UDDI(UDDIClerk clerk, URLLocalizer urlLocalizer, Properties properties) throws ConfigurationException { super(); if (properties == null) { throw new IllegalArgumentException("properties"); } this.clerk = clerk; this.urlLocalizer = urlLocalizer; this.properties = properties; if (clerk != null) { if (!properties.containsKey("keyDomain")) { throw new ConfigurationException("Property keyDomain is a required property when using WSDL2UDDI."); } if (!properties.containsKey("businessKey") && !properties.containsKey("businessName")) { throw new ConfigurationException( "Either property businessKey, or businessName, is a required property when using WSDL2UDDI."); } if (!properties.containsKey("nodeName")) { if (properties.containsKey("serverName") && properties.containsKey("serverPort")) { String nodeName = properties.getProperty("serverName") + "_" + properties.getProperty("serverPort"); properties.setProperty("nodeName", nodeName); } else { throw new ConfigurationException( "Property nodeName is not defined and is a required property when using WSDL2UDDI."); } } } //Obtaining values from the properties this.keyDomainURI = "uddi:" + properties.getProperty("keyDomain") + ":"; if (properties.contains(Property.BUSINESS_KEY)) { this.businessKey = properties.getProperty(Property.BUSINESS_KEY); } else { //using the BusinessKey Template, and the businessName to construct the key this.businessKey = UDDIKeyConvention.getBusinessKey(properties); } this.lang = properties.getProperty(Property.LANG, Property.DEFAULT_LANG); } public BusinessServices registerBusinessServices(Definition wsdlDefinition) throws RemoteException, ConfigurationException, TransportException, WSDLException, MalformedURLException { BusinessServices businessServices = new BusinessServices(); for (Object serviceName : wsdlDefinition.getAllServices().keySet()) { QName serviceQName = (QName) serviceName; Service service = wsdlDefinition.getService(serviceQName); BusinessService businessService = null; //add service URL serviceUrl = null; if (service.getPorts() != null && service.getPorts().size() > 0) { for (Object portName : service.getPorts().keySet()) { businessService = registerBusinessService(serviceQName, (String) portName, serviceUrl, wsdlDefinition).getBusinessService(); } } if (businessService != null) { businessServices.getBusinessService().add(businessService); } } return businessServices; } @SuppressWarnings("unchecked") public ServiceRegistrationResponse registerBusinessService(QName serviceQName, String portName, URL serviceUrl, Definition wsdlDefinition) throws RemoteException, ConfigurationException, TransportException, WSDLException, MalformedURLException { String genericWSDLURL = wsdlDefinition.getDocumentBaseURI(); //TODO maybe point to repository version ServiceRegistrationResponse response = new ServiceRegistrationResponse(); String serviceKey = UDDIKeyConvention.getServiceKey(properties, serviceQName.getLocalPart()); BusinessService businessService = lookupService(serviceKey); if (businessService == null) { List<TModel> tModels = new ArrayList<TModel>(); // Create the PortType tModels Map<QName, PortType> portTypes = (Map<QName, PortType>) wsdlDefinition.getAllPortTypes(); tModels.addAll(createWSDLPortTypeTModels(genericWSDLURL, portTypes)); // Create the Binding tModels Map<QName, Binding> bindings = (Map<QName, Binding>) wsdlDefinition.getAllBindings(); tModels.addAll(createWSDLBindingTModels(genericWSDLURL, bindings)); // Register these tModels for (TModel tModel : tModels) { clerk.register(tModel); } // Service businessService = createBusinessService(serviceQName, wsdlDefinition); // Register this Service clerk.register(businessService); } //Add the BindingTemplate to this Service BindingTemplate binding = createWSDLBinding(serviceQName, portName, serviceUrl, wsdlDefinition); // Register BindingTemplate if (binding.getAccessPoint() != null) { clerk.register(binding); if (businessService.getBindingTemplates() == null) { businessService.setBindingTemplates(new BindingTemplates()); } businessService.getBindingTemplates().getBindingTemplate().add(binding); response.setBindingKey(binding.getBindingKey()); } response.setBusinessService(businessService); return response; } public String[] unRegisterBusinessServices(Definition wsdlDefinition) throws RemoteException, ConfigurationException, TransportException, MalformedURLException { String[] businessServices = new String[wsdlDefinition.getAllServices().size()]; int i = 0; for (Object serviceName : wsdlDefinition.getAllServices().keySet()) { QName serviceQName = (QName) serviceName; Service service = wsdlDefinition.getService(serviceQName); //unregister service URL serviceUrl = null; if (service.getPorts() != null && service.getPorts().size() > 0) { for (Object portName : service.getPorts().keySet()) { //construct the accessURL serviceUrl = new URL(getBindingURL((Port) service.getPorts().get(portName))); businessServices[i++] = unRegisterBusinessService(serviceQName, (String) portName, serviceUrl); } } } return businessServices; } public String unRegisterBusinessService(QName serviceName, String portName, URL serviceUrl) throws RemoteException, ConfigurationException, TransportException { String serviceKey = UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart()); BusinessService service = lookupService(serviceKey); boolean isRemoveServiceIfNoTemplates = true; String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceName, portName, serviceUrl); //check if this bindingKey is in the service's binding templates for (BindingTemplate bindingTemplate : service.getBindingTemplates().getBindingTemplate()) { if (bindingKey.equals(bindingTemplate.getBindingKey())) { clerk.unRegisterBinding(bindingKey); //if this is the last binding for this service, and if (service.getBindingTemplates().getBindingTemplate().size() == 1 && isRemoveServiceIfNoTemplates) { clerk.unRegisterService(serviceKey); if (bindingTemplate.getTModelInstanceDetails() != null && bindingTemplate.getTModelInstanceDetails().getTModelInstanceInfo() != null) { for (TModelInstanceInfo tModelInstanceInfo : bindingTemplate.getTModelInstanceDetails() .getTModelInstanceInfo()) { String tModelKey = tModelInstanceInfo.getTModelKey(); TModelDetail tModelDetail = clerk.getTModelDetail(tModelKey); //delete all tModels assuming they are the portType and Binding tModels. if (tModelDetail.getTModel() != null && tModelDetail.getTModel().size() > 0) { for (TModel tModel : tModelDetail.getTModel()) { if (!tModel.getTModelKey().startsWith("uddi:uddi.org:")) { clerk.unRegisterTModel(tModel.getTModelKey()); } else { log.info("Skipping the removal of " + tModel.getTModelKey() + " because it starts with uddi.org"); } } } } } } } } return serviceKey; } public String getKeyDomainURI() { return keyDomainURI; } public void setKeyDomain(String keyDomainURI) { this.keyDomainURI = keyDomainURI; } public String getLang() { return lang; } public void setLang(String lang) { this.lang = lang; } /** * <h3>2.4.2 wsdl:binding -> uddi:tModel</h3> * * <p> * A wsdl:binding MUST be modeled as a uddi:tModel. The minimum * information that must be captured about a binding is its entity type, * its local name, its namespace, the location of the WSDL document that * defines the binding, the portType that it implements, its protocol, * and, optionally, the transport information. Capturing the entity type * enables users to search for tModels that represent binding artifacts. * Capturing the local name, namespace, and WSDL location enables users * to locate the definition of the specified binding artifact. The link * to the portType enables users to search for bindings that implement a * particular portType.</p> * * <p> * A wsdl:binding corresponds to a WSDL service interface definition as * defined by the mapping in the Version 1 Best Practice. To maintain * compatibility with the previous mapping, the binding must also be * characterized as type "wsdlSpec".</p> * * <p> * The wsdl:binding information is captured as follows:</p> * * <p> * The uddi:name element of the tModel MUST be the value of the name * attribute of the wsdl:binding.</p> * * <p> * The tModel MUST contain a categoryBag, and the categoryBag MUST * contain at least the following keyedReference elements:</p> <ol> <li> * A keyedReference with a tModelKey of the WSDL Entity Type category * system and a keyValue of "binding".</li> <li> A keyedReference with a * tModelKey of the WSDL portType Reference category system and a * keyValue of the tModelKey that models the wsdl:portType to which the * wsdl:binding relates.</li> <li> A keyedReference with a tModelKey of * the UDDI Types category system and a keyValue of "wsdlSpec" for * backward compatibility[1].</li> <li> One or two keyedReferences as * required to capture the protocol and optionally the transport * information refer to the next section.</li> </ol> * * <p> * If the wsdl:binding has a targetNamespace then the categoryBag MUST * also contain an additional keyedReference with a tModelKey of the XML * Namespace category system and a keyValue of the target namespace of * the wsdl:definitions element that contains the wsdl:binding. If the * targetNamespace is absent from the binding, a categoryBag MUST NOT * contain a keyedReference to the XML Namespace category system.</p> * * <p> * The tModel MUST contain an overviewDoc with an overviewURL containing * the location of the WSDL document that describes the * wsdl:binding.</p> * * <h4>2.4.2.1 wsdl:binding Extensions</h4> * * <p> * Information about the protocol and transport, if applicable, * specified in an extension to the wsdl:binding is used to categorize * the binding tModel as described in the following sections. This * information is specified using two of the category systems defined in * this Technical Note:</p> <ol> <li> Protocol Categorization</li> <li> * Transport Categorization</li> </ol> * <p> * The valid values for the Protocol Categorization category system are * tModelKeys of tModels that are categorized as protocol tModels. * Similarly, the valid values for the Transport Categorization category * system are tModelKeys of tModels that are categorized as transport * tModels.</p> * <p> * The reason for having these two categorization schemes that take * tModel keys as values is to allow other standard or proprietary * protocols and transports to be defined and used in the same way as * the standard SOAP and HTTP protocols and transport.</p> * * <h4>2.4.2.1.1 soap:binding</h4> * * <p> * If the wsdl:binding contains a soap:binding extensibility element * from the http://schemas.xmlsoap.org/wsdl/soap/ namespace then the * categoryBag MUST include a keyedReference with a tModelKey of the * Protocol Categorization category system and a keyValue of the * tModelKey of the SOAP Protocol tModel.</p> * * <p> * If the value of the transport attribute of the soap:binding element * is http://schemas.xmlsoap.org/soap/http then the categoryBag MUST * include a keyedReference with a tModelKey of the Transport * Categorization category system and a keyValue of the tModelKey of the * HTTP Transport tModel.</p> * * <p> * If the value of the transport attribute is anything else, then the * bindingTemplate MUST include an additional keyedReference with a * tModelKey of the Transport Categorization category system and a * keyValue of the tModelKey of an appropriate transport tModel.</p> * * <h4>2.4.2.1.2 http:binding</h4> * * <p> * If the wsdl:binding contains an http:binding extensibility element * from the http://schemas.xmlsoap.org/wsdl/http/ namespace then the * categoryBag MUST include a keyedReference with a tModelKey of the * Protocol Categorization category system and a keyValue of the * tModelKey of the HTTP Protocol tModel.</p> * * <p> * Note that this is a different tModel from the HTTP Transport tModel, * and in this case there is no separate transport tModel, and therefore * no keyedReference in the categoryBag from the Transport * Categorization category system.</p> * * <h4>2.4.2.1.3 Other wsdl:binding Extensions</h4> * * <p> * Other wsdl:binding extensibility elements are handled in a similar * fashion. It is assumed that vendors who provide other bindings will * provide the appropriate protocol and transport tModels.</p> * * Example Code * <pre> * URL url = new URL("http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl"); * String domain = url.getHost(); * ReadWSDL rw = new ReadWSDL(); * Definition wsdlDefinition = rw.readWSDL(url); * properties.put("keyDomain", domain); * properties.put("businessName", domain); * properties.put("serverName", url.getHost()); * properties.put("serverPort", url.getPort()); * wsdlURL = wsdlDefinition.getDocumentBaseURI(); * WSDL2UDDI wsdl2UDDI = new WSDL2UDDI(null, new URLLocalizerDefaultImpl(), properties); * Map allBindings = wsdlDefinition.getAllBindings(); * Set<TModel> createWSDLBindingTModels = wsdl2UDDI.createWSDLBindingTModels(url.toString(), allBindings); * </pre> * * @param wsdlURL * @param bindings Map * @return set of WSDL Binding tModels * @throws WSDLException */ public Set<TModel> createWSDLBindingTModels(String wsdlURL, Map<QName, Binding> bindings) throws WSDLException { Set<TModel> tModels = new HashSet<TModel>(); //Register a tModel for each portType for (QName qName : bindings.keySet()) { String localpart = qName.getLocalPart(); String namespace = qName.getNamespaceURI(); // Build the tModel TModel tModel = new TModel(); // Set the Key tModel.setTModelKey(keyDomainURI + localpart); // Set the Name Name name = new Name(); name.setLang(lang); name.setValue(localpart); tModel.setName(name); // Set the OverviewURL OverviewURL overviewURL = new OverviewURL(); overviewURL.setUseType(AccessPointType.WSDL_DEPLOYMENT.toString()); overviewURL.setValue(wsdlURL); OverviewDoc overviewDoc = new OverviewDoc(); overviewDoc.setOverviewURL(overviewURL); tModel.getOverviewDoc().add(overviewDoc); // Set the categoryBag CategoryBag categoryBag = new CategoryBag(); if (namespace != null && !"".equals(namespace)) { // A keyedReference with a tModelKey of the WSDL Entity Type category system and a keyValue of "binding". KeyedReference namespaceReference = newKeyedReference("uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace); categoryBag.getKeyedReference().add(namespaceReference); } // A keyedReference with a tModelKey of the WSDL Entity Type category system and a keyValue of "binding". KeyedReference typesReference = newKeyedReference("uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "binding"); categoryBag.getKeyedReference().add(typesReference); // A keyedReference with a tModelKey of the WSDL portType Reference category system and a keyValue // of the tModelKey that models the wsdl:portType to which the wsdl:binding relates. Binding binding = bindings.get(qName); String portTypeKey = keyDomainURI + binding.getPortType().getQName().getLocalPart(); KeyedReference namespaceReference = newKeyedReference("uddi:uddi.org:wsdl:porttypereference", "uddi-org:wsdl:portTypeReference", portTypeKey); categoryBag.getKeyedReference().add(namespaceReference); // A keyedReference with a tModelKey of the UDDI Types category system and a keyValue of // "wsdlSpec" for backward compatibility. KeyedReference typesReferenceBackwardsCompatible = newKeyedReference( "uddi:uddi.org:categorization:types", "uddi-org:types", "wsdlSpec"); categoryBag.getKeyedReference().add(typesReferenceBackwardsCompatible); // One or two keyedReferences as required to capture the protocol for (Object object : binding.getExtensibilityElements()) { SOAPBinding sb = null; SOAP12Binding sb12 = null; HTTPBinding hb = null; try { hb = (HTTPBinding) object; } catch (Exception x) { } try { sb = (SOAPBinding) object; } catch (Exception x) { } try { sb12 = (SOAP12Binding) object; } catch (Exception x) { } if (sb != null) { // If the wsdl:binding contains a soap:binding extensibility element from the // 'http://schemas.xmlsoap.org/wsdl/soap/' namespace then the categoryBag MUST //include a keyedReference with a tModelKey of the Protocol Categorization // category system and a keyValue of the tModelKey of the SOAP Protocol tModel. SOAPBinding soapBinding = sb; KeyedReference soapProtocol = newKeyedReference("uddi:uddi.org:wsdl:categorization:protocol", "uddi-org:protocol:soap", "uddi:uddi.org:protocol:soap"); categoryBag.getKeyedReference().add(soapProtocol); // If the value of the transport attribute of the soap:binding element // is 'http://schemas.xmlsoap.org/soap/http' then the categoryBag MUST // include a keyedReference with a tModelKey of the Transport Categorization // category system and a keyValue of the tModelKey of the HTTP Transport tModel. if ("http://schemas.xmlsoap.org/soap/http".equals(soapBinding.getTransportURI())) { KeyedReference httpTransport = newKeyedReference( "uddi:uddi.org:wsdl:categorization:transport", "uddi-org:http", "uddi:uddi.org:transport:http"); categoryBag.getKeyedReference().add(httpTransport); } else if (soapBinding.getTransportURI() != null) { // TODO If the value of the transport attribute is anything else, // then the bindingTemplate MUST include an additional keyedReference with a tModelKey // of the Transport Categorization category system and a keyValue of the tModelKey of // an appropriate transport tModel. log.warn("not implemented, binding transport is " + soapBinding.getTransportURI()); } } else if (hb != null) { // If the wsdl:binding contains an http:binding extensibility element from the // http://schemas.xmlsoap.org/wsdl/http/ namespace then the categoryBag MUST // include a keyedReference with a tModelKey of the Protocol Categorization // category system and a keyValue of the tModelKey of the HTTP Protocol tModel. KeyedReference soapProtocol = newKeyedReference("uddi:uddi.org:wsdl:categorization:protocol", "uddi-org:protocol:http", "uddi:uddi.org:protocol:http"); categoryBag.getKeyedReference().add(soapProtocol); } else if (sb12 != null) { // If the wsdl:binding contains a soap:binding extensibility element from the // 'http://schemas.xmlsoap.org/wsdl/soap/' namespace then the categoryBag MUST //include a keyedReference with a tModelKey of the Protocol Categorization // category system and a keyValue of the tModelKey of the SOAP Protocol tModel. KeyedReference soapProtocol = newKeyedReference("uddi:uddi.org:wsdl:categorization:protocol", "uddi-org:protocol:soap", "uddi:uddi.org:protocol:soap"); categoryBag.getKeyedReference().add(soapProtocol); // If the value of the transport attribute of the soap:binding element // is 'http://schemas.xmlsoap.org/soap/http' then the categoryBag MUST // include a keyedReference with a tModelKey of the Transport Categorization // category system and a keyValue of the tModelKey of the HTTP Transport tModel. if ("http://schemas.xmlsoap.org/soap/http".equals(sb12.getTransportURI())) { KeyedReference httpTransport = newKeyedReference( "uddi:uddi.org:wsdl:categorization:transport", "uddi-org:http", "uddi:uddi.org:transport:http"); categoryBag.getKeyedReference().add(httpTransport); } else if (sb12.getTransportURI() != null) { // TODO If the value of the transport attribute is anything else, // then the bindingTemplate MUST include an additional keyedReference with a tModelKey // of the Transport Categorization category system and a keyValue of the tModelKey of // an appropriate transport tModel. log.warn("not implemented, binding transport is " + sb12.getTransportURI()); } } else { log.warn("Unrecongnized binding type: " + object.getClass().getCanonicalName() + ". Generated" + "binding tModel may be missing the required (according to WSDL2UDDI spec) " + "uddi:uddi.org:wsdl:categorization:protocol keyedReference."); } } tModel.setCategoryBag(categoryBag); tModels.add(tModel); } return tModels; } /** * <h3>2.4.1 wsdl:portType -> uddi:tModel</h3> * * <p> * A wsdl:portType MUST be modeled as a uddi:tModel.</p> * * <p> * The minimum information that must be captured about a portType is its * entity type, its local name, its namespace, and the location of the * WSDL document that defines the portType. Capturing the entity type * enables users to search for tModels that represent portType * artifacts. Capturing the local name, namespace, and WSDL location * enables users to locate the definition of the specified portType * artifact.</p> * * <p> * The wsdl:portType information is captured as follows:</p> * * <p> * The uddi:name element of the tModel MUST be the value of the name * attribute of the wsdl:portType.</p> * * <p> * The tModel MUST contain a categoryBag, and the categoryBag MUST * contain a keyedReference with a tModelKey of the WSDL Entity Type * category system and a keyValue of "portType".</p> * * <p> * If the wsdl:portType has a targetNamespace then the categoryBag MUST * also contain an additional keyedReference with a tModelKey of the XML * Namespace category system and a keyValue of the target namespace of * the wsdl:definitions element that contains the wsdl:portType. If the * targetNamespace is absent from the portType, a categoryBag MUST NOT * contain a keyedReference to the XML Namespace category system.</p> * * <p> * The tModel MUST contain an overviewDoc with an overviewURL containing * the location of the WSDL document that describes the * wsdl:portType.</p> * Example Code * <pre> * URL url = new URL("http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl"); * String domain = url.getHost(); * ReadWSDL rw = new ReadWSDL(); * Definition wsdlDefinition = rw.readWSDL(url); * properties.put("keyDomain", domain); * properties.put("businessName", domain); * properties.put("serverName", url.getHost()); * properties.put("serverPort", url.getPort()); * wsdlURL = wsdlDefinition.getDocumentBaseURI(); * WSDL2UDDI wsdl2UDDI = new WSDL2UDDI(null, new URLLocalizerDefaultImpl(), properties); * Map<QName, PortType> portTypes = (Map<QName, PortType>) wsdlDefinition.getAllPortTypes(); * Set<TModel> portTypeTModels = wsdl2UDDI.createWSDLPortTypeTModels(wsdlURL, portTypes); * </pre> * * @param wsdlURL This is used to set the Overview URL * @param portTypes Map * @return set of WSDL PortType tModels * @throws WSDLException */ public Set<TModel> createWSDLPortTypeTModels(String wsdlURL, Map<QName, PortType> portTypes) throws WSDLException { Set<TModel> tModels = new HashSet<TModel>(); // Create a tModel for each portType for (QName qName : portTypes.keySet()) { // Build the tModel TModel tModel = new TModel(); String localpart = qName.getLocalPart(); String namespace = qName.getNamespaceURI(); // Set the Key tModel.setTModelKey(keyDomainURI + localpart); // Set the Name. The uddi:name element of the tModel MUST be the value of // the name attribute of the wsdl:portType. Name name = new Name(); name.setLang(lang); name.setValue(localpart); tModel.setName(name); // Set the OverviewURL. The tModel MUST contain an overviewDoc with an // overviewURL containing the location of the WSDL document that // describes the wsdl:portType. OverviewURL overviewURL = new OverviewURL(); overviewURL.setUseType(AccessPointType.WSDL_DEPLOYMENT.toString()); overviewURL.setValue(wsdlURL); OverviewDoc overviewDoc = new OverviewDoc(); overviewDoc.setOverviewURL(overviewURL); tModel.getOverviewDoc().add(overviewDoc); // Create the categoryBag, The tModel MUST contain a categoryBag CategoryBag categoryBag = new CategoryBag(); // the categoryBag MUST contain a keyedReference with a tModelKey of the WSDL // Entity Type category system and a keyValue of "portType". KeyedReference typesReference = newKeyedReference("uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "portType"); categoryBag.getKeyedReference().add(typesReference); // If the wsdl:portType has a targetNamespace then the categoryBag MUST also contain an // additional keyedReference with a tModelKey of the XML Namespace category system and a // keyValue of the target namespace of the wsdl:definitions element that contains the // wsdl:portType. If the targetNamespace is absent from the portType, a categoryBag // MUST NOT contain a keyedReference to the XML Namespace category system. if (namespace != null && !"".equals(namespace)) { KeyedReference namespaceReference = newKeyedReference("uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace); categoryBag.getKeyedReference().add(namespaceReference); } tModel.setCategoryBag(categoryBag); tModels.add(tModel); } return tModels; } protected static KeyedReference newKeyedReference(String tModelKey, String keyName, String value) { KeyedReference typesReference = new KeyedReference(); typesReference.setTModelKey(tModelKey); typesReference.setKeyName(keyName); typesReference.setKeyValue(value); return typesReference; } /** * Builds a finder to find the binding tModels for a portType. * * @param portType * @param namespace * @return tModel info */ public static FindTModel createFindBindingTModelForPortType(String portType, String namespace) { FindTModel findTModel = new FindTModel(); CategoryBag categoryBag = new CategoryBag(); if (namespace != null && namespace.length() != 0) { KeyedReference namespaceReference = newKeyedReference("uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace); categoryBag.getKeyedReference().add(namespaceReference); } KeyedReference bindingReference = newKeyedReference("uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "binding"); categoryBag.getKeyedReference().add(bindingReference); KeyedReference portTypeReference = newKeyedReference("uddi:uddi.org:wsdl:porttypereference", "uddi-org:wsdl:portTypeReference", portType); categoryBag.getKeyedReference().add(portTypeReference); findTModel.setCategoryBag(categoryBag); if (log.isDebugEnabled()) { log.debug(new PrintUDDI<FindTModel>().print(findTModel)); } return findTModel; } /** * Builds a finder to find the portType tModels for a portType. * * @param portTypeName * @param namespace * @return tModel info */ public static FindTModel createFindPortTypeTModelForPortType(String portTypeName, String namespace) { FindTModel findTModel = new FindTModel(); Name name = new Name(); name.setLang("en"); name.setValue(portTypeName); findTModel.setName(name); CategoryBag categoryBag = new CategoryBag(); if (namespace != null && namespace.length() != 0) { KeyedReference namespaceReference = newKeyedReference("uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace); categoryBag.getKeyedReference().add(namespaceReference); } KeyedReference bindingReference = newKeyedReference("uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "portType"); categoryBag.getKeyedReference().add(bindingReference); findTModel.setCategoryBag(categoryBag); if (log.isDebugEnabled()) { log.debug(new PrintUDDI<FindTModel>().print(findTModel)); } return findTModel; } /** * Perform a lookup by serviceKey, and will return null if not found. * * @param serviceKey * @return business service * @throws RemoteException * @throws ConfigurationException * @throws TransportException */ private BusinessService lookupService(String serviceKey) throws RemoteException, ConfigurationException, TransportException { //Checking if this serviceKey already exist BusinessService service = clerk.getServiceDetail(serviceKey); return service; } /** * Creates a business service based off of a WSDL definition<Br>No * changes are made to the UDDI endpoints using this method * <br> * Example Code: * <pre> * URL url = new URL("http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl"); * String domain = url.getHost(); * ReadWSDL rw = new ReadWSDL(); * Definition wsdlDefinition = rw.readWSDL(url); * properties.put("keyDomain", domain); * properties.put("businessName", domain); * properties.put("serverName", url.getHost()); * properties.put("serverPort", url.getPort()); * wsdlURL = wsdlDefinition.getDocumentBaseURI(); * WSDL2UDDI wsdl2UDDI = new WSDL2UDDI(null, new URLLocalizerDefaultImpl(), properties); * BusinessServices businessServices = wsdl2UDDI.createBusinessServices(wsdlDefinition); * </pre> * * @param wsdlDefinition must not be null * @return a business service * @throws MalformedURLException * @throws IllegalArgumentException if the wsdlDefinition is null */ public BusinessServices createBusinessServices(Definition wsdlDefinition) throws MalformedURLException { if (wsdlDefinition == null) { throw new IllegalArgumentException(); } BusinessServices businessServices = new BusinessServices(); for (Object serviceName : wsdlDefinition.getAllServices().keySet()) { QName serviceQName = (QName) serviceName; Service service = wsdlDefinition.getService(serviceQName); BusinessService businessService = createBusinessService(serviceQName, wsdlDefinition); //service.getExtensibilityElements(). //add the bindingTemplates URL serviceUrl = null; if (service.getPorts() != null && service.getPorts().size() > 0) { businessService.setBindingTemplates(new BindingTemplates()); for (Object portName : service.getPorts().keySet()) { BindingTemplate bindingTemplate = createWSDLBinding(serviceQName, (String) portName, serviceUrl, wsdlDefinition); businessService.getBindingTemplates().getBindingTemplate().add(bindingTemplate); } } businessServices.getBusinessService().add(businessService); } return businessServices; } /** * Creates a UDDI Business Service. * * @param serviceQName * @param wsdlDefinition * @return a business service */ protected BusinessService createBusinessService(QName serviceQName, Definition wsdlDefinition) { log.debug("Constructing Service UDDI Information for " + serviceQName); BusinessService service = new BusinessService(); // BusinessKey service.setBusinessKey(businessKey); // ServiceKey service.setServiceKey(UDDIKeyConvention.getServiceKey(properties, serviceQName.getLocalPart())); // Description String serviceDescription = properties.getProperty(Property.SERVICE_DESCRIPTION, Property.DEFAULT_SERVICE_DESCRIPTION); // Override with the service description from the WSDL if present if (wsdlDefinition.getService(serviceQName) != null) { Element docElement = wsdlDefinition.getService(serviceQName).getDocumentationElement(); if (docElement != null && docElement.getTextContent() != null) { serviceDescription = docElement.getTextContent(); } } service.getDescription().addAll(Common2UDDI.mapDescription(serviceDescription, lang)); // Service name Name sName = new Name(); sName.setLang(lang); sName.setValue(serviceQName.getLocalPart()); service.getName().add(sName); CategoryBag categoryBag = new CategoryBag(); String namespace = serviceQName.getNamespaceURI(); if (namespace != null && namespace.length() != 0) { KeyedReference namespaceReference = newKeyedReference("uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace); categoryBag.getKeyedReference().add(namespaceReference); } KeyedReference serviceReference = newKeyedReference("uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "service"); categoryBag.getKeyedReference().add(serviceReference); KeyedReference localNameReference = newKeyedReference("uddi:uddi.org:xml:localname", "uddi-org:xml:localName", serviceQName.getLocalPart()); categoryBag.getKeyedReference().add(localNameReference); service.setCategoryBag(categoryBag); return service; } protected BindingTemplate createWSDLBinding(QName serviceQName, String portName, URL serviceUrl, Definition wsdlDefinition) throws MalformedURLException { BindingTemplate bindingTemplate = new BindingTemplate(); // Set BusinessService Key bindingTemplate.setServiceKey(UDDIKeyConvention.getServiceKey(properties, serviceQName.getLocalPart())); if (serviceUrl != null) { // Set AccessPoint AccessPoint accessPoint = new AccessPoint(); accessPoint.setUseType(AccessPointType.END_POINT.toString()); accessPoint.setValue(urlLocalizer.rewrite(serviceUrl)); bindingTemplate.setAccessPoint(accessPoint); // Set Binding Key String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceQName, portName, serviceUrl); bindingTemplate.setBindingKey(bindingKey); } Service service = wsdlDefinition.getService(serviceQName); if (service != null) { TModelInstanceDetails tModelInstanceDetails = new TModelInstanceDetails(); Port port = service.getPort(portName); if (port != null) { if (serviceUrl == null) { for (Object element : port.getExtensibilityElements()) { String location = null; if (element instanceof SOAPAddress) { SOAPAddress address = (SOAPAddress) element; location = urlLocalizer.rewrite(new URL(address.getLocationURI())); } else if (element instanceof HTTPAddress) { HTTPAddress address = (HTTPAddress) element; urlLocalizer.rewrite(new URL(location = address.getLocationURI())); } else if (element instanceof SOAP12Address) { SOAP12Address address = (SOAP12Address) element; location = urlLocalizer.rewrite(new URL(address.getLocationURI())); } if (location != null) { try { URL locationURI = new URL(location); AccessPoint accessPoint = new AccessPoint(); accessPoint.setUseType(AccessPointType.END_POINT.toString()); accessPoint.setValue(urlLocalizer.rewrite(locationURI)); bindingTemplate.setAccessPoint(accessPoint); // Set Binding Key String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceQName, portName, locationURI); bindingTemplate.setBindingKey(bindingKey); break; } catch (MalformedURLException e) { log.error(e.getMessage()); } } } } Binding binding = port.getBinding(); // Set the Binding Description String bindingDescription = properties.getProperty(Property.BINDING_DESCRIPTION, Property.DEFAULT_BINDING_DESCRIPTION); // Override with the service description from the WSDL if present Element docElement = binding.getDocumentationElement(); if (docElement != null && docElement.getTextContent() != null) { bindingDescription = docElement.getTextContent(); } bindingTemplate.getDescription().addAll(Common2UDDI.mapDescription(bindingDescription, lang)); // reference wsdl:binding tModel TModelInstanceInfo tModelInstanceInfoBinding = new TModelInstanceInfo(); tModelInstanceInfoBinding.setTModelKey(keyDomainURI + binding.getQName().getLocalPart()); InstanceDetails instanceDetails = new InstanceDetails(); instanceDetails.setInstanceParms(portName); tModelInstanceInfoBinding.setInstanceDetails(instanceDetails); tModelInstanceInfoBinding.getDescription() .addAll(Common2UDDI.mapDescription("The wsdl:binding that this wsdl:port implements. " + bindingDescription + " The instanceParms specifies the port local name.", lang)); tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoBinding); // reference wsdl:portType tModel PortType portType = binding.getPortType(); TModelInstanceInfo tModelInstanceInfoPortType = new TModelInstanceInfo(); tModelInstanceInfoPortType.setTModelKey(keyDomainURI + portType.getQName().getLocalPart()); String portTypeDescription = ""; docElement = portType.getDocumentationElement(); if (docElement != null && docElement.getTextContent() != null) { portTypeDescription = docElement.getTextContent(); } tModelInstanceInfoPortType.getDescription().addAll(Common2UDDI.mapDescription( "The wsdl:portType that this wsdl:port implements." + portTypeDescription, lang)); tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoPortType); bindingTemplate.setTModelInstanceDetails(tModelInstanceDetails); } else { log.error("Could not find Port with portName: " + portName); } } else { log.error("Could not find Service with serviceName: " + serviceQName.getLocalPart()); } return UDDIClient.addSOAPtModels(bindingTemplate); } /** * Obtains the accessUrl from the WSDL * * @param port * @return a string url * @throws MalformedURLException */ private String getBindingURL(Port port) throws MalformedURLException { String bindingUrl = null; for (Object element : port.getExtensibilityElements()) { if (element instanceof SOAPAddress) { SOAPAddress address = (SOAPAddress) element; URL locationURI = new URL(address.getLocationURI()); if (locationURI != null) { bindingUrl = urlLocalizer.rewrite(locationURI); break; } } } return bindingUrl; } }