001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: WSDLFile.java 5607 2004-10-13 14:04:22Z sauthieg $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_ws.deployment.api;
025:
026: import java.io.StringWriter;
027: import java.net.MalformedURLException;
028: import java.net.URL;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.Map;
032: import java.util.Vector;
033:
034: import javax.wsdl.Definition;
035: import javax.wsdl.Message;
036: import javax.wsdl.Part;
037: import javax.wsdl.Port;
038: import javax.wsdl.Service;
039: import javax.wsdl.WSDLException;
040: import javax.wsdl.extensions.soap.SOAPAddress;
041: import javax.wsdl.extensions.soap.SOAPBinding;
042: import javax.wsdl.factory.WSDLFactory;
043: import javax.wsdl.xml.WSDLReader;
044: import javax.wsdl.xml.WSDLWriter;
045: import javax.xml.namespace.QName;
046:
047: import org.objectweb.jonas_lib.I18n;
048:
049: /**
050: * Gives methods to get WSDL informations and to validate these one.
051: * @author Xavier Delplanque
052: * @author Guillaume Sauthier
053: */
054: public class WSDLFile {
055:
056: /** list of each ports of each wsdl services */
057: private String name;
058:
059: /** list of each ports of each wsdl services */
060: private List wsdlPorts = null;
061:
062: /** wsdl definition */
063: private Definition def = null;
064:
065: /** verbose mode */
066: private static final boolean VERBOSE = false;
067:
068: /**
069: * Internationalization
070: */
071: private static I18n i18n = I18n.getInstance(WSDLFile.class);
072:
073: /**
074: * Creates a new WSDLFile object.
075: * @param cl ClassLoader to use
076: * @param name wsdl file name
077: * @throws WSDeploymentDescException when a parse error occurs
078: */
079: public WSDLFile(ClassLoader cl, String name)
080: throws WSDeploymentDescException {
081: this (cl.getResource(name), name);
082: }
083:
084: /**
085: * Creates a new WSDLFile object.
086: * @param url URL to load
087: * @param name wsdl file name
088: * @throws WSDeploymentDescException when a parse error occurs
089: */
090: public WSDLFile(URL url, String name)
091: throws WSDeploymentDescException {
092: this .name = name;
093:
094: try {
095: WSDLFactory f = WSDLFactory.newInstance();
096: WSDLReader r = f.newWSDLReader();
097:
098: r.setFeature("javax.wsdl.verbose", VERBOSE); //$NON-NLS-1$
099: r.setFeature("javax.wsdl.importDocuments", true); //$NON-NLS-1$
100:
101: if (url == null) {
102: throw new WSDeploymentDescException(getI18n()
103: .getMessage("WSDLFile.notFound", name)); //$NON-NLS-1$
104: }
105:
106: def = r
107: .readWSDL(url.toExternalForm(), url
108: .toExternalForm());
109: } catch (WSDLException e) {
110: throw new WSDeploymentDescException(getI18n().getMessage(
111: "WSDLFile.WSDLParsingError", name), e); //$NON-NLS-1$
112: }
113:
114: wsdlPorts = new Vector();
115: fillWsdlPorts();
116: }
117:
118: /**
119: * return true if the port identified by portQname is defined in WSDL ports.
120: * @param portQName the port to check.
121: * @return if the gived Qname is contained in the
122: * WSDL.definition.service.port.
123: */
124: public boolean hasPort(QName portQName) {
125: return hasPort(portQName.getLocalPart());
126: }
127:
128: /**
129: * return true if the port identified by portName is defined in WSDL ports.
130: * @param portName the port to check.
131: * @return if the gived port is contained in the
132: * WSDL.definition.service.port.
133: */
134: public boolean hasPort(String portName) {
135: return getPort(portName) != null;
136: }
137:
138: /**
139: * return true if the service identified by srvQName is defined in WSDL
140: * services.
141: * @param srvQName the service to check.
142: * @return true if the given Qname is contained in the
143: * WSDL.definition.service.
144: */
145: public boolean hasService(QName srvQName) {
146: return def.getService(srvQName) != null;
147: }
148:
149: /**
150: * return true if shQName is defined in WSDL services.
151: * @param shQName a soap header Qname that could be defined in the WSDL.
152: * @return true if SOAP Header has been found in WSDL Definition.
153: */
154: public boolean hasSOAPHeader(QName shQName) {
155: Map msgs = def.getMessages();
156:
157: for (Iterator m = msgs.values().iterator(); m.hasNext();) {
158: Message msg = (Message) m.next();
159:
160: if (msg.getQName().getNamespaceURI() == shQName
161: .getNamespaceURI()) {
162: Part p = msg.getPart(shQName.getLocalPart());
163:
164: if (p != null) {
165: return true;
166: }
167: }
168: }
169:
170: return false;
171: }
172:
173: /**
174: * return true if all WSDL ports are defined in portList.
175: * @param portList the ports List to check.
176: * @return true if all WSDL ports are defined in
177: * WSDL.definition.service.port.
178: */
179: public boolean hasPortsIncludedIn(List portList) {
180: return portList.containsAll(wsdlPorts);
181: }
182:
183: /**
184: * return true if the port identified by portQname use a SOAP binding.
185: * @param portQName the port to check.
186: * @return if the port identified by portQname use a SOAP binding. return
187: * false if the portQname is not defined in the WSDL file.
188: */
189: public boolean hasSOAPBinding(QName portQName) {
190: boolean isSoapBinding = false;
191: Port port = getPort(portQName.getLocalPart());
192:
193: // get Port
194: if (port != null) {
195: List ee = port.getBinding().getExtensibilityElements();
196: Iterator eeIt = ee.iterator();
197:
198: while (eeIt.hasNext() && !isSoapBinding) {
199: // verify that it uses a soap binding
200: Object elem = eeIt.next();
201:
202: if (elem != null) {
203: isSoapBinding = elem instanceof SOAPBinding;
204: }
205: }
206: }
207:
208: return isSoapBinding;
209: }
210:
211: /**
212: * return WSDL definition, null if it's undefined.
213: * @return WSDL definition.
214: */
215: public Definition getDefinition() {
216: return def;
217: }
218:
219: /**
220: * return the number of services defined inside the wsdl.
221: * @return the number of services defined inside the wsdl.
222: */
223: public int getNbServices() {
224: return def.getServices().size();
225: }
226:
227: /**
228: * return the QName of the first service, null if no service is defined.
229: * @return the QName of the first service, null if no service is defined.
230: */
231: public QName getServiceQname() {
232: Map srvs = def.getServices();
233: Iterator svcIt = srvs.values().iterator();
234: QName res = null;
235:
236: if (svcIt.hasNext()) {
237: Service svc = (Service) svcIt.next();
238: res = svc.getQName();
239: }
240:
241: return res;
242: }
243:
244: /**
245: * return the given port location, null if the port is undefined.
246: * @param portQName the port QName identifying the port searched.
247: * @return portQname location.
248: * @throws WSDeploymentDescException when port is not found
249: */
250: public URL getLocation(QName portQName)
251: throws WSDeploymentDescException {
252: Port port = getPort(portQName.getLocalPart());
253:
254: // get portQName port
255: if (port != null) {
256: List ee = port.getExtensibilityElements();
257: Iterator eeIt = ee.iterator();
258:
259: while (eeIt.hasNext()) {
260: // find the soap address element
261: Object elem = eeIt.next();
262:
263: if ((elem != null) && elem instanceof SOAPAddress) {
264: try {
265: return new URL(((SOAPAddress) elem)
266: .getLocationURI());
267: } catch (MalformedURLException e) {
268: throw new WSDeploymentDescException(
269: getI18n()
270: .getMessage(
271: "WSDLFile.MalformedPortLocation", portQName)); //$NON-NLS-1$
272: }
273: }
274: }
275: }
276:
277: return null;
278: }
279:
280: /**
281: * set the given port location if it exists.
282: * @param portQName the port to set.
283: * @param loc the port location.
284: */
285: public void setLocation(QName portQName, URL loc) {
286: Port port = getPort(portQName.getLocalPart());
287:
288: if (port != null) {
289: List ee = port.getExtensibilityElements();
290: Iterator eeIt = ee.iterator();
291:
292: while (eeIt.hasNext()) {
293: // find the soap address element
294: Object elem = eeIt.next();
295:
296: if ((elem != null) && elem instanceof SOAPAddress) {
297: ((SOAPAddress) elem).setLocationURI(loc.toString());
298: }
299: }
300: }
301: }
302:
303: /**
304: * Init the wsdlPorts list.
305: */
306: private void fillWsdlPorts() {
307: Map svcs = def.getServices();
308: Iterator svcsIt = svcs.values().iterator();
309:
310: while (svcsIt.hasNext()) {
311: Service svc = (Service) svcsIt.next();
312:
313: if (svc != null) {
314: for (Iterator j = svc.getPorts().values().iterator(); j
315: .hasNext();) {
316: Port p = (Port) j.next();
317: wsdlPorts.add(new QName(def.getTargetNamespace(), p
318: .getName()));
319: }
320: }
321: }
322: }
323:
324: /**
325: * Return the Port identified by portName in the WSDL, return null if it's
326: * not defined inside the wsdl.
327: * @param portName the port name.
328: * @return The port object identified by the name portName
329: */
330: private Port getPort(String portName) {
331: Map svcs = def.getServices();
332: Iterator svcsIt = svcs.values().iterator();
333:
334: while (svcsIt.hasNext()) {
335: Service svc = (Service) svcsIt.next();
336:
337: if (svc != null) {
338: Port port = svc.getPort(portName);
339:
340: // get the port identified by portQname
341: return port;
342: }
343: }
344:
345: return null;
346: }
347:
348: /**
349: * Return wsdl file name
350: * @return wsdl file name
351: */
352: public String getName() {
353: return name;
354: }
355:
356: /**
357: * @return Returns a String representation of this WSDLFile.
358: */
359: public String toString() {
360: StringBuffer sb = new StringBuffer();
361:
362: sb.append("\n" + getClass().getName()); //$NON-NLS-1$
363: sb.append("\ngetName()=" + getName()); //$NON-NLS-1$
364:
365: StringWriter sw = new StringWriter();
366: // Write Definition
367: try {
368: WSDLFactory factory = WSDLFactory.newInstance();
369: WSDLWriter writer = factory.newWSDLWriter();
370:
371: writer.writeWSDL(def, sw);
372:
373: } catch (WSDLException e) {
374: sb.append(getI18n().getMessage("WSDLFile.writeDefError")); //$NON-NLS-1$
375: }
376:
377: sb.append(sw.getBuffer().toString());
378:
379: return sb.toString();
380: }
381:
382: /**
383: * Return true if the 2 objects seems equals. Because the equals() method
384: * doesn't exist on Definition, it's hard to known if 2 Definition are
385: * equals in value. So we just test lists lengths. Use it ONLY in test/debug
386: * case. !!!
387: * @param other the object to compare.
388: * @return true if the 2 objects seems equals.
389: */
390: public boolean equals(Object other) {
391: if (other == null) {
392: return false;
393: }
394:
395: if (!(other instanceof WSDLFile)) {
396: return false;
397: }
398:
399: WSDLFile ref = (WSDLFile) other;
400: Definition odef = ref.getDefinition();
401:
402: if (def.getServices().size() != odef.getServices().size()) {
403: return false;
404: }
405:
406: if (def.getPortTypes().size() != odef.getPortTypes().size()) {
407: return false;
408: }
409:
410: if (def.getMessages().size() != odef.getMessages().size()) {
411: return false;
412: }
413:
414: if (def.getBindings().size() != odef.getBindings().size()) {
415: return false;
416: }
417:
418: // After all theses tests, the 2 objects are equals in value
419: return true;
420: }
421:
422: /**
423: * @return Returns the i18n.
424: */
425: protected static I18n getI18n() {
426: return i18n;
427: }
428: }
|