1 19 20 package org.netbeans.modules.websvc.jaxrpc.client.wizard; 21 22 import java.io.*; 23 import java.net.URI ; 24 import java.net.URISyntaxException ; 25 import java.net.URL ; 26 import java.util.*; 27 28 import javax.xml.parsers.SAXParser ; 29 import javax.xml.parsers.SAXParserFactory ; 30 import javax.xml.parsers.ParserConfigurationException ; 31 import javax.xml.transform.*; 32 33 import javax.xml.transform.stream.StreamResult ; 34 import javax.xml.transform.stream.StreamSource ; 35 import org.netbeans.api.java.classpath.ClassPath; 36 import org.netbeans.api.java.project.JavaProjectConstants; 37 import org.netbeans.api.progress.ProgressHandle; 38 import org.netbeans.api.project.ProjectUtils; 39 import org.netbeans.api.project.SourceGroup; 40 import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; 41 import org.netbeans.modules.websvc.api.client.ClientStubDescriptor; 42 import org.netbeans.modules.websvc.jaxrpc.PortInformation; 43 import org.netbeans.modules.websvc.jaxrpc.Utilities; 44 import org.netbeans.modules.websvc.wsdl.WsdlDataObject; 45 import org.xml.sax.Attributes ; 46 import org.xml.sax.InputSource ; 47 import org.xml.sax.SAXException ; 48 import org.xml.sax.helpers.DefaultHandler ; 49 50 import org.openide.ErrorManager; 51 import org.openide.NotifyDescriptor; 52 import org.openide.DialogDisplayer; 53 import org.openide.execution.ExecutorTask; 54 import org.openide.util.Lookup; 55 import org.openide.util.NbBundle; 56 import org.openide.filesystems.FileLock; 57 import org.openide.filesystems.FileObject; 58 import org.openide.filesystems.FileSystem; 59 import org.openide.filesystems.FileUtil; 60 import org.openide.filesystems.FileAlreadyLockedException; 61 62 import org.netbeans.api.project.Project; 63 import org.netbeans.spi.project.support.ant.GeneratedFilesHelper; 64 import org.apache.tools.ant.module.api.support.ActionUtils; 65 66 import org.netbeans.modules.j2ee.dd.api.web.DDProvider; 67 import org.netbeans.modules.j2ee.dd.api.common.ServiceRef; 68 import org.netbeans.modules.j2ee.dd.api.common.PortComponentRef; 69 import org.netbeans.modules.j2ee.dd.api.common.RootInterface; 70 import org.netbeans.modules.j2ee.dd.api.common.CommonDDBean; 71 import org.netbeans.modules.j2ee.dd.api.common.NameAlreadyUsedException; 72 import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; 73 74 import org.netbeans.modules.websvc.api.registry.WebServicesRegistryView; 75 import org.netbeans.modules.websvc.api.client.WebServicesClientSupport; 76 import org.netbeans.modules.websvc.api.webservices.StubDescriptor; 77 import org.netbeans.modules.websvc.wsdl.config.WsCompileConfigDataObject; 78 import org.netbeans.modules.websvc.wsdl.config.PortInformationHandler; 79 80 81 85 public class ClientBuilder { 86 87 private static final String TEMPLATE_BASE = "/org/netbeans/modules/websvc/core/client/resources/"; 89 private Project project; 91 private WebServicesClientSupport projectSupport; 92 private FileObject wsdlSource; 93 private String packageName; 94 private String sourceUrl; 95 private ClientStubDescriptor stubDescriptor; 96 97 private FileObject wsdlTarget; 99 private FileObject configFile; 100 private List importedWsdlList; 101 102 public ClientBuilder(Project project, WebServicesClientSupport support, FileObject wsdlSource, String packageName, String sourceUrl, ClientStubDescriptor sd) { 103 this.project = project; 104 this.projectSupport = support; 105 this.wsdlSource = wsdlSource; 106 this.packageName = packageName; 107 this.sourceUrl = sourceUrl; 108 this.stubDescriptor = sd; 109 importedWsdlList = new ArrayList(); 110 } 111 112 118 private static String classFromName(final String name) { 119 String result = name; 120 121 if(name.length() > 0 && !Character.isUpperCase(name.charAt(0))) { 122 StringBuffer buf = new StringBuffer (name); 123 buf.setCharAt(0, Character.toUpperCase(name.charAt(0))); 124 result = buf.toString(); 125 } 126 127 return result; 128 } 129 130 public Set generate(final ProgressHandle handle) { 131 Set result = Collections.EMPTY_SET; 132 133 try { 134 SourceGroup[] sourceGroups = ProjectUtils.getSources(project).getSourceGroups( 135 JavaProjectConstants.SOURCES_TYPE_JAVA); 136 137 ClassPath classPath = ClassPath.getClassPath(sourceGroups[0].getRootFolder(),ClassPath.COMPILE); 138 FileObject wscompileFO = classPath.findResource("com/sun/xml/rpc/tools/ant/Wscompile.class"); if (wscompileFO==null) return result; 140 141 handle.progress(NbBundle.getMessage(ClientBuilder.class, "MSG_WizAddToRegistry")); 142 143 146 WebServicesRegistryView registryView = (WebServicesRegistryView) Lookup.getDefault().lookup(WebServicesRegistryView.class); 148 registryView.registerService(wsdlSource, true); 149 150 151 handle.progress(NbBundle.getMessage(ClientBuilder.class, "MSG_WizParsingWSDL"),20); 152 153 PortInformationHandler handler = new PortInformationHandler(); 154 try { 155 parse (wsdlSource, handler); 156 } catch(ParserConfigurationException ex) { 157 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 158 String mes = NbBundle.getMessage(ClientBuilder.class, "ERR_WsdlParseFailure", ex.getMessage()); NotifyDescriptor desc = new NotifyDescriptor.Message(mes, NotifyDescriptor.Message.ERROR_MESSAGE); 160 DialogDisplayer.getDefault().notify(desc); 161 return result; 162 } catch(SAXException ex) { 163 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 164 String mes = NbBundle.getMessage(ClientBuilder.class, "ERR_WsdlParseFailure", ex.getMessage()); NotifyDescriptor desc = new NotifyDescriptor.Message(mes, NotifyDescriptor.Message.ERROR_MESSAGE); 166 DialogDisplayer.getDefault().notify(desc); 167 return result; 168 } 169 170 handle.progress(NbBundle.getMessage(ClientBuilder.class, "MSG_WizCopyingWSDL"),35); 171 172 final FileObject wsdlFolder = projectSupport.getWsdlFolder(true); 174 175 FileObject target = wsdlFolder.getFileObject(wsdlSource.getName(), WsdlDataObject.WSDL_EXTENSION); 177 if(target != null) { 178 target.delete(); 179 } 180 target = wsdlFolder.getFileObject(wsdlSource.getName() + WsCompileConfigDataObject.WSCOMPILE_CONFIG_FILENAME_SUFFIX, "xml"); if(target != null) { 182 target.delete(); 183 } 184 185 if (handler.isServiceNameConflict()) { 187 wsdlTarget = generateWSDL(wsdlFolder, wsdlSource.getName() , new StreamSource (wsdlSource.getInputStream())); 188 } else { 189 wsdlTarget = wsdlSource.copy(wsdlFolder, wsdlSource.getName(), WsdlDataObject.WSDL_EXTENSION); 190 } 191 192 handle.progress(NbBundle.getMessage(ClientBuilder.class, "MSG_WizCopyingSchemas"),40); 194 copyImportedSchemas(wsdlSource.getParent(),wsdlFolder,wsdlTarget); 195 196 handle.progress(NbBundle.getMessage(ClientBuilder.class, "MSG_WizProcessingWSDL"),45); 197 198 File wsdlAsFile = FileUtil.toFile(wsdlTarget); 200 201 if(wsdlAsFile != null) { 202 final String wsdlConfigEntry = "\t<wsdl location=\"file:@CONFIG_ABSOLUTE_PATH@/" + wsdlAsFile.getName() + "\" packageName=\"" + packageName + "\"/>"; FileSystem fs = wsdlFolder.getFileSystem(); 204 fs.runAtomicAction(new FileSystem.AtomicAction() { 205 public void run() throws IOException { 206 configFile = wsdlFolder.createData(wsdlTarget.getName() + WsCompileConfigDataObject.WSCOMPILE_CONFIG_FILENAME_SUFFIX, "xml"); FileLock configLock = configFile.lock(); 208 209 try { 211 PrintWriter configWriter = new PrintWriter(configFile.getOutputStream(configLock)); 212 213 try { 214 configWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); configWriter.println("<configuration xmlns=\"http://java.sun.com/xml/ns/jax-rpc/ri/config\">"); configWriter.println(wsdlConfigEntry); 217 configWriter.println("</configuration>"); } finally { 219 configWriter.close(); 220 } 221 } finally { 222 configLock.releaseLock(); 223 } 224 } 225 }); 226 } else { 227 String mes = NbBundle.getMessage(ClientBuilder.class, "ERR_CannotOpenWsdlFile", wsdlTarget.getNameExt()); NotifyDescriptor desc = new NotifyDescriptor.Message(mes, NotifyDescriptor.Message.ERROR_MESSAGE); 230 DialogDisplayer.getDefault().notify(desc); 231 return result; 232 } 233 234 240 247 253 List wsdlLocationsList = handler.getImportedSchemas(); 255 if (wsdlLocationsList.size()>0 && handler.getServices().size()>0 && handler.getEntirePortList().size()>0) { 256 handler = new PortInformationHandler(handler.getTargetNamespace(),handler.getServices(),handler.getEntirePortList(),handler.getBindings(), wsdlLocationsList); 257 Iterator it = wsdlLocationsList.iterator(); 258 while (it.hasNext()) { 259 String wsdlLocation = (String )it.next(); 260 try { 261 if (wsdlLocation.indexOf("/")<0) { FileObject wsdlFo = wsdlFolder.getFileObject(wsdlLocation); 263 if (wsdlFo!=null && importedWsdlList.contains(wsdlFo)) 264 parse (wsdlFo, handler); 265 } else { URL wsdlURL = new URL (wsdlLocation); 267 parse (wsdlURL, handler); 268 } 269 270 } catch(ParserConfigurationException ex) { 271 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 272 String mes = NbBundle.getMessage(ClientBuilder.class, "ERR_WsdlParseFailure", ex.getMessage()); NotifyDescriptor desc = new NotifyDescriptor.Message(mes, NotifyDescriptor.Message.ERROR_MESSAGE); 274 DialogDisplayer.getDefault().notify(desc); 275 return result; 276 } catch(SAXException ex) { 277 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 278 String mes = NbBundle.getMessage(ClientBuilder.class, "ERR_WsdlParseFailure", ex.getMessage()); NotifyDescriptor desc = new NotifyDescriptor.Message(mes, NotifyDescriptor.Message.ERROR_MESSAGE); 280 DialogDisplayer.getDefault().notify(desc); 281 return result; 282 } 283 } 284 } 285 286 handle.progress(50); 287 288 if (ClientStubDescriptor.JSR109_CLIENT_STUB.equals(stubDescriptor.getName())) { 290 306 handle.progress(NbBundle.getMessage(ClientBuilder.class, "MSG_WizUpdatingDD")); 307 308 J2eeModuleProvider j2eeMP = (J2eeModuleProvider) project.getLookup ().lookup(J2eeModuleProvider.class); 310 j2eeMP.getConfigSupport().ensureConfigurationReady(); 311 312 String prefix = J2eeModule.WAR.equals(j2eeMP.getJ2eeModule().getModuleType()) 315 ? "WEB-INF/" : "META-INF/"; 318 322 326 String [] serviceNames = handler.getServiceNames(); 328 for(int si = 0; si < serviceNames.length; si++) { 329 String serviceName = serviceNames[si]; 330 331 PortInformation.ServiceInfo serviceInfo = handler.getServiceInfo(serviceName); 332 List portList = serviceInfo.getPorts(); 333 334 if (handler.isServiceNameConflict()) serviceName+="_Service"; try { 336 serviceName = Utilities.removeSpacesFromServiceName(serviceName); 337 String ddServiceName = "service/" + serviceName; String fullyQualifiedServiceName = packageName + "." + classFromName(serviceName); String relativeWsdlPath = prefix + "wsdl/" + wsdlTarget.getNameExt(); String relativeMappingPath = prefix + wsdlTarget.getName() + "-mapping.xml"; 342 List seiList = new ArrayList(); 343 344 for (int pi = 0; pi < portList.size(); pi++) { 345 PortInformation.PortInfo portInfo = (PortInformation.PortInfo) portList.get(pi); 346 String portTypeName = portInfo.getPortType(); 347 if (portTypeName!=null) seiList.add(packageName + "." + classFromName(portTypeName)); } 349 350 String [] portInfoSEI = new String [seiList.size()]; 351 seiList.toArray(portInfoSEI); 352 353 projectSupport.addServiceClientReference(ddServiceName, 354 fullyQualifiedServiceName, 355 relativeWsdlPath, 356 relativeMappingPath, 357 portInfoSEI); 358 359 } catch(ClassCastException ex) { 394 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 396 } 397 } 398 399 } 406 407 413 handle.progress(NbBundle.getMessage(ClientBuilder.class, "MSG_WizUpdatingBuildScript"),65); 414 Set features = handler.getWscompileFeatures(); 415 String [] wscompileFeatures = new String [features.size()]; 416 features.toArray(wscompileFeatures); 417 projectSupport.addServiceClient(wsdlTarget.getName(), packageName, sourceUrl, configFile, stubDescriptor, wscompileFeatures); 418 419 handle.progress(NbBundle.getMessage(ClientBuilder.class, "MSG_WizGenerateClient"),80); 421 422 String targetName = wsdlTarget.getName() + "-client-wscompile"; FileObject buildFO = findBuildXml(); 424 if(buildFO != null) { 425 ExecutorTask task = ActionUtils.runTarget(buildFO, new String [] { targetName }, null); 426 task.waitFinished(); 427 if(task.result() != 0){ 428 String mes = NbBundle.getMessage(ClientBuilder.class, "ERR_WsCompileFailed"); NotifyDescriptor desc = new NotifyDescriptor.Message(mes, NotifyDescriptor.Message.ERROR_MESSAGE); 430 DialogDisplayer.getDefault().notify(desc); 431 } 432 } else { 433 String mes = NbBundle.getMessage(ClientBuilder.class, "ERR_NoBuildScript"); NotifyDescriptor desc = new NotifyDescriptor.Message(mes, NotifyDescriptor.Message.ERROR_MESSAGE); 435 DialogDisplayer.getDefault().notify(desc); 436 } 437 438 project.getProjectDirectory().refresh(); 439 } catch(FileAlreadyLockedException ex) { 440 ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, ex); 442 } catch(IOException ex) { 443 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 444 String mes = NbBundle.getMessage(ClientBuilder.class, "ERR_ClientIOError", wsdlSource.getNameExt(), ex.getMessage()); NotifyDescriptor desc = new NotifyDescriptor.Message(mes, NotifyDescriptor.Message.ERROR_MESSAGE); 446 DialogDisplayer.getDefault().notify(desc); 447 } finally { 448 handle.progress(95); 449 } 450 451 return result; 452 } 453 454 private FileObject findBuildXml() { 455 return project.getProjectDirectory().getFileObject(GeneratedFilesHelper.BUILD_XML_PATH); 456 } 457 458 459 461 static List getSchemaNames(FileObject fo, boolean fromWsdl) { 462 List result = null; 463 try { 464 SAXParserFactory factory = SAXParserFactory.newInstance(); 465 factory.setNamespaceAware(true); 466 SAXParser saxParser = factory.newSAXParser(); 467 ImportsHandler handler= (fromWsdl?(ImportsHandler)new WsdlImportsHandler():(ImportsHandler)new SchemaImportsHandler()); 468 saxParser.parse(new InputSource (fo.getInputStream()), (DefaultHandler )handler); 469 result = handler.getSchemaNames(); 470 } catch(ParserConfigurationException ex) { 471 } catch(SAXException ex) { 473 } catch(IOException ex) { 475 } 477 478 return result; 479 } 480 481 private static interface ImportsHandler { 482 public List getSchemaNames(); 483 } 484 485 private static class WsdlImportsHandler extends DefaultHandler implements ImportsHandler { 486 487 private static final String W3C_WSDL_SCHEMA = "http://schemas.xmlsoap.org/wsdl"; private static final String W3C_WSDL_SCHEMA_SLASH = "http://schemas.xmlsoap.org/wsdl/"; 490 private List schemaNames; 491 492 private boolean insideSchema; 493 494 WsdlImportsHandler() { 495 schemaNames = new ArrayList(); 496 } 497 498 public void startElement(String uri, String localname, String qname, Attributes attributes) throws SAXException { 499 if(W3C_WSDL_SCHEMA.equals(uri) || W3C_WSDL_SCHEMA_SLASH.equals(uri)) { 500 if("types".equals(localname)) { insideSchema=true; 502 } 503 if("import".equals(localname)) { String wsdlLocation = attributes.getValue("location"); if (wsdlLocation!=null && wsdlLocation.indexOf("/")<0 && wsdlLocation.endsWith(".wsdl")) { schemaNames.add(wsdlLocation); 507 } 508 } 509 } 510 if(insideSchema && "import".equals(localname)) { String schemaLocation = attributes.getValue("schemaLocation"); if (schemaLocation!=null && schemaLocation.indexOf("/")<0 && schemaLocation.endsWith(".xsd")) { schemaNames.add(schemaLocation); 514 } 515 } 516 } 517 518 public void endElement(String uri, String localname, String qname) throws SAXException { 519 if(W3C_WSDL_SCHEMA.equals(uri) || W3C_WSDL_SCHEMA_SLASH.equals(uri)) { 520 if("types".equals(localname)) { insideSchema=false; 522 } 523 } 524 } 525 526 public List getSchemaNames() { 527 return schemaNames; 528 } 529 } 530 531 private static class SchemaImportsHandler extends DefaultHandler implements ImportsHandler { 532 533 private List schemaNames; 534 535 SchemaImportsHandler() { 536 schemaNames = new ArrayList(); 537 } 538 539 public void startElement(String uri, String localname, String qname, Attributes attributes) throws SAXException { 540 if("import".equals(localname)) { String schemaLocation = attributes.getValue("schemaLocation"); if (schemaLocation!=null && schemaLocation.indexOf("/")<0 && schemaLocation.endsWith(".xsd")) { schemaNames.add(schemaLocation); 544 } 545 } 546 } 547 548 public List getSchemaNames() { 549 return schemaNames; 550 } 551 } 552 553 555 private synchronized void copyImportedSchemas(FileObject resourceFolder, FileObject targetFolder, FileObject fo) throws IOException { 556 List schemaNames = getSchemaNames(fo,"wsdl".equals(fo.getExt())); Iterator it = schemaNames.iterator(); 558 while (it.hasNext()) { 559 String schemaName = (String )it.next(); 560 FileObject schemaFile = resourceFolder.getFileObject(schemaName); 561 if (schemaFile!=null) { 562 FileObject target = targetFolder.getFileObject(schemaFile.getName(),schemaFile.getExt()); 563 if(target != null) { 564 FileLock lock = target.lock(); 565 if (lock!=null) 566 try { 567 target.delete(lock); 568 } finally { 569 lock.releaseLock(); 570 } 571 } 572 FileObject copy = schemaFile.copy(targetFolder,schemaFile.getName(),schemaFile.getExt()); 574 if ("wsdl".equals(schemaFile.getExt())) { importedWsdlList.add(copy); 576 } 577 copyImportedSchemas(resourceFolder, targetFolder, copy); 578 } else { 579 DialogDisplayer.getDefault().notify( 580 new NotifyDescriptor.Message(NbBundle.getMessage(ClientBuilder.class,"ERR_FileNotFound",schemaName,resourceFolder.getPath()), 581 NotifyDescriptor.ERROR_MESSAGE)); 582 break; 583 } 584 } 585 } 586 587 private void parse(FileObject fo, PortInformationHandler handler) throws ParserConfigurationException , SAXException , IOException { 588 SAXParserFactory factory = SAXParserFactory.newInstance(); 589 factory.setNamespaceAware(true); 590 SAXParser saxParser = factory.newSAXParser(); 591 saxParser.parse(fo.getInputStream(), handler); 592 } 593 594 private void parse(URL url, PortInformationHandler handler) throws ParserConfigurationException , SAXException , IOException { 595 SAXParserFactory factory = SAXParserFactory.newInstance(); 596 factory.setNamespaceAware(true); 597 SAXParser saxParser = factory.newSAXParser(); 598 try { 599 saxParser.parse(url.openConnection().getInputStream(), handler); 600 } catch (java.net.UnknownHostException ex) { 601 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 602 String mes = NbBundle.getMessage(ClientBuilder.class, "ERR_UnknownHost", ex.getMessage()); NotifyDescriptor desc = new NotifyDescriptor.Message(mes, NotifyDescriptor.Message.ERROR_MESSAGE); 604 DialogDisplayer.getDefault().notify(desc); 605 } 606 } 607 608 private FileObject generateWSDL(FileObject folder, String wsdlName, StreamSource source) throws IOException 609 { 610 FileObject wsdlFile = folder.createData(wsdlName, "wsdl"); FileLock fl = null; 612 OutputStream os = null; 613 try { 614 fl = wsdlFile.lock(); 615 os = new BufferedOutputStream(wsdlFile.getOutputStream(fl)); 616 Transformer transformer = getTransformer(); 617 transformer.transform(source, new StreamResult (os)); 618 os.close(); 619 } 620 catch(TransformerConfigurationException tce) { 621 IOException ioe = new IOException(); 622 ioe.initCause(tce); 623 throw ioe; 624 } 625 catch(TransformerException te) { 626 IOException ioe = new IOException(); 627 ioe.initCause(te); 628 throw ioe; 629 } 630 finally { 631 if(os != null) { 632 os.close(); 633 } 634 if(fl != null) { 635 fl.releaseLock(); 636 } 637 } 638 return wsdlFile; 639 } 640 641 private Transformer getTransformer() throws TransformerConfigurationException { 642 InputStream is = new BufferedInputStream(getClass().getResourceAsStream(TEMPLATE_BASE+"WSDL.xml")); TransformerFactory transFactory = TransformerFactory.newInstance(); 644 transFactory.setURIResolver(new URIResolver() { 645 public Source resolve(String href, String base) 646 throws TransformerException { 647 InputStream is = getClass().getResourceAsStream( 648 TEMPLATE_BASE + href.substring(href.lastIndexOf('/')+1)); 649 if (is == null) { 650 return null; 651 } 652 653 return new StreamSource (is); 654 } 655 }); 656 Templates t = transFactory.newTemplates(new StreamSource (is)); 657 return t.newTransformer(); 658 } 659 660 } 661 | Popular Tags |