1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  package org.jomc.ant;
32  
33  import java.io.ByteArrayOutputStream;
34  import java.io.File;
35  import java.io.IOException;
36  import java.io.InputStream;
37  import java.io.OutputStreamWriter;
38  import java.net.HttpURLConnection;
39  import java.net.SocketTimeoutException;
40  import java.net.URISyntaxException;
41  import java.net.URL;
42  import java.net.URLConnection;
43  import java.util.ArrayList;
44  import java.util.HashSet;
45  import java.util.Iterator;
46  import java.util.LinkedList;
47  import java.util.List;
48  import java.util.Set;
49  import java.util.logging.Level;
50  import javax.xml.bind.JAXBElement;
51  import javax.xml.bind.JAXBException;
52  import javax.xml.bind.Marshaller;
53  import javax.xml.bind.Unmarshaller;
54  import javax.xml.bind.util.JAXBResult;
55  import javax.xml.bind.util.JAXBSource;
56  import javax.xml.transform.Source;
57  import javax.xml.transform.Transformer;
58  import javax.xml.transform.TransformerConfigurationException;
59  import javax.xml.transform.TransformerException;
60  import javax.xml.transform.stream.StreamSource;
61  import org.apache.tools.ant.BuildException;
62  import org.apache.tools.ant.Project;
63  import org.jomc.ant.types.ModletResourceType;
64  import org.jomc.ant.types.NameType;
65  import org.jomc.ant.types.ResourceType;
66  import org.jomc.ant.types.TransformerResourceType;
67  import org.jomc.modlet.DefaultModletProvider;
68  import org.jomc.modlet.ModelContext;
69  import org.jomc.modlet.ModelException;
70  import org.jomc.modlet.ModelValidationReport;
71  import org.jomc.modlet.Modlet;
72  import org.jomc.modlet.ModletObject;
73  import org.jomc.modlet.Modlets;
74  import org.jomc.modlet.ObjectFactory;
75  
76  
77  
78  
79  
80  
81  
82  public final class MergeModletsTask extends JomcTask
83  {
84  
85      
86  
87  
88      private String modletEncoding;
89  
90      
91  
92  
93      private File modletFile;
94  
95      
96  
97  
98      private String modletName;
99  
100     
101 
102 
103     private String modletVersion;
104 
105     
106 
107 
108     private String modletVendor;
109 
110     
111 
112 
113     private Set<ModletResourceType> modletResources;
114 
115     
116 
117 
118     private Set<NameType> modletIncludes;
119 
120     
121 
122 
123     private Set<NameType> modletExcludes;
124 
125     
126 
127 
128     private List<TransformerResourceType> modletObjectStylesheetResources;
129 
130     
131 
132 
133     public MergeModletsTask()
134     {
135         super();
136     }
137 
138     
139 
140 
141 
142 
143 
144 
145     public File getModletFile()
146     {
147         return this.modletFile;
148     }
149 
150     
151 
152 
153 
154 
155 
156 
157     public void setModletFile( final File value )
158     {
159         this.modletFile = value;
160     }
161 
162     
163 
164 
165 
166 
167 
168 
169     public String getModletEncoding()
170     {
171         if ( this.modletEncoding == null )
172         {
173             this.modletEncoding = new OutputStreamWriter( new ByteArrayOutputStream() ).getEncoding();
174         }
175 
176         return this.modletEncoding;
177     }
178 
179     
180 
181 
182 
183 
184 
185 
186     public void setModletEncoding( final String value )
187     {
188         this.modletEncoding = value;
189     }
190 
191     
192 
193 
194 
195 
196 
197 
198     public String getModletName()
199     {
200         return this.modletName;
201     }
202 
203     
204 
205 
206 
207 
208 
209 
210     public void setModletName( final String value )
211     {
212         this.modletName = value;
213     }
214 
215     
216 
217 
218 
219 
220 
221 
222     public String getModletVersion()
223     {
224         return this.modletVersion;
225     }
226 
227     
228 
229 
230 
231 
232 
233 
234     public void setModletVersion( final String value )
235     {
236         this.modletVersion = value;
237     }
238 
239     
240 
241 
242 
243 
244 
245 
246     public String getModletVendor()
247     {
248         return this.modletVendor;
249     }
250 
251     
252 
253 
254 
255 
256 
257 
258     public void setModletVendor( final String value )
259     {
260         this.modletVendor = value;
261     }
262 
263     
264 
265 
266 
267 
268 
269 
270 
271 
272 
273 
274 
275     public Set<ModletResourceType> getModletResources()
276     {
277         if ( this.modletResources == null )
278         {
279             this.modletResources = new HashSet<ModletResourceType>();
280         }
281 
282         return this.modletResources;
283     }
284 
285     
286 
287 
288 
289 
290 
291 
292     public ModletResourceType createModletResource()
293     {
294         final ModletResourceType modletResource = new ModletResourceType();
295         this.getModletResources().add( modletResource );
296         return modletResource;
297     }
298 
299     
300 
301 
302 
303 
304 
305 
306 
307 
308 
309 
310 
311     public Set<NameType> getModletIncludes()
312     {
313         if ( this.modletIncludes == null )
314         {
315             this.modletIncludes = new HashSet<NameType>();
316         }
317 
318         return this.modletIncludes;
319     }
320 
321     
322 
323 
324 
325 
326 
327 
328     public NameType createModletInclude()
329     {
330         final NameType modletInclude = new NameType();
331         this.getModletIncludes().add( modletInclude );
332         return modletInclude;
333     }
334 
335     
336 
337 
338 
339 
340 
341 
342 
343 
344 
345 
346 
347     public Set<NameType> getModletExcludes()
348     {
349         if ( this.modletExcludes == null )
350         {
351             this.modletExcludes = new HashSet<NameType>();
352         }
353 
354         return this.modletExcludes;
355     }
356 
357     
358 
359 
360 
361 
362 
363 
364     public NameType createModletExclude()
365     {
366         final NameType modletExclude = new NameType();
367         this.getModletExcludes().add( modletExclude );
368         return modletExclude;
369     }
370 
371     
372 
373 
374 
375 
376 
377 
378 
379 
380 
381 
382 
383     public List<TransformerResourceType> getModletObjectStylesheetResources()
384     {
385         if ( this.modletObjectStylesheetResources == null )
386         {
387             this.modletObjectStylesheetResources = new LinkedList<TransformerResourceType>();
388         }
389 
390         return this.modletObjectStylesheetResources;
391     }
392 
393     
394 
395 
396 
397 
398 
399 
400     public TransformerResourceType createModletObjectStylesheetResource()
401     {
402         final TransformerResourceType modletObjectStylesheetResource = new TransformerResourceType();
403         this.getModletObjectStylesheetResources().add( modletObjectStylesheetResource );
404         return modletObjectStylesheetResource;
405     }
406 
407     
408 
409 
410     @Override
411     public void preExecuteTask() throws BuildException
412     {
413         super.preExecuteTask();
414 
415         this.assertNotNull( "modletFile", this.getModletFile() );
416         this.assertNotNull( "modletName", this.getModletName() );
417         this.assertNamesNotNull( this.getModletExcludes() );
418         this.assertNamesNotNull( this.getModletIncludes() );
419         this.assertLocationsNotNull( this.getModletResources() );
420         this.assertLocationsNotNull( this.getModletObjectStylesheetResources() );
421     }
422 
423     
424 
425 
426 
427 
428     @Override
429     public void executeTask() throws BuildException
430     {
431         ProjectClassLoader classLoader = null;
432 
433         try
434         {
435             this.log( Messages.getMessage( "mergingModlets", this.getModel() ) );
436 
437             classLoader = this.newProjectClassLoader();
438             final Modlets modlets = new Modlets();
439             final Set<ResourceType> resources = new HashSet<ResourceType>( this.getModletResources() );
440             final ModelContext context = this.newModelContext( classLoader );
441             final Marshaller marshaller = context.createMarshaller( ModletObject.MODEL_PUBLIC_ID );
442             final Unmarshaller unmarshaller = context.createUnmarshaller( ModletObject.MODEL_PUBLIC_ID );
443 
444             if ( this.isModletResourceValidationEnabled() )
445             {
446                 unmarshaller.setSchema( context.createSchema( ModletObject.MODEL_PUBLIC_ID ) );
447             }
448 
449             if ( resources.isEmpty() )
450             {
451                 final ResourceType defaultResource = new ResourceType();
452                 defaultResource.setLocation( DefaultModletProvider.getDefaultModletLocation() );
453                 defaultResource.setOptional( true );
454                 resources.add( defaultResource );
455             }
456 
457             for ( final ResourceType resource : resources )
458             {
459                 final URL[] urls = this.getResources( context, resource.getLocation() );
460 
461                 if ( urls.length == 0 )
462                 {
463                     if ( resource.isOptional() )
464                     {
465                         this.logMessage( Level.WARNING, Messages.getMessage( "modletResourceNotFound",
466                                                                              resource.getLocation() ) );
467 
468                     }
469                     else
470                     {
471                         throw new BuildException( Messages.getMessage( "modletResourceNotFound",
472                                                                        resource.getLocation() ) );
473 
474                     }
475                 }
476 
477                 for ( int i = urls.length - 1; i >= 0; i-- )
478                 {
479                     InputStream in = null;
480                     URLConnection con = null;
481 
482                     try
483                     {
484                         this.logMessage( Level.FINEST, Messages.getMessage( "reading", urls[i].toExternalForm() ) );
485 
486                         con = urls[i].openConnection();
487                         con.setConnectTimeout( resource.getConnectTimeout() );
488                         con.setReadTimeout( resource.getReadTimeout() );
489                         con.connect();
490                         in = con.getInputStream();
491 
492                         final Source source = new StreamSource( in, urls[i].toURI().toASCIIString() );
493                         Object o = unmarshaller.unmarshal( source );
494                         if ( o instanceof JAXBElement<?> )
495                         {
496                             o = ( (JAXBElement<?>) o ).getValue();
497                         }
498 
499                         if ( o instanceof Modlet )
500                         {
501                             modlets.getModlet().add( (Modlet) o );
502                         }
503                         else if ( o instanceof Modlets )
504                         {
505                             modlets.getModlet().addAll( ( (Modlets) o ).getModlet() );
506                         }
507                         else
508                         {
509                             this.logMessage( Level.WARNING, Messages.getMessage( "unsupportedModletResource",
510                                                                                  urls[i].toExternalForm() ) );
511 
512                         }
513 
514                         in.close();
515                         in = null;
516                     }
517                     catch ( final SocketTimeoutException e )
518                     {
519                         String message = Messages.getMessage( e );
520                         message = Messages.getMessage( "resourceTimeout", message != null ? " " + message : "" );
521 
522                         if ( resource.isOptional() )
523                         {
524                             this.getProject().log( message, e, Project.MSG_WARN );
525                         }
526                         else
527                         {
528                             throw new BuildException( message, e, this.getLocation() );
529                         }
530                     }
531                     catch ( final IOException e )
532                     {
533                         String message = Messages.getMessage( e );
534                         message = Messages.getMessage( "resourceFailure", message != null ? " " + message : "" );
535 
536                         if ( resource.isOptional() )
537                         {
538                             this.getProject().log( message, e, Project.MSG_WARN );
539                         }
540                         else
541                         {
542                             throw new BuildException( message, e, this.getLocation() );
543                         }
544                     }
545                     finally
546                     {
547                         try
548                         {
549                             if ( in != null )
550                             {
551                                 in.close();
552                             }
553                         }
554                         catch ( final IOException e )
555                         {
556                             this.logMessage( Level.SEVERE, Messages.getMessage( e ), e );
557                         }
558                         finally
559                         {
560                             if ( con instanceof HttpURLConnection )
561                             {
562                                 ( (HttpURLConnection) con ).disconnect();
563                             }
564                         }
565                     }
566                 }
567             }
568 
569             for ( final Iterator<Modlet> it = modlets.getModlet().iterator(); it.hasNext(); )
570             {
571                 final Modlet modlet = it.next();
572 
573                 if ( !this.isModletIncluded( modlet ) || this.isModletExcluded( modlet ) )
574                 {
575                     it.remove();
576                     this.log( Messages.getMessage( "excludingModlet", modlet.getName() ) );
577                 }
578                 else
579                 {
580                     this.log( Messages.getMessage( "includingModlet", modlet.getName() ) );
581                 }
582             }
583 
584             final ModelValidationReport validationReport =
585                 context.validateModel( ModletObject.MODEL_PUBLIC_ID,
586                                        new JAXBSource( marshaller, new ObjectFactory().createModlets( modlets ) ) );
587 
588             this.logValidationReport( context, validationReport );
589 
590             if ( !validationReport.isModelValid() )
591             {
592                 throw new ModelException( Messages.getMessage( "invalidModel", ModletObject.MODEL_PUBLIC_ID ) );
593             }
594 
595             Modlet mergedModlet = modlets.getMergedModlet( this.getModletName(), this.getModel() );
596             mergedModlet.setVendor( this.getModletVendor() );
597             mergedModlet.setVersion( this.getModletVersion() );
598 
599             for ( int i = 0, s0 = this.getModletObjectStylesheetResources().size(); i < s0; i++ )
600             {
601                 final Transformer transformer =
602                     this.getTransformer( this.getModletObjectStylesheetResources().get( i ) );
603 
604                 if ( transformer != null )
605                 {
606                     final JAXBSource source =
607                         new JAXBSource( marshaller, new ObjectFactory().createModlet( mergedModlet ) );
608 
609                     final JAXBResult result = new JAXBResult( unmarshaller );
610                     transformer.transform( source, result );
611 
612                     if ( result.getResult() instanceof JAXBElement<?>
613                              && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Modlet )
614                     {
615                         mergedModlet = (Modlet) ( (JAXBElement<?>) result.getResult() ).getValue();
616                     }
617                     else
618                     {
619                         throw new BuildException( Messages.getMessage(
620                             "illegalTransformationResult",
621                             this.getModletObjectStylesheetResources().get( i ).getLocation() ), this.getLocation() );
622 
623                     }
624                 }
625             }
626 
627             this.log( Messages.getMessage( "writingEncoded", this.getModletFile().getAbsolutePath(),
628                                            this.getModletEncoding() ) );
629 
630             marshaller.setProperty( Marshaller.JAXB_ENCODING, this.getModletEncoding() );
631             marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
632             marshaller.setSchema( context.createSchema( ModletObject.MODEL_PUBLIC_ID ) );
633             marshaller.marshal( new ObjectFactory().createModlet( mergedModlet ), this.getModletFile() );
634 
635             classLoader.close();
636             classLoader = null;
637         }
638         catch ( final IOException e )
639         {
640             throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
641         }
642         catch ( final URISyntaxException e )
643         {
644             throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
645         }
646         catch ( final JAXBException e )
647         {
648             String message = Messages.getMessage( e );
649             if ( message == null )
650             {
651                 message = Messages.getMessage( e.getLinkedException() );
652             }
653 
654             throw new BuildException( message, e, this.getLocation() );
655         }
656         catch ( final TransformerConfigurationException e )
657         {
658             throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
659         }
660         catch ( final TransformerException e )
661         {
662             throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
663         }
664         catch ( final ModelException e )
665         {
666             throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
667         }
668         finally
669         {
670             try
671             {
672                 if ( classLoader != null )
673                 {
674                     classLoader.close();
675                 }
676             }
677             catch ( final IOException e )
678             {
679                 this.logMessage( Level.SEVERE, Messages.getMessage( e ), e );
680             }
681         }
682     }
683 
684     
685 
686 
687 
688 
689 
690 
691 
692 
693 
694 
695     public boolean isModletIncluded( final Modlet modlet )
696     {
697         if ( modlet == null )
698         {
699             throw new NullPointerException( "modlet" );
700         }
701 
702         for ( final NameType include : this.getModletIncludes() )
703         {
704             if ( include.getName().equals( modlet.getName() ) )
705             {
706                 return true;
707             }
708         }
709 
710         return this.getModletIncludes().isEmpty() ? true : false;
711     }
712 
713     
714 
715 
716 
717 
718 
719 
720 
721 
722 
723 
724     public boolean isModletExcluded( final Modlet modlet )
725     {
726         if ( modlet == null )
727         {
728             throw new NullPointerException( "modlet" );
729         }
730 
731         for ( final NameType exclude : this.getModletExcludes() )
732         {
733             if ( exclude.getName().equals( modlet.getName() ) )
734             {
735                 return true;
736             }
737         }
738 
739         return false;
740     }
741 
742     
743 
744 
745     @Override
746     public MergeModletsTask clone()
747     {
748         final MergeModletsTask clone = (MergeModletsTask) super.clone();
749         clone.modletFile = this.modletFile != null ? new File( this.modletFile.getAbsolutePath() ) : null;
750 
751         if ( this.modletResources != null )
752         {
753             clone.modletResources = new HashSet<ModletResourceType>( this.modletResources.size() );
754             for ( final ModletResourceType e : this.modletResources )
755             {
756                 clone.modletResources.add( e.clone() );
757             }
758         }
759 
760         if ( this.modletExcludes != null )
761         {
762             clone.modletExcludes = new HashSet<NameType>( this.modletExcludes.size() );
763             for ( final NameType e : this.modletExcludes )
764             {
765                 clone.modletExcludes.add( e.clone() );
766             }
767         }
768 
769         if ( this.modletIncludes != null )
770         {
771             clone.modletIncludes = new HashSet<NameType>( this.modletIncludes.size() );
772             for ( final NameType e : this.modletIncludes )
773             {
774                 clone.modletIncludes.add( e.clone() );
775             }
776         }
777 
778         if ( this.modletObjectStylesheetResources != null )
779         {
780             clone.modletObjectStylesheetResources =
781                 new ArrayList<TransformerResourceType>( this.modletObjectStylesheetResources.size() );
782 
783             for ( final TransformerResourceType e : this.modletObjectStylesheetResources )
784             {
785                 clone.modletObjectStylesheetResources.add( e.clone() );
786             }
787         }
788 
789         return clone;
790     }
791 
792 }