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 }