View Javadoc
1   /*
2    * Copyright (C) 2009 Christian Schulte <cs@schulte.it>
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *   o Redistributions of source code must retain the above copyright
10   *     notice, this list of conditions and the following disclaimer.
11   *
12   *   o Redistributions in binary form must reproduce the above copyright
13   *     notice, this list of conditions and the following disclaimer in
14   *     the documentation and/or other materials provided with the
15   *     distribution.
16   *
17   * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19   * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20   * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27   *
28   * $JOMC: AbstractModelCommand.java 5253 2016-04-25 20:18:36Z schulte $
29   *
30   */
31  package org.jomc.cli.commands;
32  
33  import java.io.File;
34  import java.util.logging.Level;
35  import javax.xml.bind.JAXBElement;
36  import javax.xml.bind.JAXBException;
37  import javax.xml.bind.Unmarshaller;
38  import org.apache.commons.cli.CommandLine;
39  import org.jomc.model.Module;
40  import org.jomc.model.Modules;
41  import org.jomc.model.modlet.DefaultModelProcessor;
42  import org.jomc.model.modlet.DefaultModelProvider;
43  import org.jomc.model.modlet.DefaultModelValidator;
44  import org.jomc.model.modlet.ModelHelper;
45  import org.jomc.modlet.Model;
46  import org.jomc.modlet.ModelContext;
47  import org.jomc.modlet.ModelException;
48  import org.jomc.tools.modlet.ToolsModelProcessor;
49  import org.jomc.tools.modlet.ToolsModelProvider;
50  
51  /**
52   * {@code Model} based command implementation.
53   *
54   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
55   */
56  public abstract class AbstractModelCommand extends AbstractModletCommand
57  {
58  
59      /**
60       * Creates a new {@code AbstractModelCommand} instance.
61       */
62      public AbstractModelCommand()
63      {
64          super();
65      }
66  
67      @Override
68      public org.apache.commons.cli.Options getOptions()
69      {
70          final org.apache.commons.cli.Options options = super.getOptions();
71          options.addOption( Options.MODULE_LOCATION_OPTION );
72          options.addOption( Options.TRANSFORMER_LOCATION_OPTION );
73          options.addOption( Options.NO_CLASSPATH_RESOLUTION_OPTION );
74          options.addOption( Options.NO_MODEL_PROCESSING_OPTION );
75          options.addOption( Options.NO_MODEL_RESOURCE_VALIDATION_OPTION );
76          options.addOption( Options.NO_JAVA_VALIDATION_OPTION );
77          return options;
78      }
79  
80      /**
81       * {@inheritDoc}
82       */
83      @Override
84      protected ModelContext createModelContext( final CommandLine commandLine, final ClassLoader classLoader )
85          throws CommandExecutionException
86      {
87          if ( commandLine == null )
88          {
89              throw new NullPointerException( "commandLine" );
90          }
91  
92          final ModelContext modelContext = super.createModelContext( commandLine, classLoader );
93  
94          if ( commandLine.hasOption( Options.TRANSFORMER_LOCATION_OPTION.getOpt() ) )
95          {
96              modelContext.setAttribute( DefaultModelProcessor.TRANSFORMER_LOCATION_ATTRIBUTE_NAME,
97                                         commandLine.getOptionValue( Options.TRANSFORMER_LOCATION_OPTION.getOpt() ) );
98  
99          }
100 
101         if ( commandLine.hasOption( Options.MODULE_LOCATION_OPTION.getOpt() ) )
102         {
103             modelContext.setAttribute( DefaultModelProvider.MODULE_LOCATION_ATTRIBUTE_NAME,
104                                        commandLine.getOptionValue( Options.MODULE_LOCATION_OPTION.getOpt() ) );
105 
106         }
107 
108         modelContext.setAttribute( ToolsModelProvider.MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME,
109                                    !commandLine.hasOption( Options.NO_CLASSPATH_RESOLUTION_OPTION.getOpt() ) );
110 
111         modelContext.setAttribute( ToolsModelProcessor.MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME,
112                                    !commandLine.hasOption( Options.NO_CLASSPATH_RESOLUTION_OPTION.getOpt() ) );
113 
114         modelContext.setAttribute( DefaultModelProvider.VALIDATING_ATTRIBUTE_NAME,
115                                    !commandLine.hasOption( Options.NO_MODEL_RESOURCE_VALIDATION_OPTION.getOpt() ) );
116 
117         modelContext.setAttribute( DefaultModelValidator.VALIDATE_JAVA_ATTRIBUTE_NAME,
118                                    !commandLine.hasOption( Options.NO_JAVA_VALIDATION_OPTION.getOpt() ) );
119 
120         return modelContext;
121     }
122 
123     /**
124      * Gets the model as specified by a given command line.
125      *
126      * @param context The context to use for getting the model.
127      * @param commandLine The command line specifying the model to get.
128      *
129      * @return The model as specified by {@code commandLine}.
130      *
131      * @throws CommandExecutionException if getting the model fails.
132      */
133     protected Model getModel( final ModelContext context, final CommandLine commandLine )
134         throws CommandExecutionException
135     {
136         try
137         {
138             Model model = new Model();
139             model.setIdentifier( this.getModel( commandLine ) );
140             Modules modules = new Modules();
141             ModelHelper.setModules( model, modules );
142 
143             if ( commandLine.hasOption( Options.DOCUMENTS_OPTION.getOpt() ) )
144             {
145                 final Unmarshaller u = context.createUnmarshaller( model.getIdentifier() );
146 
147                 if ( !commandLine.hasOption( Options.NO_MODEL_RESOURCE_VALIDATION_OPTION.getOpt() ) )
148                 {
149                     u.setSchema( context.createSchema( model.getIdentifier() ) );
150                 }
151 
152                 for ( final File f : this.getDocumentFiles( commandLine ) )
153                 {
154                     if ( this.isLoggable( Level.FINEST ) )
155                     {
156                         this.log( Level.FINEST,
157                                   Messages.getMessage( "readingResource", f.getAbsolutePath() ),
158                                   null );
159 
160                     }
161 
162                     Object o = u.unmarshal( f );
163                     if ( o instanceof JAXBElement<?> )
164                     {
165                         o = ( (JAXBElement<?>) o ).getValue();
166                     }
167 
168                     if ( o instanceof Module )
169                     {
170                         modules.getModule().add( (Module) o );
171                     }
172                     else if ( o instanceof Modules )
173                     {
174                         modules.getModule().addAll( ( (Modules) o ).getModule() );
175                     }
176                     else if ( this.isLoggable( Level.WARNING ) )
177                     {
178                         this.log( Level.WARNING,
179                                   Messages.getMessage( "failureProcessing", f.getAbsolutePath(), o.toString() ),
180                                   null );
181 
182                     }
183                 }
184             }
185 
186             model = context.findModel( model );
187             modules = ModelHelper.getModules( model );
188 
189             if ( modules != null && !commandLine.hasOption( Options.NO_CLASSPATH_RESOLUTION_OPTION.getOpt() ) )
190             {
191                 final Module classpathModule = modules.getClasspathModule(
192                     Modules.getDefaultClasspathModuleName(), context.getClassLoader() );
193 
194                 if ( classpathModule != null && modules.getModule( classpathModule.getName() ) == null )
195                 {
196                     modules.getModule().add( classpathModule );
197                 }
198             }
199 
200             if ( !commandLine.hasOption( Options.NO_MODEL_PROCESSING_OPTION.getOpt() ) )
201             {
202                 model = context.processModel( model );
203                 modules = ModelHelper.getModules( model );
204             }
205 
206             assert modules != null : "Modules '" + this.getModel( commandLine ) + "' not found.";
207             return model;
208         }
209         catch ( final ModelException e )
210         {
211             throw new CommandExecutionException( Messages.getMessage( e ), e );
212         }
213         catch ( final JAXBException e )
214         {
215             String message = Messages.getMessage( e );
216             if ( message == null )
217             {
218                 message = Messages.getMessage( e.getLinkedException() );
219             }
220 
221             throw new CommandExecutionException( message, e );
222         }
223     }
224 
225 }