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