KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > webservice > WSDLFilePublisher


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

7
8 // $Id: WSDLFilePublisher.java,v 1.6.2.8 2005/03/22 13:21:56 tdiesler Exp $
9
package org.jboss.webservice;
10
11 // $Id: WSDLFilePublisher.java,v 1.6.2.8 2005/03/22 13:21:56 tdiesler Exp $
12

13 import org.dom4j.Document;
14 import org.dom4j.Element;
15 import org.dom4j.io.DOMReader;
16 import org.dom4j.io.SAXReader;
17 import org.jboss.deployment.DeploymentException;
18 import org.jboss.deployment.DeploymentInfo;
19 import org.jboss.logging.Logger;
20 import org.jboss.system.server.ServerConfig;
21 import org.jboss.webservice.metadata.WebserviceDescriptionMetaData;
22 import org.jboss.webservice.metadata.WebservicesMetaData;
23 import org.jboss.util.xml.JBossEntityResolver;
24
25 import javax.wsdl.Definition;
26 import javax.wsdl.Import;
27 import javax.wsdl.factory.WSDLFactory;
28 import javax.wsdl.xml.WSDLWriter;
29 import java.io.File JavaDoc;
30 import java.io.FileOutputStream JavaDoc;
31 import java.io.FileWriter JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.io.OutputStream JavaDoc;
35 import java.net.MalformedURLException JavaDoc;
36 import java.net.URL JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import java.util.List JavaDoc;
39
40 /**
41  * A helper class that publishes the wsdl files and thei imports to the server/data/wsdl directory.
42  *
43  * @author Thomas.Diesler@jboss.org
44  * @since 02-June-2004
45  */

