KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > webservice > server > WSDLRequestHandler


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.webservice.server;
8
9 // $Id: WSDLRequestHandler.java,v 1.1.2.3 2005/04/14 18:44:54 tdiesler Exp $
10

11 import org.jboss.deployment.DeploymentInfo;
12 import org.jboss.logging.Logger;
13 import org.jboss.webservice.metadata.WebserviceDescriptionMetaData;
14 import org.w3c.dom.Attr JavaDoc;
15 import org.w3c.dom.Document JavaDoc;
16 import org.w3c.dom.Element JavaDoc;
17 import org.w3c.dom.Node JavaDoc;
18 import org.w3c.dom.NodeList JavaDoc;
19
20 import javax.wsdl.Definition;
21 import javax.wsdl.WSDLException;
22 import javax.wsdl.factory.WSDLFactory;
23 import javax.wsdl.xml.WSDLWriter;
24 import javax.xml.parsers.DocumentBuilder JavaDoc;
25 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.net.URLClassLoader JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32
33 /**
34  * Handles the delivery of the WSDL and its included artifacts.
35  * It rewrites the include URL's.
36  *
37  * http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3871263#3871263
38  *
39  * For a discussion of this topic.
40  *
41  * @author Thomas.Diesler@jboss.org
42  * @since 23-Mar-2005
43  */

44 public class WSDLRequestHandler
45 {
46    // provide logging
47
private Logger log = Logger.getLogger(WSDLRequestHandler.class);
48
49    private WebserviceDescriptionMetaData wsdMetaData;
50    private DeploymentInfo di;
51
52    public WSDLRequestHandler(WebserviceDescriptionMetaData wsdMetaData, DeploymentInfo di)
53    {
54       this.wsdMetaData = wsdMetaData;
55       this.di = di;
56    }
57
58    /**
59     * Get the WSDL resource for a given resource path
60     * <p/>
61     * Use path value of null to get the root document
62     *
63     * @param resourcePath The wsdl resource to get, can be null for the top level wsdl
64     * @return A wsdl document, or null if it cannot be found
65     */

66    public Document JavaDoc getDocumentForPath(String JavaDoc requestURI, String JavaDoc resourcePath)
67    {
68       Document JavaDoc wsdlDoc = null;
69
70       // Get the root wsdl
71
if (resourcePath == null)
72       {
73          wsdlDoc = getWSDLDocument(wsdMetaData.getWsdlDefinition());
74       }
75       else
76       {
77          String JavaDoc wsdlFile = wsdMetaData.getWsdlFile();
78          String JavaDoc rootDir = wsdlFile.substring(0, wsdlFile.lastIndexOf("/"));
79
80          // Load the resource from the deployment
81
URLClassLoader JavaDoc cl = di.localCl;
82
83          String JavaDoc resource = rootDir + "/" + resourcePath;
84          resource = canonicalize(resource);
85          if (resource.startsWith("WEB-INF/wsdl/") == false && resource.startsWith("META-INF/wsdl/") == false)
86             throw new SecurityException JavaDoc("Cannot access a resource below the wsdl root: " + resource);
87
88          URL JavaDoc resURL = cl.findResource(resource);
89          if (resURL == null)
90             throw new IllegalStateException JavaDoc("Cannot obtain wsdl resource from: " + resource);
91
92          try
93          {
94             DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
95             factory.setNamespaceAware(true);
96             factory.setValidating(false);
97             DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
98             wsdlDoc = builder.parse(resURL.openStream());
99          }
100          catch (Exception JavaDoc e)
101          {
102             throw new IllegalArgumentException JavaDoc("Cannot parse wsdl resource: " + resURL);
103          }
104       }
105
106       modifyImportLocations(requestURI, resourcePath, wsdlDoc.getDocumentElement());
107       return wsdlDoc;
108    }
109
110    /**
111     * Get the Document for a given wsdl definition
112     */

113    private Document JavaDoc getWSDLDocument(Definition wsdlDefinition)
114    {
115       try
116       {
117          WSDLFactory factory = WSDLFactory.newInstance();
118          WSDLWriter wsdlWriter = factory.newWSDLWriter();
119          return wsdlWriter.getDocument(wsdlDefinition);
120       }
121       catch (WSDLException e)
122       {
123          throw new RuntimeException JavaDoc(e);
124       }
125    }
126
127    /**
128     * Modify the location of wsdl and schema imports
129     */

130    private void modifyImportLocations(String JavaDoc requestURI, String JavaDoc resourcePath, Element JavaDoc element)
131    {
132       // map wsdl definition imports
133
NodeList JavaDoc nlist = element.getChildNodes();
134       for (int i = 0; i < nlist.getLength(); i++)
135       {
136          Node JavaDoc childNode = nlist.item(i);
137          if (childNode.getNodeType() == Node.ELEMENT_NODE)
138          {
139             Element JavaDoc childElement = (Element JavaDoc)childNode;
140             String JavaDoc nodeName = childElement.getLocalName();
141             if ("import".equals(nodeName) || "include".equals(nodeName))
142             {
143                Attr JavaDoc locationAttr = childElement.getAttributeNode("schemaLocation");
144                if (locationAttr == null)
145                   locationAttr = childElement.getAttributeNode("location");
146
147                if (locationAttr != null)
148                {
149                   String JavaDoc orgLocation = locationAttr.getNodeValue();
150                   boolean isAbsolute = orgLocation.startsWith("http://") || orgLocation.startsWith("https://");
151                   if (isAbsolute == false && orgLocation.startsWith(requestURI) == false)
152                   {
153                      String JavaDoc resource = orgLocation;
154
155                      // This covers an include from within another include
156
// http://jira.jboss.com/jira/browse/JBWS-153
157
if (resourcePath != null && resourcePath.indexOf("/") > 0)
158                      {
159                         resource = resourcePath.substring(0, resourcePath.lastIndexOf("/") + 1);
160                         resource = resource + orgLocation;
161                      }
162
163                      String JavaDoc newLocation = requestURI + "?wsdl&resource=" + resource;
164                      locationAttr.setNodeValue(newLocation);
165
166                      log.debug("Mapping import from '" + orgLocation + "' to '" + newLocation + "'");
167                   }
168                }
169             }
170             else
171             {
172                modifyImportLocations(requestURI, resourcePath, childElement);
173             }
174          }
175       }
176    }
177
178    /**
179     * Canonicalizes a path, removing .. and . references.
180     */

181    private String JavaDoc canonicalize(String JavaDoc path)
182    {
183       StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(path, "/");
184       List JavaDoc parts = new ArrayList JavaDoc();
185       while (tok.hasMoreTokens())
186       {
187          String JavaDoc t = tok.nextToken();
188          if (".".equals(t))
189          {
190             // do nothing
191
}
192          else if ("..".equals(t) && parts.size() > 0)
193          {
194             // pop off the last one
195
parts.remove(parts.size() - 1);
196          }
197          else
198          {
199             parts.add(t);
200          }
201       }
202
203       StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
204       for (Iterator JavaDoc iter = parts.iterator(); iter.hasNext();)
205       {
206          ret.append((String JavaDoc)iter.next());
207          if (iter.hasNext())
208             ret.append('/');
209       }
210       return ret.toString();
211    }
212
213 }
214
Popular Tags