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