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.IOException;
34 import java.io.InputStream;
35 import java.net.SocketTimeoutException;
36 import java.net.URISyntaxException;
37 import java.net.URL;
38 import java.net.URLConnection;
39 import java.util.HashSet;
40 import java.util.Set;
41 import java.util.logging.Level;
42 import javax.xml.bind.JAXBElement;
43 import javax.xml.bind.JAXBException;
44 import javax.xml.bind.Unmarshaller;
45 import javax.xml.transform.Source;
46 import javax.xml.transform.stream.StreamSource;
47 import org.apache.tools.ant.BuildException;
48 import org.apache.tools.ant.Project;
49 import org.jomc.ant.types.KeyValueType;
50 import org.jomc.ant.types.ModuleResourceType;
51 import org.jomc.ant.types.ResourceType;
52 import org.jomc.model.Module;
53 import org.jomc.model.Modules;
54 import org.jomc.model.modlet.DefaultModelProcessor;
55 import org.jomc.model.modlet.DefaultModelProvider;
56 import org.jomc.model.modlet.DefaultModelValidator;
57 import org.jomc.model.modlet.ModelHelper;
58 import org.jomc.modlet.Model;
59 import org.jomc.modlet.ModelContext;
60 import org.jomc.modlet.ModelException;
61 import org.jomc.tools.modlet.ToolsModelProcessor;
62 import org.jomc.tools.modlet.ToolsModelProvider;
63
64
65
66
67
68
69
70 public class JomcModelTask extends JomcTask
71 {
72
73
74
75
76 private boolean modelObjectClasspathResolutionEnabled = true;
77
78
79
80
81 private String moduleLocation;
82
83
84
85
86 private String transformerLocation;
87
88
89
90
91 private Set<ModuleResourceType> moduleResources;
92
93
94
95
96 private boolean modelResourceValidationEnabled = true;
97
98
99
100
101 private boolean javaValidationEnabled = true;
102
103
104
105
106 public JomcModelTask()
107 {
108 super();
109 }
110
111
112
113
114
115
116
117
118 public final String getModuleLocation()
119 {
120 return this.moduleLocation;
121 }
122
123
124
125
126
127
128
129
130 public final void setModuleLocation( final String value )
131 {
132 this.moduleLocation = value;
133 }
134
135
136
137
138
139
140
141
142 public final String getTransformerLocation()
143 {
144 return this.transformerLocation;
145 }
146
147
148
149
150
151
152
153
154 public final void setTransformerLocation( final String value )
155 {
156 this.transformerLocation = value;
157 }
158
159
160
161
162
163
164
165
166 public final boolean isModelObjectClasspathResolutionEnabled()
167 {
168 return this.modelObjectClasspathResolutionEnabled;
169 }
170
171
172
173
174
175
176
177
178
179 public final void setModelObjectClasspathResolutionEnabled( final boolean value )
180 {
181 this.modelObjectClasspathResolutionEnabled = value;
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195
196 public Set<ModuleResourceType> getModuleResources()
197 {
198 if ( this.moduleResources == null )
199 {
200 this.moduleResources = new HashSet<ModuleResourceType>();
201 }
202
203 return this.moduleResources;
204 }
205
206
207
208
209
210
211
212
213 public ModuleResourceType createModuleResource()
214 {
215 final ModuleResourceType moduleResource = new ModuleResourceType();
216 this.getModuleResources().add( moduleResource );
217 return moduleResource;
218 }
219
220
221
222
223
224
225
226
227 public final boolean isModelResourceValidationEnabled()
228 {
229 return this.modelResourceValidationEnabled;
230 }
231
232
233
234
235
236
237
238
239
240 public final void setModelResourceValidationEnabled( final boolean value )
241 {
242 this.modelResourceValidationEnabled = value;
243 }
244
245
246
247
248
249
250
251
252
253
254 public final boolean isJavaValidationEnabled()
255 {
256 return this.javaValidationEnabled;
257 }
258
259
260
261
262
263
264
265
266
267
268 public final void setJavaValidationEnabled( final boolean value )
269 {
270 this.javaValidationEnabled = value;
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 @Override
289 public Model getModel( final ModelContext context ) throws BuildException, ModelException
290 {
291 if ( context == null )
292 {
293 throw new NullPointerException( "context" );
294 }
295
296 Model model = new Model();
297 model.setIdentifier( this.getModel() );
298 Modules modules = new Modules();
299 ModelHelper.setModules( model, modules );
300 Unmarshaller unmarshaller = null;
301
302 for ( final ResourceType resource : this.getModuleResources() )
303 {
304 final URL[] urls = this.getResources( context, resource.getLocation() );
305
306 if ( urls.length == 0 )
307 {
308 if ( resource.isOptional() )
309 {
310 this.logMessage( Level.WARNING, Messages.getMessage( "moduleResourceNotFound",
311 resource.getLocation() ) );
312
313 }
314 else
315 {
316 throw new BuildException( Messages.getMessage( "moduleResourceNotFound", resource.getLocation() ),
317 this.getLocation() );
318
319 }
320 }
321
322 for ( int i = urls.length - 1; i >= 0; i-- )
323 {
324 InputStream in = null;
325 boolean suppressExceptionOnClose = true;
326
327 try
328 {
329 this.logMessage( Level.FINEST, Messages.getMessage( "reading", urls[i].toExternalForm() ) );
330
331 final URLConnection con = urls[i].openConnection();
332 con.setConnectTimeout( resource.getConnectTimeout() );
333 con.setReadTimeout( resource.getReadTimeout() );
334 con.connect();
335 in = con.getInputStream();
336
337 final Source source = new StreamSource( in, urls[i].toURI().toASCIIString() );
338
339 if ( unmarshaller == null )
340 {
341 unmarshaller = context.createUnmarshaller( this.getModel() );
342 if ( this.isModelResourceValidationEnabled() )
343 {
344 unmarshaller.setSchema( context.createSchema( this.getModel() ) );
345 }
346 }
347
348 Object o = unmarshaller.unmarshal( source );
349 if ( o instanceof JAXBElement<?> )
350 {
351 o = ( (JAXBElement<?>) o ).getValue();
352 }
353
354 if ( o instanceof Module )
355 {
356 modules.getModule().add( (Module) o );
357 }
358 else
359 {
360 this.log( Messages.getMessage( "unsupportedModuleResource", urls[i].toExternalForm() ),
361 Project.MSG_WARN );
362
363 }
364
365 suppressExceptionOnClose = false;
366 }
367 catch ( final SocketTimeoutException e )
368 {
369 String message = Messages.getMessage( e );
370 message = Messages.getMessage( "resourceTimeout", message != null ? " " + message : "" );
371
372 if ( resource.isOptional() )
373 {
374 this.getProject().log( message, e, Project.MSG_WARN );
375 }
376 else
377 {
378 throw new BuildException( message, e, this.getLocation() );
379 }
380 }
381 catch ( final IOException e )
382 {
383 String message = Messages.getMessage( e );
384 message = Messages.getMessage( "resourceFailure", message != null ? " " + message : "" );
385
386 if ( resource.isOptional() )
387 {
388 this.getProject().log( message, e, Project.MSG_WARN );
389 }
390 else
391 {
392 throw new BuildException( message, e, this.getLocation() );
393 }
394 }
395 catch ( final URISyntaxException e )
396 {
397 throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
398 }
399 catch ( final JAXBException e )
400 {
401 String message = Messages.getMessage( e );
402 if ( message == null )
403 {
404 message = Messages.getMessage( e.getLinkedException() );
405 }
406
407 throw new BuildException( message, e, this.getLocation() );
408 }
409 finally
410 {
411 try
412 {
413 if ( in != null )
414 {
415 in.close();
416 }
417 }
418 catch ( final IOException e )
419 {
420 if ( suppressExceptionOnClose )
421 {
422 this.logMessage( Level.SEVERE, Messages.getMessage( e ), e );
423 }
424 else
425 {
426 throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
427 }
428 }
429 }
430 }
431 }
432
433 model = context.findModel( model );
434 modules = ModelHelper.getModules( model );
435
436 if ( modules != null && this.isModelObjectClasspathResolutionEnabled() )
437 {
438 final Module classpathModule =
439 modules.getClasspathModule( Modules.getDefaultClasspathModuleName(), context.getClassLoader() );
440
441 if ( classpathModule != null && modules.getModule( Modules.getDefaultClasspathModuleName() ) == null )
442 {
443 modules.getModule().add( classpathModule );
444 }
445 }
446
447 if ( this.isModelProcessingEnabled() )
448 {
449 model = context.processModel( model );
450 }
451
452 return model;
453 }
454
455
456
457
458 @Override
459 public void preExecuteTask() throws BuildException
460 {
461 super.preExecuteTask();
462 this.assertLocationsNotNull( this.getModuleResources() );
463 }
464
465
466
467
468 @Override
469 public ModelContext newModelContext( final ClassLoader classLoader ) throws ModelException
470 {
471 final ModelContext modelContext = super.newModelContext( classLoader );
472
473 if ( this.getTransformerLocation() != null )
474 {
475 modelContext.setAttribute( DefaultModelProcessor.TRANSFORMER_LOCATION_ATTRIBUTE_NAME,
476 this.getTransformerLocation() );
477
478 }
479
480 if ( this.getModuleLocation() != null )
481 {
482 modelContext.setAttribute( DefaultModelProvider.MODULE_LOCATION_ATTRIBUTE_NAME, this.getModuleLocation() );
483 }
484
485 modelContext.setAttribute( ToolsModelProvider.MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME,
486 this.isModelObjectClasspathResolutionEnabled() );
487
488 modelContext.setAttribute( ToolsModelProcessor.MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME,
489 this.isModelObjectClasspathResolutionEnabled() );
490
491 modelContext.setAttribute( DefaultModelProvider.VALIDATING_ATTRIBUTE_NAME,
492 this.isModelResourceValidationEnabled() );
493
494 modelContext.setAttribute( DefaultModelValidator.VALIDATE_JAVA_ATTRIBUTE_NAME, this.isJavaValidationEnabled() );
495
496 for ( int i = 0, s0 = this.getModelContextAttributes().size(); i < s0; i++ )
497 {
498 final KeyValueType kv = this.getModelContextAttributes().get( i );
499 final Object object = kv.getObject( this.getLocation() );
500
501 if ( object != null )
502 {
503 modelContext.setAttribute( kv.getKey(), object );
504 }
505 else
506 {
507 modelContext.clearAttribute( kv.getKey() );
508 }
509 }
510
511 return modelContext;
512 }
513
514
515
516
517 @Override
518 public JomcModelTask clone()
519 {
520 final JomcModelTask clone = (JomcModelTask) super.clone();
521
522 if ( this.moduleResources != null )
523 {
524 clone.moduleResources = new HashSet<ModuleResourceType>( this.moduleResources.size() );
525 for ( final ModuleResourceType e : this.moduleResources )
526 {
527 clone.moduleResources.add( e.clone() );
528 }
529 }
530
531 return clone;
532 }
533
534 }