1 22 23 package org.objectweb.petals.tools.jbicommon.descriptor; 25 import java.io.ByteArrayOutputStream ; 26 import java.io.File ; 27 import java.io.FileInputStream ; 28 import java.io.FileNotFoundException ; 29 import java.io.IOException ; 30 import java.io.InputStream ; 31 import java.net.URI ; 32 import java.net.URISyntaxException ; 33 import java.net.URL ; 34 import java.util.ArrayList ; 35 import java.util.HashMap ; 36 import java.util.List ; 37 import java.util.Map ; 38 import java.util.logging.Level ; 39 import java.util.logging.Logger ; 40 41 import javax.xml.XMLConstants ; 42 import javax.xml.parsers.DocumentBuilder ; 43 import javax.xml.parsers.DocumentBuilderFactory ; 44 import javax.xml.parsers.ParserConfigurationException ; 45 import javax.xml.transform.stream.StreamSource ; 46 import javax.xml.validation.Schema ; 47 import javax.xml.validation.SchemaFactory ; 48 import javax.xml.validation.Validator ; 49 50 import org.objectweb.petals.tools.jbicommon.util.FileUtil; 51 import org.objectweb.petals.tools.jbicommon.util.XMLUtil; 52 import org.w3c.dom.Document ; 53 import org.w3c.dom.DocumentFragment ; 54 import org.w3c.dom.Element ; 55 import org.w3c.dom.Node ; 56 import org.xml.sax.ErrorHandler ; 57 import org.xml.sax.SAXException ; 58 import org.xml.sax.SAXParseException ; 59 60 68 public class JBIDescriptorBuilder { 69 73 private class JbiXmlErrorHandler implements ErrorHandler { 74 75 78 public JbiXmlErrorHandler() { super(); 80 } 81 82 85 public void error(final SAXParseException se) throws SAXException { 86 log.log(Level.SEVERE, se.getMessage(), se); 87 throw se; 88 } 89 90 93 public void fatalError(final SAXParseException se) throws SAXException { 94 log.log(Level.SEVERE, se.getMessage(), se); 95 throw se; 96 } 97 98 101 public void warning(final SAXParseException e) throws SAXException { 102 log.log(Level.WARNING, e.getMessage(), e); 103 } 104 105 } 106 107 public static final String JBI_XSD = "jbi.xsd"; 108 109 112 public static final String JBI_DESCRIPTOR_RESOURCE = "META-INF" 113 + File.separator + "jbi.xml"; 114 115 118 public static final String JBI_SCHEMA_RESOURCE = "schema" + File.separator 119 + JBI_XSD; 120 121 private static final String BOOTSTRAP_CLASS_NAME_ELEM_NAME = "bootstrap-class-name"; 122 123 private static final String BOOTSTRAP_CLASS_PATH_ELEM_NAME = "bootstrap-class-path"; 124 125 private static final String COMPONENT_CLASS_NAME_ELEM_NAME = "component-class-name"; 126 127 private static final String COMPONENT_CLASS_PATH_ELEM_NAME = "component-class-path"; 128 129 private static final String ENDPOINT_ATTR_NAME = "endpoint-name"; 130 131 private static final String IDENTIFICATION_ELEM_NAME = "identification"; 132 133 private static final String INTERFACE_ATTR_NAME = "interface-name"; 134 135 private static final String INVALID_EXTENSION_NAMESPACE = "Invalid namespace for jbi extensions "; 136 137 140 private static Schema schema = null; 141 142 private static final String SERVICE_ATTR_NAME = "service-name"; 143 144 private static final String SHARED_LIBRARY_ELEM_NAME = "shared-library"; 145 146 149 private static final String VERSION_ATTR_NAME = "version"; 150 151 154 private URI jbiXmlUri; 155 156 159 private Logger log; 161 164 private Document source; 165 166 private final JbiXmlErrorHandler xmlErrorHandler = new JbiXmlErrorHandler(); 167 168 172 public JBIDescriptorBuilder(final URI sourceUri, final Logger logger) { 173 if (sourceUri == null) { 174 throw new IllegalArgumentException ( 175 "DescriptorBuilder: invalid source URI argument."); 176 } 177 178 this.jbiXmlUri = sourceUri; 179 log = logger; 180 } 181 182 191 public JBIDescriptor build() throws JBIDescriptorException { 192 193 if (source == null) { 195 196 if (!validateJbiXml(jbiXmlUri)) { 198 throw new JBIDescriptorException( 199 "Can't validate jbi descriptor :" 200 + jbiXmlUri.toString()); 201 } 202 203 source = parseJbiXml(jbiXmlUri); 205 206 } 207 return buildDescriptor(source); 208 } 209 210 217 public String getJbiDescriptorAsString() { 218 File descriptorFile = new File (jbiXmlUri); 219 String ret = null; 220 if (descriptorFile.isFile()) { 221 ByteArrayOutputStream os = null; 222 InputStream is = null; 223 try { 224 os = new ByteArrayOutputStream (); 225 is = new FileInputStream (descriptorFile); 226 FileUtil.copyInputStream(is, os); 227 ret = os.toString(); 228 } catch (IOException e) { 229 log.log(Level.SEVERE, "Error reading jbi descritor: " 230 + descriptorFile, e); 231 } 232 } 233 return ret; 234 } 235 236 239 public Document getSource() { 240 return source; 241 } 242 243 246 public URI getURI() { 247 return jbiXmlUri; 248 } 249 250 255 public Document parseJbiXml(final URI sourceURI) 256 throws JBIDescriptorException { 257 258 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory 259 .newInstance(); 260 docBuilderFactory.setNamespaceAware(true); 261 262 DocumentBuilder docBuilder = null; 263 264 try { 265 docBuilder = docBuilderFactory.newDocumentBuilder(); 266 } catch (ParserConfigurationException pce) { 267 throw new JBIDescriptorException("Bad XML parser configuration", 268 pce); 269 } 270 271 docBuilder.setErrorHandler(xmlErrorHandler); 273 274 String jbiXmlURI = sourceURI.toString(); 276 277 Document document = null; 278 279 try { 280 document = docBuilder.parse(jbiXmlURI); 281 } catch (SAXException saxe) { 282 throw new JBIDescriptorException( 283 "JBI descriptor is not well formed XML", saxe); 284 } catch (IOException ioe) { 285 throw new JBIDescriptorException("Can't read JBI descriptor", ioe); 286 } 287 return document; 288 } 289 290 297 public boolean validateJbiXml(final URI sourceURI) { 298 boolean res = true; 299 301 Schema jbiSchema = getJBISchema(); 302 if (jbiSchema == null) { 305 log.log(Level.WARNING, "Can't check jbi descriptor validity " 306 + "because jbi schema is unavailable"); 307 } else { 308 Validator validator = schema.newValidator(); 309 validator.setErrorHandler(xmlErrorHandler); 310 311 try { 312 validator.validate(new StreamSource (new File (sourceURI))); 314 } catch (SAXException e) { 315 log.log(Level.SEVERE, "Bad JBI descriptor for " + sourceURI, e); 316 res = false; 317 } catch (IOException e) { 318 log.log(Level.SEVERE, "JBI descriptor not found " + sourceURI, 319 e); 320 res = false; 321 } 322 } 323 return res; 324 } 325 326 protected URI getJbiXmlUri() { 327 return jbiXmlUri; 328 } 329 330 protected void setJbiXmlUri(final URI jbiXmlUri) { 331 this.jbiXmlUri = jbiXmlUri; 332 } 333 334 340 protected void setLog(final Logger log) { 341 this.log = log; 342 } 343 344 354 private JBIDescriptor buildDescriptor(final Document document) 355 throws JBIDescriptorException { 356 357 JBIDescriptor descriptor = new JBIDescriptor(); 358 359 Element jbi = document.getDocumentElement(); 361 362 String versionAttr = XMLUtil.getRequiredAttributeValue(jbi, 364 VERSION_ATTR_NAME); 365 descriptor.setVersion(Double.parseDouble(versionAttr)); 366 367 List <Node > children = XMLUtil.getNodeChildren(jbi); 368 for (Node child : children) { 369 if ("component".equals(child.getNodeName())) { 370 descriptor.setComponent(loadComponentXml(child)); 371 } else if (SHARED_LIBRARY_ELEM_NAME.equals(child.getNodeName())) { 372 descriptor.setSharedLibrary(loadSharedLibraryXml(child)); 373 } else if ("service-assembly".equals(child.getNodeName())) { 374 descriptor.setServiceAssembly(loadServiceAssemblyXml(child)); 375 } else if ("services".equals(child.getNodeName())) { 376 descriptor.setServices(loadServicesXml(child)); 377 } 378 } 379 return descriptor; 380 } 381 382 private synchronized Schema getJBISchema() { if (schema == null) { 384 385 SchemaFactory factory = SchemaFactory 387 .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 388 389 factory.setErrorHandler(xmlErrorHandler); 390 391 try { 393 schema = factory 394 .newSchema(new StreamSource (openJbiSchemaFile())); 395 } catch (SAXException saxe) { 396 log.log(Level.SEVERE, saxe.getMessage(), saxe); 397 } 398 } 399 return schema; 400 } 401 402 406 private ComponentDescription loadComponentXml(final Node production) 407 throws JBIDescriptorException { 408 ComponentDescription component = new ComponentDescription(); 409 410 component 412 .setType(XMLUtil.getRequiredAttributeValue(production, "type")); 413 component.setComponentClassLoaderDelegation(XMLUtil.getAttributeValue( 414 production, "component-class-loader-delegation")); 415 component.setBootstrapClassLoaderDelegation(XMLUtil.getAttributeValue( 416 production, "bootstrap-class-loader-delegation")); 417 418 Extensions extensions = new Extensions(); 419 List <SharedLibraryList> slList = new ArrayList <SharedLibraryList>(); 420 List <Node > children = XMLUtil.getNodeChildren(production); 422 for (Node child : children) { 423 if (IDENTIFICATION_ELEM_NAME.equals(child.getNodeName())) { 424 component.setIdentification(loadIdentificationXml(child)); 425 } else if (COMPONENT_CLASS_NAME_ELEM_NAME.equals(child 426 .getNodeName())) { 427 component.setComponentClassName(XMLUtil.getTextContent(child)); 428 } else if (COMPONENT_CLASS_PATH_ELEM_NAME.equals(child 429 .getNodeName())) { 430 component.setComponentClassPath(XMLUtil.getTextContents(child 431 .getChildNodes())); 432 } else if (BOOTSTRAP_CLASS_NAME_ELEM_NAME.equals(child 433 .getNodeName())) { 434 component.setBootstrapClassName(XMLUtil.getTextContent(child)); 435 } else if (BOOTSTRAP_CLASS_PATH_ELEM_NAME.equals(child 436 .getNodeName())) { 437 component.setBootstrapClassPath(XMLUtil.getTextContents(child 438 .getChildNodes())); 439 } else if (SHARED_LIBRARY_ELEM_NAME.equals(child.getNodeName())) { 440 loadSharedLibraryListXml(slList, child); 441 } else { 442 loadExtensions(extensions, child); 443 } 444 } 445 component.setExtensions(extensions); 447 component.setSharedLibraryList(slList); 449 450 return component; 451 } 452 453 458 private List <Connection> loadConnectionsXml(final Node connectionsTree) 459 throws JBIDescriptorException { 460 461 List <Connection> connections = new ArrayList <Connection>(); 462 463 if (connectionsTree != null) { 464 List <Node > children = XMLUtil.getNodeChildren(connectionsTree); 466 for (Node child : children) { 467 if ("connection".equals(child.getNodeName())) { 468 connections.add(loadConnectionXml(child)); 469 } 470 } 471 } 472 return connections; 473 } 474 475 private Connection loadConnectionXml(final Node node) 476 throws JBIDescriptorException { 477 478 Connection newItem = new Connection(); 480 481 List <Node > children = XMLUtil.getNodeChildren(node); 482 for (Node child : children) { 483 if ("consumer".equals(child.getNodeName())) { 484 490 491 newItem.setConsumerServiceName(XMLUtil 492 .extractXmlAttributeQName(child, SERVICE_ATTR_NAME)); 493 494 newItem.setConsumerEndpointName(XMLUtil.getAttributeValue( 495 child, ENDPOINT_ATTR_NAME)); 496 } else if ("provider".equals(child.getNodeName())) { 497 newItem.setProviderServiceName(XMLUtil 498 .extractRequiredXmlAttributeQName(child, 499 SERVICE_ATTR_NAME)); 500 501 newItem.setProviderEndpointName(XMLUtil 502 .getRequiredAttributeValue(child, ENDPOINT_ATTR_NAME)); 503 } 504 } 505 return newItem; 506 } 507 508 513 private Consumes loadConsumesXml(final Node node) 514 throws JBIDescriptorException { 515 Consumes newItem = new Consumes(); 516 517 newItem.setInterfaceName(XMLUtil.extractRequiredXmlAttributeQName(node, 519 INTERFACE_ATTR_NAME)); 520 521 newItem.setServiceName(XMLUtil.extractXmlAttributeQName(node, 522 SERVICE_ATTR_NAME)); 523 524 newItem.setEndpointName(XMLUtil.getAttributeValue(node, 525 ENDPOINT_ATTR_NAME)); 526 527 newItem.setLinkType(XMLUtil.getAttributeValue(node, "link-type")); 528 529 Extensions extensions = new Extensions(); 531 List <Node > children = XMLUtil.getNodeChildren(node); 532 for (Node child : children) { 533 loadExtensions(extensions, child); 534 } 535 newItem.setExtensions(extensions); 536 537 return newItem; 538 } 539 540 547 private void loadExtensions(final Extensions extensions, final Node node) { 548 549 DocumentFragment fragment = extensions.getDocumentFragment(); 552 if (fragment == null) { 553 fragment = node.getOwnerDocument().createDocumentFragment(); 554 extensions.setDocumentFragment(fragment); 555 } 556 fragment.appendChild(node); 557 558 String uriString = node.lookupNamespaceURI(node.getPrefix()); 560 if (uriString != null) { 561 URI uri = null; 562 try { 563 uri = new URI (uriString); 564 } catch (URISyntaxException e) { 565 log.warning(INVALID_EXTENSION_NAMESPACE + node.getNodeName()); 566 } 567 568 if (PetalsExtensionsUris.PETALS_EXTENSIONS 570 .equals(PetalsExtensionsUris.valueOf(uri))) { 571 loadPetalsExtensions(extensions, node); 572 } else { 573 loadUnknownExtension(extensions, node); 574 } 575 } 576 } 577 578 private Identification loadIdentificationXml(final Node identificationNode) { 579 Identification identification = new Identification(); 580 581 Extensions extensions = new Extensions(); 582 List <Node > children = XMLUtil.getNodeChildren(identificationNode); 584 for (Node child : children) { 585 if ("name".equals(child.getNodeName())) { 586 identification.setName(XMLUtil.getTextContent(child)); 587 } else if ("description".equals(child.getNodeName())) { 588 identification.setDescription(XMLUtil.getTextContent(child)); 589 } else { 590 loadExtensions(extensions, child); 591 } 592 } 593 identification.setExtensions(extensions); 595 596 return identification; 597 } 598 599 private void loadPetalsExtensions(final Extensions extensions, 600 final Node node) { 601 List <Node > children = XMLUtil.getNodeChildren(node); 602 for (Node child : children) { 603 String childURIString = child.lookupNamespaceURI(child.getPrefix()); 604 if (childURIString != null) { 605 URI childURI = null; 606 try { 607 childURI = new URI (childURIString); } catch (URISyntaxException e) { 609 log.warning(INVALID_EXTENSION_NAMESPACE 610 + child.getNodeName()); 611 } 612 613 if (PetalsExtensionsUris.PETALS_EXTENSION_KEY_VALUE 614 .equals(PetalsExtensionsUris.valueOf(childURI))) { 615 loadPetalsKeyValueExtension(extensions, child); 616 } else { 617 loadUnknownExtension(extensions, child); 618 } 619 } 620 } 621 } 622 623 private void loadPetalsKeyValueExtension(final Extensions extensions, 624 final Node child) { 625 PetalsExtension petalsExtension = new PetalsExtension(); 626 petalsExtension 627 .setExtensionURI(PetalsExtensionsUris.PETALS_EXTENSION_KEY_VALUE 628 .value()); 629 Map <String , String > keyValues = new HashMap <String , String >(); 631 List <Node > children = XMLUtil.getNodeChildren(child); 632 for (Node extChild : children) { 633 keyValues.put(extChild.getNodeName(), XMLUtil 634 .getTextContent(extChild)); 635 } 636 petalsExtension.setExtensionObject(keyValues); 637 extensions.addPetalsExtension( 638 PetalsExtensionsUris.PETALS_EXTENSION_KEY_VALUE.value(), 639 petalsExtension); 640 } 641 642 647 private Provides loadProvidesXml(final Node node) 648 throws JBIDescriptorException { 649 Provides newItem = new Provides(); 650 651 newItem.setInterfaceName(XMLUtil.extractRequiredXmlAttributeQName(node, 653 INTERFACE_ATTR_NAME)); 654 655 newItem.setServiceName(XMLUtil.extractRequiredXmlAttributeQName(node, 656 SERVICE_ATTR_NAME)); 657 658 newItem.setEndpointName(XMLUtil.getRequiredAttributeValue(node, 659 ENDPOINT_ATTR_NAME)); 660 661 Extensions extensions = new Extensions(); 663 List <Node > children = XMLUtil.getNodeChildren(node); 664 for (Node child : children) { 665 loadExtensions(extensions, child); 666 } 667 newItem.setExtensions(extensions); 668 669 return newItem; 670 } 671 672 676 private ServiceAssembly loadServiceAssemblyXml(final Node node) 677 throws JBIDescriptorException { 678 ServiceAssembly serviceAssembly = new ServiceAssembly(); 679 680 Extensions extensions = new Extensions(); 681 List <Node > children = XMLUtil.getNodeChildren(node); 683 for (Node child : children) { 684 if (IDENTIFICATION_ELEM_NAME.equals(child.getNodeName())) { 685 serviceAssembly.setIdentification(loadIdentificationXml(child)); 686 } else if ("service-unit".equals(child.getNodeName())) { 687 serviceAssembly.addServiceUnit(loadServiceUnitXml(child)); 688 } else if ("connections".equals(child.getNodeName())) { 689 serviceAssembly.setConnections(loadConnectionsXml(child)); 690 } else { 691 loadExtensions(extensions, child); 692 } 693 } 694 serviceAssembly.setExtensions(extensions); 696 697 return serviceAssembly; 698 } 699 700 704 private Services loadServicesXml(final Node production) 705 throws JBIDescriptorException { 706 707 Services services = new Services(); 708 709 String isBindingComponent = XMLUtil.getRequiredAttributeValue( 712 production, "binding-component"); 713 services.setBindingComponent(Boolean.parseBoolean(isBindingComponent)); 714 715 Extensions extensions = new Extensions(); 716 List <Node > children = XMLUtil.getNodeChildren(production); 718 for (Node child : children) { 719 if ("provides".equals(child.getNodeName())) { 720 services.addProvides(loadProvidesXml(child)); 721 } else if ("consumes".equals(child.getNodeName())) { 722 services.addConsumes(loadConsumesXml(child)); 723 } else { 724 loadExtensions(extensions, child); 725 } 726 } 727 services.setExtensions(extensions); 729 730 return services; 731 } 732 733 737 private ServiceUnit loadServiceUnitXml(final Node node) { 738 739 ServiceUnit result = new ServiceUnit(); 740 741 Extensions extensions = new Extensions(); 742 List <Node > children = XMLUtil.getNodeChildren(node); 744 for (Node child : children) { 745 if (IDENTIFICATION_ELEM_NAME.equals(child.getNodeName())) { 746 result.setIdentification(loadIdentificationXml(child)); 747 } else if ("target".equals(child.getNodeName())) { 748 List <Node > childChildren = XMLUtil.getNodeChildren(child); 749 for (Node targetChild : childChildren) { 750 if ("artifacts-zip".equals(targetChild.getNodeName())) { 751 result.setTargetArtifactsZip(XMLUtil 752 .getTextContent(targetChild)); 753 } else if ("component-name".equals(targetChild 754 .getNodeName())) { 755 result.setTargetComponentName(XMLUtil 756 .getTextContent(targetChild)); 757 } 758 } 759 } else { 760 loadExtensions(extensions, child); 761 } 762 } 763 result.setExtensions(extensions); 765 766 return result; 767 } 768 769 773 private void loadSharedLibraryListXml(final List <SharedLibraryList> slList, 774 final Node node) { 775 SharedLibraryList sharedLibrary = new SharedLibraryList(); 776 sharedLibrary.setName(XMLUtil.getTextContent(node)); 777 sharedLibrary.setVersion(XMLUtil.getAttributeValue(node, 778 VERSION_ATTR_NAME)); 779 slList.add(sharedLibrary); 780 } 781 782 785 private SharedLibrary loadSharedLibraryXml(final Node production) { 786 SharedLibrary sharedLibrary = new SharedLibrary(); 787 788 sharedLibrary.setClassLoaderDelegation(XMLUtil.getAttributeValue( 790 production, "class-loader-delegation")); 791 sharedLibrary.setVersion(XMLUtil.getAttributeValue(production, 792 VERSION_ATTR_NAME)); 793 794 List <Node > children = XMLUtil.getNodeChildren(production); 795 for (Node child : children) { 796 if (IDENTIFICATION_ELEM_NAME.equals(child.getNodeName())) { 797 sharedLibrary.setIdentification(loadIdentificationXml(child)); 798 } else if ("shared-library-class-path".equals(child.getNodeName())) { 799 sharedLibrary.setSharedLibraryClassPath(XMLUtil 800 .getTextContents(child.getChildNodes())); 801 } 802 } 803 return sharedLibrary; 804 } 805 806 private void loadUnknownExtension(final Extensions extensions, 807 final Node node) { 808 String namespaceURI = node.lookupNamespaceURI(node.getPrefix()); 809 UnknownExtension unknownExtension = new UnknownExtension(); 810 URI unknownURI = null; 811 try { 812 unknownURI = new URI (namespaceURI); 813 } catch (URISyntaxException e) { 814 log.warning(INVALID_EXTENSION_NAMESPACE + node.getNodeName()); 815 } 816 if (unknownURI != null) { 817 unknownExtension.setExtensionURI(unknownURI); 818 unknownExtension.setNode(node); 819 extensions.addUnknownExtension(unknownURI, unknownExtension); 820 } 821 } 822 823 832 private InputStream openJbiSchemaFile() { 833 InputStream theJbiSchemaResource = null; 834 835 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 838 843 URL schemaURL = cl.getResource(JBI_XSD); 845 if (schemaURL != null) { 846 try { 847 theJbiSchemaResource = schemaURL.openStream(); 848 } catch (IOException e) { 849 log.log(Level.SEVERE, e.getMessage(), e); 850 } 851 } 852 853 if (theJbiSchemaResource == null) { 854 String petalsRoot = System.getProperty("petals.home"); 856 if (petalsRoot != null) { 857 try { 858 theJbiSchemaResource = new FileInputStream (new File ( 859 petalsRoot + JBI_SCHEMA_RESOURCE)); 860 } catch (FileNotFoundException e) { 861 log.log(Level.SEVERE, e.getMessage(), e); 862 } 863 } 864 } 865 866 return theJbiSchemaResource; 867 } 868 869 } 870 | Popular Tags |