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: AbstractModelCommand.java 5253 2016-04-25 20:18:36Z schulte $ 029 * 030 */ 031package org.jomc.cli.commands; 032 033import java.io.File; 034import java.util.logging.Level; 035import javax.xml.bind.JAXBElement; 036import javax.xml.bind.JAXBException; 037import javax.xml.bind.Unmarshaller; 038import org.apache.commons.cli.CommandLine; 039import org.jomc.model.Module; 040import org.jomc.model.Modules; 041import org.jomc.model.modlet.DefaultModelProcessor; 042import org.jomc.model.modlet.DefaultModelProvider; 043import org.jomc.model.modlet.DefaultModelValidator; 044import org.jomc.model.modlet.ModelHelper; 045import org.jomc.modlet.Model; 046import org.jomc.modlet.ModelContext; 047import org.jomc.modlet.ModelException; 048import org.jomc.tools.modlet.ToolsModelProcessor; 049import org.jomc.tools.modlet.ToolsModelProvider; 050 051/** 052 * {@code Model} based command implementation. 053 * 054 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 055 */ 056public abstract class AbstractModelCommand extends AbstractModletCommand 057{ 058 059 /** 060 * Creates a new {@code AbstractModelCommand} instance. 061 */ 062 public AbstractModelCommand() 063 { 064 super(); 065 } 066 067 @Override 068 public org.apache.commons.cli.Options getOptions() 069 { 070 final org.apache.commons.cli.Options options = super.getOptions(); 071 options.addOption( Options.MODULE_LOCATION_OPTION ); 072 options.addOption( Options.TRANSFORMER_LOCATION_OPTION ); 073 options.addOption( Options.NO_CLASSPATH_RESOLUTION_OPTION ); 074 options.addOption( Options.NO_MODEL_PROCESSING_OPTION ); 075 options.addOption( Options.NO_MODEL_RESOURCE_VALIDATION_OPTION ); 076 options.addOption( Options.NO_JAVA_VALIDATION_OPTION ); 077 return options; 078 } 079 080 /** 081 * {@inheritDoc} 082 */ 083 @Override 084 protected ModelContext createModelContext( final CommandLine commandLine, final ClassLoader classLoader ) 085 throws CommandExecutionException 086 { 087 if ( commandLine == null ) 088 { 089 throw new NullPointerException( "commandLine" ); 090 } 091 092 final ModelContext modelContext = super.createModelContext( commandLine, classLoader ); 093 094 if ( commandLine.hasOption( Options.TRANSFORMER_LOCATION_OPTION.getOpt() ) ) 095 { 096 modelContext.setAttribute( DefaultModelProcessor.TRANSFORMER_LOCATION_ATTRIBUTE_NAME, 097 commandLine.getOptionValue( Options.TRANSFORMER_LOCATION_OPTION.getOpt() ) ); 098 099 } 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}