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.cli.commands;
32
33 import java.io.File;
34 import java.io.IOException;
35 import java.net.URL;
36 import java.util.Arrays;
37 import java.util.Enumeration;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.Locale;
41 import java.util.logging.Level;
42 import javax.xml.bind.JAXBElement;
43 import javax.xml.bind.JAXBException;
44 import javax.xml.bind.Marshaller;
45 import javax.xml.bind.Unmarshaller;
46 import javax.xml.bind.util.JAXBResult;
47 import javax.xml.bind.util.JAXBSource;
48 import javax.xml.transform.Transformer;
49 import javax.xml.transform.TransformerException;
50 import javax.xml.transform.stream.StreamSource;
51 import org.apache.commons.cli.CommandLine;
52 import org.apache.commons.cli.Option;
53 import org.jomc.modlet.DefaultModletProvider;
54 import org.jomc.modlet.ModelContext;
55 import org.jomc.modlet.ModelException;
56 import org.jomc.modlet.ModelValidationReport;
57 import org.jomc.modlet.Modlet;
58 import org.jomc.modlet.ModletObject;
59 import org.jomc.modlet.Modlets;
60 import org.jomc.modlet.ObjectFactory;
61
62
63
64
65
66
67 public final class MergeModletsCommand extends AbstractModletCommand
68 {
69
70
71
72
73 public MergeModletsCommand()
74 {
75 super();
76 }
77
78 @Override
79 public org.apache.commons.cli.Options getOptions()
80 {
81 final org.apache.commons.cli.Options options = super.getOptions();
82 Option option = (Option) Options.DOCUMENT_OPTION.clone();
83 option.setRequired( true );
84 options.addOption( option );
85
86 options.addOption( Options.DOCUMENT_ENCODING_OPTION );
87 options.addOption( Options.STYLESHEET_OPTION );
88
89 option = (Option) Options.MODLET_OPTION.clone();
90 option.setRequired( true );
91 options.addOption( option );
92
93 options.addOption( Options.MODLET_VERSION_OPTION );
94 options.addOption( Options.MODLET_VENDOR_OPTION );
95 options.addOption( Options.MODLET_INCLUDES_OPTION );
96 options.addOption( Options.MODLET_EXCLUDES_OPTION );
97 options.addOption( Options.RESOURCES_OPTION );
98 return options;
99 }
100
101 public String getName()
102 {
103 return "merge-modlets";
104 }
105
106 public String getAbbreviatedName()
107 {
108 return "mmd";
109 }
110
111 public String getShortDescription( final Locale locale )
112 {
113 return Messages.getMessage( "mergeModletsShortDescription" );
114 }
115
116 public String getLongDescription( final Locale locale )
117 {
118 return null;
119 }
120
121 protected void executeCommand( final CommandLine commandLine ) throws CommandExecutionException
122 {
123 if ( commandLine == null )
124 {
125 throw new NullPointerException( "commandLine" );
126 }
127
128 CommandLineClassLoader classLoader = null;
129
130 try
131 {
132 classLoader = new CommandLineClassLoader( commandLine );
133 final Modlets modlets = new Modlets();
134 final ModelContext context = this.createModelContext( commandLine, classLoader );
135 final Marshaller marshaller = context.createMarshaller( ModletObject.MODEL_PUBLIC_ID );
136 final Unmarshaller unmarshaller = context.createUnmarshaller( ModletObject.MODEL_PUBLIC_ID );
137
138 if ( !commandLine.hasOption( Options.NO_MODLET_RESOURCE_VALIDATION_OPTION.getOpt() ) )
139 {
140 unmarshaller.setSchema( context.createSchema( ModletObject.MODEL_PUBLIC_ID ) );
141 }
142
143 File stylesheetFile = null;
144 if ( commandLine.hasOption( Options.STYLESHEET_OPTION.getOpt() ) )
145 {
146 stylesheetFile = new File( commandLine.getOptionValue( Options.STYLESHEET_OPTION.getOpt() ) );
147 }
148
149 String modletVersion = null;
150 if ( commandLine.hasOption( Options.MODLET_VERSION_OPTION.getOpt() ) )
151 {
152 modletVersion = commandLine.getOptionValue( Options.MODLET_VERSION_OPTION.getOpt() );
153 }
154
155 String modletVendor = null;
156 if ( commandLine.hasOption( Options.MODLET_VENDOR_OPTION.getOpt() ) )
157 {
158 modletVendor = commandLine.getOptionValue( Options.MODLET_VENDOR_OPTION.getOpt() );
159 }
160
161 if ( commandLine.hasOption( Options.DOCUMENTS_OPTION.getOpt() ) )
162 {
163 for ( final File f : this.getDocumentFiles( commandLine ) )
164 {
165 if ( this.isLoggable( Level.FINEST ) )
166 {
167 this.log( Level.FINEST, Messages.getMessage( "readingResource", f.getAbsolutePath() ), null );
168 }
169
170 Object o = unmarshaller.unmarshal( f );
171 if ( o instanceof JAXBElement<?> )
172 {
173 o = ( (JAXBElement<?>) o ).getValue();
174 }
175
176 if ( o instanceof Modlet )
177 {
178 modlets.getModlet().add( (Modlet) o );
179 }
180 else if ( o instanceof Modlets )
181 {
182 modlets.getModlet().addAll( ( (Modlets) o ).getModlet() );
183 }
184 else if ( this.isLoggable( Level.WARNING ) )
185 {
186 this.log( Level.WARNING,
187 Messages.getMessage( "failureProcessing", f.getAbsolutePath(), o.toString() ),
188 null );
189
190 }
191 }
192 }
193
194 if ( commandLine.hasOption( Options.CLASSPATH_OPTION.getOpt() ) )
195 {
196 String[] resourceNames = null;
197
198 if ( commandLine.hasOption( Options.RESOURCES_OPTION.getOpt() ) )
199 {
200 resourceNames = commandLine.getOptionValues( Options.RESOURCES_OPTION.getOpt() );
201 }
202
203 if ( resourceNames == null )
204 {
205 resourceNames = new String[]
206 {
207 DefaultModletProvider.getDefaultModletLocation()
208 };
209 }
210
211 for ( final String resource : resourceNames )
212 {
213 for ( final Enumeration<URL> e = classLoader.getResources( resource ); e.hasMoreElements(); )
214 {
215 final URL url = e.nextElement();
216
217 if ( this.isLoggable( Level.FINEST ) )
218 {
219 this.log( Level.FINEST,
220 Messages.getMessage( "readingResource", url.toExternalForm() ),
221 null );
222
223 }
224
225 Object o = unmarshaller.unmarshal( url );
226 if ( o instanceof JAXBElement<?> )
227 {
228 o = ( (JAXBElement<?>) o ).getValue();
229 }
230
231 if ( o instanceof Modlet )
232 {
233 modlets.getModlet().add( (Modlet) o );
234 }
235 else if ( o instanceof Modlets )
236 {
237 modlets.getModlet().addAll( ( (Modlets) o ).getModlet() );
238 }
239 else if ( this.isLoggable( Level.WARNING ) )
240 {
241 this.log( Level.WARNING,
242 Messages.getMessage( "failureProcessing", url.toExternalForm(), o.toString() ),
243 null );
244
245 }
246 }
247 }
248 }
249
250 if ( commandLine.hasOption( Options.MODLET_INCLUDES_OPTION.getOpt() ) )
251 {
252 final String[] values = commandLine.getOptionValues( Options.MODLET_INCLUDES_OPTION.getOpt() );
253
254 if ( values != null )
255 {
256 final List<String> includes = Arrays.asList( values );
257
258 for ( final Iterator<Modlet> it = modlets.getModlet().iterator(); it.hasNext(); )
259 {
260 final Modlet m = it.next();
261
262 if ( !includes.contains( m.getName() ) )
263 {
264 this.log( Level.INFO,
265 Messages.getMessage( "modletNameExclusionInfo", m.getName() ),
266 null );
267
268 it.remove();
269 }
270 else
271 {
272 this.log( Level.INFO,
273 Messages.getMessage( "modletNameInclusionInfo", m.getName() ),
274 null );
275
276 }
277 }
278 }
279 }
280
281 if ( commandLine.hasOption( Options.MODLET_EXCLUDES_OPTION.getOpt() ) )
282 {
283 final String[] values = commandLine.getOptionValues( Options.MODLET_EXCLUDES_OPTION.getOpt() );
284
285 if ( values != null )
286 {
287 for ( final String exclude : values )
288 {
289 final Modlet m = modlets.getModlet( exclude );
290
291 if ( m != null )
292 {
293 this.log( Level.INFO,
294 Messages.getMessage( "modletNameExclusionInfo", m.getName() ),
295 null );
296
297 modlets.getModlet().remove( m );
298 }
299 }
300 }
301 }
302
303 final ModelValidationReport validationReport =
304 context.validateModel( ModletObject.MODEL_PUBLIC_ID,
305 new JAXBSource( marshaller, new ObjectFactory().createModlets( modlets ) ) );
306
307 this.log( validationReport, marshaller );
308
309 if ( !validationReport.isModelValid() )
310 {
311 throw new CommandExecutionException( Messages.getMessage( "invalidModel",
312 ModletObject.MODEL_PUBLIC_ID ) );
313
314 }
315
316 Modlet mergedModlet = modlets.getMergedModlet(
317 commandLine.getOptionValue( Options.MODLET_OPTION.getOpt() ), this.getModel( commandLine ) );
318
319 mergedModlet.setVersion( modletVersion );
320 mergedModlet.setVendor( modletVendor );
321
322 final File modletFile = new File( commandLine.getOptionValue( Options.DOCUMENT_OPTION.getOpt() ) );
323
324 if ( stylesheetFile != null )
325 {
326 final Transformer transformer = this.createTransformer( new StreamSource( stylesheetFile ) );
327 final JAXBSource source =
328 new JAXBSource( marshaller, new ObjectFactory().createModlet( mergedModlet ) );
329
330 final JAXBResult result = new JAXBResult( unmarshaller );
331 unmarshaller.setSchema( null );
332 transformer.transform( source, result );
333
334 if ( result.getResult() instanceof JAXBElement<?>
335 && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Modlet )
336 {
337 mergedModlet = (Modlet) ( (JAXBElement<?>) result.getResult() ).getValue();
338 }
339 else
340 {
341 throw new CommandExecutionException( Messages.getMessage( "illegalTransformationResultError",
342 stylesheetFile.getAbsolutePath() ) );
343
344 }
345 }
346
347 marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
348
349 if ( commandLine.hasOption( Options.DOCUMENT_ENCODING_OPTION.getOpt() ) )
350 {
351 marshaller.setProperty( Marshaller.JAXB_ENCODING,
352 commandLine.getOptionValue( Options.DOCUMENT_ENCODING_OPTION.getOpt() ) );
353
354 }
355
356 marshaller.setSchema( context.createSchema( ModletObject.MODEL_PUBLIC_ID ) );
357 marshaller.marshal( new ObjectFactory().createModlet( mergedModlet ), modletFile );
358
359 if ( this.isLoggable( Level.INFO ) )
360 {
361 this.log( Level.INFO, Messages.getMessage( "writingResource", modletFile.getAbsolutePath() ), null );
362 }
363
364 classLoader.close();
365 classLoader = null;
366 }
367 catch ( final IOException e )
368 {
369 throw new CommandExecutionException( Messages.getMessage( e ), e );
370 }
371 catch ( final TransformerException e )
372 {
373 String message = Messages.getMessage( e );
374 if ( message == null )
375 {
376 message = Messages.getMessage( e.getException() );
377 }
378
379 throw new CommandExecutionException( message, e );
380 }
381 catch ( final JAXBException e )
382 {
383 String message = Messages.getMessage( e );
384 if ( message == null )
385 {
386 message = Messages.getMessage( e.getLinkedException() );
387 }
388
389 throw new CommandExecutionException( message, e );
390 }
391 catch ( final ModelException e )
392 {
393 throw new CommandExecutionException( Messages.getMessage( e ), e );
394 }
395 finally
396 {
397 try
398 {
399 if ( classLoader != null )
400 {
401 classLoader.close();
402 }
403 }
404 catch ( final IOException e )
405 {
406 this.log( Level.SEVERE, Messages.getMessage( e ), e );
407 }
408 }
409 }
410
411 }