001/* 002 * Copyright (C) 2005 Christian Schulte <cs@schulte.it> 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions 007 * are met: 008 * 009 * o Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 012 * o Redistributions in binary form must reproduce the above copyright 013 * notice, this list of conditions and the following disclaimer in 014 * the documentation and/or other materials provided with the 015 * distribution. 016 * 017 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 018 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 019 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 020 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, 021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 027 * 028 * $JOMC: JomcContainerDescriptorHandler.java 5135 2016-04-08 13:53:07Z schulte $ 029 * 030 */ 031package org.jomc.mojo; 032 033import java.io.File; 034import java.io.IOException; 035import java.io.InputStream; 036import java.net.MalformedURLException; 037import java.net.URISyntaxException; 038import java.net.URL; 039import java.util.Collections; 040import java.util.Iterator; 041import java.util.LinkedList; 042import java.util.List; 043import java.util.Map; 044import javax.xml.bind.JAXBElement; 045import javax.xml.bind.JAXBException; 046import javax.xml.bind.Marshaller; 047import javax.xml.bind.Unmarshaller; 048import javax.xml.bind.util.JAXBResult; 049import javax.xml.bind.util.JAXBSource; 050import javax.xml.transform.Transformer; 051import javax.xml.transform.TransformerConfigurationException; 052import javax.xml.transform.TransformerException; 053import javax.xml.transform.TransformerFactory; 054import javax.xml.transform.stream.StreamSource; 055import org.apache.maven.plugin.assembly.filter.ContainerDescriptorHandler; 056import org.codehaus.plexus.archiver.Archiver; 057import org.codehaus.plexus.archiver.ArchiverException; 058import org.codehaus.plexus.archiver.ResourceIterator; 059import org.codehaus.plexus.archiver.UnArchiver; 060import org.codehaus.plexus.components.io.fileselectors.FileInfo; 061import org.codehaus.plexus.logging.AbstractLogEnabled; 062import org.codehaus.plexus.util.StringUtils; 063import org.jomc.model.ModelObject; 064import org.jomc.model.Module; 065import org.jomc.model.Modules; 066import org.jomc.model.modlet.DefaultModelProvider; 067import org.jomc.modlet.DefaultModelContext; 068import org.jomc.modlet.DefaultModletProvider; 069import org.jomc.modlet.ModelContext; 070import org.jomc.modlet.ModelContextFactory; 071import org.jomc.modlet.ModelException; 072import org.jomc.modlet.Modlet; 073import org.jomc.modlet.ModletObject; 074import org.jomc.modlet.Modlets; 075 076/** 077 * Maven Assembly Plugin {@code ContainerDescriptorHandler} implementation for assembling JOMC resources. 078 * 079 * <p> 080 * <b>Maven Assembly Plugin Usage</b><pre> 081 * <containerDescriptorHandler> 082 * <handlerName>JOMC</handlerName> 083 * <configuration> 084 * <model>http://jomc.org/model</model> 085 * <modelContextFactoryClassName>class name</modelContextFactoryClassName> 086 * <modelContextAttributes> 087 * <modelContextAttribute> 088 * <key>The name of the attribute</key> 089 * <value>The name of the attribute</value> 090 * <type>The name of the class of the object.</type> 091 * </modelContextAttribute> 092 * </modelContextAttributes/> 093 * <moduleEncoding>${project.build.sourceEncoding}</moduleEncoding> 094 * <moduleName>${project.name}</moduleName> 095 * <moduleVersion>${project.version}</moduleVersion> 096 * <moduleVendor>${project.organization.name}</moduleVendor> 097 * <moduleResource>META-INF/custom-jomc.xml</moduleResource> 098 * <moduleResources> 099 * <moduleResource>META-INF/jomc.xml</moduleResource> 100 * </moduleResources> 101 * <moduleIncludes> 102 * <moduleInclude>module name</moduleInclude> 103 * </moduleIncludes> 104 * <moduleExcludes> 105 * <moduleExclude>module name</moduleExclude> 106 * </moduleExcludes> 107 * <modletEncoding>${project.build.sourceEncoding}</modletEncoding> 108 * <modletName>${project.name}</modletName> 109 * <modletVersion>${project.version}</modletVersion> 110 * <modletVendor>${project.organization.name}</modletVendor> 111 * <modletResource>META-INF/custom-jomc-modlet.xml</modletResource> 112 * <modletResources> 113 * <modletResource>META-INF/jomc-modlet.xml</modletResource> 114 * </modletResources> 115 * <modletIncludes> 116 * <modletInclude>modlet name</modletInclude> 117 * </modletIncludes> 118 * <modletExcludes> 119 * <modletExclude>modlet name</modletExclude> 120 * </modletExcludes> 121 * <modelObjectStylesheet>Location of a XSLT document to use for transforming the merged model document.</modelObjectStylesheet> 122 * <modletObjectStylesheet>Location of a XSLT document to use for transforming the merged modlet document.</modletObjectStylesheet> 123 * <providerLocation>META-INF/custom-services</providerLocation> 124 * <platformProviderLocation>${java.home}/jre/lib/custom-jomc.properties</platformProviderLocation> 125 * <modletLocation>META-INF/custom-jomc-modlet.xml</modletLocation> 126 * <modletSchemaSystemId>http://custom.host.tld/custom/path/jomc-modlet-1.9.xsd</modletSchemaSystemId> 127 * </configuration> 128 * </containerDescriptorHandler> 129 * </pre></p> 130 * 131 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 132 * @version $JOMC: JomcContainerDescriptorHandler.java 5135 2016-04-08 13:53:07Z schulte $ 133 * @since 1.2 134 * @plexus.component role="org.apache.maven.plugin.assembly.filter.ContainerDescriptorHandler" 135 * role-hint="JOMC" 136 */ 137public class JomcContainerDescriptorHandler extends AbstractLogEnabled implements ContainerDescriptorHandler 138{ 139 140 /** 141 * Prefix prepended to log messages. 142 */ 143 private static final String LOG_PREFIX = "[JOMC] "; 144 145 /** 146 * The identifier of the model to process. 147 */ 148 private String model = ModelObject.MODEL_PUBLIC_ID; 149 150 /** 151 * The encoding of the assembled module. 152 */ 153 private String moduleEncoding; 154 155 /** 156 * The name of the assembled module. 157 */ 158 private String moduleName; 159 160 /** 161 * The version of the assembled module. 162 */ 163 private String moduleVersion; 164 165 /** 166 * The vendor of the assembled module. 167 */ 168 private String moduleVendor; 169 170 /** 171 * The resource name of the assembled module. 172 */ 173 private String moduleResource = DefaultModelProvider.getDefaultModuleLocation(); 174 175 /** 176 * Names of resources to process. 177 */ 178 private String[] moduleResources = 179 { 180 DefaultModelProvider.getDefaultModuleLocation() 181 }; 182 183 /** 184 * Included modules. 185 */ 186 private List<String> moduleIncludes; 187 188 /** 189 * Excluded modules. 190 */ 191 private List<String> moduleExcludes; 192 193 /** 194 * The encoding of the assembled modlet. 195 */ 196 private String modletEncoding; 197 198 /** 199 * The name of the assembled modlet. 200 */ 201 private String modletName; 202 203 /** 204 * The version of the assembled modlet. 205 */ 206 private String modletVersion; 207 208 /** 209 * The vendor of the assembled modlet. 210 */ 211 private String modletVendor; 212 213 /** 214 * The resource name of the assembled modlet resources. 215 */ 216 private String modletResource = DefaultModletProvider.getDefaultModletLocation(); 217 218 /** 219 * Names of modlet resources to process. 220 */ 221 private String[] modletResources = 222 { 223 DefaultModletProvider.getDefaultModletLocation() 224 }; 225 226 /** 227 * Included modlets. 228 */ 229 private List<String> modletIncludes; 230 231 /** 232 * Excluded modlets. 233 */ 234 private List<String> modletExcludes; 235 236 /** 237 * Location of a XSLT document to use for transforming the merged model document. 238 */ 239 private String modelObjectStylesheet; 240 241 /** 242 * Location of a XSLT document to use for transforming the merged modlet document. 243 */ 244 private String modletObjectStylesheet; 245 246 /** 247 * The location to search for providers. 248 */ 249 private String providerLocation; 250 251 /** 252 * The location to search for platform providers. 253 */ 254 private String platformProviderLocation; 255 256 /** 257 * The system id of the modlet schema. 258 */ 259 private String modletSchemaSystemId; 260 261 /** 262 * The location to search for modlets. 263 */ 264 private String modletLocation; 265 266 /** 267 * Name of the {@code ModelContextFactory} implementation class. 268 */ 269 private String modelContextFactoryClassName; 270 271 /** 272 * {@code ModelContext} attributes to apply. 273 */ 274 private List<ModelContextAttribute> modelContextAttributes; 275 276 /** 277 * Modlet resources. 278 */ 279 private Modlets modlets = new Modlets(); 280 281 /** 282 * Model resources. 283 */ 284 private Modules modules = new Modules(); 285 286 /** 287 * The JOMC JAXB marshaller of the instance. 288 */ 289 private Marshaller jomcMarshaller; 290 291 /** 292 * The JOMC JAXB unmarshaller of the instance. 293 */ 294 private Unmarshaller jomcUnmarshaller; 295 296 /** 297 * The modlet JAXB marshaller of the instance. 298 */ 299 private Marshaller modletMarshaller; 300 301 /** 302 * The modlet JAXB unmarshaller of the instance. 303 */ 304 private Unmarshaller modletUnmarshaller; 305 306 /** 307 * Creates a new {@code JomcContainerDescriptorHandler} instance. 308 */ 309 public JomcContainerDescriptorHandler() 310 { 311 super(); 312 } 313 314 public void finalizeArchiveCreation( final Archiver archiver ) throws ArchiverException 315 { 316 if ( StringUtils.isEmpty( this.model ) ) 317 { 318 throw new ArchiverException( Messages.getMessage( "mandatoryParameter", "model" ) ); 319 } 320 if ( StringUtils.isEmpty( this.modletName ) ) 321 { 322 throw new ArchiverException( Messages.getMessage( "mandatoryParameter", "modletName" ) ); 323 } 324 if ( StringUtils.isEmpty( this.modletResource ) ) 325 { 326 throw new ArchiverException( Messages.getMessage( "mandatoryParameter", "modletResource" ) ); 327 } 328 if ( StringUtils.isEmpty( this.moduleName ) ) 329 { 330 throw new ArchiverException( Messages.getMessage( "mandatoryParameter", "moduleName" ) ); 331 } 332 if ( StringUtils.isEmpty( this.moduleResource ) ) 333 { 334 throw new ArchiverException( Messages.getMessage( "mandatoryParameter", "moduleResource" ) ); 335 } 336 337 try 338 { 339 // This will prompt the isSelected() call, below, for all resources added to the archive. This needs to be 340 // corrected in the AbstractArchiver, where runArchiveFinalizers() is called before regular resources are 341 // added, which is done because the manifest needs to be added first, and the manifest-creation component is 342 // a finalizer in the assembly plugin. 343 for ( final ResourceIterator it = archiver.getResources(); it.hasNext(); it.next() ); 344 345 if ( !this.modules.getModule().isEmpty() ) 346 { 347 if ( this.moduleIncludes != null ) 348 { 349 for ( final Iterator<Module> it = this.modules.getModule().iterator(); it.hasNext(); ) 350 { 351 final Module m = it.next(); 352 353 if ( !this.moduleIncludes.contains( m.getName() ) ) 354 { 355 it.remove(); 356 357 if ( this.getLogger() != null && this.getLogger().isInfoEnabled() ) 358 { 359 this.getLogger().info( LOG_PREFIX + Messages.getMessage( 360 "excludingModule", m.getName() ) ); 361 362 } 363 } 364 } 365 } 366 367 if ( this.moduleExcludes != null ) 368 { 369 for ( final String exclude : this.moduleExcludes ) 370 { 371 final Module excluded = this.modules.getModule( exclude ); 372 373 if ( excluded != null ) 374 { 375 this.modules.getModule().remove( excluded ); 376 377 if ( this.getLogger() != null && this.getLogger().isInfoEnabled() ) 378 { 379 this.getLogger().info( LOG_PREFIX + Messages.getMessage( 380 "excludingModule", excluded.getName() ) ); 381 382 } 383 } 384 } 385 } 386 387 if ( this.getLogger() != null && this.getLogger().isInfoEnabled() ) 388 { 389 for ( final Module m : this.modules.getModule() ) 390 { 391 this.getLogger().info( LOG_PREFIX + Messages.getMessage( "includingModule", m.getName() ) ); 392 } 393 } 394 395 final Module mergedModule = this.modules.getMergedModule( this.moduleName ); 396 mergedModule.setVersion( this.moduleVersion ); 397 mergedModule.setVendor( this.moduleVendor ); 398 399 final JAXBElement<Module> transformedModule = this.transformModelObject( 400 new org.jomc.model.ObjectFactory().createModule( mergedModule ), Module.class ); 401 402 final File moduleFile = File.createTempFile( "maven-assembly-plugin", ".tmp" ); 403 moduleFile.deleteOnExit(); 404 405 this.marshalModelObject( transformedModule, moduleFile ); 406 407 archiver.addFile( moduleFile, normalizeResourceName( this.moduleResource ) ); 408 } 409 410 if ( !this.modlets.getModlet().isEmpty() ) 411 { 412 if ( this.modletIncludes != null ) 413 { 414 for ( final Iterator<Modlet> it = this.modlets.getModlet().iterator(); it.hasNext(); ) 415 { 416 final Modlet m = it.next(); 417 418 if ( !this.modletIncludes.contains( m.getName() ) ) 419 { 420 it.remove(); 421 422 if ( this.getLogger() != null && this.getLogger().isInfoEnabled() ) 423 { 424 this.getLogger().info( LOG_PREFIX + Messages.getMessage( 425 "excludingModlet", m.getName() ) ); 426 427 } 428 } 429 } 430 } 431 432 if ( this.modletExcludes != null ) 433 { 434 for ( final String exclude : this.modletExcludes ) 435 { 436 final Modlet excluded = this.modlets.getModlet( exclude ); 437 438 if ( excluded != null ) 439 { 440 this.modlets.getModlet().remove( excluded ); 441 442 if ( this.getLogger() != null && this.getLogger().isInfoEnabled() ) 443 { 444 this.getLogger().info( LOG_PREFIX + Messages.getMessage( 445 "excludingModlet", excluded.getName() ) ); 446 447 } 448 } 449 } 450 } 451 452 if ( this.getLogger() != null && this.getLogger().isInfoEnabled() ) 453 { 454 for ( final Modlet m : this.modlets.getModlet() ) 455 { 456 this.getLogger().info( LOG_PREFIX + Messages.getMessage( "includingModlet", m.getName() ) ); 457 } 458 } 459 460 final Modlet mergedModlet = this.modlets.getMergedModlet( this.modletName, this.model ); 461 mergedModlet.setVendor( this.modletVendor ); 462 mergedModlet.setVersion( this.modletVersion ); 463 464 final JAXBElement<Modlet> transformedModlet = this.transformModletObject( 465 new org.jomc.modlet.ObjectFactory().createModlet( mergedModlet ), Modlet.class ); 466 467 final File modletFile = File.createTempFile( "maven-assembly-plugin", ".tmp" ); 468 modletFile.deleteOnExit(); 469 470 this.marshalModletObject( transformedModlet, modletFile ); 471 472 archiver.addFile( modletFile, normalizeResourceName( this.modletResource ) ); 473 } 474 } 475 catch ( final InstantiationException e ) 476 { 477 throw new ArchiverException( Messages.getMessage( e ), e ); 478 } 479 catch ( final TransformerConfigurationException e ) 480 { 481 String message = Messages.getMessage( e ); 482 if ( message == null && e.getException() != null ) 483 { 484 message = Messages.getMessage( e.getException() ); 485 } 486 487 throw new ArchiverException( message, e ); 488 } 489 catch ( final TransformerException e ) 490 { 491 String message = Messages.getMessage( e ); 492 if ( message == null && e.getException() != null ) 493 { 494 message = Messages.getMessage( e.getException() ); 495 } 496 497 throw new ArchiverException( message, e ); 498 } 499 catch ( final JAXBException e ) 500 { 501 String message = Messages.getMessage( e ); 502 if ( message == null && e.getLinkedException() != null ) 503 { 504 message = Messages.getMessage( e.getLinkedException() ); 505 } 506 507 throw new ArchiverException( message, e ); 508 } 509 catch ( final ModelException e ) 510 { 511 throw new ArchiverException( Messages.getMessage( e ), e ); 512 } 513 catch ( final IOException e ) 514 { 515 throw new ArchiverException( Messages.getMessage( e ), e ); 516 } 517 catch ( final URISyntaxException e ) 518 { 519 throw new ArchiverException( Messages.getMessage( e ), e ); 520 } 521 finally 522 { 523 this.modlets = new Modlets(); 524 this.modules = new Modules(); 525 this.jomcMarshaller = null; 526 this.jomcUnmarshaller = null; 527 this.modletMarshaller = null; 528 this.modletUnmarshaller = null; 529 } 530 } 531 532 public void finalizeArchiveExtraction( final UnArchiver unarchiver ) throws ArchiverException 533 { 534 } 535 536 public List<String> getVirtualFiles() 537 { 538 final List<String> virtualFiles = new LinkedList<String>(); 539 540 if ( !this.modlets.getModlet().isEmpty() ) 541 { 542 virtualFiles.add( normalizeResourceName( this.modletResource ) ); 543 } 544 545 if ( !this.modules.getModule().isEmpty() ) 546 { 547 virtualFiles.add( normalizeResourceName( this.moduleResource ) ); 548 } 549 550 return virtualFiles.isEmpty() ? null : Collections.unmodifiableList( virtualFiles ); 551 } 552 553 public boolean isSelected( final FileInfo fileInfo ) throws IOException 554 { 555 try 556 { 557 boolean selected = true; 558 final String name = normalizeResourceName( fileInfo.getName() ); 559 560 if ( this.moduleResources != null ) 561 { 562 for ( final String r : this.moduleResources ) 563 { 564 if ( name.equals( normalizeResourceName( r ) ) ) 565 { 566 Object modelObject = this.unmarshalModelObject( fileInfo.getContents() ); 567 568 if ( modelObject instanceof JAXBElement<?> ) 569 { 570 modelObject = ( (JAXBElement<?>) modelObject ).getValue(); 571 } 572 if ( modelObject instanceof Modules ) 573 { 574 this.modules.getModule().addAll( ( (Modules) modelObject ).getModule() ); 575 } 576 if ( modelObject instanceof Module ) 577 { 578 this.modules.getModule().add( (Module) modelObject ); 579 } 580 581 if ( this.getLogger() != null && this.getLogger().isDebugEnabled() ) 582 { 583 this.getLogger().debug( LOG_PREFIX + Messages.getMessage( 584 "processingModuleResource", name ) ); 585 586 } 587 588 selected = false; 589 break; 590 } 591 } 592 } 593 594 if ( selected && this.modletResources != null ) 595 { 596 for ( final String r : this.modletResources ) 597 { 598 if ( name.equals( normalizeResourceName( r ) ) ) 599 { 600 Object modletObject = this.unmarshalModletObject( fileInfo.getContents() ); 601 602 if ( modletObject instanceof JAXBElement<?> ) 603 { 604 modletObject = ( (JAXBElement<?>) modletObject ).getValue(); 605 } 606 if ( modletObject instanceof Modlets ) 607 { 608 this.modlets.getModlet().addAll( ( (Modlets) modletObject ).getModlet() ); 609 } 610 if ( modletObject instanceof Modlet ) 611 { 612 this.modlets.getModlet().add( (Modlet) modletObject ); 613 } 614 615 if ( this.getLogger() != null && this.getLogger().isDebugEnabled() ) 616 { 617 this.getLogger().debug( LOG_PREFIX + Messages.getMessage( 618 "processingModletResource", name ) ); 619 620 } 621 622 selected = false; 623 break; 624 } 625 } 626 } 627 628 if ( selected && ( name.equals( normalizeResourceName( this.modletResource ) ) 629 || name.equals( normalizeResourceName( this.moduleResource ) ) ) ) 630 { 631 if ( this.getLogger() != null && this.getLogger().isWarnEnabled() ) 632 { 633 this.getLogger().warn( LOG_PREFIX + Messages.getMessage( "overridingResource", name ) ); 634 } 635 636 selected = false; 637 } 638 639 return selected; 640 } 641 catch ( final InstantiationException e ) 642 { 643 // JDK: As of JDK 6, "new IOException( message, cause )". 644 throw (IOException) new IOException( Messages.getMessage( e ) ).initCause( e ); 645 } 646 catch ( final JAXBException e ) 647 { 648 String message = Messages.getMessage( e ); 649 if ( message == null && e.getLinkedException() != null ) 650 { 651 message = Messages.getMessage( e.getLinkedException() ); 652 } 653 654 // JDK: As of JDK 6, "new IOException( message, cause )". 655 throw (IOException) new IOException( message ).initCause( e ); 656 } 657 catch ( final ModelException e ) 658 { 659 // JDK: As of JDK 6, "new IOException( message, cause )". 660 throw (IOException) new IOException( Messages.getMessage( e ) ).initCause( e ); 661 } 662 } 663 664 /** 665 * Creates an {@code URL} for a given resource location. 666 * <p> 667 * This method first searches the class loader of the class for a single resource matching {@code location}. If 668 * such a resource is found, the URL of that resource is returned. If no such resource is found, an attempt is made 669 * to parse the given location to an URL. On successful parsing, that URL is returned. Failing that, the given 670 * location is interpreted as a file name. If that file is found, the URL of that file is returned. Otherwise an 671 * {@code IOException} is thrown. 672 * </p> 673 * 674 * @param location The location to create an {@code URL} from. 675 * 676 * @return An {@code URL} for {@code location}. 677 * 678 * @throws NullPointerException if {@code location} is {@code null}. 679 * @throws IOException if creating an URL fails. 680 */ 681 protected URL getResource( final String location ) throws IOException 682 { 683 if ( location == null ) 684 { 685 throw new NullPointerException( "location" ); 686 } 687 688 try 689 { 690 String absolute = location; 691 if ( !absolute.startsWith( "/" ) ) 692 { 693 absolute = "/" + location; 694 } 695 696 URL resource = this.getClass().getResource( absolute ); 697 if ( resource == null ) 698 { 699 try 700 { 701 resource = new URL( location ); 702 } 703 catch ( final MalformedURLException e ) 704 { 705 if ( this.getLogger() != null && this.getLogger().isDebugEnabled() ) 706 { 707 this.getLogger().debug( Messages.getMessage( e ), e ); 708 } 709 710 resource = null; 711 } 712 } 713 714 if ( resource == null ) 715 { 716 final File f = new File( location ); 717 718 if ( f.isFile() ) 719 { 720 resource = f.toURI().toURL(); 721 } 722 } 723 724 if ( resource == null ) 725 { 726 throw new IOException( Messages.getMessage( "resourceNotFound", location ) ); 727 } 728 729 return resource; 730 } 731 catch ( final MalformedURLException e ) 732 { 733 String m = Messages.getMessage( e ); 734 m = m == null ? "" : " " + m; 735 736 // JDK: As of JDK 6, "new IOException( message, cause )". 737 throw (IOException) new IOException( Messages.getMessage( 738 "malformedLocation", location, m ) ).initCause( e ); 739 740 } 741 } 742 743 private Object unmarshalModelObject( final InputStream in ) 744 throws ModelException, JAXBException, InstantiationException 745 { 746 if ( in == null ) 747 { 748 throw new NullPointerException( "in" ); 749 } 750 751 if ( this.jomcUnmarshaller == null ) 752 { 753 this.jomcUnmarshaller = this.createModelContext().createUnmarshaller( this.model ); 754 } 755 756 return this.jomcUnmarshaller.unmarshal( in ); 757 } 758 759 private void marshalModelObject( final JAXBElement<? extends ModelObject> element, final File file ) 760 throws ModelException, JAXBException, InstantiationException 761 { 762 if ( element == null ) 763 { 764 throw new NullPointerException( "element" ); 765 } 766 if ( file == null ) 767 { 768 throw new NullPointerException( "file" ); 769 } 770 771 if ( this.jomcMarshaller == null ) 772 { 773 final ModelContext modelContext = this.createModelContext(); 774 this.jomcMarshaller = modelContext.createMarshaller( this.model ); 775 this.jomcMarshaller.setSchema( modelContext.createSchema( this.model ) ); 776 this.jomcMarshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE ); 777 778 if ( this.moduleEncoding != null ) 779 { 780 this.jomcMarshaller.setProperty( Marshaller.JAXB_ENCODING, this.moduleEncoding ); 781 } 782 } 783 784 this.jomcMarshaller.marshal( element, file ); 785 } 786 787 private <T> JAXBElement<T> transformModelObject( final JAXBElement<? extends ModelObject> element, 788 final Class<T> boundType ) 789 throws ModelException, TransformerException, JAXBException, IOException, URISyntaxException, 790 InstantiationException 791 { 792 if ( element == null ) 793 { 794 throw new NullPointerException( "element" ); 795 } 796 if ( !boundType.isInstance( element.getValue() ) ) 797 { 798 throw new IllegalArgumentException( element.toString() ); 799 } 800 801 @SuppressWarnings( "unchecked" ) 802 JAXBElement<T> transformed = (JAXBElement<T>) element; 803 804 if ( this.modelObjectStylesheet != null ) 805 { 806 final Transformer transformer = TransformerFactory.newInstance().newTransformer( 807 new StreamSource( this.getResource( this.modelObjectStylesheet ).toURI().toASCIIString() ) ); 808 809 final ModelContext modelContext = this.createModelContext(); 810 final Marshaller marshaller = modelContext.createMarshaller( this.model ); 811 final Unmarshaller unmarshaller = modelContext.createUnmarshaller( this.model ); 812 final JAXBSource source = new JAXBSource( marshaller, element ); 813 final JAXBResult result = new JAXBResult( unmarshaller ); 814 815 for ( final Map.Entry<Object, Object> e : System.getProperties().entrySet() ) 816 { 817 transformer.setParameter( e.getKey().toString(), e.getValue() ); 818 } 819 820 transformer.transform( source, result ); 821 822 if ( result.getResult() instanceof JAXBElement<?> 823 && boundType.isInstance( ( (JAXBElement<?>) result.getResult() ).getValue() ) ) 824 { 825 @SuppressWarnings( "unchecked" ) final JAXBElement<T> e = (JAXBElement<T>) result.getResult(); 826 transformed = e; 827 } 828 else 829 { 830 throw new ModelException( Messages.getMessage( 831 "illegalModuleTransformationResult", this.modelObjectStylesheet ) ); 832 833 } 834 } 835 836 return transformed; 837 } 838 839 private Object unmarshalModletObject( final InputStream in ) 840 throws ModelException, JAXBException, InstantiationException 841 { 842 if ( in == null ) 843 { 844 throw new NullPointerException( "in" ); 845 } 846 847 if ( this.modletUnmarshaller == null ) 848 { 849 this.modletUnmarshaller = this.createModelContext().createUnmarshaller( ModletObject.MODEL_PUBLIC_ID ); 850 } 851 852 return this.modletUnmarshaller.unmarshal( in ); 853 } 854 855 private void marshalModletObject( final JAXBElement<? extends ModletObject> element, final File file ) 856 throws ModelException, JAXBException, InstantiationException 857 { 858 if ( element == null ) 859 { 860 throw new NullPointerException( "element" ); 861 } 862 if ( file == null ) 863 { 864 throw new NullPointerException( "file" ); 865 } 866 867 if ( this.modletMarshaller == null ) 868 { 869 final ModelContext modletContext = this.createModelContext(); 870 this.modletMarshaller = modletContext.createMarshaller( ModletObject.MODEL_PUBLIC_ID ); 871 this.modletMarshaller.setSchema( modletContext.createSchema( ModletObject.MODEL_PUBLIC_ID ) ); 872 this.modletMarshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE ); 873 874 if ( this.modletEncoding != null ) 875 { 876 this.modletMarshaller.setProperty( Marshaller.JAXB_ENCODING, this.modletEncoding ); 877 } 878 } 879 880 this.modletMarshaller.marshal( element, file ); 881 } 882 883 private <T> JAXBElement<T> transformModletObject( final JAXBElement<? extends ModletObject> element, 884 final Class<T> boundType ) 885 throws ModelException, TransformerException, JAXBException, IOException, URISyntaxException, 886 InstantiationException 887 { 888 if ( element == null ) 889 { 890 throw new NullPointerException( "element" ); 891 } 892 if ( !boundType.isInstance( element.getValue() ) ) 893 { 894 throw new IllegalArgumentException( element.toString() ); 895 } 896 897 @SuppressWarnings( "unchecked" ) 898 JAXBElement<T> transformed = (JAXBElement<T>) element; 899 900 if ( this.modletObjectStylesheet != null ) 901 { 902 final Transformer transformer = TransformerFactory.newInstance().newTransformer( 903 new StreamSource( this.getResource( this.modletObjectStylesheet ).toURI().toASCIIString() ) ); 904 905 final ModelContext modletContext = this.createModelContext(); 906 final Marshaller marshaller = modletContext.createMarshaller( ModletObject.MODEL_PUBLIC_ID ); 907 final Unmarshaller unmarshaller = modletContext.createUnmarshaller( ModletObject.MODEL_PUBLIC_ID ); 908 final JAXBSource source = new JAXBSource( marshaller, element ); 909 final JAXBResult result = new JAXBResult( unmarshaller ); 910 911 for ( final Map.Entry<Object, Object> e : System.getProperties().entrySet() ) 912 { 913 transformer.setParameter( e.getKey().toString(), e.getValue() ); 914 } 915 916 transformer.transform( source, result ); 917 918 if ( result.getResult() instanceof JAXBElement<?> 919 && boundType.isInstance( ( (JAXBElement<?>) result.getResult() ).getValue() ) ) 920 { 921 @SuppressWarnings( "unchecked" ) final JAXBElement<T> e = (JAXBElement<T>) result.getResult(); 922 transformed = e; 923 } 924 else 925 { 926 throw new ModelException( Messages.getMessage( 927 "illegalModletTransformationResult", this.modletObjectStylesheet ) ); 928 929 } 930 } 931 932 return transformed; 933 } 934 935 private static String normalizeResourceName( final String name ) 936 { 937 String normalized = name; 938 939 if ( normalized != null ) 940 { 941 normalized = normalized.replace( '\\', '/' ); 942 943 if ( normalized.startsWith( "/" ) ) 944 { 945 normalized = normalized.substring( 1 ); 946 } 947 948 if ( normalized.endsWith( "/" ) ) 949 { 950 normalized = normalized.substring( 0, normalized.length() ); 951 } 952 } 953 954 return normalized; 955 } 956 957 private ModelContext createModelContext() throws ModelException, InstantiationException 958 { 959 final ModelContextFactory modelContextFactory; 960 if ( this.modelContextFactoryClassName != null ) 961 { 962 modelContextFactory = ModelContextFactory.newInstance( this.modelContextFactoryClassName ); 963 } 964 else 965 { 966 modelContextFactory = ModelContextFactory.newInstance(); 967 } 968 969 final ModelContext modelContext = modelContextFactory.newModelContext(); 970 modelContext.setModletSchemaSystemId( this.modletSchemaSystemId ); 971 972 if ( this.providerLocation != null ) 973 { 974 modelContext.setAttribute( DefaultModelContext.PROVIDER_LOCATION_ATTRIBUTE_NAME, this.providerLocation ); 975 } 976 977 if ( this.platformProviderLocation != null ) 978 { 979 modelContext.setAttribute( DefaultModelContext.PLATFORM_PROVIDER_LOCATION_ATTRIBUTE_NAME, 980 this.platformProviderLocation ); 981 982 } 983 984 if ( this.modletLocation != null ) 985 { 986 modelContext.setAttribute( DefaultModletProvider.MODLET_LOCATION_ATTRIBUTE_NAME, this.modletLocation ); 987 } 988 989 if ( this.modelContextAttributes != null ) 990 { 991 for ( final ModelContextAttribute e : this.modelContextAttributes ) 992 { 993 final Object object = e.getObject( modelContext ); 994 995 if ( object != null ) 996 { 997 modelContext.setAttribute( e.getKey(), object ); 998 } 999 else 1000 { 1001 modelContext.clearAttribute( e.getKey() ); 1002 } 1003 } 1004 } 1005 1006 return modelContext; 1007 } 1008 1009}