001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)WSDLHelper.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.messaging.util;
030:
031: import com.sun.jbi.messaging.LocalStringKeys;
032: import com.sun.jbi.messaging.ExchangeFactory;
033: import com.sun.jbi.messaging.ExchangePattern;
034:
035: import com.sun.jbi.wsdl2.Description;
036: import com.sun.jbi.wsdl2.Endpoint;
037: import com.sun.jbi.wsdl2.Interface;
038: import com.sun.jbi.wsdl2.InterfaceOperation;
039: import com.sun.jbi.wsdl2.Service;
040: import com.sun.jbi.wsdl2.WsdlReader;
041: import com.sun.jbi.wsdl2.WsdlException;
042: import com.sun.jbi.wsdl2.impl.WsdlFactory;
043:
044: import java.net.URI;
045: import java.util.ArrayList;
046: import java.util.HashMap;
047: import java.util.logging.Logger;
048: import javax.xml.namespace.QName;
049:
050: import org.w3c.dom.Document;
051: import org.w3c.dom.Element;
052: import org.w3c.dom.Node;
053: import org.w3c.dom.NodeList;
054:
055: /** Silly little utility object to help out in parsing WSDL for some NMR-specific
056: * requirements. NOTE: this is built as a layer on top of our existing WSDL
057: * API.
058: * @author Sun Microsystems, Inc.
059: */
060: public final class WSDLHelper {
061: private static final String WSDL_11 = "http://schemas.xmlsoap.org/wsdl/";
062: private static final String WSDL_20 = "http://www.w3.org/2005/05/wsdl";
063:
064: private static final String TARGET_NS = "targetNamespace";
065: private static final String BINDING = "binding";
066: private static final String BINDING_TYPE = "type";
067: private static final String PORTTYPE = "portType";
068: private static final String SERVICE = "service";
069: private static final String PORT = "port";
070: private static final String NAME = "name";
071: private static final String OPERATION = "operation";
072: private static final String IN_MSG = "input";
073: private static final String OUT_MSG = "output";
074:
075: /** Entry point to WSDL API. */
076: private static WsdlFactory mFactory;
077: /** Reads WSDL definitions. */
078: private static WsdlReader mReader;
079:
080: private static Logger mLog = Logger
081: .getLogger("com.sun.jbi.messaging.util");
082:
083: /** Static initializer for factory and reader objects. */
084: static {
085: mFactory = new WsdlFactory();
086: mReader = mFactory.newWsdlReader();
087: }
088:
089: /** Uses the owner id of the reference to query the appopriate channel. */
090: public static HashMap getOperationsForService(Document serviceDesc,
091: QName serviceName)
092: throws javax.jbi.messaging.MessagingException {
093: HashMap operations;
094: String version;
095:
096: version = getWSDLVersion(serviceDesc);
097:
098: if (version.equals(WSDL_11)) {
099: operations = getOperationsForService11(serviceDesc,
100: serviceName);
101: } else {
102: operations = getOperationsForService20(serviceDesc,
103: serviceName);
104: }
105:
106: mLog.fine(Translator.translate(
107: LocalStringKeys.OPERATIONS_FOUND_FOR_SERVICE,
108: new Object[] { operations.size() + "", serviceName }));
109:
110: return operations;
111: }
112:
113: public static QName[] getInterfacesForService(Document serviceDesc,
114: QName serviceName)
115: throws javax.jbi.messaging.MessagingException {
116: QName[] interfaces;
117: String version;
118:
119: version = getWSDLVersion(serviceDesc);
120:
121: if (version.equals(WSDL_11)) {
122: interfaces = getInterfacesForService11(serviceDesc,
123: serviceName);
124: } else {
125: interfaces = getInterfacesForService20(serviceDesc,
126: serviceName);
127: }
128:
129: mLog.fine(Translator.translate(
130: LocalStringKeys.INTERFACES_FOUND_FOR_SERVICE,
131: new Object[] { interfaces.length + "", serviceName }));
132:
133: return interfaces;
134: }
135:
136: private static HashMap getOperationsForService11(
137: Document serviceDesc, QName serviceName)
138: throws javax.jbi.messaging.MessagingException {
139: HashMap operations = new HashMap();
140: ArrayList portTypes;
141: String namespace;
142: Element definitions;
143:
144: definitions = serviceDesc.getDocumentElement();
145: namespace = getTargetNamespace(serviceDesc);
146:
147: if (namespace != null
148: && serviceName.getNamespaceURI().equals(namespace)) {
149: portTypes = getPortTypes(definitions, serviceName
150: .getLocalPart());
151:
152: for (int i = 0; i < portTypes.size(); i++) {
153: Element portType = (Element) portTypes.get(i);
154: NodeList opList = portType.getElementsByTagNameNS(
155: WSDL_11, OPERATION);
156:
157: for (int j = 0; j < opList.getLength(); j++) {
158: Element op = (Element) opList.item(j);
159: QName name = new QName(namespace, op
160: .getAttribute(NAME));
161: NodeList ins = op.getElementsByTagNameNS(WSDL_11,
162: IN_MSG);
163: NodeList outs = op.getElementsByTagNameNS(WSDL_11,
164: OUT_MSG);
165:
166: // All supported meps must have an in message
167: if (ins.getLength() > 0) {
168: if (outs.getLength() > 0) {
169: operations.put(name.toString(),
170: ExchangePattern.IN_OUT.toString());
171: } else {
172: operations.put(name.toString(),
173: ExchangePattern.IN_ONLY.toString());
174: }
175: }
176: }
177: }
178: } else {
179: mLog.info(Translator.translate(
180: LocalStringKeys.WSDL_NS_MISMATCH,
181: new Object[] { serviceName }));
182: }
183:
184: return operations;
185: }
186:
187: private static HashMap getOperationsForService20(
188: Document serviceDesc, QName serviceName)
189: throws javax.jbi.messaging.MessagingException {
190: HashMap operations = new HashMap();
191: Description defs;
192: Service service;
193:
194: defs = readWSDL(serviceDesc, serviceName);
195:
196: for (int i = 0; i < defs.getServicesLength(); i++) {
197: service = defs.getService(i);
198: if (service.getName().equals(serviceName.getLocalPart())) {
199: Interface interfaze;
200: InterfaceOperation[] iops;
201:
202: interfaze = service.getInterface();
203: iops = interfaze.getExtendedOperations();
204:
205: for (int j = 0; j < iops.length; j++) {
206: operations.put(iops[j].getQualifiedName()
207: .toString(), iops[j].getPattern());
208: }
209: break;
210: }
211: }
212:
213: return operations;
214: }
215:
216: private static QName[] getInterfacesForService11(
217: Document serviceDesc, QName serviceName)
218: throws javax.jbi.messaging.MessagingException {
219: QName[] interfaces;
220: ArrayList portTypes;
221: String namespace;
222: Element definitions;
223:
224: definitions = serviceDesc.getDocumentElement();
225: namespace = getTargetNamespace(serviceDesc);
226:
227: if (namespace != null
228: && serviceName.getNamespaceURI().equals(namespace)) {
229: portTypes = getPortTypes(definitions, serviceName
230: .getLocalPart());
231: interfaces = new QName[portTypes.size()];
232:
233: for (int i = 0; i < portTypes.size(); i++) {
234: Element portType = (Element) portTypes.get(i);
235: String name = portType.getAttribute(NAME);
236:
237: interfaces[i] = new QName(namespace, name);
238: }
239: } else {
240: interfaces = new QName[0];
241: mLog.info(Translator.translate(
242: LocalStringKeys.WSDL_NS_MISMATCH,
243: new Object[] { serviceName }));
244: }
245:
246: return interfaces;
247: }
248:
249: private static QName[] getInterfacesForService20(
250: Document serviceDesc, QName serviceName)
251: throws javax.jbi.messaging.MessagingException {
252: ArrayList interfaces = new ArrayList();
253: Description defs;
254: Service service;
255:
256: defs = readWSDL(serviceDesc, serviceName);
257:
258: for (int i = 0; i < defs.getServicesLength(); i++) {
259: service = defs.getService(i);
260: if (service.getName().equals(serviceName.getLocalPart())) {
261: Interface impl = service.getInterface();
262: Interface[] extended = impl.getExtendedInterfaces();
263:
264: interfaces.add(impl.getQName());
265: for (int j = 0; j < extended.length; j++) {
266: interfaces.add(extended[j].getQName());
267: }
268:
269: break;
270: }
271: }
272:
273: return (QName[]) interfaces.toArray(new QName[0]);
274: }
275:
276: private static String getWSDLVersion(Document description) {
277: return description.getDocumentElement().getNamespaceURI();
278: }
279:
280: private static String getTargetNamespace(Document description) {
281: String namespace = null;
282: Element definitions;
283:
284: definitions = description.getDocumentElement();
285: namespace = definitions.getAttribute(TARGET_NS);
286:
287: return namespace;
288: }
289:
290: private static ArrayList getPortTypes(Element definitions,
291: String serviceName) {
292: NodeList services;
293: NodeList bindings;
294: NodeList portTypes;
295: ArrayList result = new ArrayList();
296: ArrayList bindingNames = new ArrayList();
297: ArrayList portTypeNames = new ArrayList();
298:
299: // get a list of service bindings
300: services = definitions.getElementsByTagNameNS(WSDL_11, SERVICE);
301: for (int i = 0; i < services.getLength(); i++) {
302: Element service = (Element) services.item(i);
303: if (service.getAttribute(NAME).equals(serviceName)) {
304: mLog.finer(Translator.translate(
305: LocalStringKeys.WSDL_11_SERVICE_FOUND,
306: new Object[] { serviceName }));
307:
308: NodeList ports = service.getElementsByTagNameNS(
309: WSDL_11, PORT);
310: for (int j = 0; j < ports.getLength(); j++) {
311: Element port = (Element) ports.item(j);
312: bindingNames.add(getLocalName(port
313: .getAttribute(BINDING)));
314: }
315:
316: mLog.finer(Translator.translate(
317: LocalStringKeys.WSDL_11_BINDINGS_FOUND,
318: new Object[] { bindingNames.size() + "",
319: serviceName }));
320:
321: break;
322: }
323: }
324:
325: // troll through the bindings we found to find port types
326: bindings = definitions.getElementsByTagNameNS(WSDL_11, BINDING);
327: for (int i = 0; i < bindings.getLength(); i++) {
328: Element binding = (Element) bindings.item(i);
329: String name = binding.getAttribute(NAME);
330:
331: // check to see if this is one of our service bindings
332: if (bindingNames.contains(name)) {
333: portTypeNames.add(getLocalName(binding
334: .getAttribute(BINDING_TYPE)));
335: }
336: }
337:
338: mLog.finer(Translator.translate(
339: LocalStringKeys.WSDL_11_PORT_TYPES_FOUND, new Object[] {
340: portTypeNames.size() + "", serviceName }));
341:
342: // troll through port type definitions to find matches
343: portTypes = definitions.getElementsByTagNameNS(WSDL_11,
344: PORTTYPE);
345: for (int i = 0; i < portTypes.getLength(); i++) {
346: Element portType = (Element) portTypes.item(i);
347: String name = portType.getAttribute(NAME);
348:
349: // check to see if this is one of our service bindings
350: if (portTypeNames.contains(name)) {
351: result.add(portType);
352: }
353: }
354:
355: return result;
356: }
357:
358: private static String getLocalName(String qname) {
359: if (qname.indexOf(':') != -1) {
360: qname = qname.split(":")[1];
361: }
362:
363: return qname;
364: }
365:
366: private static Description readWSDL(Document description,
367: QName serviceName)
368: throws javax.jbi.messaging.MessagingException {
369: try {
370: return mReader.readDescription(null, description);
371: } catch (java.io.IOException ioEx) {
372: throw new javax.jbi.messaging.MessagingException(Translator
373: .translate(LocalStringKeys.WSDL_IMPORT_ERROR,
374: new Object[] { serviceName.toString(),
375: ioEx.toString() }));
376: } catch (WsdlException wEx) {
377: throw new javax.jbi.messaging.MessagingException(Translator
378: .translate(LocalStringKeys.WSDL_IMPORT_ERROR,
379: new Object[] { serviceName.toString(),
380: wEx.toString() }));
381: }
382: }
383: }
|