1/*2 * Copyright 2001-2011 The Apache Software Foundation.3 * 4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 * 8 * http://www.apache.org/licenses/LICENSE-2.09 * 10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 *16 */17package org.apache.juddi.v3.client.mapping.wsdl;
1819import org.apache.juddi.v3.client.mapping.Common2UDDI;
20import java.net.MalformedURLException;
21import java.net.URL;
22import java.rmi.RemoteException;
23import java.util.ArrayList;
24import java.util.HashSet;
25import java.util.List;
26import java.util.Map;
27import java.util.Properties;
28import java.util.Set;
2930import javax.wsdl.Binding;
31import javax.wsdl.Definition;
32import javax.wsdl.Port;
33import javax.wsdl.PortType;
34import javax.wsdl.Service;
35import javax.wsdl.WSDLException;
36import javax.wsdl.extensions.http.HTTPAddress;
37import javax.wsdl.extensions.http.HTTPBinding;
38import javax.wsdl.extensions.soap.SOAPAddress;
39import javax.wsdl.extensions.soap.SOAPBinding;
40import javax.wsdl.extensions.soap12.SOAP12Address;
41import javax.wsdl.extensions.soap12.SOAP12Binding;
42import javax.xml.namespace.QName;
4344import org.apache.commons.configuration.ConfigurationException;
45import org.apache.commons.logging.Log;
46import org.apache.commons.logging.LogFactory;
47import org.apache.juddi.api_v3.AccessPointType;
48import org.apache.juddi.jaxb.PrintUDDI;
49import org.apache.juddi.v3.client.config.Property;
50import org.apache.juddi.v3.client.config.UDDIClerk;
51import org.apache.juddi.v3.client.config.UDDIClient;
52import org.apache.juddi.v3.client.config.UDDIKeyConvention;
53import org.apache.juddi.v3.client.mapping.ServiceRegistrationResponse;
54import org.apache.juddi.v3.client.mapping.URLLocalizer;
55import org.apache.juddi.v3.client.mapping.wadl.WADL2UDDI;
56import org.apache.juddi.v3.client.transport.TransportException;
57import org.uddi.api_v3.AccessPoint;
58import org.uddi.api_v3.BindingTemplate;
59import org.uddi.api_v3.BindingTemplates;
60import org.uddi.api_v3.BusinessService;
61import org.uddi.api_v3.BusinessServices;
62import org.uddi.api_v3.CategoryBag;
63import org.uddi.api_v3.FindTModel;
64import org.uddi.api_v3.InstanceDetails;
65import org.uddi.api_v3.KeyedReference;
66import org.uddi.api_v3.Name;
67import org.uddi.api_v3.OverviewDoc;
68import org.uddi.api_v3.OverviewURL;
69import org.uddi.api_v3.TModel;
70import org.uddi.api_v3.TModelDetail;
71import org.uddi.api_v3.TModelInstanceDetails;
72import org.uddi.api_v3.TModelInstanceInfo;
73import org.w3c.dom.Element;
7475/**76 * This class implements the OASIS <a77 * href="http://www.oasis-open.org/committees/uddi-spec/doc/tn/uddi-spec-tc-tn-wsdl-v202-20040631.htm">78 * 'Using WSDL in a UDDI Registry, Version 2.0.2'</a> technote. This class79 * creates a detailed mapping of WSDL 1.1 artifacts to the UDDI V3 data model.80 * <ul> <th>Section 2.4 in the technote</th> <li>2.4.1 wsdl:portType ->81 * uddi:tModel - {@link #createWSDLPortTypeTModels(String, Map)}</li> <li>2.4.282 * wsdl:binding -> uddi:tModel -83 * {@link #createWSDLBindingTModels(String, Map)}</li> <li>TODO: 2.4.384 * wsdl:service -> uddi:businessService</li> <li>TODO: 2.4.4 wsdl:port ->85 * uddi:bindingTemplate</li> <li>TODO: 2.4.5 wsdl:port Address Extensions ->86 * uddi:bindingTemplate</li> </ul>87 *88 * @see WADL2UDDI89 * @see BPEL2UDDI90 * @author Kurt T Stam91 * @since 3.1.592 */93publicclassWSDL2UDDI {
9495privatestaticfinal Log log = LogFactory.getLog(WSDL2UDDI.class);
96private String keyDomainURI;
97private String businessKey;
98private String lang;
99privateUDDIClerk clerk = null;
100private Properties properties = null;
101privateURLLocalizer urlLocalizer;
102103/**104 * Required Properties are: businessName, for example: 'Apache'105 * nodeName, for example: 'uddi.example.org_80' keyDomain, for example:106 * juddi.apache.org107 *108 * Optional Properties are: lang: for example: 'nl'109 *110 * @param clerk - can be null if register/unregister methods are not111 * used.112 * @param urlLocalizer - A reference to an custom113 * @param properties - required values keyDomain, businessKey, nodeName114 * @throws ConfigurationException115 */116publicWSDL2UDDI(UDDIClerk clerk, URLLocalizer urlLocalizer, Properties properties) throws ConfigurationException {
117super();
118if (properties == null) {
119thrownew IllegalArgumentException("properties");
120 }
121this.clerk = clerk;
122this.urlLocalizer = urlLocalizer;
123this.properties = properties;
124125if (clerk != null) {
126if (!properties.containsKey("keyDomain")) {
127thrownew ConfigurationException("Property keyDomain is a required property when using WSDL2UDDI.");
128 }
129if (!properties.containsKey("businessKey") && !properties.containsKey("businessName")) {
130thrownew ConfigurationException("Either property businessKey, or businessName, is a required property when using WSDL2UDDI.");
131 }
132if (!properties.containsKey("nodeName")) {
133if (properties.containsKey("serverName") && properties.containsKey("serverPort")) {
134 String nodeName = properties.getProperty("serverName") + "_" + properties.getProperty("serverPort");
135 properties.setProperty("nodeName", nodeName);
136 } else {
137thrownew ConfigurationException("Property nodeName is not defined and is a required property when using WSDL2UDDI.");
138 }
139 }
140 }
141142//Obtaining values from the properties143this.keyDomainURI = "uddi:" + properties.getProperty("keyDomain") + ":";
144if (properties.contains(Property.BUSINESS_KEY)) {
145this.businessKey = properties.getProperty(Property.BUSINESS_KEY);
146 } else {
147//using the BusinessKey Template, and the businessName to construct the key 148this.businessKey = UDDIKeyConvention.getBusinessKey(properties);
149 }
150this.lang = properties.getProperty(Property.LANG, Property.DEFAULT_LANG);
151 }
152153public BusinessServices registerBusinessServices(Definition wsdlDefinition) throws RemoteException, ConfigurationException, TransportException, WSDLException, MalformedURLException {
154155 BusinessServices businessServices = new BusinessServices();
156157for (Object serviceName : wsdlDefinition.getAllServices().keySet()) {
158 QName serviceQName = (QName) serviceName;
159 Service service = wsdlDefinition.getService(serviceQName);
160 BusinessService businessService = null;
161//add service162 URL serviceUrl = null;
163if (service.getPorts() != null && service.getPorts().size() > 0) {
164for (Object portName : service.getPorts().keySet()) {
165 businessService = registerBusinessService(serviceQName, (String) portName, serviceUrl, wsdlDefinition).getBusinessService();
166 }
167 }
168if (businessService != null) {
169 businessServices.getBusinessService().add(businessService);
170 }
171 }
172173return businessServices;
174175 }
176177 @SuppressWarnings("unchecked")
178publicServiceRegistrationResponse registerBusinessService(QName serviceQName, String portName, URL serviceUrl, Definition wsdlDefinition) throws RemoteException, ConfigurationException, TransportException, WSDLException, MalformedURLException {
179180 String genericWSDLURL = wsdlDefinition.getDocumentBaseURI(); //TODO maybe point to repository version181ServiceRegistrationResponse response = newServiceRegistrationResponse();
182 String serviceKey = UDDIKeyConvention.getServiceKey(properties, serviceQName.getLocalPart());
183 BusinessService businessService = lookupService(serviceKey);
184if (businessService == null) {
185 List<TModel> tModels = new ArrayList<TModel>();
186// Create the PortType tModels187 Map<QName, PortType> portTypes = (Map<QName, PortType>) wsdlDefinition.getAllPortTypes();
188 tModels.addAll(createWSDLPortTypeTModels(genericWSDLURL, portTypes));
189// Create the Binding tModels190 Map<QName, Binding> bindings = (Map<QName, Binding>) wsdlDefinition.getAllBindings();
191 tModels.addAll(createWSDLBindingTModels(genericWSDLURL, bindings));
192// Register these tModels193for (TModel tModel : tModels) {
194 clerk.register(tModel);
195 }
196// Service197 businessService = createBusinessService(serviceQName, wsdlDefinition);
198// Register this Service199 clerk.register(businessService);
200 }
201//Add the BindingTemplate to this Service202 BindingTemplate binding = createWSDLBinding(serviceQName, portName, serviceUrl, wsdlDefinition);
203// Register BindingTemplate204if (binding.getAccessPoint() != null) {
205 clerk.register(binding);
206if (businessService.getBindingTemplates() == null) {
207 businessService.setBindingTemplates(new BindingTemplates());
208 }
209 businessService.getBindingTemplates().getBindingTemplate().add(binding);
210 response.setBindingKey(binding.getBindingKey());
211 }
212 response.setBusinessService(businessService);
213return response;
214 }
215216public String[] unRegisterBusinessServices(Definition wsdlDefinition) throws RemoteException, ConfigurationException, TransportException, MalformedURLException {
217218 String[] businessServices = new String[wsdlDefinition.getAllServices().size()];
219int i = 0;
220for (Object serviceName : wsdlDefinition.getAllServices().keySet()) {
221 QName serviceQName = (QName) serviceName;
222 Service service = wsdlDefinition.getService(serviceQName);
223//unregister service224 URL serviceUrl = null;
225if (service.getPorts() != null && service.getPorts().size() > 0) {
226for (Object portName : service.getPorts().keySet()) {
227//construct the accessURL228 serviceUrl = new URL(getBindingURL((Port) service.getPorts().get(portName)));
229 businessServices[i++] = unRegisterBusinessService(serviceQName, (String) portName, serviceUrl);
230 }
231 }
232 }
233return businessServices;
234 }
235236public String unRegisterBusinessService(QName serviceName, String portName, URL serviceUrl) throws RemoteException, ConfigurationException, TransportException {
237238 String serviceKey = UDDIKeyConvention.getServiceKey(properties, serviceName.getLocalPart());
239 BusinessService service = lookupService(serviceKey);
240boolean isRemoveServiceIfNoTemplates = true;
241 String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceName, portName, serviceUrl);
242//check if this bindingKey is in the service's binding templates243for (BindingTemplate bindingTemplate : service.getBindingTemplates().getBindingTemplate()) {
244if (bindingKey.equals(bindingTemplate.getBindingKey())) {
245 clerk.unRegisterBinding(bindingKey);
246//if this is the last binding for this service, and 247if (service.getBindingTemplates().getBindingTemplate().size() == 1 && isRemoveServiceIfNoTemplates) {
248 clerk.unRegisterService(serviceKey);
249if (bindingTemplate.getTModelInstanceDetails() != null250 && bindingTemplate.getTModelInstanceDetails().getTModelInstanceInfo() != null) {
251for (TModelInstanceInfo tModelInstanceInfo : bindingTemplate.getTModelInstanceDetails().getTModelInstanceInfo()) {
252 String tModelKey = tModelInstanceInfo.getTModelKey();
253 TModelDetail tModelDetail = clerk.getTModelDetail(tModelKey);
254//delete all tModels assuming they are the portType and Binding tModels.255if (tModelDetail.getTModel() != null && tModelDetail.getTModel().size() > 0) {
256for (TModel tModel : tModelDetail.getTModel()) {
257if (!tModel.getTModelKey().startsWith("uddi:uddi.org:")) {
258 clerk.unRegisterTModel(tModel.getTModelKey());
259 } else {
260 log.info("Skipping the removal of " + tModel.getTModelKey() + " because it starts with uddi.org");
261 }
262 }
263 }
264 }
265 }
266 }
267 }
268 }
269return serviceKey;
270 }
271272public String getKeyDomainURI() {
273return keyDomainURI;
274 }
275276publicvoid setKeyDomain(String keyDomainURI) {
277this.keyDomainURI = keyDomainURI;
278 }
279280public String getLang() {
281return lang;
282 }
283284publicvoid setLang(String lang) {
285this.lang = lang;
286 }
287288/**289 * <h3>2.4.2 wsdl:binding -> uddi:tModel</h3>290 *291 * <p>292 * A wsdl:binding MUST be modeled as a uddi:tModel. The minimum293 * information that must be captured about a binding is its entity type,294 * its local name, its namespace, the location of the WSDL document that295 * defines the binding, the portType that it implements, its protocol,296 * and, optionally, the transport information. Capturing the entity type297 * enables users to search for tModels that represent binding artifacts.298 * Capturing the local name, namespace, and WSDL location enables users299 * to locate the definition of the specified binding artifact. The link300 * to the portType enables users to search for bindings that implement a301 * particular portType.</p>302 *303 * <p>304 * A wsdl:binding corresponds to a WSDL service interface definition as305 * defined by the mapping in the Version 1 Best Practice. To maintain306 * compatibility with the previous mapping, the binding must also be307 * characterized as type "wsdlSpec".</p>308 *309 * <p>310 * The wsdl:binding information is captured as follows:</p>311 *312 * <p>313 * The uddi:name element of the tModel MUST be the value of the name314 * attribute of the wsdl:binding.</p>315 *316 * <p>317 * The tModel MUST contain a categoryBag, and the categoryBag MUST318 * contain at least the following keyedReference elements:</p> <ol> <li>319 * A keyedReference with a tModelKey of the WSDL Entity Type category320 * system and a keyValue of "binding".</li> <li> A keyedReference with a321 * tModelKey of the WSDL portType Reference category system and a322 * keyValue of the tModelKey that models the wsdl:portType to which the323 * wsdl:binding relates.</li> <li> A keyedReference with a tModelKey of324 * the UDDI Types category system and a keyValue of "wsdlSpec" for325 * backward compatibility[1].</li> <li> One or two keyedReferences as326 * required to capture the protocol and optionally the transport327 * information refer to the next section.</li> </ol>328 *329 * <p>330 * If the wsdl:binding has a targetNamespace then the categoryBag MUST331 * also contain an additional keyedReference with a tModelKey of the XML332 * Namespace category system and a keyValue of the target namespace of333 * the wsdl:definitions element that contains the wsdl:binding. If the334 * targetNamespace is absent from the binding, a categoryBag MUST NOT335 * contain a keyedReference to the XML Namespace category system.</p>336 *337 * <p>338 * The tModel MUST contain an overviewDoc with an overviewURL containing339 * the location of the WSDL document that describes the340 * wsdl:binding.</p>341 *342 * <h4>2.4.2.1 wsdl:binding Extensions</h4>343 *344 * <p>345 * Information about the protocol and transport, if applicable,346 * specified in an extension to the wsdl:binding is used to categorize347 * the binding tModel as described in the following sections. This348 * information is specified using two of the category systems defined in349 * this Technical Note:</p> <ol> <li> Protocol Categorization</li> <li>350 * Transport Categorization</li> </ol>351 * <p>352 * The valid values for the Protocol Categorization category system are353 * tModelKeys of tModels that are categorized as protocol tModels.354 * Similarly, the valid values for the Transport Categorization category355 * system are tModelKeys of tModels that are categorized as transport356 * tModels.</p>357 * <p>358 * The reason for having these two categorization schemes that take359 * tModel keys as values is to allow other standard or proprietary360 * protocols and transports to be defined and used in the same way as361 * the standard SOAP and HTTP protocols and transport.</p>362 *363 * <h4>2.4.2.1.1 soap:binding</h4>364 *365 * <p>366 * If the wsdl:binding contains a soap:binding extensibility element367 * from the http://schemas.xmlsoap.org/wsdl/soap/ namespace then the368 * categoryBag MUST include a keyedReference with a tModelKey of the369 * Protocol Categorization category system and a keyValue of the370 * tModelKey of the SOAP Protocol tModel.</p>371 *372 * <p>373 * If the value of the transport attribute of the soap:binding element374 * is http://schemas.xmlsoap.org/soap/http then the categoryBag MUST375 * include a keyedReference with a tModelKey of the Transport376 * Categorization category system and a keyValue of the tModelKey of the377 * HTTP Transport tModel.</p>378 *379 * <p>380 * If the value of the transport attribute is anything else, then the381 * bindingTemplate MUST include an additional keyedReference with a382 * tModelKey of the Transport Categorization category system and a383 * keyValue of the tModelKey of an appropriate transport tModel.</p>384 *385 * <h4>2.4.2.1.2 http:binding</h4>386 *387 * <p>388 * If the wsdl:binding contains an http:binding extensibility element389 * from the http://schemas.xmlsoap.org/wsdl/http/ namespace then the390 * categoryBag MUST include a keyedReference with a tModelKey of the391 * Protocol Categorization category system and a keyValue of the392 * tModelKey of the HTTP Protocol tModel.</p>393 *394 * <p>395 * Note that this is a different tModel from the HTTP Transport tModel,396 * and in this case there is no separate transport tModel, and therefore397 * no keyedReference in the categoryBag from the Transport398 * Categorization category system.</p>399 *400 * <h4>2.4.2.1.3 Other wsdl:binding Extensions</h4>401 *402 * <p>403 * Other wsdl:binding extensibility elements are handled in a similar404 * fashion. It is assumed that vendors who provide other bindings will405 * provide the appropriate protocol and transport tModels.</p>406 *407 * Example Code408 * <pre>409 * URL url = new URL("http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl");410 * String domain = url.getHost();411 * ReadWSDL rw = new ReadWSDL();412 * Definition wsdlDefinition = rw.readWSDL(url);413 * properties.put("keyDomain", domain);414 * properties.put("businessName", domain);415 * properties.put("serverName", url.getHost());416 * properties.put("serverPort", url.getPort());417 * wsdlURL = wsdlDefinition.getDocumentBaseURI();418 * WSDL2UDDI wsdl2UDDI = new WSDL2UDDI(null, new URLLocalizerDefaultImpl(), properties);419 * Map allBindings = wsdlDefinition.getAllBindings();420 * Set<TModel> createWSDLBindingTModels = wsdl2UDDI.createWSDLBindingTModels(url.toString(), allBindings);421 * </pre>422 *423 * @param wsdlURL424 * @param bindings Map425 * @return set of WSDL Binding tModels426 * @throws WSDLException427 */428public Set<TModel> createWSDLBindingTModels(String wsdlURL, Map<QName, Binding> bindings) throws WSDLException {
429430 Set<TModel> tModels = new HashSet<TModel>();
431//Register a tModel for each portType432for (QName qName : bindings.keySet()) {
433 String localpart = qName.getLocalPart();
434 String namespace = qName.getNamespaceURI();
435// Build the tModel436 TModel tModel = new TModel();
437// Set the Key438 tModel.setTModelKey(keyDomainURI + localpart);
439// Set the Name440 Name name = new Name();
441 name.setLang(lang);
442 name.setValue(localpart);
443 tModel.setName(name);
444// Set the OverviewURL445 OverviewURL overviewURL = new OverviewURL();
446 overviewURL.setUseType(AccessPointType.WSDL_DEPLOYMENT.toString());
447 overviewURL.setValue(wsdlURL);
448 OverviewDoc overviewDoc = new OverviewDoc();
449 overviewDoc.setOverviewURL(overviewURL);
450 tModel.getOverviewDoc().add(overviewDoc);
451// Set the categoryBag452 CategoryBag categoryBag = new CategoryBag();
453454if (namespace != null && !"".equals(namespace)) {
455// A keyedReference with a tModelKey of the WSDL Entity Type category system and a keyValue of "binding".456 KeyedReference namespaceReference = newKeyedReference(
457"uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace);
458 categoryBag.getKeyedReference().add(namespaceReference);
459 }
460461// A keyedReference with a tModelKey of the WSDL Entity Type category system and a keyValue of "binding".462 KeyedReference typesReference = newKeyedReference(
463"uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "binding");
464 categoryBag.getKeyedReference().add(typesReference);
465466// A keyedReference with a tModelKey of the WSDL portType Reference category system and a keyValue 467// of the tModelKey that models the wsdl:portType to which the wsdl:binding relates.468 Binding binding = bindings.get(qName);
469 String portTypeKey = keyDomainURI + binding.getPortType().getQName().getLocalPart();
470 KeyedReference namespaceReference = newKeyedReference(
471"uddi:uddi.org:wsdl:porttypereference", "uddi-org:wsdl:portTypeReference",
472 portTypeKey);
473 categoryBag.getKeyedReference().add(namespaceReference);
474475// A keyedReference with a tModelKey of the UDDI Types category system and a keyValue of 476// "wsdlSpec" for backward compatibility.477 KeyedReference typesReferenceBackwardsCompatible = newKeyedReference(
478"uddi:uddi.org:categorization:types", "uddi-org:types", "wsdlSpec");
479 categoryBag.getKeyedReference().add(typesReferenceBackwardsCompatible);
480481// One or two keyedReferences as required to capture the protocol482for (Object object : binding.getExtensibilityElements()) {
483 SOAPBinding sb = null;
484 SOAP12Binding sb12 = null;
485 HTTPBinding hb = null;
486487try {
488 hb = (HTTPBinding) object;
489 } catch (Exception x) {
490 }
491try {
492 sb = (SOAPBinding) object;
493 } catch (Exception x) {
494 }
495try {
496 sb12 = (SOAP12Binding) object;
497 } catch (Exception x) {
498 }
499if (sb != null) {
500// If the wsdl:binding contains a soap:binding extensibility element from the 501// 'http://schemas.xmlsoap.org/wsdl/soap/' namespace then the categoryBag MUST 502//include a keyedReference with a tModelKey of the Protocol Categorization 503// category system and a keyValue of the tModelKey of the SOAP Protocol tModel.504 SOAPBinding soapBinding = sb;
505 KeyedReference soapProtocol = newKeyedReference(
506"uddi:uddi.org:wsdl:categorization:protocol", "uddi-org:protocol:soap", "uddi:uddi.org:protocol:soap");
507 categoryBag.getKeyedReference().add(soapProtocol);
508// If the value of the transport attribute of the soap:binding element 509// is 'http://schemas.xmlsoap.org/soap/http' then the categoryBag MUST 510// include a keyedReference with a tModelKey of the Transport Categorization 511// category system and a keyValue of the tModelKey of the HTTP Transport tModel.512if ("http://schemas.xmlsoap.org/soap/http".equals(soapBinding.getTransportURI())) {
513 KeyedReference httpTransport = newKeyedReference(
514"uddi:uddi.org:wsdl:categorization:transport", "uddi-org:http", "uddi:uddi.org:transport:http");
515 categoryBag.getKeyedReference().add(httpTransport);
516 } elseif (soapBinding.getTransportURI() != null) {
517// TODO If the value of the transport attribute is anything else, 518// then the bindingTemplate MUST include an additional keyedReference with a tModelKey 519// of the Transport Categorization category system and a keyValue of the tModelKey of 520// an appropriate transport tModel.521 log.warn("not implemented, binding transport is " + soapBinding.getTransportURI());
522 }
523524 } elseif (hb != null) {
525526// If the wsdl:binding contains an http:binding extensibility element from the 527// http://schemas.xmlsoap.org/wsdl/http/ namespace then the categoryBag MUST 528// include a keyedReference with a tModelKey of the Protocol Categorization 529// category system and a keyValue of the tModelKey of the HTTP Protocol tModel.530 KeyedReference soapProtocol = newKeyedReference(
531"uddi:uddi.org:wsdl:categorization:protocol", "uddi-org:protocol:http", "uddi:uddi.org:protocol:http");
532 categoryBag.getKeyedReference().add(soapProtocol);
533 } elseif (sb12 != null) {
534// If the wsdl:binding contains a soap:binding extensibility element from the 535// 'http://schemas.xmlsoap.org/wsdl/soap/' namespace then the categoryBag MUST 536//include a keyedReference with a tModelKey of the Protocol Categorization 537// category system and a keyValue of the tModelKey of the SOAP Protocol tModel.538539 KeyedReference soapProtocol = newKeyedReference(
540"uddi:uddi.org:wsdl:categorization:protocol", "uddi-org:protocol:soap", "uddi:uddi.org:protocol:soap");
541 categoryBag.getKeyedReference().add(soapProtocol);
542// If the value of the transport attribute of the soap:binding element 543// is 'http://schemas.xmlsoap.org/soap/http' then the categoryBag MUST 544// include a keyedReference with a tModelKey of the Transport Categorization 545// category system and a keyValue of the tModelKey of the HTTP Transport tModel.546if ("http://schemas.xmlsoap.org/soap/http".equals(sb12.getTransportURI())) {
547 KeyedReference httpTransport = newKeyedReference(
548"uddi:uddi.org:wsdl:categorization:transport", "uddi-org:http", "uddi:uddi.org:transport:http");
549 categoryBag.getKeyedReference().add(httpTransport);
550 } elseif (sb12.getTransportURI() != null) {
551// TODO If the value of the transport attribute is anything else, 552// then the bindingTemplate MUST include an additional keyedReference with a tModelKey 553// of the Transport Categorization category system and a keyValue of the tModelKey of 554// an appropriate transport tModel.555 log.warn("not implemented, binding transport is " + sb12.getTransportURI());
556 }
557558 } else {
559 log.warn("Unrecongnized binding type: " + object.getClass().getCanonicalName() + ". Generated"560 + "binding tModel may be missing the required (according to WSDL2UDDI spec) "561 + "uddi:uddi.org:wsdl:categorization:protocol keyedReference.");
562563 }
564 }
565566 tModel.setCategoryBag(categoryBag);
567 tModels.add(tModel);
568 }
569return tModels;
570 }
571572/**573 * <h3>2.4.1 wsdl:portType -> uddi:tModel</h3>574 *575 * <p>576 * A wsdl:portType MUST be modeled as a uddi:tModel.</p>577 *578 * <p>579 * The minimum information that must be captured about a portType is its580 * entity type, its local name, its namespace, and the location of the581 * WSDL document that defines the portType. Capturing the entity type582 * enables users to search for tModels that represent portType583 * artifacts. Capturing the local name, namespace, and WSDL location584 * enables users to locate the definition of the specified portType585 * artifact.</p>586 *587 * <p>588 * The wsdl:portType information is captured as follows:</p>589 *590 * <p>591 * The uddi:name element of the tModel MUST be the value of the name592 * attribute of the wsdl:portType.</p>593 *594 * <p>595 * The tModel MUST contain a categoryBag, and the categoryBag MUST596 * contain a keyedReference with a tModelKey of the WSDL Entity Type597 * category system and a keyValue of "portType".</p>598 *599 * <p>600 * If the wsdl:portType has a targetNamespace then the categoryBag MUST601 * also contain an additional keyedReference with a tModelKey of the XML602 * Namespace category system and a keyValue of the target namespace of603 * the wsdl:definitions element that contains the wsdl:portType. If the604 * targetNamespace is absent from the portType, a categoryBag MUST NOT605 * contain a keyedReference to the XML Namespace category system.</p>606 *607 * <p>608 * The tModel MUST contain an overviewDoc with an overviewURL containing609 * the location of the WSDL document that describes the610 * wsdl:portType.</p>611 * Example Code612 * <pre>613 * URL url = new URL("http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl");614 * String domain = url.getHost();615 * ReadWSDL rw = new ReadWSDL();616 * Definition wsdlDefinition = rw.readWSDL(url);617 * properties.put("keyDomain", domain);618 * properties.put("businessName", domain);619 * properties.put("serverName", url.getHost());620 * properties.put("serverPort", url.getPort());621 * wsdlURL = wsdlDefinition.getDocumentBaseURI();622 * WSDL2UDDI wsdl2UDDI = new WSDL2UDDI(null, new URLLocalizerDefaultImpl(), properties);623 * Map<QName, PortType> portTypes = (Map<QName, PortType>) wsdlDefinition.getAllPortTypes();624 * Set<TModel> portTypeTModels = wsdl2UDDI.createWSDLPortTypeTModels(wsdlURL, portTypes);625 * </pre>626 *627 * @param wsdlURL This is used to set the Overview URL628 * @param portTypes Map629 * @return set of WSDL PortType tModels630 * @throws WSDLException631 */632public Set<TModel> createWSDLPortTypeTModels(String wsdlURL, Map<QName, PortType> portTypes) throws WSDLException {
633 Set<TModel> tModels = new HashSet<TModel>();
634// Create a tModel for each portType635for (QName qName : portTypes.keySet()) {
636// Build the tModel637 TModel tModel = new TModel();
638 String localpart = qName.getLocalPart();
639 String namespace = qName.getNamespaceURI();
640// Set the Key641 tModel.setTModelKey(keyDomainURI + localpart);
642// Set the Name. The uddi:name element of the tModel MUST be the value of643// the name attribute of the wsdl:portType.644 Name name = new Name();
645 name.setLang(lang);
646 name.setValue(localpart);
647 tModel.setName(name);
648// Set the OverviewURL. The tModel MUST contain an overviewDoc with an 649// overviewURL containing the location of the WSDL document that 650// describes the wsdl:portType.651 OverviewURL overviewURL = new OverviewURL();
652 overviewURL.setUseType(AccessPointType.WSDL_DEPLOYMENT.toString());
653 overviewURL.setValue(wsdlURL);
654 OverviewDoc overviewDoc = new OverviewDoc();
655 overviewDoc.setOverviewURL(overviewURL);
656 tModel.getOverviewDoc().add(overviewDoc);
657// Create the categoryBag, The tModel MUST contain a categoryBag658 CategoryBag categoryBag = new CategoryBag();
659660// the categoryBag MUST contain a keyedReference with a tModelKey of the WSDL 661// Entity Type category system and a keyValue of "portType".662 KeyedReference typesReference = newKeyedReference(
663"uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "portType");
664 categoryBag.getKeyedReference().add(typesReference);
665666// If the wsdl:portType has a targetNamespace then the categoryBag MUST also contain an 667// additional keyedReference with a tModelKey of the XML Namespace category system and a 668// keyValue of the target namespace of the wsdl:definitions element that contains the 669// wsdl:portType. If the targetNamespace is absent from the portType, a categoryBag 670// MUST NOT contain a keyedReference to the XML Namespace category system.671if (namespace != null && !"".equals(namespace)) {
672 KeyedReference namespaceReference = newKeyedReference(
673"uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace);
674 categoryBag.getKeyedReference().add(namespaceReference);
675 }
676677 tModel.setCategoryBag(categoryBag);
678 tModels.add(tModel);
679 }
680return tModels;
681 }
682683protectedstatic KeyedReference newKeyedReference(String tModelKey, String keyName, String value) {
684 KeyedReference typesReference = new KeyedReference();
685 typesReference.setTModelKey(tModelKey);
686 typesReference.setKeyName(keyName);
687 typesReference.setKeyValue(value);
688return typesReference;
689 }
690691/**692 * Builds a finder to find the binding tModels for a portType.693 *694 * @param portType695 * @param namespace696 * @return tModel info697 */698publicstatic FindTModel createFindBindingTModelForPortType(String portType, String namespace) {
699700 FindTModel findTModel = new FindTModel();
701 CategoryBag categoryBag = new CategoryBag();
702703if (namespace != null && namespace.length() != 0) {
704 KeyedReference namespaceReference = newKeyedReference(
705"uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace);
706 categoryBag.getKeyedReference().add(namespaceReference);
707 }
708 KeyedReference bindingReference = newKeyedReference(
709"uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "binding");
710 categoryBag.getKeyedReference().add(bindingReference);
711712 KeyedReference portTypeReference = newKeyedReference(
713"uddi:uddi.org:wsdl:porttypereference", "uddi-org:wsdl:portTypeReference", portType);
714 categoryBag.getKeyedReference().add(portTypeReference);
715716 findTModel.setCategoryBag(categoryBag);
717718if (log.isDebugEnabled()) {
719 log.debug(new PrintUDDI<FindTModel>().print(findTModel));
720 }
721return findTModel;
722 }
723724/**725 * Builds a finder to find the portType tModels for a portType.726 *727 * @param portTypeName728 * @param namespace729 * @return tModel info730 */731publicstatic FindTModel createFindPortTypeTModelForPortType(String portTypeName, String namespace) {
732733 FindTModel findTModel = new FindTModel();
734 Name name = new Name();
735 name.setLang("en");
736 name.setValue(portTypeName);
737 findTModel.setName(name);
738739 CategoryBag categoryBag = new CategoryBag();
740if (namespace != null && namespace.length() != 0) {
741 KeyedReference namespaceReference = newKeyedReference(
742"uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace);
743 categoryBag.getKeyedReference().add(namespaceReference);
744 }
745 KeyedReference bindingReference = newKeyedReference(
746"uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "portType");
747 categoryBag.getKeyedReference().add(bindingReference);
748749 findTModel.setCategoryBag(categoryBag);
750751if (log.isDebugEnabled()) {
752 log.debug(new PrintUDDI<FindTModel>().print(findTModel));
753 }
754return findTModel;
755 }
756757/**758 * Perform a lookup by serviceKey, and will return null if not found.759 *760 * @param serviceKey761 * @return business service762 * @throws RemoteException763 * @throws ConfigurationException764 * @throws TransportException765 */766private BusinessService lookupService(String serviceKey) throws RemoteException, ConfigurationException, TransportException {
767768//Checking if this serviceKey already exist769 BusinessService service = clerk.getServiceDetail(serviceKey);
770return service;
771 }
772773/**774 * Creates a business service based off of a WSDL definition<Br>No775 * changes are made to the UDDI endpoints using this method776 * <br>777 * Example Code:778 * <pre>779 * URL url = new URL("http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl");780 * String domain = url.getHost();781 * ReadWSDL rw = new ReadWSDL();782 * Definition wsdlDefinition = rw.readWSDL(url);783 * properties.put("keyDomain", domain);784 * properties.put("businessName", domain);785 * properties.put("serverName", url.getHost());786 * properties.put("serverPort", url.getPort());787 * wsdlURL = wsdlDefinition.getDocumentBaseURI();788 * WSDL2UDDI wsdl2UDDI = new WSDL2UDDI(null, new URLLocalizerDefaultImpl(), properties);789 * BusinessServices businessServices = wsdl2UDDI.createBusinessServices(wsdlDefinition);790 * </pre>791 *792 * @param wsdlDefinition must not be null793 * @return a business service794 * @throws MalformedURLException795 * @throws IllegalArgumentException if the wsdlDefinition is null796 */797public BusinessServices createBusinessServices(Definition wsdlDefinition) throws MalformedURLException {
798if (wsdlDefinition == null) {
799thrownew IllegalArgumentException();
800 }
801 BusinessServices businessServices = new BusinessServices();
802for (Object serviceName : wsdlDefinition.getAllServices().keySet()) {
803 QName serviceQName = (QName) serviceName;
804 Service service = wsdlDefinition.getService(serviceQName);
805 BusinessService businessService = createBusinessService(serviceQName, wsdlDefinition);
806//service.getExtensibilityElements().807//add the bindingTemplates808 URL serviceUrl = null;
809if (service.getPorts() != null && service.getPorts().size() > 0) {
810 businessService.setBindingTemplates(new BindingTemplates());
811for (Object portName : service.getPorts().keySet()) {
812 BindingTemplate bindingTemplate = createWSDLBinding(serviceQName, (String) portName, serviceUrl, wsdlDefinition);
813 businessService.getBindingTemplates().getBindingTemplate().add(bindingTemplate);
814 }
815 }
816 businessServices.getBusinessService().add(businessService);
817 }
818819return businessServices;
820 }
821822/**823 * Creates a UDDI Business Service.824 *825 * @param serviceQName826 * @param wsdlDefinition827 * @return a business service828 */829protected BusinessService createBusinessService(QName serviceQName, Definition wsdlDefinition) {
830831 log.debug("Constructing Service UDDI Information for " + serviceQName);
832 BusinessService service = new BusinessService();
833// BusinessKey834 service.setBusinessKey(businessKey);
835// ServiceKey836 service.setServiceKey(UDDIKeyConvention.getServiceKey(properties, serviceQName.getLocalPart()));
837// Description838 String serviceDescription = properties.getProperty(Property.SERVICE_DESCRIPTION, Property.DEFAULT_SERVICE_DESCRIPTION);
839// Override with the service description from the WSDL if present840if (wsdlDefinition.getService(serviceQName) != null) {
841 Element docElement = wsdlDefinition.getService(serviceQName).getDocumentationElement();
842if (docElement != null && docElement.getTextContent() != null) {
843 serviceDescription = docElement.getTextContent();
844 }
845 }
846847 service.getDescription().addAll(Common2UDDI.mapDescription(serviceDescription, lang));
848849// Service name850 Name sName = new Name();
851 sName.setLang(lang);
852 sName.setValue(serviceQName.getLocalPart());
853 service.getName().add(sName);
854855 CategoryBag categoryBag = new CategoryBag();
856857 String namespace = serviceQName.getNamespaceURI();
858if (namespace != null && namespace.length() != 0) {
859 KeyedReference namespaceReference = newKeyedReference(
860"uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", namespace);
861 categoryBag.getKeyedReference().add(namespaceReference);
862 }
863864 KeyedReference serviceReference = newKeyedReference(
865"uddi:uddi.org:wsdl:types", "uddi-org:wsdl:types", "service");
866 categoryBag.getKeyedReference().add(serviceReference);
867868 KeyedReference localNameReference = newKeyedReference(
869"uddi:uddi.org:xml:localname", "uddi-org:xml:localName", serviceQName.getLocalPart());
870 categoryBag.getKeyedReference().add(localNameReference);
871872 service.setCategoryBag(categoryBag);
873874return service;
875 }
876877protected BindingTemplate createWSDLBinding(QName serviceQName, String portName, URL serviceUrl, Definition wsdlDefinition) throws MalformedURLException {
878879 BindingTemplate bindingTemplate = new BindingTemplate();
880// Set BusinessService Key881 bindingTemplate.setServiceKey(UDDIKeyConvention.getServiceKey(properties, serviceQName.getLocalPart()));
882883if (serviceUrl != null) {
884// Set AccessPoint885 AccessPoint accessPoint = new AccessPoint();
886 accessPoint.setUseType(AccessPointType.END_POINT.toString());
887 accessPoint.setValue(urlLocalizer.rewrite(serviceUrl));
888 bindingTemplate.setAccessPoint(accessPoint);
889// Set Binding Key890 String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceQName, portName, serviceUrl);
891 bindingTemplate.setBindingKey(bindingKey);
892 }
893894 Service service = wsdlDefinition.getService(serviceQName);
895if (service != null) {
896 TModelInstanceDetails tModelInstanceDetails = new TModelInstanceDetails();
897898 Port port = service.getPort(portName);
899if (port != null) {
900if (serviceUrl == null) {
901for (Object element : port.getExtensibilityElements()) {
902 String location = null;
903if (element instanceof SOAPAddress) {
904 SOAPAddress address = (SOAPAddress) element;
905 location = urlLocalizer.rewrite(new URL(address.getLocationURI()));
906 } elseif (element instanceof HTTPAddress) {
907 HTTPAddress address = (HTTPAddress) element;
908 urlLocalizer.rewrite(new URL(location = address.getLocationURI()));
909 } elseif (element instanceof SOAP12Address) {
910 SOAP12Address address = (SOAP12Address) element;
911 location = urlLocalizer.rewrite(new URL(address.getLocationURI()));
912 }
913if (location != null) {
914try {
915 URL locationURI = new URL(location);
916 AccessPoint accessPoint = new AccessPoint();
917 accessPoint.setUseType(AccessPointType.END_POINT.toString());
918 accessPoint.setValue(urlLocalizer.rewrite(locationURI));
919 bindingTemplate.setAccessPoint(accessPoint);
920// Set Binding Key921 String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceQName, portName, locationURI);
922 bindingTemplate.setBindingKey(bindingKey);
923break;
924 } catch (MalformedURLException e) {
925 log.error(e.getMessage());
926 }
927 }
928 }
929930 }
931 Binding binding = port.getBinding();
932// Set the Binding Description933 String bindingDescription = properties.getProperty(Property.BINDING_DESCRIPTION, Property.DEFAULT_BINDING_DESCRIPTION);
934// Override with the service description from the WSDL if present935 Element docElement = binding.getDocumentationElement();
936if (docElement != null && docElement.getTextContent() != null) {
937 bindingDescription = docElement.getTextContent();
938 }
939940 bindingTemplate.getDescription().addAll(Common2UDDI.mapDescription(bindingDescription, lang));
941942// reference wsdl:binding tModel943 TModelInstanceInfo tModelInstanceInfoBinding = new TModelInstanceInfo();
944 tModelInstanceInfoBinding.setTModelKey(keyDomainURI + binding.getQName().getLocalPart());
945 InstanceDetails instanceDetails = new InstanceDetails();
946 instanceDetails.setInstanceParms(portName);
947 tModelInstanceInfoBinding.setInstanceDetails(instanceDetails);
948949 tModelInstanceInfoBinding.getDescription().addAll(Common2UDDI.mapDescription("The wsdl:binding that this wsdl:port implements. " + bindingDescription
950 + " The instanceParms specifies the port local name.", lang));
951 tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoBinding);
952953// reference wsdl:portType tModel954 PortType portType = binding.getPortType();
955 TModelInstanceInfo tModelInstanceInfoPortType = new TModelInstanceInfo();
956 tModelInstanceInfoPortType.setTModelKey(keyDomainURI + portType.getQName().getLocalPart());
957 String portTypeDescription = "";
958 docElement = portType.getDocumentationElement();
959if (docElement != null && docElement.getTextContent() != null) {
960 portTypeDescription = docElement.getTextContent();
961 }
962963 tModelInstanceInfoPortType.getDescription().addAll(Common2UDDI.mapDescription("The wsdl:portType that this wsdl:port implements." + portTypeDescription, lang));
964 tModelInstanceDetails.getTModelInstanceInfo().add(tModelInstanceInfoPortType);
965966 bindingTemplate.setTModelInstanceDetails(tModelInstanceDetails);
967 } else {
968 log.error("Could not find Port with portName: " + portName);
969 }
970 } else {
971 log.error("Could not find Service with serviceName: " + serviceQName.getLocalPart());
972 }
973974return UDDIClient.addSOAPtModels(bindingTemplate);
975 }
976977/**978 * Obtains the accessUrl from the WSDL979 *980 * @param port981 * @return a string url982 * @throws MalformedURLException983 */984private String getBindingURL(Port port) throws MalformedURLException {
985986 String bindingUrl = null;
987for (Object element : port.getExtensibilityElements()) {
988if (element instanceof SOAPAddress) {
989 SOAPAddress address = (SOAPAddress) element;
990 URL locationURI = new URL(address.getLocationURI());
991if (locationURI != null) {
992 bindingUrl = urlLocalizer.rewrite(locationURI);
993break;
994 }
995 }
996 }
997return bindingUrl;
998 }
999 }