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.net.URISyntaxException;
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.Locale;
40 import java.util.Map;
41 import java.util.ResourceBundle;
42 import java.util.logging.Level;
43 import javax.xml.bind.JAXBContext;
44 import javax.xml.bind.JAXBElement;
45 import javax.xml.bind.JAXBException;
46 import javax.xml.bind.util.JAXBResult;
47 import javax.xml.bind.util.JAXBSource;
48 import javax.xml.transform.ErrorListener;
49 import javax.xml.transform.Transformer;
50 import javax.xml.transform.TransformerConfigurationException;
51 import javax.xml.transform.TransformerException;
52 import javax.xml.transform.TransformerFactory;
53 import javax.xml.transform.stream.StreamSource;
54
55
56
57
58
59
60
61
62
63 public class DefaultModletProcessor implements ModletProcessor
64 {
65
66
67
68
69
70
71
72 public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.modlet.DefaultModletProcessor.enabledAttribute";
73
74
75
76
77
78
79 private static final String DEFAULT_ENABLED_PROPERTY_NAME =
80 "org.jomc.modlet.DefaultModletProcessor.defaultEnabled";
81
82
83
84
85
86
87 private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
88
89
90
91
92 private static volatile Boolean defaultEnabled;
93
94
95
96
97 private Boolean enabled;
98
99
100
101
102
103
104 private static final String DEFAULT_ORDINAL_PROPERTY_NAME =
105 "org.jomc.modlet.DefaultModletProcessor.defaultOrdinal";
106
107
108
109
110
111
112 private static final Integer DEFAULT_ORDINAL = 0;
113
114
115
116
117 private static volatile Integer defaultOrdinal;
118
119
120
121
122 private Integer ordinal;
123
124
125
126
127
128
129
130
131 public static final String TRANSFORMER_LOCATION_ATTRIBUTE_NAME =
132 "org.jomc.modlet.DefaultModletProcessor.transformerLocationAttribute";
133
134
135
136
137
138
139 private static final String DEFAULT_TRANSFORMER_LOCATION_PROPERTY_NAME =
140 "org.jomc.modlet.DefaultModletProcessor.defaultTransformerLocation";
141
142
143
144
145
146
147 private static final String DEFAULT_TRANSFORMER_LOCATION = "META-INF/jomc-modlet.xsl";
148
149
150
151
152 private static volatile String defaultTransformerLocation;
153
154
155
156
157 private String transformerLocation;
158
159
160
161
162 public DefaultModletProcessor()
163 {
164 super();
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181 public static boolean isDefaultEnabled()
182 {
183 if ( defaultEnabled == null )
184 {
185 defaultEnabled = Boolean.valueOf( System.getProperty(
186 DEFAULT_ENABLED_PROPERTY_NAME, Boolean.toString( DEFAULT_ENABLED ) ) );
187
188 }
189
190 return defaultEnabled;
191 }
192
193
194
195
196
197
198
199
200 public static void setDefaultEnabled( final Boolean value )
201 {
202 defaultEnabled = value;
203 }
204
205
206
207
208
209
210
211
212
213 public final boolean isEnabled()
214 {
215 if ( this.enabled == null )
216 {
217 this.enabled = isDefaultEnabled();
218 }
219
220 return this.enabled;
221 }
222
223
224
225
226
227
228
229
230 public final void setEnabled( final Boolean value )
231 {
232 this.enabled = value;
233 }
234
235
236
237
238
239
240
241
242
243
244
245
246
247 public static int getDefaultOrdinal()
248 {
249 if ( defaultOrdinal == null )
250 {
251 defaultOrdinal = Integer.getInteger( DEFAULT_ORDINAL_PROPERTY_NAME, DEFAULT_ORDINAL );
252 }
253
254 return defaultOrdinal;
255 }
256
257
258
259
260
261
262
263
264 public static void setDefaultOrdinal( final Integer value )
265 {
266 defaultOrdinal = value;
267 }
268
269
270
271
272
273
274
275
276
277 public final int getOrdinal()
278 {
279 if ( this.ordinal == null )
280 {
281 this.ordinal = getDefaultOrdinal();
282 }
283
284 return this.ordinal;
285 }
286
287
288
289
290
291
292
293
294 public final void setOrdinal( final Integer value )
295 {
296 this.ordinal = value;
297 }
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312 public static String getDefaultTransformerLocation()
313 {
314 if ( defaultTransformerLocation == null )
315 {
316 defaultTransformerLocation =
317 System.getProperty( DEFAULT_TRANSFORMER_LOCATION_PROPERTY_NAME, DEFAULT_TRANSFORMER_LOCATION );
318
319 }
320
321 return defaultTransformerLocation;
322 }
323
324
325
326
327
328
329
330
331 public static void setDefaultTransformerLocation( final String value )
332 {
333 defaultTransformerLocation = value;
334 }
335
336
337
338
339
340
341
342
343
344 public final String getTransformerLocation()
345 {
346 if ( this.transformerLocation == null )
347 {
348 this.transformerLocation = getDefaultTransformerLocation();
349 }
350
351 return this.transformerLocation;
352 }
353
354
355
356
357
358
359
360
361 public final void setTransformerLocation( final String value )
362 {
363 this.transformerLocation = value;
364 }
365
366
367
368
369
370
371
372
373
374
375
376
377
378 public List<Transformer> findTransformers( final ModelContext context, final String location ) throws ModelException
379 {
380 if ( context == null )
381 {
382 throw new NullPointerException( "context" );
383 }
384 if ( location == null )
385 {
386 throw new NullPointerException( "location" );
387 }
388
389 try
390 {
391 final long t0 = System.currentTimeMillis();
392 final List<Transformer> transformers = new LinkedList<Transformer>();
393 final TransformerFactory transformerFactory = TransformerFactory.newInstance();
394 final Enumeration<URL> resources = context.findResources( location );
395 final ErrorListener errorListener = new ErrorListener()
396 {
397
398 public void warning( final TransformerException exception ) throws TransformerException
399 {
400 if ( context.isLoggable( Level.WARNING ) )
401 {
402 context.log( Level.WARNING, getMessage( exception ), exception );
403 }
404 }
405
406 public void error( final TransformerException exception ) throws TransformerException
407 {
408 if ( context.isLoggable( Level.SEVERE ) )
409 {
410 context.log( Level.SEVERE, getMessage( exception ), exception );
411 }
412
413 throw exception;
414 }
415
416 public void fatalError( final TransformerException exception ) throws TransformerException
417 {
418 if ( context.isLoggable( Level.SEVERE ) )
419 {
420 context.log( Level.SEVERE, getMessage( exception ), exception );
421 }
422
423 throw exception;
424 }
425
426 };
427
428 transformerFactory.setErrorListener( errorListener );
429
430 int count = 0;
431 while ( resources.hasMoreElements() )
432 {
433 count++;
434 final URL url = resources.nextElement();
435
436 if ( context.isLoggable( Level.FINEST ) )
437 {
438 context.log( Level.FINEST, getMessage( "processing", url.toExternalForm() ), null );
439 }
440
441 final Transformer transformer =
442 transformerFactory.newTransformer( new StreamSource( url.toURI().toASCIIString() ) );
443
444 transformer.setErrorListener( errorListener );
445
446 for ( final Map.Entry<Object, Object> e : System.getProperties().entrySet() )
447 {
448 transformer.setParameter( e.getKey().toString(), e.getValue() );
449 }
450
451 transformers.add( transformer );
452 }
453
454 if ( context.isLoggable( Level.FINE ) )
455 {
456 context.log( Level.FINE, getMessage( "contextReport", count, location,
457 Long.valueOf( System.currentTimeMillis() - t0 ) ), null );
458
459 }
460
461 return transformers.isEmpty() ? null : transformers;
462 }
463 catch ( final URISyntaxException e )
464 {
465 throw new ModelException( getMessage( e ), e );
466 }
467 catch ( final TransformerConfigurationException e )
468 {
469 String message = getMessage( e );
470 if ( message == null && e.getException() != null )
471 {
472 message = getMessage( e.getException() );
473 }
474
475 throw new ModelException( message, e );
476 }
477 }
478
479
480
481
482
483
484
485
486
487
488 public Modlets processModlets( final ModelContext context, final Modlets modlets ) throws ModelException
489 {
490 if ( context == null )
491 {
492 throw new NullPointerException( "context" );
493 }
494 if ( modlets == null )
495 {
496 throw new NullPointerException( "modlets" );
497 }
498
499 try
500 {
501 Modlets processed = null;
502
503 boolean contextEnabled = this.isEnabled();
504 if ( DEFAULT_ENABLED == contextEnabled
505 && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
506 {
507 contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
508 }
509
510 String contextTransformerLocation = this.getTransformerLocation();
511 if ( DEFAULT_TRANSFORMER_LOCATION.equals( contextTransformerLocation )
512 && context.getAttribute( TRANSFORMER_LOCATION_ATTRIBUTE_NAME ) instanceof String )
513 {
514 contextTransformerLocation = (String) context.getAttribute( TRANSFORMER_LOCATION_ATTRIBUTE_NAME );
515 }
516
517 if ( contextEnabled )
518 {
519 final org.jomc.modlet.ObjectFactory objectFactory = new org.jomc.modlet.ObjectFactory();
520 final JAXBContext jaxbContext = context.createContext( ModletObject.MODEL_PUBLIC_ID );
521 final List<Transformer> transformers = this.findTransformers( context, contextTransformerLocation );
522
523 if ( transformers != null )
524 {
525 processed = modlets.clone();
526
527 for ( int i = 0, s0 = transformers.size(); i < s0; i++ )
528 {
529 final JAXBElement<Modlets> e = objectFactory.createModlets( processed );
530 final JAXBSource source = new JAXBSource( jaxbContext, e );
531 final JAXBResult result = new JAXBResult( jaxbContext );
532 transformers.get( i ).transform( source, result );
533
534 if ( result.getResult() instanceof JAXBElement<?>
535 && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Modlets )
536 {
537 processed = (Modlets) ( (JAXBElement<?>) result.getResult() ).getValue();
538 }
539 else
540 {
541 throw new ModelException( getMessage( "illegalTransformationResult" ) );
542 }
543 }
544 }
545 }
546 else if ( context.isLoggable( Level.FINER ) )
547 {
548 context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName() ), null );
549 }
550
551 return processed;
552 }
553 catch ( final TransformerException e )
554 {
555 String message = getMessage( e );
556 if ( message == null && e.getException() != null )
557 {
558 message = getMessage( e.getException() );
559 }
560
561 throw new ModelException( message, e );
562 }
563 catch ( final JAXBException e )
564 {
565 String message = getMessage( e );
566 if ( message == null && e.getLinkedException() != null )
567 {
568 message = getMessage( e.getLinkedException() );
569 }
570
571 throw new ModelException( message, e );
572 }
573 }
574
575 private static String getMessage( final String key, final Object... args )
576 {
577 return MessageFormat.format( ResourceBundle.getBundle(
578 DefaultModletProcessor.class.getName().replace( '.', '/' ), Locale.getDefault() ).getString( key ), args );
579
580 }
581
582 private static String getMessage( final Throwable t )
583 {
584 return t != null
585 ? t.getMessage() != null && t.getMessage().trim().length() > 0
586 ? t.getMessage()
587 : getMessage( t.getCause() )
588 : null;
589
590 }
591
592 }