46 public class WSDLFilePublisher
47 {
48    // provide logging
49
private static final Logger log = Logger.getLogger(WSDLFilePublisher.class);
50
51    // The deployment info for the web service archive
52
private DeploymentInfo di;
53    // The expected wsdl location in the deployment
54
private String JavaDoc expLocation;
55
56    public WSDLFilePublisher(DeploymentInfo di)
57    {
58       this.di = di;
59
60       String JavaDoc archiveName = di.shortName;
61       if (archiveName.endsWith(".jar"))
62          expLocation = "META-INF/wsdl/";
63       if (archiveName.endsWith(".war"))
64          expLocation = "WEB-INF/wsdl/";
65
66       if (expLocation == null)
67          throw new IllegalStateException JavaDoc("Can only publish wsdl from WAR or JAR deployment");
68    }
69
70    /**
71     * Publish the deployed wsdl file to the data directory
72     */

73    public void publishWsdlFile(WebservicesMetaData webservices) throws DeploymentException
74    {
75       String JavaDoc deploymentName = di.getCanonicalName();
76
77       // For each webservice-description
78
WebserviceDescriptionMetaData[] wsdArray = webservices.getWebserviceDescriptions();
79       for (int i = 0; i < wsdArray.length; i++)
80       {
81          WebserviceDescriptionMetaData wsd = wsdArray[i];
82          File JavaDoc targetFile = getPublishLocation(deploymentName, wsd);
83          targetFile.getParentFile().mkdirs();
84
85          // Get the wsdl definition and write it to the wsdl publish location
86
try
87          {
88             Definition wsdlDefinition = wsd.getWsdlDefinition();
89             WSDLFactory wsdlFactory = WSDLFactory.newInstance();
90             WSDLWriter wsdlWriter = wsdlFactory.newWSDLWriter();
91             FileWriter JavaDoc fw = new FileWriter JavaDoc(targetFile);
92             wsdlWriter.writeWSDL(wsdlDefinition, fw);
93             fw.close();
94
95             wsd.setWsdlPublishLocation(targetFile.getCanonicalPath());
96             log.info("WSDL published to: " + targetFile.toURL());
97
98             // Process the wsdl imports
99
publishWsdlImports(targetFile.toURL(), wsdlDefinition);
100
101             // Get the dom4j representation and try to publish XMLSchema imports
102
Document document = new DOMReader().read(wsdlWriter.getDocument(wsdlDefinition));
103             publishSchemaImports(targetFile.toURL(), document.getRootElement());
104          }
105          catch (Exception JavaDoc e)
106          {
107             throw new DeploymentException("Cannot publish wsdl to: " + targetFile, e);
108          }
109       }
110    }
111
112    /**
113     * Publish the wsdl imports for a given wsdl definition
114     */

115    private void publishWsdlImports(URL JavaDoc parentURL, Definition parentDefinition) throws Exception JavaDoc
116    {
117       String JavaDoc baseURI = parentURL.toExternalForm();
118
119       Iterator JavaDoc it = parentDefinition.getImports().values().iterator();
120       while (it.hasNext())
121       {
122          List JavaDoc list = (List JavaDoc)it.next();
123          for (int j = 0; j < list.size(); j++)
124          {
125             Import wsdlImport = (Import)list.get(j);
126             String JavaDoc locationURI = wsdlImport.getLocationURI();
127             Definition subdef = wsdlImport.getDefinition();
128
129             // its an external import, don't publish locally
130
if (locationURI.startsWith("http://") == false)
131             {
132                URL JavaDoc wsdlURL = new URL JavaDoc(baseURI.substring(0, baseURI.lastIndexOf("/") + 1) + locationURI);
133                File JavaDoc targetFile = new File JavaDoc(wsdlURL.getPath());
134                targetFile.getParentFile().mkdirs();
135
136                WSDLFactory wsdlFactory = WSDLFactory.newInstance();
137                WSDLWriter wsdlWriter = wsdlFactory.newWSDLWriter();
138                FileWriter JavaDoc fw = new FileWriter JavaDoc(targetFile);
139                wsdlWriter.writeWSDL(subdef, fw);
140                fw.close();
141
142                log.debug("WSDL import published to: " + wsdlURL);
143
144                // recursivly publish imports
145
publishWsdlImports(wsdlURL, subdef);
146
147                // Get the dom4j representation and try to publish XMLSchema imports
148
Document document = new DOMReader().read(wsdlWriter.getDocument(subdef));
149                publishSchemaImports(wsdlURL, document.getRootElement());
150             }
151          }
152       }
153    }
154
155    /**
156     * Publish the schema imports for a given wsdl definition
157     * <p/>
158     * wsdl4j does not have a representation for <xsd:schema> elements
159     */

160    private void publishSchemaImports(URL JavaDoc parentURL, Element element) throws Exception JavaDoc
161    {
162       String JavaDoc baseURI = parentURL.toExternalForm();
163
164       Iterator JavaDoc it = element.elementIterator();
165       while (it.hasNext())
166       {
167          Element childElement = (Element)it.next();
168          if ("import".equals(childElement.getQName().getName()) || "include".equals(childElement.getQName().getName()))
169          {
170             if (childElement.attribute("schemaLocation") != null)
171             {
172                String JavaDoc locationURI = childElement.attribute("schemaLocation").getText();
173                if (locationURI.startsWith("http://") == false)
174                {
175                   URL JavaDoc xsdURL = new URL JavaDoc(baseURI.substring(0, baseURI.lastIndexOf("/") + 1) + locationURI);
176                   File JavaDoc targetFile = new File JavaDoc(xsdURL.getPath());
177                   targetFile.getParentFile().mkdirs();
178
179                   String JavaDoc deploymentName = di.getCanonicalName();
180
181                   // get the resource path
182
int index = baseURI.indexOf(deploymentName);
183                   String JavaDoc resourcePath = baseURI.substring(index + deploymentName.length());
184                   resourcePath = resourcePath.substring(0, resourcePath.lastIndexOf("/"));
185                   if (resourcePath.length() > 0)
186                      resourcePath = resourcePath + "/";
187
188                   resourcePath = expLocation + resourcePath + locationURI;
189                   InputStream JavaDoc is = di.localCl.getResourceAsStream(resourcePath);
190                   if (is == null)
191                      throw new IllegalArgumentException JavaDoc("Cannot find schema import in deployment: " + resourcePath);
192
193                   FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(targetFile);
194                   copyStream(fos, is);
195                   fos.close();
196                   is.close();
197
198                   log.debug("XMLSchema import published to: " + xsdURL);
199
200                   // recursivly publish imports
201
SAXReader saxReader = new SAXReader();
202                   saxReader.setEntityResolver(new JBossEntityResolver());
203
204                   Document subdoc = saxReader.read(xsdURL);
205                   publishSchemaImports(xsdURL, subdoc.getRootElement());
206                }
207             }
208          }
209          else
210          {
211             publishSchemaImports(parentURL, childElement);
212          }
213       }
214    }
215
216    /**
217     * Delete the published wsdl
218     */

219    public void unpublishWsdlFile()
220    {
221       String JavaDoc deploymentDir = (di.parent != null ? di.parent.shortName : di.shortName);
222       String JavaDoc dataDir = System.getProperty(ServerConfig.SERVER_DATA_DIR);
223       File JavaDoc serviceDir = new File JavaDoc(dataDir + "/wsdl/" + deploymentDir);
224       deleteWsdlPublishDirectory(serviceDir);
225    }
226
227    /**
228     * Delete the published wsdl document, traversing down the dir structure
229     */

230    private void deleteWsdlPublishDirectory(File JavaDoc dir)
231    {
232       String JavaDoc[] files = dir.list();
233       for (int i = 0; files != null && i < files.length; i++)
234       {
235          String JavaDoc fileName = files[i];
236          File JavaDoc file = new File JavaDoc(dir + "/" + fileName);
237          if (file.isDirectory())
238          {
239             deleteWsdlPublishDirectory(file);
240          }
241          else
242          {
243             if (file.delete() == false)
244                log.warn("Cannot delete published wsdl document: " + file);
245          }
246       }
247
248       // delete the directory as well
249
dir.delete();
250    }
251
252    /**
253     * Get the file publish location
254     */

255    private File JavaDoc getPublishLocation(String JavaDoc archiveName, WebserviceDescriptionMetaData wsd)
256    {
257       // Only file URLs are supported in <wsdl-publish-location>
258
boolean predefinedLocation = wsd.getWsdlPublishLocation() != null && wsd.getWsdlPublishLocation().startsWith("file:");
259
260       File JavaDoc publishLocation = null;
261       if (predefinedLocation == false)
262       {
263          String JavaDoc dataDir = System.getProperty(ServerConfig.SERVER_DATA_DIR);
264          publishLocation = new File JavaDoc(dataDir + "/wsdl/" + archiveName);
265       }
266       else
267       {
268          try
269          {
270             publishLocation = new File JavaDoc(new URL JavaDoc(wsd.getWsdlPublishLocation()).getPath());
271          }
272          catch (MalformedURLException JavaDoc e)
273          {
274             throw new IllegalArgumentException JavaDoc("Invalid publish location: " + e.getMessage());
275          }
276       }
277
278       // make sure we don't have a leadig '/'
279
String JavaDoc wsdlFile = wsd.getWsdlFile();
280       if (wsdlFile.startsWith("/"))
281          wsdlFile = wsdlFile.substring(1);
282
283       if (wsdlFile.startsWith(expLocation) == false)
284          throw new IllegalArgumentException JavaDoc("The wsdl file should be located in: " + expLocation);
285
286       wsdlFile = wsdlFile.substring(expLocation.length());
287       File JavaDoc wsdlLocation = new File JavaDoc(publishLocation + "/" + wsdlFile);
288       return wsdlLocation;
289    }
290
291    /**
292     * Copies the input stream to the output stream
293     */

294    private void copyStream(OutputStream JavaDoc outputStream, InputStream JavaDoc inputStream) throws IOException JavaDoc
295    {
296       byte[] bytes = new byte[4096];
297       int read = inputStream.read(bytes, 0, 4096);
298       while (read > 0)
299       {
300          outputStream.write(bytes, 0, read);
301          read = inputStream.read(bytes, 0, 4096);
302       }
303    }
304 }
305
Popular Tags