1 7 8 package org.jboss.webservice; 10 11 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 ; 30 import java.io.FileOutputStream ; 31 import java.io.FileWriter ; 32 import java.io.IOException ; 33 import java.io.InputStream ; 34 import java.io.OutputStream ; 35 import java.net.MalformedURLException ; 36 import java.net.URL ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 40 46 public class WSDLFilePublisher 47 { 48 private static final Logger log = Logger.getLogger(WSDLFilePublisher.class); 50 51 private DeploymentInfo di; 53 private String expLocation; 55 56 public WSDLFilePublisher(DeploymentInfo di) 57 { 58 this.di = di; 59 60 String 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 ("Can only publish wsdl from WAR or JAR deployment"); 68 } 69 70 73 public void publishWsdlFile(WebservicesMetaData webservices) throws DeploymentException 74 { 75 String deploymentName = di.getCanonicalName(); 76 77 WebserviceDescriptionMetaData[] wsdArray = webservices.getWebserviceDescriptions(); 79 for (int i = 0; i < wsdArray.length; i++) 80 { 81 WebserviceDescriptionMetaData wsd = wsdArray[i]; 82 File targetFile = getPublishLocation(deploymentName, wsd); 83 targetFile.getParentFile().mkdirs(); 84 85 try 87 { 88 Definition wsdlDefinition = wsd.getWsdlDefinition(); 89 WSDLFactory wsdlFactory = WSDLFactory.newInstance(); 90 WSDLWriter wsdlWriter = wsdlFactory.newWSDLWriter(); 91 FileWriter fw = new FileWriter (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 publishWsdlImports(targetFile.toURL(), wsdlDefinition); 100 101 Document document = new DOMReader().read(wsdlWriter.getDocument(wsdlDefinition)); 103 publishSchemaImports(targetFile.toURL(), document.getRootElement()); 104 } 105 catch (Exception e) 106 { 107 throw new DeploymentException("Cannot publish wsdl to: " + targetFile, e); 108 } 109 } 110 } 111 112 115 private void publishWsdlImports(URL parentURL, Definition parentDefinition) throws Exception 116 { 117 String baseURI = parentURL.toExternalForm(); 118 119 Iterator it = parentDefinition.getImports().values().iterator(); 120 while (it.hasNext()) 121 { 122 List list = (List )it.next(); 123 for (int j = 0; j < list.size(); j++) 124 { 125 Import wsdlImport = (Import)list.get(j); 126 String locationURI = wsdlImport.getLocationURI(); 127 Definition subdef = wsdlImport.getDefinition(); 128 129 if (locationURI.startsWith("http://") == false) 131 { 132 URL wsdlURL = new URL (baseURI.substring(0, baseURI.lastIndexOf("/") + 1) + locationURI); 133 File targetFile = new File (wsdlURL.getPath()); 134 targetFile.getParentFile().mkdirs(); 135 136 WSDLFactory wsdlFactory = WSDLFactory.newInstance(); 137 WSDLWriter wsdlWriter = wsdlFactory.newWSDLWriter(); 138 FileWriter fw = new FileWriter (targetFile); 139 wsdlWriter.writeWSDL(subdef, fw); 140 fw.close(); 141 142 log.debug("WSDL import published to: " + wsdlURL); 143 144 publishWsdlImports(wsdlURL, subdef); 146 147 Document document = new DOMReader().read(wsdlWriter.getDocument(subdef)); 149 publishSchemaImports(wsdlURL, document.getRootElement()); 150 } 151 } 152 } 153 } 154 155 160 private void publishSchemaImports(URL parentURL, Element element) throws Exception 161 { 162 String baseURI = parentURL.toExternalForm(); 163 164 Iterator 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 locationURI = childElement.attribute("schemaLocation").getText(); 173 if (locationURI.startsWith("http://") == false) 174 { 175 URL xsdURL = new URL (baseURI.substring(0, baseURI.lastIndexOf("/") + 1) + locationURI); 176 File targetFile = new File (xsdURL.getPath()); 177 targetFile.getParentFile().mkdirs(); 178 179 String deploymentName = di.getCanonicalName(); 180 181 int index = baseURI.indexOf(deploymentName); 183 String 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 is = di.localCl.getResourceAsStream(resourcePath); 190 if (is == null) 191 throw new IllegalArgumentException ("Cannot find schema import in deployment: " + resourcePath); 192 193 FileOutputStream fos = new FileOutputStream (targetFile); 194 copyStream(fos, is); 195 fos.close(); 196 is.close(); 197 198 log.debug("XMLSchema import published to: " + xsdURL); 199 200 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 219 public void unpublishWsdlFile() 220 { 221 String deploymentDir = (di.parent != null ? di.parent.shortName : di.shortName); 222 String dataDir = System.getProperty(ServerConfig.SERVER_DATA_DIR); 223 File serviceDir = new File (dataDir + "/wsdl/" + deploymentDir); 224 deleteWsdlPublishDirectory(serviceDir); 225 } 226 227 230 private void deleteWsdlPublishDirectory(File dir) 231 { 232 String [] files = dir.list(); 233 for (int i = 0; files != null && i < files.length; i++) 234 { 235 String fileName = files[i]; 236 File file = new File (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 dir.delete(); 250 } 251 252 255 private File getPublishLocation(String archiveName, WebserviceDescriptionMetaData wsd) 256 { 257 boolean predefinedLocation = wsd.getWsdlPublishLocation() != null && wsd.getWsdlPublishLocation().startsWith("file:"); 259 260 File publishLocation = null; 261 if (predefinedLocation == false) 262 { 263 String dataDir = System.getProperty(ServerConfig.SERVER_DATA_DIR); 264 publishLocation = new File (dataDir + "/wsdl/" + archiveName); 265 } 266 else 267 { 268 try 269 { 270 publishLocation = new File (new URL (wsd.getWsdlPublishLocation()).getPath()); 271 } 272 catch (MalformedURLException e) 273 { 274 throw new IllegalArgumentException ("Invalid publish location: " + e.getMessage()); 275 } 276 } 277 278 String wsdlFile = wsd.getWsdlFile(); 280 if (wsdlFile.startsWith("/")) 281 wsdlFile = wsdlFile.substring(1); 282 283 if (wsdlFile.startsWith(expLocation) == false) 284 throw new IllegalArgumentException ("The wsdl file should be located in: " + expLocation); 285 286 wsdlFile = wsdlFile.substring(expLocation.length()); 287 File wsdlLocation = new File (publishLocation + "/" + wsdlFile); 288 return wsdlLocation; 289 } 290 291 294 private void copyStream(OutputStream outputStream, InputStream inputStream) throws IOException 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 |