001/* 002 * jDTAUS Core RI Client Container 003 * Copyright (C) 2005 Christian Schulte 004 * <cs@schulte.it> 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License, or any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 019 * 020 */ 021package org.jdtaus.core.container.ri.client; 022 023import java.beans.Beans; 024import java.io.IOException; 025import java.io.InputStream; 026import java.lang.reflect.Constructor; 027import java.lang.reflect.InvocationTargetException; 028import java.lang.reflect.Method; 029import java.lang.reflect.Modifier; 030import java.net.URI; 031import java.net.URISyntaxException; 032import java.net.URL; 033import java.text.MessageFormat; 034import java.text.ParseException; 035import java.util.Arrays; 036import java.util.Collection; 037import java.util.Collections; 038import java.util.Comparator; 039import java.util.Enumeration; 040import java.util.HashMap; 041import java.util.HashSet; 042import java.util.Iterator; 043import java.util.LinkedList; 044import java.util.List; 045import java.util.Locale; 046import java.util.Map; 047import java.util.Set; 048import java.util.TreeMap; 049import java.util.logging.Level; 050import java.util.logging.Logger; 051import javax.xml.parsers.DocumentBuilder; 052import javax.xml.parsers.DocumentBuilderFactory; 053import javax.xml.parsers.ParserConfigurationException; 054import javax.xml.transform.ErrorListener; 055import javax.xml.transform.Transformer; 056import javax.xml.transform.TransformerConfigurationException; 057import javax.xml.transform.TransformerException; 058import javax.xml.transform.TransformerFactory; 059import javax.xml.transform.dom.DOMResult; 060import javax.xml.transform.dom.DOMSource; 061import javax.xml.transform.stream.StreamSource; 062import org.jdtaus.core.container.Argument; 063import org.jdtaus.core.container.Arguments; 064import org.jdtaus.core.container.Dependencies; 065import org.jdtaus.core.container.Dependency; 066import org.jdtaus.core.container.DuplicateSpecificationException; 067import org.jdtaus.core.container.IllegalPropertyTypeException; 068import org.jdtaus.core.container.Implementation; 069import org.jdtaus.core.container.Implementations; 070import org.jdtaus.core.container.IncompatibleImplementationException; 071import org.jdtaus.core.container.Message; 072import org.jdtaus.core.container.Messages; 073import org.jdtaus.core.container.MissingImplementationException; 074import org.jdtaus.core.container.MissingPropertyException; 075import org.jdtaus.core.container.MissingSpecificationException; 076import org.jdtaus.core.container.Model; 077import org.jdtaus.core.container.ModelError; 078import org.jdtaus.core.container.ModelObject; 079import org.jdtaus.core.container.Module; 080import org.jdtaus.core.container.Modules; 081import org.jdtaus.core.container.Properties; 082import org.jdtaus.core.container.Property; 083import org.jdtaus.core.container.PropertyOverwriteConstraintException; 084import org.jdtaus.core.container.Specification; 085import org.jdtaus.core.container.Specifications; 086import org.jdtaus.core.container.Text; 087import org.jdtaus.core.container.ri.client.versioning.VersionParser; 088import org.w3c.dom.Document; 089import org.w3c.dom.Element; 090import org.w3c.dom.NodeList; 091import org.xml.sax.ErrorHandler; 092import org.xml.sax.SAXException; 093import org.xml.sax.SAXParseException; 094 095/** 096 * {@code Model} reference implementation. 097 * 098 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 099 * @version $JDTAUS: DefaultModel.java 8743 2012-10-07 03:06:20Z schulte $ 100 * 101 * @see <a href="http://xml.jdtaus.org/1.0.x/jdtaus-core/jdtaus-core-schemas/jdtaus-container-1.1.xsd">jdtaus-container-1.1.xsd</a> 102 */ 103public class DefaultModel implements Model 104{ 105 //--Constants--------------------------------------------------------------- 106 107 /** JAXP configuration key to the Schema implementation attribute. */ 108 private static final String SCHEMA_LANGUAGE_KEY = 109 "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; 110 111 /** JAXP Schema implementation to use. */ 112 private static final String SCHEMA_LANGUAGE = 113 "http://www.w3.org/2001/XMLSchema"; 114 115 /** 116 * jDTAUS {@code Model} namespace URI for the deprecated 1.0 and 1.1 model. 117 */ 118 private static final String MODEL_NS = 119 "http://jdtaus.org/runtime/container/xml"; 120 121 /** {@code jDTAUS Container Model} namespace URI. */ 122 private static final String CONTAINER_NS = 123 "http://jdtaus.org/core/model/container"; 124 125 /** {@code jDTAUS Container Model RI} namespace URI. */ 126 private static final String MODULE_NS = 127 "http://jdtaus.org/core/model/container/module"; 128 129 /** Location of the document resources searched for by default. */ 130 private static final String MODEL_LOCATION = 131 "META-INF/jdtaus/module.xml"; 132 133 /** Location of the transformation resources searched for by default. */ 134 private static final String TRANSFORMATION_LOCATION = 135 "META-INF/jdtaus/container.xslt"; 136 137 /** Model versions supported by this implementation. */ 138 private static final String[] SUPPORTED_MODEL_VERSIONS = 139 { 140 "1.0", "1.1", "1.2", "1.3", "1.4" 141 }; 142 143 /** String constructor arguments. */ 144 private static final Class[] CTOR_ARGS_STRING = 145 { 146 String.class 147 }; 148 149 /** String constructor arguments. */ 150 private static final Class[] CTOR_ARGS_CHAR = 151 { 152 char.class 153 }; 154 155 /** Constant for the name of the platform module. */ 156 private static final String PLATFORM_MODULE_NAME = Model.class.getName(); 157 158 /** Constant for the version of the platform module. */ 159 private static final String PLATFORM_MODULE_VERSION = "1.0"; 160 161 /** Constant for model version 1.1. */ 162 private static final String V_1_1 = "1.1"; 163 164 /** Constant for model version 1.3. */ 165 private static final String V_1_3 = "1.3"; 166 167 /** Constant for model version 1.4. */ 168 private static final String V_1_4 = "1.4"; 169 170 /** Constant for the maximum supported model version. */ 171 private static final String MODEL_VERSION = V_1_4; 172 173 //---------------------------------------------------------------Constants-- 174 //--Constructors------------------------------------------------------------ 175 176 /** 177 * Creates a new {@code DefaultModel} instance. 178 * 179 * @throws ModelError if no model can be read. 180 * 181 * @see #readModules() 182 */ 183 public DefaultModel() 184 { 185 try 186 { 187 this.modules = this.readModules(); 188 // Add the platform module. 189 final Module[] modulesWithPlatform = 190 new Module[ this.modules.size() + 1 ]; 191 192 System.arraycopy( this.modules.getModules(), 0, modulesWithPlatform, 193 0, this.modules.size() ); 194 195 modulesWithPlatform[this.modules.size()] = this.getPlatformModule(); 196 this.modules.setModules( modulesWithPlatform ); 197 198 this.linkParentImplementations(); 199 this.assertSpecificationsAvailable(); 200 this.updateSpecificationReferences(); 201 this.linkImplementedSpecifications(); 202 this.linkDependencies(); 203 this.assertCompatibility(); 204 this.assertOverwrittenProperties(); 205 this.assertImplementedProperties(); 206 } 207 catch ( final ParserConfigurationException e ) 208 { 209 throw new ModelError( e ); 210 } 211 catch ( final SAXException e ) 212 { 213 throw new ModelError( e ); 214 } 215 catch ( final IOException e ) 216 { 217 throw new ModelError( e ); 218 } 219 catch ( final ParseException e ) 220 { 221 throw new ModelError( e ); 222 } 223 catch ( final TransformerConfigurationException e ) 224 { 225 throw new ModelError( e ); 226 } 227 catch ( final TransformerException e ) 228 { 229 throw new ModelError( e ); 230 } 231 catch ( final URISyntaxException e ) 232 { 233 throw new ModelError( e ); 234 } 235 finally 236 { 237 this.specifications = null; 238 this.implementations = null; 239 this.dependencies = null; 240 this.impl2parent = null; 241 this.moduleMap = null; 242 } 243 } 244 245 //------------------------------------------------------------Constructors-- 246 //--Model------------------------------------------------------------------- 247 248 public Modules getModules() 249 { 250 return this.modules; 251 } 252 253 //-------------------------------------------------------------------Model-- 254 //--DefaultModel------------------------------------------------------------ 255 256 /** Logger of the class. */ 257 private static final Logger LOGGER = 258 Logger.getLogger( DefaultModel.class.getName() ); 259 260 /** Holds the instance of the platform module. */ 261 private Module platformModule; 262 263 /** Holds the loaded model. */ 264 private Modules modules; 265 266 /** 267 * Maps specification identifiers to a list of specification instances by 268 * version. 269 */ 270 private Map/*<String,Collection>*/ specifications = new HashMap( 1000 ); 271 272 /** Maps implementation identifiers to implementation instances. */ 273 private Map/*<String,Implementation>*/ implementations = new HashMap( 1000 ); 274 275 /** 276 * Maps identifiers of implementations to identifiers of parent 277 * implementations. 278 */ 279 private Map/*<String,String>*/ impl2parent = new HashMap( 1000 ); 280 281 /** Maps dependency keys to implementation names. */ 282 private Map/*<String,String>*/ dependencies = new HashMap( 1000 ); 283 284 /** Maps module names to resource URLs. */ 285 private Map/*<String,URL>*/ moduleMap = new HashMap( 1000 ); 286 287 /** 288 * Reads the module resources. 289 * 290 * @return all read modules without resolved references. 291 * 292 * @throws IOException if reading fails. 293 * @throws ParserConfigurationException if configuring the parser fails. 294 * @throws SAXException if parsing documents fails. 295 * @throws ParseException if parsing versions fails. 296 * @throws TransformerException if creating a transformer fails or if 297 * transforming documents fails. 298 * @throws URISyntaxException if creating a resource URI fails. 299 */ 300 private Modules readModules() 301 throws IOException, ParserConfigurationException, SAXException, 302 ParseException, TransformerException, URISyntaxException 303 { 304 final Map documents = new HashMap(); 305 final DocumentBuilderFactory xmlFactory = 306 DocumentBuilderFactory.newInstance(); 307 308 final Enumeration resources = ClassLoaderFactory.loadResources( 309 this.getClass(), MODEL_LOCATION ); 310 311 xmlFactory.setNamespaceAware( true ); 312 313 try 314 { 315 xmlFactory.setValidating( true ); 316 xmlFactory.setAttribute( SCHEMA_LANGUAGE_KEY, SCHEMA_LANGUAGE ); 317 } 318 catch ( final IllegalArgumentException e ) 319 { 320 LOGGER.log( Level.CONFIG, e.getMessage() ); 321 LOGGER.log( Level.WARNING, DefaultModelBundle.getInstance(). 322 getNoValidationWarningMessage( Locale.getDefault(), 323 e.getMessage() ) ); 324 325 xmlFactory.setValidating( false ); 326 } 327 328 final DocumentBuilder xmlBuilder = xmlFactory.newDocumentBuilder(); 329 xmlBuilder.setEntityResolver( new BootstrapEntityResolver() ); 330 331 // Parse and validate all files from the classpath. 332 while ( resources.hasMoreElements() ) 333 { 334 final URL resource = (URL) resources.nextElement(); 335 336 if ( LOGGER.isLoggable( Level.FINE ) ) 337 { 338 LOGGER.log( Level.FINE, DefaultModelBundle.getInstance(). 339 getResourceInformationMessage( 340 Locale.getDefault(), resource.toExternalForm() ) ); 341 342 } 343 344 final InputStream stream = resource.openStream(); 345 xmlBuilder.setErrorHandler( 346 new ErrorHandler() 347 { 348 349 public void warning( final SAXParseException e ) 350 { 351 LOGGER.log( Level.WARNING, 352 DefaultModelBundle.getInstance(). 353 getParseExceptionMessage( 354 Locale.getDefault(), resource.toExternalForm(), 355 e.getMessage(), new Integer( e.getLineNumber() ), 356 new Integer( e.getColumnNumber() ) ) ); 357 358 } 359 360 public void fatalError( final SAXParseException e ) 361 throws SAXException 362 { 363 throw new SAXException( 364 DefaultModelBundle.getInstance(). 365 getParseExceptionMessage( 366 Locale.getDefault(), resource.toExternalForm(), 367 e.getMessage(), new Integer( e.getLineNumber() ), 368 new Integer( e.getColumnNumber() ) ), e ); 369 370 } 371 372 public void error( final SAXParseException e ) 373 throws SAXException 374 { 375 throw new SAXException( 376 DefaultModelBundle.getInstance(). 377 getParseExceptionMessage( 378 Locale.getDefault(), resource.toExternalForm(), 379 e.getMessage(), new Integer( e.getLineNumber() ), 380 new Integer( e.getColumnNumber() ) ), e ); 381 382 } 383 384 } ); 385 386 final Document doc = xmlBuilder.parse( stream ); 387 stream.close(); 388 documents.put( new URI( resource.toString() ), doc ); 389 } 390 391 // Transform the XML documents. 392 return this.transformDocuments( documents ); 393 } 394 395 private void updateSpecificationReferences() 396 { 397 for ( int m = this.modules.size() - 1; m >= 0; m-- ) 398 { 399 final Module module = this.modules.getModule( m ); 400 for ( int s = module.getSpecifications().size() - 1; s >= 0; s-- ) 401 { 402 final Specification spec = module.getSpecifications(). 403 getSpecification( s ); 404 405 final Collection references = 406 (Collection) this.specifications.get( spec.getIdentifier() ); 407 408 assert references != null : "Expected specification meta-data."; 409 410 for ( final Iterator it = references.iterator(); it.hasNext(); ) 411 { 412 final Specification reference = (Specification) it.next(); 413 reference.setModuleName( module.getName() ); 414 415 if ( !reference.equals( spec ) ) 416 { 417 reference.setDocumentation( spec.getDocumentation() ); 418 reference.setMultiplicity( spec.getMultiplicity() ); 419 reference.setProperties( spec.getProperties() ); 420 reference.setScope( spec.getScope() ); 421 reference.setStateless( spec.isStateless() ); 422 reference.setVendor( spec.getVendor() ); 423 reference.setModelVersion( spec.getModelVersion() ); 424 } 425 } 426 } 427 } 428 } 429 430 private void linkParentImplementations() 431 { 432 for ( final Iterator it = this.implementations.entrySet().iterator(); 433 it.hasNext(); ) 434 { 435 final Map.Entry e = (Map.Entry) it.next(); 436 final String identifier = (String) e.getKey(); 437 final Implementation implementation = (Implementation) e.getValue(); 438 final String parentIdentifier = 439 (String) this.impl2parent.get( identifier ); 440 441 if ( parentIdentifier != null ) 442 { 443 final Implementation parent = 444 (Implementation) this.implementations.get( 445 parentIdentifier ); 446 447 if ( parent == null ) 448 { 449 throw new MissingImplementationException( 450 parentIdentifier ); 451 452 } 453 454 implementation.setParent( parent ); 455 } 456 } 457 } 458 459 private void linkImplementedSpecifications() 460 { 461 for ( final Iterator it = this.implementations.values().iterator(); 462 it.hasNext(); ) 463 { 464 final Implementation implementation = (Implementation) it.next(); 465 466 for ( int i = implementation.getImplementedSpecifications(). 467 size() - 1; i >= 0; i-- ) 468 { 469 final Specification implemented = 470 implementation.getImplementedSpecifications(). 471 getSpecification( i ); 472 473 final Collection specs = 474 (Collection) this.specifications.get( 475 implemented.getIdentifier() ); 476 477 assert specs != null : "Expected specification meta-data."; 478 479 for ( final Iterator s = specs.iterator(); s.hasNext(); ) 480 { 481 final Specification spec = (Specification) s.next(); 482 final Collection col = new LinkedList( 483 Arrays.asList( spec.getImplementations(). 484 getImplementations() ) ); 485 486 col.add( implementation ); 487 488 final Implementations impls = new Implementations(); 489 impls.setImplementations( 490 (Implementation[]) col.toArray( 491 new Implementation[ col.size() ] ) ); 492 493 spec.setImplementations( impls ); 494 } 495 } 496 } 497 } 498 499 private void linkDependencies() 500 { 501 for ( final Iterator it = this.implementations.values().iterator(); 502 it.hasNext(); ) 503 { 504 final Implementation implementation = (Implementation) it.next(); 505 for ( int i = implementation.getDeclaredDependencies().size() - 1; 506 i >= 0; i-- ) 507 { 508 final Dependency d = implementation.getDeclaredDependencies(). 509 getDependency( i ); 510 511 final String key = 512 implementation.getIdentifier() + '/' + d.getName(); 513 514 final String name = (String) this.dependencies.get( key ); 515 516 if ( name != null ) 517 { 518 d.setImplementation( d.getSpecification(). 519 getImplementation( name ) ); 520 521 } 522 } 523 } 524 } 525 526 private void assertSpecificationsAvailable() 527 { 528 final Implementation[] impls = this.modules.getImplementations(). 529 getImplementations(); 530 531 for ( int i = impls.length - 1; i >= 0; i-- ) 532 { 533 final Specifications specs = impls[i].getImplementedSpecifications(); 534 final Dependencies deps = impls[i].getDependencies(); 535 536 for ( int j = specs.size() - 1; j >= 0; j-- ) 537 { 538 try 539 { 540 this.modules.getSpecification( 541 specs.getSpecification( j ).getIdentifier() ); 542 543 } 544 catch ( final MissingSpecificationException e ) 545 { 546 if ( !this.addPlatformSpecification( 547 specs.getSpecification( j ).getIdentifier(), true ) ) 548 { 549 throw e; 550 } 551 } 552 } 553 554 for ( int j = deps.size() - 1; j >= 0; j-- ) 555 { 556 try 557 { 558 this.modules.getSpecification( 559 deps.getDependency( j ).getSpecification(). 560 getIdentifier() ); 561 562 } 563 catch ( final MissingSpecificationException e ) 564 { 565 if ( !this.addPlatformSpecification( 566 deps.getDependency( j ).getSpecification(). 567 getIdentifier(), true ) ) 568 { 569 throw e; 570 } 571 } 572 } 573 } 574 } 575 576 private void assertCompatibility() throws ParseException 577 { 578 for ( int i = this.modules.getImplementations().size() - 1; i >= 0; 579 i-- ) 580 { 581 final Implementation impl = this.modules.getImplementations(). 582 getImplementation( i ); 583 584 if ( impl.getModelVersion() == null || 585 VersionParser.compare( impl.getModelVersion(), V_1_3 ) < 0 ) 586 { 587 continue; 588 } 589 590 final Specifications specs = impl.getImplementedSpecifications(); 591 final Dependencies deps = impl.getDependencies(); 592 593 for ( int s = specs.size() - 1; s >= 0; s-- ) 594 { 595 final Specification implemented = specs.getSpecification( s ); 596 final Specification available = 597 this.modules.getSpecification( implemented.getIdentifier() ); 598 599 if ( available.getModelVersion() == null || 600 VersionParser.compare( available.getModelVersion(), 601 V_1_3 ) < 0 ) 602 { 603 continue; 604 } 605 606 if ( implemented.getVersion() != null ) 607 { 608 try 609 { 610 if ( VersionParser.compare( 611 implemented.getVersion(), 612 available.getVersion() ) < 0 ) 613 { 614 throw new IncompatibleImplementationException( 615 available.getIdentifier(), 616 available.getVersion(), 617 impl.getIdentifier(), implemented.getVersion(), 618 null ); 619 620 } 621 } 622 catch ( final ParseException e ) 623 { 624 final IncompatibleImplementationException iie = 625 new IncompatibleImplementationException( 626 available.getIdentifier(), available.getVersion(), 627 impl.getIdentifier(), implemented.getVersion(), 628 null ); 629 630 iie.initCause( e ); 631 throw iie; 632 } 633 } 634 } 635 636 for ( int d = deps.size() - 1; d >= 0; d-- ) 637 { 638 final Specification required = 639 deps.getDependency( d ).getSpecification(); 640 641 final Specification available = 642 this.modules.getSpecification( required.getIdentifier() ); 643 644 if ( available.getModelVersion() == null || 645 VersionParser.compare( available.getModelVersion(), 646 V_1_3 ) < 0 ) 647 { 648 continue; 649 } 650 651 if ( required.getVersion() != null ) 652 { 653 try 654 { 655 if ( VersionParser.compare( 656 available.getVersion(), 657 required.getVersion() ) < 0 ) 658 { 659 throw new IncompatibleImplementationException( 660 available.getIdentifier(), 661 available.getVersion(), 662 impl.getIdentifier(), null, 663 required.getVersion() ); 664 665 } 666 } 667 catch ( final ParseException e ) 668 { 669 final IncompatibleImplementationException iie = 670 new IncompatibleImplementationException( 671 available.getIdentifier(), available.getVersion(), 672 impl.getIdentifier(), null, required.getVersion() ); 673 674 iie.initCause( e ); 675 throw iie; 676 } 677 } 678 } 679 } 680 } 681 682 private void assertOverwrittenProperties() throws ParseException 683 { 684 for ( int i = this.modules.getImplementations().size() - 1; i >= 0; 685 i-- ) 686 { 687 final Implementation impl = this.modules.getImplementations(). 688 getImplementation( i ); 689 690 final Dependencies deps = impl.getDependencies(); 691 for ( int d = deps.size() - 1; d >= 0; d-- ) 692 { 693 final Dependency dep = deps.getDependency( d ); 694 if ( dep.getSpecification().getScope() != 695 Specification.SCOPE_MULTITON && 696 dep.getDeclaredProperties().size() > 0 ) 697 { 698 throw new PropertyOverwriteConstraintException( 699 impl.getIdentifier(), dep.getName() ); 700 701 } 702 703 final Properties properties = dep.getDeclaredProperties(); 704 for ( int p = properties.size() - 1; p >= 0; p-- ) 705 { 706 final Property dependencyProperty = 707 properties.getProperty( p ); 708 709 try 710 { 711 final Property specificationProperty = 712 dep.getSpecification().getProperties(). 713 getProperty( dependencyProperty.getName() ); 714 715 if ( !dependencyProperty.getType(). 716 equals( specificationProperty.getType() ) ) 717 { 718 throw new IllegalPropertyTypeException( 719 dependencyProperty.getName(), 720 dependencyProperty.getType(), 721 specificationProperty.getType() ); 722 723 } 724 725 dependencyProperty.setApi( true ); 726 } 727 catch ( final MissingPropertyException e ) 728 { 729 if ( VersionParser.compare( 730 dep.getSpecification().getModelVersion(), 731 V_1_3 ) >= 0 ) 732 { 733 final PropertyOverwriteConstraintException poce = 734 new PropertyOverwriteConstraintException( 735 impl.getIdentifier(), dep.getName() ); 736 737 poce.initCause( e ); 738 throw poce; 739 } 740 } 741 } 742 } 743 } 744 } 745 746 private void assertImplementedProperties() throws ParseException 747 { 748 for ( int i = this.modules.getImplementations().size() - 1; i >= 0; 749 i-- ) 750 { 751 final Map properties = new HashMap( 100 ); 752 final Implementation impl = this.modules.getImplementations(). 753 getImplementation( i ); 754 755 final Specifications specs = impl.getImplementedSpecifications(); 756 for ( int s = specs.size() - 1; s >= 0; s-- ) 757 { 758 final Specification implementedSpec = 759 specs.getSpecification( s ); 760 761 final Properties props = implementedSpec.getProperties(); 762 for ( int p = props.size() - 1; p >= 0; p-- ) 763 { 764 final Property implementedProperty = 765 props.getProperty( p ); 766 767 final Property alreadyImplemented = 768 (Property) properties.get( 769 implementedProperty.getName() ); 770 771 if ( alreadyImplemented != null ) 772 { 773 if ( !implementedProperty.getType(). 774 equals( alreadyImplemented.getType() ) ) 775 { 776 throw new IllegalPropertyTypeException( 777 implementedProperty.getName(), 778 implementedProperty.getType(), 779 alreadyImplemented.getType() ); 780 781 } 782 } 783 else 784 { 785 properties.put( implementedProperty.getName(), 786 implementedProperty ); 787 788 } 789 790 try 791 { 792 final Property property = 793 impl.getProperties().getProperty( 794 implementedProperty.getName() ); 795 796 if ( !property.getType(). 797 equals( implementedProperty.getType() ) ) 798 { 799 throw new IllegalPropertyTypeException( 800 property.getName(), property.getType(), 801 implementedProperty.getType() ); 802 803 } 804 } 805 catch ( final MissingPropertyException e ) 806 { 807 if ( VersionParser.compare( impl.getModelVersion(), 808 V_1_3 ) >= 0 ) 809 { 810 final PropertyOverwriteConstraintException poce = 811 new PropertyOverwriteConstraintException( 812 impl.getIdentifier(), 813 implementedSpec.getIdentifier(), 814 implementedProperty.getName() ); 815 816 poce.initCause( e ); 817 throw poce; 818 } 819 } 820 } 821 } 822 823 for ( int p = impl.getProperties().size() - 1; p >= 0; p-- ) 824 { 825 final Property property = impl.getProperties().getProperty( p ); 826 final Property specified = 827 (Property) properties.get( property.getName() ); 828 829 if ( specified != null && 830 !property.getType().equals( specified.getType() ) ) 831 { 832 throw new IllegalPropertyTypeException( 833 property.getName(), property.getType(), 834 specified.getType() ); 835 836 } 837 } 838 } 839 } 840 841 private Specification getSpecification( final String identifier, 842 final String version ) 843 { 844 Collection c = (Collection) this.specifications.get( identifier ); 845 if ( c == null ) 846 { 847 c = new LinkedList(); 848 this.specifications.put( identifier, c ); 849 } 850 851 Specification specification = null; 852 for ( final Iterator it = c.iterator(); it.hasNext(); ) 853 { 854 final Specification s = (Specification) it.next(); 855 856 if ( s.getVersion() == null 857 ? version == null 858 : s.getVersion().equals( version ) ) 859 { 860 specification = s; 861 break; 862 } 863 } 864 865 if ( specification == null ) 866 { 867 specification = new Specification(); 868 specification.setIdentifier( identifier ); 869 specification.setVersion( version ); 870 c.add( specification ); 871 } 872 873 return specification; 874 } 875 876 private Implementation getImplementation( final String identifier ) 877 { 878 Implementation implementation = 879 (Implementation) this.implementations.get( identifier ); 880 881 if ( implementation == null ) 882 { 883 implementation = new Implementation(); 884 implementation.setIdentifier( identifier ); 885 this.implementations.put( identifier, implementation ); 886 } 887 888 return implementation; 889 } 890 891 private Modules transformDocuments( final Map xml ) 892 throws ParseException, IOException, TransformerException 893 { 894 final Modules mods = new Modules(); 895 mods.setModelVersion( MODEL_VERSION ); 896 897 final List list = new LinkedList(); 898 899 for ( final Iterator it = xml.entrySet().iterator(); it.hasNext(); ) 900 { 901 final Map.Entry entry = (Map.Entry) it.next(); 902 Document doc = (Document) entry.getValue(); 903 904 final TransformerFactory f = TransformerFactory.newInstance(); 905 final Enumeration transformers = ClassLoaderFactory.loadResources( 906 this.getClass(), TRANSFORMATION_LOCATION ); 907 908 while ( transformers.hasMoreElements() ) 909 { 910 final URL rsrc = (URL) transformers.nextElement(); 911 912 if ( LOGGER.isLoggable( Level.CONFIG ) ) 913 { 914 LOGGER.log( Level.CONFIG, DefaultModelBundle.getInstance(). 915 getResourceInformationMessage( 916 Locale.getDefault(), rsrc.toExternalForm() ) ); 917 918 } 919 920 f.setErrorListener( new ErrorListener() 921 { 922 923 public void warning( final TransformerException e ) 924 throws TransformerException 925 { 926 LOGGER.log( Level.WARNING, 927 DefaultModelBundle.getInstance(). 928 getParseExceptionMessage( 929 Locale.getDefault(), rsrc.toExternalForm(), 930 e.getMessage(), 931 new Integer( e.getLocator().getLineNumber() ), 932 new Integer( e.getLocator().getColumnNumber() ) ) ); 933 934 } 935 936 public void error( final TransformerException e ) 937 throws TransformerException 938 { 939 throw new TransformerException( 940 DefaultModelBundle.getInstance(). 941 getParseExceptionMessage( 942 Locale.getDefault(), rsrc.toExternalForm(), 943 e.getMessage(), 944 new Integer( e.getLocator().getLineNumber() ), 945 new Integer( e.getLocator().getColumnNumber() ) ), 946 e ); 947 948 } 949 950 public void fatalError( final TransformerException e ) 951 throws TransformerException 952 { 953 throw new TransformerException( 954 DefaultModelBundle.getInstance(). 955 getParseExceptionMessage( 956 Locale.getDefault(), rsrc.toExternalForm(), 957 e.getMessage(), 958 new Integer( e.getLocator().getLineNumber() ), 959 new Integer( e.getLocator().getColumnNumber() ) ), 960 e ); 961 962 } 963 964 } ); 965 966 final Transformer t = 967 f.newTransformer( new StreamSource( rsrc.openStream() ) ); 968 969 final DOMSource source = new DOMSource( doc ); 970 final DOMResult result = new DOMResult(); 971 t.transform( source, result ); 972 973 doc = (Document) result.getNode(); 974 } 975 976 final URL documentResource = ( (URI) entry.getKey() ).toURL(); 977 final Element e = doc.getDocumentElement(); 978 String namespace = doc.getDocumentElement().getNamespaceURI(); 979 980 if ( namespace == null ) 981 { 982 throw new ModelError( 983 DefaultModelBundle.getInstance(). 984 getUnknownNamespaceMessage( 985 Locale.getDefault(), namespace, 986 doc.getDocumentElement().getNodeName() ) ); 987 988 } 989 990 final boolean deprecatedModel; 991 final String modelVersion; 992 993 if ( MODEL_NS.equals( namespace ) ) 994 { 995 deprecatedModel = true; 996 997 if ( !e.hasAttributeNS( namespace, "version" ) ) 998 { 999 throw new ModelError( 1000 DefaultModelBundle.getInstance(). 1001 getMissingAttributeMessage( 1002 Locale.getDefault(), "version", e.getLocalName() ) ); 1003 1004 } 1005 1006 modelVersion = e.getAttributeNS( namespace, "version" ); 1007 } 1008 else if ( MODULE_NS.equals( namespace ) ) 1009 { 1010 deprecatedModel = true; 1011 namespace = CONTAINER_NS; 1012 1013 if ( !e.hasAttributeNS( MODULE_NS, "modelVersion" ) ) 1014 { 1015 throw new ModelError( 1016 DefaultModelBundle.getInstance(). 1017 getMissingAttributeMessage( 1018 Locale.getDefault(), "modelVersion", 1019 e.getLocalName() ) ); 1020 1021 } 1022 1023 modelVersion = e.getAttributeNS( MODULE_NS, "modelVersion" ); 1024 } 1025 else if ( CONTAINER_NS.equals( namespace ) ) 1026 { 1027 deprecatedModel = false; 1028 1029 if ( !e.hasAttributeNS( CONTAINER_NS, "modelVersion" ) ) 1030 { 1031 throw new ModelError( 1032 DefaultModelBundle.getInstance(). 1033 getMissingAttributeMessage( 1034 Locale.getDefault(), "modelVersion", 1035 e.getLocalName() ) ); 1036 1037 } 1038 1039 modelVersion = e.getAttributeNS( CONTAINER_NS, "modelVersion" ); 1040 } 1041 else 1042 { 1043 throw new ModelError( 1044 DefaultModelBundle.getInstance(). 1045 getUnknownNamespaceMessage( 1046 Locale.getDefault(), namespace, 1047 doc.getDocumentElement().getLocalName() ) ); 1048 1049 } 1050 1051 boolean versionSupported = false; 1052 if ( modelVersion != null ) 1053 { 1054 for ( int i = SUPPORTED_MODEL_VERSIONS.length - 1; i >= 0; i-- ) 1055 { 1056 if ( SUPPORTED_MODEL_VERSIONS[i].equals( modelVersion ) ) 1057 { 1058 versionSupported = true; 1059 break; 1060 } 1061 } 1062 } 1063 1064 if ( !versionSupported ) 1065 { 1066 throw new ModelError( 1067 DefaultModelBundle.getInstance(). 1068 getUnsupportedModelversionMessage( 1069 Locale.getDefault(), modelVersion ) ); 1070 1071 } 1072 1073 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1074 { 1075 if ( e.getLocalName().equals( "module" ) ) 1076 { 1077 final Module m = this.transformModule( 1078 modelVersion, namespace, e, documentResource ); 1079 1080 if ( m != null ) 1081 { 1082 list.add( m ); 1083 } 1084 } 1085 else if ( e.getLocalName().equals( "modules" ) ) 1086 { 1087 final NodeList l = e.getElementsByTagNameNS( namespace, 1088 "module" ); 1089 1090 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1091 { 1092 if ( l.item( i ).getParentNode().equals( e ) ) 1093 { 1094 final Module m = this.transformModule( 1095 modelVersion, namespace, (Element) l.item( i ), 1096 documentResource ); 1097 1098 if ( m != null ) 1099 { 1100 list.add( m ); 1101 } 1102 } 1103 } 1104 } 1105 else 1106 { 1107 throw new ModelError( 1108 DefaultModelBundle.getInstance(). 1109 getUnsupportedElementMessage( Locale.getDefault(), 1110 e.getLocalName() ) ); 1111 1112 } 1113 } 1114 else 1115 { 1116 final Module m = this.transformModule( modelVersion, namespace, 1117 e, documentResource ); 1118 1119 if ( m != null ) 1120 { 1121 list.add( m ); 1122 } 1123 } 1124 1125 if ( deprecatedModel ) 1126 { 1127 if ( LOGGER.isLoggable( Level.CONFIG ) ) 1128 { 1129 LOGGER.log( Level.CONFIG, DefaultModelBundle.getInstance(). 1130 getDeprecatedModelMessage( Locale.getDefault(), 1131 namespace, 1132 modelVersion ) ); 1133 1134 } 1135 } 1136 } 1137 1138 // Merge any provided platform modules. 1139 Module providedPlatformModule = null; 1140 for ( final Iterator it = list.iterator(); it.hasNext(); ) 1141 { 1142 final Module module = (Module) it.next(); 1143 if ( PLATFORM_MODULE_NAME.equals( module.getName() ) ) 1144 { 1145 providedPlatformModule = module; 1146 it.remove(); 1147 break; 1148 } 1149 } 1150 1151 mods.setModules( 1152 (Module[]) list.toArray( new Module[ list.size() ] ) ); 1153 1154 this.modules = mods; 1155 1156 if ( providedPlatformModule != null && 1157 providedPlatformModule.getSpecifications() != null ) 1158 { 1159 for ( int i = providedPlatformModule.getSpecifications().size() - 1; 1160 i >= 0; i-- ) 1161 { 1162 this.addPlatformSpecification( 1163 providedPlatformModule.getSpecifications(). 1164 getSpecification( i ).getIdentifier(), true ); 1165 1166 } 1167 } 1168 1169 return mods; 1170 } 1171 1172 private Specifications transformSpecifications( 1173 final String modelVersion, final String namespace, 1174 final Element specificationsElement ) throws ParseException 1175 { 1176 final List list = new LinkedList(); 1177 NodeList l = 1178 specificationsElement.getElementsByTagNameNS( namespace, 1179 "specification" ); 1180 1181 if ( l != null && l.getLength() > 0 ) 1182 { 1183 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1184 { 1185 if ( l.item( i ).getParentNode(). 1186 equals( specificationsElement ) ) 1187 { 1188 list.add( this.transformSpecification( 1189 modelVersion, namespace, (Element) l.item( i ) ) ); 1190 1191 } 1192 } 1193 } 1194 1195 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1196 { 1197 l = specificationsElement.getElementsByTagNameNS( namespace, 1198 "reference" ); 1199 1200 if ( l != null && l.getLength() > 0 ) 1201 { 1202 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1203 { 1204 if ( l.item( i ).getParentNode(). 1205 equals( specificationsElement ) ) 1206 { 1207 list.add( 1208 this.transformSpecificationReference( 1209 namespace, (Element) l.item( i ) ) ); 1210 1211 } 1212 } 1213 } 1214 } 1215 1216 final Specifications specs = new Specifications(); 1217 specs.setModelVersion( modelVersion ); 1218 specs.setSpecifications( (Specification[]) list.toArray( 1219 new Specification[ list.size() ] ) ); 1220 1221 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1222 { 1223 this.transformModelObject( namespace, specificationsElement, specs ); 1224 } 1225 1226 return specs; 1227 } 1228 1229 private Implementations transformImplementations( 1230 final String modelVersion, final String namespace, 1231 final Module module, final Element implementationsElement ) 1232 throws ParseException 1233 { 1234 final List list = new LinkedList(); 1235 final NodeList l = 1236 implementationsElement.getElementsByTagNameNS( namespace, 1237 "implementation" ); 1238 1239 if ( l != null && l.getLength() > 0 ) 1240 { 1241 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1242 { 1243 if ( l.item( i ).getParentNode(). 1244 equals( implementationsElement ) ) 1245 { 1246 list.add( this.transformImplementation( 1247 modelVersion, namespace, module, 1248 (Element) l.item( i ) ) ); 1249 1250 } 1251 } 1252 } 1253 1254 final Implementations impls = new Implementations(); 1255 impls.setModelVersion( modelVersion ); 1256 impls.setImplementations( (Implementation[]) list.toArray( 1257 new Implementation[ list.size() ] ) ); 1258 1259 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1260 { 1261 this.transformModelObject( namespace, implementationsElement, 1262 impls ); 1263 1264 } 1265 1266 return impls; 1267 } 1268 1269 private Properties transformProperties( 1270 final String modelVersion, final String namespace, 1271 final Element propertiesElement ) 1272 throws ParseException 1273 { 1274 final Map transformed = new TreeMap(); 1275 final NodeList l = 1276 propertiesElement.getElementsByTagNameNS( namespace, "property" ); 1277 1278 if ( l != null && l.getLength() > 0 ) 1279 { 1280 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1281 { 1282 if ( l.item( i ).getParentNode().equals( propertiesElement ) ) 1283 { 1284 final Property p = this.transformProperty( 1285 modelVersion, namespace, (Element) l.item( i ) ); 1286 1287 if ( propertiesElement.getParentNode().getLocalName(). 1288 equals( "specification" ) ) 1289 { 1290 p.setValue( null ); 1291 p.setApi( true ); 1292 } 1293 1294 transformed.put( p.getName(), p ); 1295 } 1296 } 1297 } 1298 1299 final Properties props = new Properties(); 1300 props.setModelVersion( modelVersion ); 1301 props.setProperties( (Property[]) transformed.values().toArray( 1302 new Property[ transformed.size() ] ) ); 1303 1304 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1305 { 1306 this.transformModelObject( namespace, propertiesElement, props ); 1307 } 1308 1309 return props; 1310 } 1311 1312 private Dependencies transformDependencies( 1313 final String modelVersion, final String namespace, 1314 final String implementationIdentifier, 1315 final Element dependenciesElement ) throws ParseException 1316 { 1317 final List list = new LinkedList(); 1318 final NodeList l = 1319 dependenciesElement.getElementsByTagNameNS( namespace, 1320 "dependency" ); 1321 1322 if ( l != null && l.getLength() > 0 ) 1323 { 1324 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1325 { 1326 if ( l.item( i ).getParentNode().equals( dependenciesElement ) ) 1327 { 1328 list.add( 1329 this.transformDependency( modelVersion, namespace, 1330 implementationIdentifier, 1331 (Element) l.item( i ) ) ); 1332 1333 } 1334 } 1335 } 1336 1337 final Dependencies deps = new Dependencies(); 1338 deps.setModelVersion( modelVersion ); 1339 deps.setDependencies( (Dependency[]) list.toArray( 1340 new Dependency[ list.size() ] ) ); 1341 1342 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1343 { 1344 this.transformModelObject( namespace, dependenciesElement, deps ); 1345 } 1346 1347 return deps; 1348 } 1349 1350 private Messages transformMessages( 1351 final String modelVersion, final String namespace, final Module module, 1352 final Element messagesElement ) 1353 { 1354 final List messages = new LinkedList(); 1355 NodeList l = messagesElement.getElementsByTagNameNS( namespace, 1356 "message" ); 1357 1358 if ( l != null && l.getLength() > 0 ) 1359 { 1360 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1361 { 1362 if ( l.item( i ).getParentNode().equals( messagesElement ) ) 1363 { 1364 messages.add( 1365 this.transformMessage( modelVersion, module.getName(), 1366 namespace, 1367 (Element) l.item( i ) ) ); 1368 1369 } 1370 } 1371 } 1372 1373 l = messagesElement.getElementsByTagNameNS( namespace, 1374 "reference" ); 1375 1376 if ( l != null && l.getLength() > 0 ) 1377 { 1378 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1379 { 1380 if ( l.item( i ).getParentNode().equals( messagesElement ) ) 1381 { 1382 final String name = 1383 ( (Element) l.item( i ) ).getAttributeNS( 1384 namespace, "name" ); 1385 1386 messages.add( module.getMessages().getMessage( name ) ); 1387 } 1388 } 1389 } 1390 1391 final Messages msgs = new Messages(); 1392 msgs.setModelVersion( modelVersion ); 1393 msgs.setMessages( (Message[]) messages.toArray( 1394 new Message[ messages.size() ] ) ); 1395 1396 this.transformModelObject( namespace, messagesElement, msgs ); 1397 1398 return msgs; 1399 } 1400 1401 private Arguments transformArguments( 1402 final String modelVersion, final String namespace, 1403 final Element argumentsElement ) 1404 { 1405 final List arguments = new LinkedList(); 1406 final NodeList l = 1407 argumentsElement.getElementsByTagNameNS( namespace, 1408 "argument" ); 1409 1410 if ( l != null && l.getLength() > 0 ) 1411 { 1412 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1413 { 1414 if ( l.item( i ).getParentNode().equals( argumentsElement ) ) 1415 { 1416 arguments.add( 1417 this.transformArgument( modelVersion, namespace, 1418 (Element) l.item( i ) ) ); 1419 1420 } 1421 } 1422 } 1423 1424 Collections.sort( arguments, new Comparator() 1425 { 1426 1427 public int compare( final Object o1, final Object o2 ) 1428 { 1429 return ( (Argument) o1 ).getIndex() - 1430 ( (Argument) o2 ).getIndex(); 1431 1432 } 1433 1434 } ); 1435 1436 final Arguments args = new Arguments(); 1437 args.setModelVersion( modelVersion ); 1438 args.setArguments( (Argument[]) arguments.toArray( 1439 new Argument[ arguments.size() ] ) ); 1440 1441 this.transformModelObject( namespace, argumentsElement, args ); 1442 1443 return args; 1444 } 1445 1446 private Module transformModule( final String modelVersion, 1447 final String namespace, final Element e, 1448 final URL documentResource ) 1449 throws ParseException 1450 { 1451 NodeList l; 1452 Module module = new Module(); 1453 module.setModelVersion( modelVersion ); 1454 module.setName( e.getAttributeNS( namespace, "name" ) ); 1455 module.setVersion( e.getAttributeNS( namespace, "version" ) ); 1456 if ( e.hasAttributeNS( namespace, "description" ) ) 1457 { 1458 final String txt = e.getAttributeNS( namespace, "description" ); 1459 module.setDescription( txt ); 1460 } 1461 1462 l = e.getElementsByTagNameNS( namespace, "specifications" ); 1463 1464 if ( l != null && l.getLength() > 0 ) 1465 { 1466 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1467 { 1468 if ( l.item( i ).getParentNode().equals( e ) ) 1469 { 1470 module.setSpecifications( 1471 this.transformSpecifications( 1472 modelVersion, namespace, (Element) l.item( i ) ) ); 1473 1474 break; 1475 } 1476 } 1477 } 1478 1479 l = e.getElementsByTagNameNS( namespace, "properties" ); 1480 1481 if ( l != null && l.getLength() > 0 ) 1482 { 1483 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1484 { 1485 if ( l.item( i ).getParentNode().equals( e ) ) 1486 { 1487 module.setProperties( 1488 this.transformProperties( 1489 modelVersion, namespace, (Element) l.item( i ) ) ); 1490 1491 break; 1492 } 1493 } 1494 } 1495 1496 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1497 { 1498 l = e.getElementsByTagNameNS( namespace, "messages" ); 1499 1500 if ( l != null && l.getLength() > 0 ) 1501 { 1502 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1503 { 1504 if ( l.item( i ).getParentNode().equals( e ) ) 1505 { 1506 module.setMessages( 1507 this.transformMessages( 1508 modelVersion, namespace, module, 1509 (Element) l.item( i ) ) ); 1510 1511 break; 1512 } 1513 } 1514 } 1515 1516 this.transformModelObject( namespace, e, module ); 1517 } 1518 1519 l = e.getElementsByTagNameNS( namespace, "implementations" ); 1520 1521 if ( l != null && l.getLength() > 0 ) 1522 { 1523 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1524 { 1525 if ( l.item( i ).getParentNode().equals( e ) ) 1526 { 1527 module.setImplementations( 1528 this.transformImplementations( 1529 modelVersion, namespace, module, 1530 (Element) l.item( i ) ) ); 1531 1532 break; 1533 } 1534 } 1535 } 1536 1537 if ( this.moduleMap.containsKey( module.getName() ) && 1538 Beans.isDesignTime() ) 1539 { 1540 if ( LOGGER.isLoggable( Level.CONFIG ) ) 1541 { 1542 LOGGER.log( Level.CONFIG, DefaultModelBundle.getInstance(). 1543 getIgnoredModuleMessage( 1544 Locale.getDefault(), documentResource.toExternalForm(), 1545 ( (URL) this.moduleMap.get( module.getName() ) ). 1546 toExternalForm() ) ); 1547 1548 } 1549 1550 module = null; 1551 } 1552 else 1553 { 1554 this.moduleMap.put( module.getName(), documentResource ); 1555 } 1556 1557 return module; 1558 } 1559 1560 private Specification transformSpecificationReference( 1561 final String namespace, final Element e ) 1562 { 1563 String version = null; 1564 final String identifier = e.getAttributeNS( namespace, "identifier" ); 1565 if ( e.hasAttributeNS( namespace, "version" ) ) 1566 { 1567 version = e.getAttributeNS( namespace, "version" ); 1568 } 1569 1570 return this.getSpecification( identifier, version ); 1571 } 1572 1573 private Specification transformSpecification( final String modelVersion, 1574 final String namespace, 1575 final Element xml ) 1576 throws ParseException 1577 { 1578 final Specification spec = 1579 this.transformSpecificationReference( namespace, xml ); 1580 1581 spec.setModelVersion( modelVersion ); 1582 spec.setVendor( xml.getAttributeNS( namespace, "vendor" ) ); 1583 if ( xml.hasAttributeNS( namespace, "description" ) ) 1584 { 1585 final String txt = xml.getAttributeNS( namespace, "description" ); 1586 spec.setDescription( txt ); 1587 } 1588 1589 if ( xml.hasAttributeNS( namespace, "singleton" ) ) 1590 { 1591 spec.setSingleton( 1592 Boolean.valueOf( xml.getAttributeNS( 1593 namespace, "singleton" ) ).booleanValue() ); 1594 1595 } 1596 1597 if ( VersionParser.compare( modelVersion, V_1_1 ) >= 0 ) 1598 { 1599 final String multiplicity = 1600 xml.getAttributeNS( namespace, "multiplicity" ); 1601 1602 if ( "one".equalsIgnoreCase( multiplicity ) ) 1603 { 1604 spec.setMultiplicity( Specification.MULTIPLICITY_ONE ); 1605 } 1606 else if ( "many".equalsIgnoreCase( multiplicity ) ) 1607 { 1608 spec.setMultiplicity( Specification.MULTIPLICITY_MANY ); 1609 } 1610 else 1611 { 1612 throw new ModelError( 1613 DefaultModelBundle.getInstance(). 1614 getUnsupportedMultiplicityMessage( Locale.getDefault(), 1615 multiplicity ) ); 1616 1617 } 1618 } 1619 1620 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1621 { 1622 if ( xml.hasAttributeNS( namespace, "stateless" ) ) 1623 { 1624 spec.setStateless( Boolean.valueOf( xml.getAttributeNS( 1625 namespace, "stateless" ) ).booleanValue() ); 1626 1627 } 1628 1629 final String scope = xml.getAttributeNS( namespace, "scope" ); 1630 if ( "multiton".equalsIgnoreCase( scope ) ) 1631 { 1632 spec.setScope( Specification.SCOPE_MULTITON ); 1633 } 1634 else if ( "context".equalsIgnoreCase( scope ) ) 1635 { 1636 spec.setScope( Specification.SCOPE_CONTEXT ); 1637 } 1638 else if ( "singleton".equalsIgnoreCase( scope ) ) 1639 { 1640 spec.setScope( Specification.SCOPE_SINGLETON ); 1641 } 1642 else 1643 { 1644 throw new ModelError( 1645 DefaultModelBundle.getInstance(). 1646 getUnsupportedScopeMessage( Locale.getDefault(), 1647 spec.getIdentifier(), scope ) ); 1648 1649 } 1650 1651 final NodeList l = 1652 xml.getElementsByTagNameNS( namespace, "properties" ); 1653 1654 if ( l != null && l.getLength() > 0 ) 1655 { 1656 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1657 { 1658 if ( l.item( i ).getParentNode().equals( xml ) ) 1659 { 1660 spec.setProperties( 1661 this.transformProperties( 1662 modelVersion, namespace, (Element) l.item( i ) ) ); 1663 1664 break; 1665 } 1666 } 1667 } 1668 1669 this.transformModelObject( namespace, xml, spec ); 1670 } 1671 1672 return spec; 1673 } 1674 1675 private Implementation transformImplementation( final String modelVersion, 1676 final String namespace, 1677 final Module module, 1678 final Element xml ) 1679 throws ParseException 1680 { 1681 final String identifier = xml.getAttributeNS( namespace, "identifier" ); 1682 final Implementation impl = this.getImplementation( identifier ); 1683 impl.setModelVersion( modelVersion ); 1684 impl.setModuleName( module.getName() ); 1685 impl.setName( xml.getAttributeNS( namespace, "name" ) ); 1686 impl.setVendor( xml.getAttributeNS( namespace, "vendor" ) ); 1687 impl.setVersion( xml.getAttributeNS( namespace, "version" ) ); 1688 1689 if ( xml.hasAttributeNS( namespace, "parent" ) ) 1690 { 1691 this.impl2parent.put( impl.getIdentifier(), 1692 xml.getAttributeNS( namespace, "parent" ) ); 1693 1694 } 1695 1696 NodeList l = xml.getElementsByTagNameNS( namespace, "dependencies" ); 1697 1698 if ( l != null && l.getLength() > 0 ) 1699 { 1700 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1701 { 1702 if ( l.item( i ).getParentNode().equals( xml ) ) 1703 { 1704 impl.setDependencies( 1705 this.transformDependencies( 1706 modelVersion, namespace, identifier, 1707 (Element) l.item( i ) ) ); 1708 1709 break; 1710 } 1711 } 1712 } 1713 1714 final String specificationsName = 1715 VersionParser.compare( modelVersion, V_1_3 ) >= 0 1716 ? "specifications" 1717 : "implementedSpecifications"; 1718 1719 l = xml.getElementsByTagNameNS( namespace, specificationsName ); 1720 if ( l != null && l.getLength() > 0 ) 1721 { 1722 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1723 { 1724 if ( l.item( i ).getParentNode().equals( xml ) ) 1725 { 1726 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1727 { 1728 impl.setImplementedSpecifications( 1729 this.transformSpecifications( 1730 modelVersion, namespace, (Element) l.item( i ) ) ); 1731 1732 break; 1733 } 1734 else 1735 { 1736 final Set set = new HashSet(); 1737 final NodeList deprecated = 1738 ( (Element) l.item( i ) ).getElementsByTagNameNS( 1739 namespace, "implementedSpecification" ); 1740 1741 if ( deprecated != null && deprecated.getLength() > 0 ) 1742 { 1743 for ( int d = deprecated.getLength() - 1; d >= 0; 1744 d-- ) 1745 { 1746 if ( deprecated.item( d ).getParentNode(). 1747 equals( l.item( i ) ) ) 1748 { 1749 set.add( 1750 this.transformSpecificationReference( 1751 namespace, 1752 (Element) deprecated.item( d ) ) ); 1753 1754 } 1755 } 1756 } 1757 1758 final Specifications specs = new Specifications(); 1759 specs.setModelVersion( modelVersion ); 1760 specs.setSpecifications( 1761 (Specification[]) set.toArray( 1762 new Specification[ set.size() ] ) ); 1763 1764 impl.setImplementedSpecifications( specs ); 1765 break; 1766 } 1767 } 1768 } 1769 } 1770 1771 l = xml.getElementsByTagNameNS( namespace, "properties" ); 1772 1773 if ( l != null && l.getLength() > 0 ) 1774 { 1775 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1776 { 1777 if ( l.item( i ).getParentNode().equals( xml ) ) 1778 { 1779 impl.setProperties( 1780 this.transformProperties( modelVersion, namespace, 1781 (Element) l.item( i ) ) ); 1782 1783 break; 1784 } 1785 } 1786 } 1787 1788 if ( VersionParser.compare( modelVersion, V_1_1 ) >= 0 && 1789 xml.hasAttributeNS( namespace, "final" ) ) 1790 { 1791 impl.setFinal( Boolean.valueOf( xml.getAttributeNS( namespace, 1792 "final" ) ). 1793 booleanValue() ); 1794 1795 } 1796 1797 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1798 { 1799 l = xml.getElementsByTagNameNS( namespace, "messages" ); 1800 1801 if ( l != null && l.getLength() > 0 ) 1802 { 1803 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1804 { 1805 if ( l.item( i ).getParentNode().equals( xml ) ) 1806 { 1807 impl.setMessages( this.transformMessages( 1808 modelVersion, namespace, module, 1809 (Element) l.item( i ) ) ); 1810 1811 break; 1812 } 1813 } 1814 } 1815 1816 this.transformModelObject( namespace, xml, impl ); 1817 } 1818 1819 return impl; 1820 } 1821 1822 private Property transformProperty( final String modelVersion, 1823 final String namespace, 1824 final Element xml ) 1825 throws ParseException 1826 { 1827 final Property prop = new Property(); 1828 prop.setModelVersion( modelVersion ); 1829 prop.setName( xml.getAttributeNS( namespace, "name" ) ); 1830 1831 if ( xml.hasAttributeNS( namespace, "api" ) ) 1832 { 1833 final String api = xml.getAttributeNS( namespace, "api" ); 1834 prop.setApi( Boolean.valueOf( api ).booleanValue() ); 1835 } 1836 1837 final String type = xml.hasAttributeNS( namespace, "type" ) 1838 ? xml.getAttributeNS( namespace, "type" ) 1839 : null; 1840 1841 final String value = xml.hasAttributeNS( namespace, "value" ) 1842 ? xml.getAttributeNS( namespace, "value" ) 1843 : null; 1844 1845 if ( type == null ) 1846 { 1847 throw new ModelError( 1848 DefaultModelBundle.getInstance(). 1849 getMissingPropertyTypeMessage( 1850 Locale.getDefault(), prop.getName(), 1851 xml.getParentNode().getParentNode().getLocalName() ) ); 1852 1853 } 1854 1855 this.updatePropertyValue( type, value, prop ); 1856 1857 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1858 { 1859 this.transformModelObject( namespace, xml, prop ); 1860 } 1861 1862 return prop; 1863 } 1864 1865 private Dependency transformDependency( 1866 final String modelVersion, final String namespace, 1867 final String implementationIdentifier, final Element xml ) 1868 throws ParseException 1869 { 1870 final Dependency dep = new Dependency(); 1871 dep.setModelVersion( modelVersion ); 1872 dep.setName( xml.getAttributeNS( namespace, "name" ) ); 1873 1874 if ( xml.hasAttributeNS( namespace, "bound" ) ) 1875 { 1876 dep.setBound( Boolean.valueOf( xml.getAttributeNS( namespace, 1877 "bound" ) ). 1878 booleanValue() ); 1879 1880 } 1881 1882 if ( xml.hasAttributeNS( namespace, "implementationName" ) ) 1883 { 1884 final String name = xml.getAttributeNS( namespace, 1885 "implementationName" ); 1886 1887 final String key = implementationIdentifier + '/' + 1888 dep.getName(); 1889 1890 this.dependencies.put( key, name ); 1891 } 1892 1893 final String specificationIdentifier = 1894 VersionParser.compare( modelVersion, V_1_3 ) < 0 1895 ? "specificationIdentifier" 1896 : "identifier"; 1897 1898 final String identifier = xml.getAttributeNS( namespace, 1899 specificationIdentifier ); 1900 1901 if ( VersionParser.compare( modelVersion, V_1_3 ) < 0 ) 1902 { 1903 dep.setSpecification( this.getSpecification( identifier, null ) ); 1904 } 1905 else 1906 { 1907 String version = null; 1908 if ( xml.hasAttributeNS( namespace, "version" ) ) 1909 { 1910 version = xml.getAttributeNS( namespace, "version" ); 1911 } 1912 1913 dep.setSpecification( this.getSpecification( identifier, 1914 version ) ); 1915 1916 } 1917 1918 final NodeList l = 1919 xml.getElementsByTagNameNS( namespace, "properties" ); 1920 1921 if ( l != null && l.getLength() > 0 ) 1922 { 1923 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1924 { 1925 if ( l.item( i ).getParentNode().equals( xml ) ) 1926 { 1927 dep.setProperties( 1928 this.transformProperties( 1929 modelVersion, namespace, (Element) l.item( i ) ) ); 1930 1931 break; 1932 } 1933 } 1934 } 1935 1936 if ( VersionParser.compare( modelVersion, V_1_3 ) >= 0 ) 1937 { 1938 this.transformModelObject( namespace, xml, dep ); 1939 } 1940 1941 return dep; 1942 } 1943 1944 private Text transformText( final String namespace, 1945 final Element textsElement ) 1946 { 1947 final Text text = new Text(); 1948 final String defaultLanguage = 1949 textsElement.getAttributeNS( namespace, "defaultLanguage" ); 1950 1951 final NodeList l = 1952 textsElement.getElementsByTagNameNS( namespace, "text" ); 1953 1954 if ( l != null && l.getLength() > 0 ) 1955 { 1956 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1957 { 1958 final Element textElement = (Element) l.item( i ); 1959 if ( textElement.getParentNode().equals( textsElement ) ) 1960 { 1961 final String language = 1962 textElement.getAttributeNS( namespace, "language" ); 1963 1964 final String value = 1965 textElement.getFirstChild().getNodeValue(); 1966 1967 final Locale locale = new Locale( language.toLowerCase() ); 1968 text.setValue( locale, value ); 1969 1970 if ( language.equalsIgnoreCase( defaultLanguage ) ) 1971 { 1972 text.setValue( value ); 1973 } 1974 } 1975 } 1976 } 1977 1978 return text; 1979 } 1980 1981 private void transformModelObject( final String namespace, 1982 final Element objectElement, 1983 final ModelObject modelObject ) 1984 { 1985 final NodeList l = objectElement.getElementsByTagNameNS( 1986 namespace, "documentation" ); 1987 1988 if ( l != null && l.getLength() > 0 ) 1989 { 1990 for ( int i = l.getLength() - 1; i >= 0; i-- ) 1991 { 1992 if ( l.item( i ).getParentNode().equals( objectElement ) ) 1993 { 1994 modelObject.setDocumentation( 1995 this.transformText( namespace, 1996 (Element) l.item( i ) ) ); 1997 1998 break; 1999 } 2000 } 2001 } 2002 } 2003 2004 private Message transformMessage( final String modelVersion, 2005 final String moduleName, 2006 final String namespace, 2007 final Element xml ) 2008 { 2009 final Message msg = new Message(); 2010 msg.setModelVersion( modelVersion ); 2011 msg.setModuleName( moduleName ); 2012 msg.setName( xml.getAttributeNS( namespace, "name" ) ); 2013 2014 NodeList l = xml.getElementsByTagNameNS( namespace, "template" ); 2015 2016 if ( l != null && l.getLength() > 0 ) 2017 { 2018 for ( int i = l.getLength() - 1; i >= 0; i-- ) 2019 { 2020 if ( l.item( i ).getParentNode().equals( xml ) ) 2021 { 2022 final Text template = this.transformText( 2023 namespace, (Element) l.item( i ) ); 2024 2025 final Locale[] locales = template.getLocales(); 2026 for ( int t = locales.length - 1; t >= 0; t-- ) 2027 { 2028 final String text = template.getValue( locales[t] ); 2029 try 2030 { 2031 new MessageFormat( text ); 2032 } 2033 catch ( final IllegalArgumentException e ) 2034 { 2035 final ModelError modelError = new ModelError( 2036 DefaultModelBundle.getInstance(). 2037 getIllegalTemplateMessage( Locale.getDefault(), 2038 text, msg.getName(), 2039 e.getMessage() ) ); 2040 2041 modelError.initCause( e ); 2042 throw modelError; 2043 } 2044 } 2045 2046 if ( template.getValue() != null ) 2047 { 2048 try 2049 { 2050 new MessageFormat( template.getValue() ); 2051 } 2052 catch ( final IllegalArgumentException e ) 2053 { 2054 final ModelError modelError = new ModelError( 2055 DefaultModelBundle.getInstance(). 2056 getIllegalTemplateMessage( Locale.getDefault(), 2057 template.getValue(), 2058 msg.getName(), 2059 e.getMessage() ) ); 2060 2061 modelError.initCause( e ); 2062 throw modelError; 2063 } 2064 } 2065 2066 msg.setTemplate( template ); 2067 break; 2068 } 2069 } 2070 } 2071 2072 l = xml.getElementsByTagNameNS( namespace, "arguments" ); 2073 2074 if ( l != null && l.getLength() > 0 ) 2075 { 2076 for ( int i = l.getLength() - 1; i >= 0; i-- ) 2077 { 2078 if ( l.item( i ).getParentNode().equals( xml ) ) 2079 { 2080 msg.setArguments( 2081 this.transformArguments( 2082 modelVersion, namespace, (Element) l.item( i ) ) ); 2083 2084 break; 2085 } 2086 } 2087 } 2088 2089 this.transformModelObject( namespace, xml, msg ); 2090 2091 return msg; 2092 } 2093 2094 private Argument transformArgument( final String modelVersion, 2095 final String namespace, 2096 final Element xml ) 2097 { 2098 final Argument arg = new Argument(); 2099 arg.setModelVersion( modelVersion ); 2100 arg.setName( xml.getAttributeNS( namespace, "name" ) ); 2101 arg.setIndex( Integer.valueOf( xml.getAttributeNS( namespace, 2102 "index" ) ). 2103 intValue() ); 2104 2105 final String type = xml.getAttributeNS( namespace, "type" ); 2106 if ( type.equalsIgnoreCase( "number" ) ) 2107 { 2108 arg.setType( Argument.TYPE_NUMBER ); 2109 } 2110 else if ( type.equalsIgnoreCase( "date" ) ) 2111 { 2112 arg.setType( Argument.TYPE_DATE ); 2113 } 2114 else if ( type.equalsIgnoreCase( "time" ) ) 2115 { 2116 arg.setType( Argument.TYPE_TIME ); 2117 } 2118 else if ( type.equalsIgnoreCase( "text" ) ) 2119 { 2120 arg.setType( Argument.TYPE_TEXT ); 2121 } 2122 else 2123 { 2124 throw new ModelError( DefaultModelBundle.getInstance(). 2125 getUnsupportedArgumentTypeMessage( 2126 Locale.getDefault(), type ) ); 2127 2128 } 2129 2130 this.transformModelObject( namespace, xml, arg ); 2131 2132 return arg; 2133 } 2134 2135 /** 2136 * Gets the {@code Module} holding platform specifications. 2137 * 2138 * @return the {@code Module} holding platform specifications. 2139 */ 2140 protected Module getPlatformModule() 2141 { 2142 if ( this.platformModule == null ) 2143 { 2144 final String description = 2145 DefaultModelBundle.getInstance(). 2146 getPlatformModuleDescriptionMessage( Locale.getDefault() ); 2147 2148 this.platformModule = new Module(); 2149 this.platformModule.getDocumentation().setValue( description ); 2150 this.platformModule.setName( PLATFORM_MODULE_NAME ); 2151 this.platformModule.setVersion( PLATFORM_MODULE_VERSION ); 2152 2153 if ( LOGGER.isLoggable( Level.CONFIG ) ) 2154 { 2155 LOGGER.log( Level.CONFIG, DefaultModelBundle.getInstance(). 2156 getAddedPlatformModuleMessage( 2157 Locale.getDefault(), 2158 this.platformModule.getDocumentation().getValue() ) ); 2159 } 2160 } 2161 2162 return this.platformModule; 2163 } 2164 2165 /** 2166 * Checks an identifier to identify a valid platform specification. 2167 * 2168 * @param identifier the identifier to check. 2169 * 2170 * @return {@code true} if {@code identifier} identifies a valid platform 2171 * specification; {@code false} else. 2172 * 2173 * @throws NullPointerException if {@code identifier} is {@code null}. 2174 */ 2175 protected boolean isPlatformSpecification( final String identifier ) 2176 { 2177 return this.addPlatformSpecification( identifier, false ); 2178 } 2179 2180 /** 2181 * Checks an identifier to identify a valid platform specification and 2182 * optionally adds a new {@code Specification} instance to the platform 2183 * module. 2184 * 2185 * @param identifier the identifier to check. 2186 * @param add {@code true} to add a new {@code Specification} instance to 2187 * the platform module; {@code false} to not update the platform module. 2188 * 2189 * @return {@code true} if {@code identifier} is an identifier of a valid 2190 * platform specification; {@code false} else. 2191 */ 2192 private boolean addPlatformSpecification( final String identifier, 2193 final boolean add ) 2194 { 2195 if ( identifier == null ) 2196 { 2197 throw new NullPointerException( "identifier" ); 2198 } 2199 2200 boolean validPlatformSpec = false; 2201 2202 try 2203 { 2204 final Class platformClass = ClassLoaderFactory.loadClass( 2205 this.getClass(), identifier ); 2206 2207 if ( Modifier.isPublic( platformClass.getModifiers() ) ) 2208 { 2209 if ( platformClass.getPackage() != null ) 2210 { 2211 final String specVersion = platformClass.getPackage(). 2212 getSpecificationVersion(); 2213 2214 String specVendor = platformClass.getPackage(). 2215 getSpecificationVendor(); 2216 2217 if ( specVendor == null ) 2218 { 2219 specVendor = DefaultModelBundle.getInstance(). 2220 getUnknownVendorMessage( Locale.getDefault() ); 2221 2222 } 2223 2224 if ( specVersion != null ) 2225 { 2226 validPlatformSpec = true; 2227 2228 if ( add ) 2229 { 2230 // Add to the platform module. 2231 try 2232 { 2233 final Specification platformSpec = 2234 this.getSpecification( identifier, 2235 specVersion ); 2236 2237 platformSpec.setModelVersion( MODEL_VERSION ); 2238 platformSpec.setDocumentation( 2239 this.getPlatformModule(). 2240 getDocumentation() ); 2241 2242 platformSpec.setIdentifier( identifier ); 2243 platformSpec.setModuleName( 2244 this.getPlatformModule().getName() ); 2245 2246 platformSpec.setMultiplicity( 2247 Specification.MULTIPLICITY_MANY ); 2248 2249 platformSpec.setScope( 2250 Specification.SCOPE_MULTITON ); 2251 2252 platformSpec.setVendor( specVendor ); 2253 2254 final Specification[] platformSpecs = 2255 this.getPlatformModule(). 2256 getSpecifications().getSpecifications(); 2257 2258 final Specification[] newPlatformSpecs = 2259 new Specification[ platformSpecs.length + 1 ]; 2260 2261 System.arraycopy( platformSpecs, 0, 2262 newPlatformSpecs, 0, 2263 platformSpecs.length ); 2264 2265 newPlatformSpecs[platformSpecs.length] = 2266 platformSpec; 2267 2268 final Specifications specs = 2269 new Specifications(); 2270 2271 specs.setSpecifications( newPlatformSpecs ); 2272 this.getPlatformModule(). 2273 setSpecifications( specs ); 2274 2275 if ( LOGGER.isLoggable( Level.FINE ) ) 2276 { 2277 LOGGER.log( Level.FINE, 2278 DefaultModelBundle.getInstance(). 2279 getAddedPlatformSpecificationMessage( 2280 Locale.getDefault(), identifier, 2281 specVersion, 2282 specVendor ) ); 2283 2284 } 2285 2286 this.addDefaultImplementation( platformClass, 2287 platformSpec ); 2288 2289 } 2290 catch ( final DuplicateSpecificationException e ) 2291 { 2292 // Specification already created. 2293 } 2294 } 2295 } 2296 else 2297 { 2298 LOGGER.log( Level.WARNING, 2299 DefaultModelBundle.getInstance(). 2300 getNoVersionAvailableMessage( Locale.getDefault(), 2301 identifier ) ); 2302 2303 validPlatformSpec = false; 2304 } 2305 } 2306 else 2307 { 2308 LOGGER.log( Level.WARNING, DefaultModelBundle.getInstance(). 2309 getNoPackageAvailableMessage( Locale.getDefault(), 2310 identifier ) ); 2311 2312 validPlatformSpec = false; 2313 } 2314 } 2315 else 2316 { 2317 LOGGER.log( Level.WARNING, DefaultModelBundle.getInstance(). 2318 getNotPublicMessage( Locale.getDefault(), identifier ) ); 2319 2320 validPlatformSpec = false; 2321 } 2322 } 2323 catch ( final ClassNotFoundException ex ) 2324 { 2325 LOGGER.log( Level.WARNING, DefaultModelBundle.getInstance(). 2326 getClassNotFoundMessage( Locale.getDefault(), identifier ) ); 2327 2328 validPlatformSpec = false; 2329 } 2330 2331 return validPlatformSpec; 2332 } 2333 2334 private void addDefaultImplementation( final Class platformClass, 2335 final Specification platformSpec ) 2336 { 2337 try 2338 { 2339 final Method accessor = platformClass.getDeclaredMethod( 2340 "getDefault", new Class[ 0 ] ); 2341 2342 if ( Modifier.isStatic( accessor.getModifiers() ) && 2343 accessor.getReturnType() == platformClass ) 2344 { 2345 boolean overwritten = false; 2346 2347 // Check for an overwritten implementation. 2348 for ( int i = this.modules.getImplementations().size() - 1; 2349 i >= 0; i-- ) 2350 { 2351 final Implementation resourceImpl = 2352 this.modules.getImplementations(). 2353 getImplementation( i ); 2354 2355 if ( !"default".equals( resourceImpl.getName() ) ) 2356 { 2357 continue; 2358 } 2359 2360 for ( int s = resourceImpl.getImplementedSpecifications(). 2361 size() - 1; s >= 0; s-- ) 2362 { 2363 final Specification implemented = 2364 resourceImpl.getImplementedSpecifications(). 2365 getSpecification( s ); 2366 2367 if ( implemented.getIdentifier().equals( 2368 platformSpec.getIdentifier() ) ) 2369 { 2370 if ( LOGGER.isLoggable( Level.FINE ) ) 2371 { 2372 LOGGER.log( Level.FINE, 2373 DefaultModelBundle.getInstance(). 2374 getOverwrittenDefaultImplementationMessage( 2375 Locale.getDefault(), 2376 platformSpec.getIdentifier(), 2377 platformSpec.getIdentifier(), 2378 resourceImpl.getIdentifier() ) ); 2379 2380 } 2381 2382 overwritten = true; 2383 break; 2384 } 2385 } 2386 } 2387 2388 final String implVersion = platformClass.getPackage(). 2389 getImplementationVersion(); 2390 2391 String implVendor = platformClass.getPackage(). 2392 getImplementationVendor(); 2393 2394 if ( implVendor == null ) 2395 { 2396 implVendor = DefaultModelBundle.getInstance(). 2397 getUnknownVendorMessage( Locale.getDefault() ); 2398 2399 } 2400 2401 if ( implVersion != null && !overwritten ) 2402 { 2403 final Implementation defaultImpl = this.getImplementation( 2404 platformClass.getName() ); 2405 2406 defaultImpl.setModelVersion( MODEL_VERSION ); 2407 defaultImpl.setVersion( implVersion ); 2408 defaultImpl.setVendor( implVendor ); 2409 defaultImpl.setDocumentation( 2410 platformSpec.getDocumentation() ); 2411 2412 defaultImpl.setFinal( true ); 2413 defaultImpl.setModuleName( PLATFORM_MODULE_NAME ); 2414 defaultImpl.setName( "default" ); 2415 2416 final Specifications implemented = new Specifications(); 2417 implemented.setSpecifications( new Specification[] 2418 { 2419 platformSpec 2420 } ); 2421 2422 defaultImpl.setImplementedSpecifications( implemented ); 2423 2424 final Implementation[] current = this.getPlatformModule(). 2425 getImplementations().getImplementations(); 2426 2427 final Implementation[] tmp = 2428 new Implementation[ current.length + 1 ]; 2429 2430 System.arraycopy( current, 0, tmp, 0, current.length ); 2431 tmp[current.length] = defaultImpl; 2432 2433 final Implementations impls = new Implementations(); 2434 impls.setImplementations( tmp ); 2435 2436 this.getPlatformModule().setImplementations( impls ); 2437 2438 if ( LOGGER.isLoggable( Level.FINE ) ) 2439 { 2440 LOGGER.log( Level.FINE, DefaultModelBundle.getInstance(). 2441 getAddedDefaultImplementationMessage( 2442 Locale.getDefault(), defaultImpl.getIdentifier(), 2443 platformSpec.getIdentifier(), implVersion, 2444 implVendor ) ); 2445 2446 } 2447 2448 } 2449 } 2450 } 2451 catch ( final NoSuchMethodException e ) 2452 { 2453 // No static accessor. 2454 } 2455 } 2456 2457 /** 2458 * Updates the value of a property. 2459 * 2460 * @param typeName the name of the type of {@code property}. 2461 * @param value the value of {@code property}. 2462 * @param property the property to update. 2463 */ 2464 private void updatePropertyValue( final String typeName, 2465 final String value, 2466 final Property property ) 2467 { 2468 final Class objectType; 2469 2470 if ( typeName.equals( Boolean.TYPE.getName() ) ) 2471 { 2472 property.setType( Boolean.TYPE ); 2473 objectType = Boolean.class; 2474 } 2475 else if ( typeName.equals( Byte.TYPE.getName() ) ) 2476 { 2477 property.setType( Byte.TYPE ); 2478 objectType = Byte.class; 2479 } 2480 else if ( typeName.equals( Character.TYPE.getName() ) ) 2481 { 2482 property.setType( Character.TYPE ); 2483 objectType = Character.class; 2484 } 2485 else if ( typeName.equals( Double.TYPE.getName() ) ) 2486 { 2487 property.setType( Double.TYPE ); 2488 objectType = Double.class; 2489 } 2490 else if ( typeName.equals( Float.TYPE.getName() ) ) 2491 { 2492 property.setType( Float.TYPE ); 2493 objectType = Float.class; 2494 } 2495 else if ( typeName.equals( Integer.TYPE.getName() ) ) 2496 { 2497 property.setType( Integer.TYPE ); 2498 objectType = Integer.class; 2499 } 2500 else if ( typeName.equals( Long.TYPE.getName() ) ) 2501 { 2502 property.setType( Long.TYPE ); 2503 objectType = Long.class; 2504 } 2505 else if ( typeName.equals( Short.TYPE.getName() ) ) 2506 { 2507 property.setType( Short.TYPE ); 2508 objectType = Short.class; 2509 } 2510 else if ( typeName.equals( Boolean.class.getName() ) ) 2511 { 2512 property.setType( Boolean.class ); 2513 objectType = Boolean.class; 2514 } 2515 else if ( typeName.equals( Byte.class.getName() ) ) 2516 { 2517 property.setType( Byte.class ); 2518 objectType = Byte.class; 2519 } 2520 else if ( typeName.equals( Character.class.getName() ) ) 2521 { 2522 property.setType( Character.class ); 2523 objectType = Character.class; 2524 } 2525 else if ( typeName.equals( Double.class.getName() ) ) 2526 { 2527 property.setType( Double.class ); 2528 objectType = Double.class; 2529 } 2530 else if ( typeName.equals( Float.class.getName() ) ) 2531 { 2532 property.setType( Float.class ); 2533 objectType = Float.class; 2534 } 2535 else if ( typeName.equals( Integer.class.getName() ) ) 2536 { 2537 property.setType( Integer.class ); 2538 objectType = Integer.class; 2539 } 2540 else if ( typeName.equals( Long.class.getName() ) ) 2541 { 2542 property.setType( Long.class ); 2543 objectType = Long.class; 2544 } 2545 else if ( typeName.equals( Short.class.getName() ) ) 2546 { 2547 property.setType( Short.class ); 2548 objectType = Short.class; 2549 } 2550 else if ( typeName.equals( String.class.getName() ) ) 2551 { 2552 property.setType( String.class ); 2553 objectType = String.class; 2554 } 2555 else 2556 { 2557 throw new ModelError( DefaultModelBundle.getInstance(). 2558 getUnsupportedPropertyTypeMessage( Locale.getDefault(), 2559 typeName ) ); 2560 2561 } 2562 2563 if ( value != null ) 2564 { 2565 try 2566 { 2567 // Special handling for class Character which does not provide 2568 // a constructor taking a string. 2569 final Constructor ctor; 2570 final Object arg; 2571 2572 if ( objectType == Character.class ) 2573 { 2574 ctor = objectType.getDeclaredConstructor( CTOR_ARGS_CHAR ); 2575 arg = new Character( value.charAt( 0 ) ); 2576 } 2577 else 2578 { 2579 ctor = objectType.getDeclaredConstructor( CTOR_ARGS_STRING ); 2580 arg = value; 2581 } 2582 2583 property.setValue( ctor.newInstance( new Object[] 2584 { 2585 arg 2586 } ) ); 2587 2588 } 2589 catch ( final SecurityException e ) 2590 { 2591 throw new ModelError( e ); 2592 } 2593 catch ( final NoSuchMethodException e ) 2594 { 2595 throw new ModelError( e ); 2596 } 2597 catch ( final InvocationTargetException e ) 2598 { 2599 final Throwable targetException = e.getTargetException(); 2600 2601 if ( targetException instanceof Error ) 2602 { 2603 throw (Error) targetException; 2604 } 2605 else if ( targetException instanceof RuntimeException ) 2606 { 2607 throw (RuntimeException) targetException; 2608 } 2609 else 2610 { 2611 throw new ModelError( targetException == null 2612 ? e 2613 : targetException ); 2614 2615 } 2616 } 2617 catch ( final IllegalAccessException e ) 2618 { 2619 throw new ModelError( e ); 2620 } 2621 catch ( final InstantiationException e ) 2622 { 2623 throw new ModelError( e ); 2624 } 2625 } 2626 else 2627 { 2628 property.setValue( value ); 2629 } 2630 } 2631 2632 //------------------------------------------------------------DefaultModel-- 2633}