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.modlet;
32
33 import java.lang.reflect.UndeclaredThrowableException;
34 import java.net.URL;
35 import java.text.MessageFormat;
36 import java.util.Enumeration;
37 import java.util.LinkedList;
38 import java.util.List;
39 import java.util.ResourceBundle;
40 import java.util.concurrent.Callable;
41 import java.util.concurrent.CancellationException;
42 import java.util.concurrent.ExecutionException;
43 import java.util.concurrent.Future;
44 import java.util.logging.Level;
45 import javax.xml.bind.JAXBContext;
46 import javax.xml.bind.JAXBElement;
47 import javax.xml.bind.JAXBException;
48 import javax.xml.bind.UnmarshalException;
49 import javax.xml.bind.Unmarshaller;
50
51
52
53
54
55
56
57
58 public class DefaultModletProvider implements ModletProvider
59 {
60
61
62
63
64
65
66
67
68 public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.modlet.DefaultModletProvider.enabledAttribute";
69
70
71
72
73
74
75
76 private static final String DEFAULT_ENABLED_PROPERTY_NAME =
77 "org.jomc.modlet.DefaultModletProvider.defaultEnabled";
78
79
80
81
82
83
84
85 private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
86
87
88
89
90 private static volatile Boolean defaultEnabled;
91
92
93
94
95 private volatile Boolean enabled;
96
97
98
99
100
101
102
103
104 public static final String MODLET_LOCATION_ATTRIBUTE_NAME =
105 "org.jomc.modlet.DefaultModletProvider.modletLocationAttribute";
106
107
108
109
110
111
112
113 private static final String DEFAULT_MODLET_LOCATION_PROPERTY_NAME =
114 "org.jomc.modlet.DefaultModletProvider.defaultModletLocation";
115
116
117
118
119
120
121 private static final String DEFAULT_MODLET_LOCATION = "META-INF/jomc-modlet.xml";
122
123
124
125
126 private static volatile String defaultModletLocation;
127
128
129
130
131 private volatile String modletLocation;
132
133
134
135
136
137
138
139
140 public static final String VALIDATING_ATTRIBUTE_NAME =
141 "org.jomc.modlet.DefaultModletProvider.validatingAttribute";
142
143
144
145
146
147
148
149 private static final String DEFAULT_VALIDATING_PROPERTY_NAME =
150 "org.jomc.modlet.DefaultModletProvider.defaultValidating";
151
152
153
154
155
156
157
158 private static final Boolean DEFAULT_VALIDATING = Boolean.TRUE;
159
160
161
162
163
164
165 private static volatile Boolean defaultValidating;
166
167
168
169
170
171
172 private volatile Boolean validating;
173
174
175
176
177
178
179
180 private static final String DEFAULT_ORDINAL_PROPERTY_NAME =
181 "org.jomc.modlet.DefaultModletProvider.defaultOrdinal";
182
183
184
185
186
187
188
189 private static final Integer DEFAULT_ORDINAL = 0;
190
191
192
193
194
195
196 private static volatile Integer defaultOrdinal;
197
198
199
200
201
202
203 private volatile Integer ordinal;
204
205
206
207
208 public DefaultModletProvider()
209 {
210 super();
211 }
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 public static boolean isDefaultEnabled()
228 {
229 if ( defaultEnabled == null )
230 {
231 defaultEnabled = Boolean.valueOf( System.getProperty(
232 DEFAULT_ENABLED_PROPERTY_NAME, Boolean.toString( DEFAULT_ENABLED ) ) );
233
234 }
235
236 return defaultEnabled;
237 }
238
239
240
241
242
243
244
245
246 public static void setDefaultEnabled( final Boolean value )
247 {
248 defaultEnabled = value;
249 }
250
251
252
253
254
255
256
257
258
259 public final boolean isEnabled()
260 {
261 if ( this.enabled == null )
262 {
263 this.enabled = isDefaultEnabled();
264 }
265
266 return this.enabled;
267 }
268
269
270
271
272
273
274
275
276 public final void setEnabled( final Boolean value )
277 {
278 this.enabled = value;
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294 public static String getDefaultModletLocation()
295 {
296 if ( defaultModletLocation == null )
297 {
298 defaultModletLocation = System.getProperty(
299 DEFAULT_MODLET_LOCATION_PROPERTY_NAME, DEFAULT_MODLET_LOCATION );
300
301 }
302
303 return defaultModletLocation;
304 }
305
306
307
308
309
310
311
312
313 public static void setDefaultModletLocation( final String value )
314 {
315 defaultModletLocation = value;
316 }
317
318
319
320
321
322
323
324
325
326 public final String getModletLocation()
327 {
328 if ( this.modletLocation == null )
329 {
330 this.modletLocation = getDefaultModletLocation();
331 }
332
333 return this.modletLocation;
334 }
335
336
337
338
339
340
341
342
343 public final void setModletLocation( final String value )
344 {
345 this.modletLocation = value;
346 }
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364 public static boolean isDefaultValidating()
365 {
366 if ( defaultValidating == null )
367 {
368 defaultValidating = Boolean.valueOf( System.getProperty(
369 DEFAULT_VALIDATING_PROPERTY_NAME, Boolean.toString( DEFAULT_VALIDATING ) ) );
370
371 }
372
373 return defaultValidating;
374 }
375
376
377
378
379
380
381
382
383
384
385
386 public static void setDefaultValidating( final Boolean value )
387 {
388 defaultValidating = value;
389 }
390
391
392
393
394
395
396
397
398
399
400
401
402 public final boolean isValidating()
403 {
404 if ( this.validating == null )
405 {
406 this.validating = isDefaultValidating();
407 }
408
409 return this.validating;
410 }
411
412
413
414
415
416
417
418
419
420
421 public final void setValidating( final Boolean value )
422 {
423 this.validating = value;
424 }
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440 public static int getDefaultOrdinal()
441 {
442 if ( defaultOrdinal == null )
443 {
444 defaultOrdinal = Integer.getInteger( DEFAULT_ORDINAL_PROPERTY_NAME, DEFAULT_ORDINAL );
445 }
446
447 return defaultOrdinal;
448 }
449
450
451
452
453
454
455
456
457
458
459 public static void setDefaultOrdinal( final Integer value )
460 {
461 defaultOrdinal = value;
462 }
463
464
465
466
467
468
469
470
471
472
473
474 public final int getOrdinal()
475 {
476 if ( this.ordinal == null )
477 {
478 this.ordinal = getDefaultOrdinal();
479 }
480
481 return this.ordinal;
482 }
483
484
485
486
487
488
489
490
491
492
493 public final void setOrdinal( final Integer value )
494 {
495 this.ordinal = value;
496 }
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513 public Modlets findModlets( final ModelContext context, final String location ) throws ModelException
514 {
515 if ( context == null )
516 {
517 throw new NullPointerException( "context" );
518 }
519 if ( location == null )
520 {
521 throw new NullPointerException( "location" );
522 }
523
524 URL url = null;
525 try
526 {
527 boolean contextValidating = this.isValidating();
528 if ( DEFAULT_VALIDATING == contextValidating
529 && context.getAttribute( VALIDATING_ATTRIBUTE_NAME ) instanceof Boolean )
530 {
531 contextValidating = (Boolean) context.getAttribute( VALIDATING_ATTRIBUTE_NAME );
532 }
533
534 final Modlets modlets = new Modlets();
535 final long t0 = System.nanoTime();
536 final Enumeration<URL> modletResourceEnumeration = context.findResources( location );
537 final JAXBContext ctx = context.createContext( ModletObject.MODEL_PUBLIC_ID );
538 final javax.xml.validation.Schema schema = contextValidating
539 ? context.createSchema( ModletObject.MODEL_PUBLIC_ID )
540 : null;
541
542 final ThreadLocal<Unmarshaller> threadLocalUnmarshaller = new ThreadLocal<Unmarshaller>();
543
544 class UnmarshalTask implements Callable<Modlets>
545 {
546
547 final URL resource;
548
549 final javax.xml.validation.Schema schema;
550
551 UnmarshalTask( final URL resource, final javax.xml.validation.Schema schema )
552 {
553 super();
554 this.resource = resource;
555 this.schema = schema;
556 }
557
558 public Modlets call() throws ModelException
559 {
560 try
561 {
562 final Modlets modlets = new Modlets();
563 Unmarshaller unmarshaller = threadLocalUnmarshaller.get();
564 if ( unmarshaller == null )
565 {
566 unmarshaller = ctx.createUnmarshaller();
567 unmarshaller.setSchema( this.schema );
568
569 threadLocalUnmarshaller.set( unmarshaller );
570 }
571
572 Object content = unmarshaller.unmarshal( this.resource );
573 if ( content instanceof JAXBElement<?> )
574 {
575 content = ( (JAXBElement<?>) content ).getValue();
576 }
577
578 if ( content instanceof Modlet )
579 {
580 modlets.getModlet().add( (Modlet) content );
581 }
582 else if ( content instanceof Modlets )
583 {
584 modlets.getModlet().addAll( ( (Modlets) content ).getModlet() );
585 }
586
587 return modlets;
588 }
589 catch ( final UnmarshalException e )
590 {
591 String message = getMessage( e );
592 if ( message == null && e.getLinkedException() != null )
593 {
594 message = getMessage( e.getLinkedException() );
595 }
596
597 message = getMessage( "unmarshalException", this.resource.toExternalForm(),
598 message != null ? " " + message : "" );
599
600 throw new ModelException( message, e );
601 }
602 catch ( final JAXBException e )
603 {
604 String message = getMessage( e );
605 if ( message == null && e.getLinkedException() != null )
606 {
607 message = getMessage( e.getLinkedException() );
608 }
609
610 throw new ModelException( message, e );
611 }
612 }
613
614 }
615
616 final List<UnmarshalTask> tasks = new LinkedList<UnmarshalTask>();
617
618 while ( modletResourceEnumeration.hasMoreElements() )
619 {
620 tasks.add( new UnmarshalTask( modletResourceEnumeration.nextElement(), schema ) );
621 }
622
623 if ( context.getExecutorService() != null && tasks.size() > 1 )
624 {
625 for ( final Future<Modlets> task : context.getExecutorService().invokeAll( tasks ) )
626 {
627 modlets.getModlet().addAll( task.get().getModlet() );
628 }
629 }
630 else
631 {
632 for ( final UnmarshalTask task : tasks )
633 {
634 modlets.getModlet().addAll( task.call().getModlet() );
635 }
636 }
637
638 if ( context.isLoggable( Level.FINE ) )
639 {
640 context.log( Level.FINE, getMessage( "contextReport",
641 modlets.getModlet().size(),
642 location, System.nanoTime() - t0 ), null );
643
644 }
645
646 return modlets.getModlet().isEmpty() ? null : modlets;
647 }
648 catch ( final CancellationException e )
649 {
650 throw new ModelException( getMessage( e ), e );
651 }
652 catch ( final InterruptedException e )
653 {
654 throw new ModelException( getMessage( e ), e );
655 }
656 catch ( final ExecutionException e )
657 {
658 if ( e.getCause() instanceof ModelException )
659 {
660 throw (ModelException) e.getCause();
661 }
662 else if ( e.getCause() instanceof RuntimeException )
663 {
664
665
666 if ( e.getCause().getCause() instanceof ModelException )
667 {
668 throw (ModelException) e.getCause().getCause();
669 }
670 else if ( e.getCause().getCause() instanceof RuntimeException )
671 {
672 throw (RuntimeException) e.getCause().getCause();
673 }
674 else if ( e.getCause().getCause() instanceof Error )
675 {
676 throw (Error) e.getCause().getCause();
677 }
678 else if ( e.getCause().getCause() instanceof Exception )
679 {
680
681 throw new UndeclaredThrowableException( e.getCause().getCause() );
682 }
683 else
684 {
685 throw (RuntimeException) e.getCause();
686 }
687 }
688 else if ( e.getCause() instanceof Error )
689 {
690 throw (Error) e.getCause();
691 }
692 else
693 {
694
695 throw new UndeclaredThrowableException( e.getCause() );
696 }
697 }
698 }
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714 @Deprecated
715 public Modlets findModlets( final ModelContext context ) throws ModelException
716 {
717 if ( context == null )
718 {
719 throw new NullPointerException( "context" );
720 }
721
722 return this.findModlets( context, new Modlets() );
723 }
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738 public Modlets findModlets( final ModelContext context, final Modlets modlets ) throws ModelException
739 {
740 if ( context == null )
741 {
742 throw new NullPointerException( "context" );
743 }
744 if ( modlets == null )
745 {
746 throw new NullPointerException( "context" );
747 }
748
749 Modlets provided = null;
750
751 boolean contextEnabled = this.isEnabled();
752 if ( DEFAULT_ENABLED == contextEnabled && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
753 {
754 contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
755 }
756
757 String contextModletLocation = this.getModletLocation();
758 if ( DEFAULT_MODLET_LOCATION.equals( contextModletLocation )
759 && context.getAttribute( MODLET_LOCATION_ATTRIBUTE_NAME ) instanceof String )
760 {
761 contextModletLocation = (String) context.getAttribute( MODLET_LOCATION_ATTRIBUTE_NAME );
762 }
763
764 if ( contextEnabled )
765 {
766 final Modlets found = this.findModlets( context, contextModletLocation );
767
768 if ( found != null )
769 {
770 provided = modlets.clone();
771 provided.getModlet().addAll( found.getModlet() );
772 }
773 }
774 else if ( context.isLoggable( Level.FINER ) )
775 {
776 context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName() ), null );
777 }
778
779 return provided;
780 }
781
782 private static String getMessage( final String key, final Object... arguments )
783 {
784 return MessageFormat.format( ResourceBundle.getBundle(
785 DefaultModletProvider.class.getName().replace( '.', '/' ) ).getString( key ), arguments );
786
787 }
788
789 private static String getMessage( final Throwable t )
790 {
791 return t != null
792 ? t.getMessage() != null && t.getMessage().trim().length() > 0
793 ? t.getMessage()
794 : getMessage( t.getCause() )
795 : null;
796
797 }
798
799 }