001/* 002 * Copyright (C) 2009 Christian Schulte <cs@schulte.it> 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions 007 * are met: 008 * 009 * o Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 012 * o Redistributions in binary form must reproduce the above copyright 013 * notice, this list of conditions and the following disclaimer in 014 * the documentation and/or other materials provided with the 015 * distribution. 016 * 017 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 018 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 019 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 020 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, 021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 027 * 028 * $JOMC: AbstractJomcToolCommand.java 5299 2016-08-30 01:50:13Z schulte $ 029 * 030 */ 031package org.jomc.cli.commands; 032 033import java.io.File; 034import java.net.MalformedURLException; 035import java.net.URL; 036import java.util.Locale; 037import java.util.logging.Level; 038import org.apache.commons.cli.CommandLine; 039import org.apache.commons.lang.StringEscapeUtils; 040import org.apache.commons.lang.StringUtils; 041import org.jomc.model.Implementation; 042import org.jomc.model.Module; 043import org.jomc.model.Modules; 044import org.jomc.model.Specification; 045import org.jomc.model.modlet.ModelHelper; 046import org.jomc.modlet.Model; 047import org.jomc.tools.JomcTool; 048 049/** 050 * {@code JomcTool} based command implementation. 051 * 052 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 053 */ 054public abstract class AbstractJomcToolCommand extends AbstractModelCommand 055{ 056 057 /** 058 * Creates a new {@code AbstractJomcToolCommand} instance. 059 */ 060 public AbstractJomcToolCommand() 061 { 062 super(); 063 } 064 065 @Override 066 public org.apache.commons.cli.Options getOptions() 067 { 068 final org.apache.commons.cli.Options options = super.getOptions(); 069 options.addOption( Options.TEMPLATE_PROFILE_OPTION ); 070 options.addOption( Options.DEFAULT_TEMPLATE_PROFILE_OPTION ); 071 options.addOption( Options.DEFAULT_TEMPLATE_ENCODING_OPTION ); 072 options.addOption( Options.TEMPLATE_LOCATION_OPTION ); 073 options.addOption( Options.OUTPUT_ENCODING_OPTION ); 074 options.addOption( Options.INPUT_ENCODING_OPTION ); 075 options.addOption( Options.INDENTATION_STRING_OPTION ); 076 options.addOption( Options.LINE_SEPARATOR_OPTION ); 077 options.addOption( Options.LANGUAGE_OPTION ); 078 options.addOption( Options.COUNTRY_OPTION ); 079 options.addOption( Options.LOCALE_VARIANT_OPTION ); 080 options.addOption( Options.IMPLEMENTATION_OPTION ); 081 options.addOption( Options.MODULE_OPTION ); 082 options.addOption( Options.SPECIFICATION_OPTION ); 083 return options; 084 } 085 086 /** 087 * Creates a new object for a given class name and type. 088 * 089 * @param className The name of the class to create an object of. 090 * @param type The class of the type of object to create. 091 * @param <T> The type of the object to create. 092 * 093 * @return A new instance of the class with name {@code className}. 094 * 095 * @throws NullPointerException if {@code className} or {@code type} is {@code null}. 096 * @throws CommandExecutionException if creating a new object fails. 097 */ 098 protected <T> T createObject( final String className, final Class<T> type ) throws CommandExecutionException 099 { 100 if ( className == null ) 101 { 102 throw new NullPointerException( "className" ); 103 } 104 if ( type == null ) 105 { 106 throw new NullPointerException( "type" ); 107 } 108 109 try 110 { 111 return Class.forName( className ).asSubclass( type ).newInstance(); 112 } 113 catch ( final InstantiationException e ) 114 { 115 throw new CommandExecutionException( Messages.getMessage( "objectCreationFailure", className ), e ); 116 } 117 catch ( final IllegalAccessException e ) 118 { 119 throw new CommandExecutionException( Messages.getMessage( "objectCreationFailure", className ), e ); 120 } 121 catch ( final ClassNotFoundException e ) 122 { 123 throw new CommandExecutionException( Messages.getMessage( "objectCreationFailure", className ), e ); 124 } 125 catch ( final ClassCastException e ) 126 { 127 throw new CommandExecutionException( Messages.getMessage( "objectCreationFailure", className ), e ); 128 } 129 } 130 131 /** 132 * Creates a new {@code JomcTool} object for a given class name and type. 133 * 134 * @param commandLine The {@code CommandLine} to configure the new {@code JomcTool} object with. 135 * @param className The name of the class to create an object of. 136 * @param type The class of the type of object to create. 137 * @param <T> The type of the object to create. 138 * 139 * @return A new instance of the class with name {@code className} configured using {@code commandLine}. 140 * 141 * @throws NullPointerException if {@code commandLine}, {@code className} or {@code type} is {@code null}. 142 * @throws CommandExecutionException if creating a new object fails. 143 * 144 * @see #createObject(java.lang.String, java.lang.Class) 145 */ 146 protected <T extends JomcTool> T createJomcTool( final String className, final Class<T> type, 147 final CommandLine commandLine ) throws CommandExecutionException 148 { 149 if ( commandLine == null ) 150 { 151 throw new NullPointerException( "commandLine" ); 152 } 153 if ( className == null ) 154 { 155 throw new NullPointerException( "className" ); 156 } 157 if ( type == null ) 158 { 159 throw new NullPointerException( "type" ); 160 } 161 162 final T tool = this.createObject( className, type ); 163 tool.setLogLevel( this.getLogLevel() ); 164 tool.setExecutorService( this.getExecutorService( commandLine ) ); 165 tool.setLocale( this.getLocale( commandLine ) ); 166 tool.getListeners().add( new JomcTool.Listener() 167 { 168 169 @Override 170 public void onLog( final Level level, final String message, final Throwable throwable ) 171 { 172 super.onLog( level, message, throwable ); 173 log( level, message, throwable ); 174 } 175 176 } ); 177 178 if ( commandLine.hasOption( Options.TEMPLATE_ENCODING_OPTION.getOpt() ) ) 179 { 180 this.log( Level.WARNING, Messages.getMessage( "deprecatedOptionMessage", 181 Options.TEMPLATE_ENCODING_OPTION.getLongOpt(), 182 Options.DEFAULT_TEMPLATE_ENCODING_OPTION.getLongOpt() ), 183 null ); 184 185 tool.setDefaultTemplateEncoding( commandLine.getOptionValue( Options.TEMPLATE_ENCODING_OPTION.getOpt() ) ); 186 } 187 else if ( commandLine.hasOption( Options.DEFAULT_TEMPLATE_ENCODING_OPTION.getOpt() ) ) 188 { 189 tool.setDefaultTemplateEncoding( 190 commandLine.getOptionValue( Options.DEFAULT_TEMPLATE_ENCODING_OPTION.getOpt() ) ); 191 192 } 193 if ( commandLine.hasOption( Options.DEFAULT_TEMPLATE_PROFILE_OPTION.getOpt() ) ) 194 { 195 tool.setDefaultTemplateProfile( 196 commandLine.getOptionValue( Options.DEFAULT_TEMPLATE_PROFILE_OPTION.getOpt() ) ); 197 198 } 199 if ( commandLine.hasOption( Options.TEMPLATE_PROFILE_OPTION.getOpt() ) ) 200 { 201 tool.setTemplateProfile( commandLine.getOptionValue( Options.TEMPLATE_PROFILE_OPTION.getOpt() ) ); 202 } 203 if ( commandLine.hasOption( Options.TEMPLATE_LOCATION_OPTION.getOpt() ) ) 204 { 205 try 206 { 207 tool.setTemplateLocation( new URL( 208 commandLine.getOptionValue( Options.TEMPLATE_LOCATION_OPTION.getOpt() ) ) ); 209 210 } 211 catch ( final MalformedURLException e ) 212 { 213 this.log( Level.FINER, null, e ); 214 215 try 216 { 217 tool.setTemplateLocation( new File( 218 commandLine.getOptionValue( Options.TEMPLATE_LOCATION_OPTION.getOpt() ) ).toURI().toURL() ); 219 220 } 221 catch ( final MalformedURLException e2 ) 222 { 223 throw new CommandExecutionException( Messages.getMessage( e2 ), e2 ); 224 } 225 } 226 } 227 if ( commandLine.hasOption( Options.INPUT_ENCODING_OPTION.getOpt() ) ) 228 { 229 tool.setInputEncoding( commandLine.getOptionValue( Options.INPUT_ENCODING_OPTION.getOpt() ) ); 230 } 231 if ( commandLine.hasOption( Options.OUTPUT_ENCODING_OPTION.getOpt() ) ) 232 { 233 tool.setOutputEncoding( commandLine.getOptionValue( Options.OUTPUT_ENCODING_OPTION.getOpt() ) ); 234 } 235 if ( commandLine.hasOption( Options.INDENTATION_STRING_OPTION.getOpt() ) ) 236 { 237 tool.setIndentation( StringEscapeUtils.unescapeJava( 238 commandLine.getOptionValue( Options.INDENTATION_STRING_OPTION.getOpt() ) ) ); 239 240 } 241 if ( commandLine.hasOption( Options.LINE_SEPARATOR_OPTION.getOpt() ) ) 242 { 243 tool.setLineSeparator( StringEscapeUtils.unescapeJava( 244 commandLine.getOptionValue( Options.LINE_SEPARATOR_OPTION.getOpt() ) ) ); 245 246 } 247 248 return tool; 249 } 250 251 /** 252 * Gets the specification to process from a given model. 253 * 254 * @param commandLine The command line specifying the specification to process. 255 * @param model The model to get the specification to process from. 256 * 257 * @return The specification to process or {@code null}. 258 * 259 * @throws NullPointerException if {@code commandLine} or {@code model} is {@code null}. 260 */ 261 protected final Specification getSpecification( final CommandLine commandLine, final Model model ) 262 { 263 if ( commandLine == null ) 264 { 265 throw new NullPointerException( "commandLine" ); 266 } 267 if ( model == null ) 268 { 269 throw new NullPointerException( "model" ); 270 } 271 272 Specification s = null; 273 274 if ( commandLine.hasOption( Options.SPECIFICATION_OPTION.getOpt() ) ) 275 { 276 final String identifier = commandLine.getOptionValue( Options.SPECIFICATION_OPTION.getOpt() ); 277 final Modules modules = ModelHelper.getModules( model ); 278 279 if ( modules != null ) 280 { 281 s = modules.getSpecification( identifier ); 282 } 283 284 if ( s == null ) 285 { 286 this.log( Level.WARNING, Messages.getMessage( "specificationNotFoundWarning", identifier ), null ); 287 } 288 } 289 290 return s; 291 } 292 293 /** 294 * Gets the implementation to process from a given model. 295 * 296 * @param commandLine The command line specifying the implementation to process. 297 * @param model The model to get the implementation to process from. 298 * 299 * @return The implementation to process or {@code null}. 300 * 301 * @throws NullPointerException if {@code commandLine} or {@code model} is {@code null}. 302 */ 303 protected final Implementation getImplementation( final CommandLine commandLine, final Model model ) 304 { 305 if ( commandLine == null ) 306 { 307 throw new NullPointerException( "commandLine" ); 308 } 309 if ( model == null ) 310 { 311 throw new NullPointerException( "model" ); 312 } 313 314 Implementation i = null; 315 316 if ( commandLine.hasOption( Options.IMPLEMENTATION_OPTION.getOpt() ) ) 317 { 318 final String identifier = commandLine.getOptionValue( Options.IMPLEMENTATION_OPTION.getOpt() ); 319 final Modules modules = ModelHelper.getModules( model ); 320 321 if ( modules != null ) 322 { 323 i = modules.getImplementation( identifier ); 324 } 325 326 if ( i == null ) 327 { 328 this.log( Level.WARNING, Messages.getMessage( "implementationNotFoundWarning", identifier ), null ); 329 } 330 } 331 332 return i; 333 } 334 335 /** 336 * Gets the module to process from a given model. 337 * 338 * @param commandLine The command line specifying the implementation to process. 339 * @param model The model to get the module to process from. 340 * 341 * @return The module to process or {@code null}. 342 * 343 * @throws NullPointerException if {@code model} is {@code null}. 344 */ 345 protected final Module getModule( final CommandLine commandLine, final Model model ) 346 { 347 if ( commandLine == null ) 348 { 349 throw new NullPointerException( "commandLine" ); 350 } 351 if ( model == null ) 352 { 353 throw new NullPointerException( "model" ); 354 } 355 356 Module m = null; 357 358 if ( commandLine.hasOption( Options.MODULE_OPTION.getOpt() ) ) 359 { 360 final String name = commandLine.getOptionValue( Options.MODULE_OPTION.getOpt() ); 361 final Modules modules = ModelHelper.getModules( model ); 362 363 if ( modules != null ) 364 { 365 m = modules.getModule( name ); 366 } 367 368 if ( m == null ) 369 { 370 this.log( Level.WARNING, Messages.getMessage( "moduleNotFoundWarning", name ), null ); 371 } 372 } 373 374 return m; 375 } 376 377 /** 378 * Gets a flag indicating that all modules are requested to be processed. 379 * 380 * @param commandLine The command line to process. 381 * 382 * @return {@code true}, if processing of all modules is requested; {@code false}, else. 383 * 384 * @throws NullPointerException if {@code commandLine} is {@code null}. 385 * 386 * @see #getSpecification(org.apache.commons.cli.CommandLine, org.jomc.modlet.Model) 387 * @see #getImplementation(org.apache.commons.cli.CommandLine, org.jomc.modlet.Model) 388 * @see #getModule(org.apache.commons.cli.CommandLine, org.jomc.modlet.Model) 389 */ 390 protected final boolean isModulesProcessingRequested( final CommandLine commandLine ) 391 { 392 if ( commandLine == null ) 393 { 394 throw new NullPointerException( "commandLine" ); 395 } 396 397 return !( commandLine.hasOption( Options.SPECIFICATION_OPTION.getOpt() ) 398 || commandLine.hasOption( Options.IMPLEMENTATION_OPTION.getOpt() ) 399 || commandLine.hasOption( Options.MODULE_OPTION.getOpt() ) ); 400 401 } 402 403 /** 404 * Gets a locale from a command line. 405 * 406 * @param commandLine The command line to get a locale from. 407 * 408 * @return The locale from {@code commandLine} or {@code null}, if {@code commandLine} does not hold options 409 * specifying a locale. 410 */ 411 protected final Locale getLocale( final CommandLine commandLine ) 412 { 413 if ( commandLine == null ) 414 { 415 throw new NullPointerException( "commandLine" ); 416 } 417 418 Locale locale = null; 419 420 final String lc = commandLine.hasOption( Options.LANGUAGE_OPTION.getOpt() ) 421 ? commandLine.getOptionValue( Options.LANGUAGE_OPTION.getOpt() ) 422 : null; 423 424 final String cc = commandLine.hasOption( Options.COUNTRY_OPTION.getOpt() ) 425 ? commandLine.getOptionValue( Options.COUNTRY_OPTION.getOpt() ) 426 : null; 427 428 final String lv = commandLine.hasOption( Options.LOCALE_VARIANT_OPTION.getOpt() ) 429 ? commandLine.getOptionValue( Options.LOCALE_VARIANT_OPTION.getOpt() ) 430 : null; 431 432 if ( lc != null || cc != null || lv != null ) 433 { 434 locale = new Locale( StringUtils.defaultString( lc ), 435 StringUtils.defaultString( cc ), 436 StringUtils.defaultString( lv ) ); 437 438 } 439 440 return locale; 441 } 442 443}