001package org.andromda.core; 002 003import java.io.EOFException; 004import java.io.InputStream; 005import java.net.ConnectException; 006import java.net.URL; 007import org.andromda.core.common.AndroMDALogger; 008import org.andromda.core.common.ComponentContainer; 009import org.andromda.core.common.ExceptionUtils; 010import org.andromda.core.configuration.Configuration; 011import org.andromda.core.engine.Engine; 012import org.andromda.core.metafacade.ModelValidationMessage; 013import org.andromda.core.server.Client; 014import org.apache.log4j.Logger; 015 016/** 017 * The main entry point to the framework. Handles the processing of models. 018 * Facilitates Model Driven Architecture by enabling the generation of source 019 * code, configuration files, and other such artifacts from a single or multiple 020 * models. 021 * 022 * @see Engine 023 * @author Chad Brandon 024 */ 025public final class AndroMDA 026{ 027 /** 028 * The logger instance. 029 */ 030 private static final Logger LOGGER = Logger.getLogger(AndroMDA.class); 031 032 /** 033 * The AndroMDA engine instance. 034 */ 035 private Engine engine; 036 037 /** 038 * Gets a new instance of AndroMDA. 039 * 040 * @return the new instance of AndroMDA. 041 */ 042 public static AndroMDA newInstance() 043 { 044 return new AndroMDA(); 045 } 046 047 /** 048 * Hidden constructor. 049 */ 050 private AndroMDA() 051 { 052 AndroMDALogger.initialize(); 053 this.engine = Engine.newInstance(); 054 } 055 056 /** 057 * Runs AndroMDA with the given configuration. 058 * 059 * @param configurationUri the URI to the configuration file that configures 060 * AndroMDA. 061 */ 062 public void run(final URL configurationUri) 063 { 064 ExceptionUtils.checkNull( 065 "configurationUri", 066 configurationUri); 067 this.run(Configuration.getInstance(configurationUri), false, null); 068 } 069 070 /** 071 * Runs AndroMDA with the given configuration. 072 * 073 * @param configurationStream the InputStream that contains the 074 * configuration contents for configuring AndroMDA. 075 */ 076 public void run(final InputStream configurationStream) 077 { 078 ExceptionUtils.checkNull( 079 "configurationStream", 080 configurationStream); 081 this.run(Configuration.getInstance(configurationStream), false, null); 082 } 083 084 /** 085 * Runs AndroMDA with the given configuration. 086 * 087 * @param configuration the String that contains the configuration contents 088 * for configuring AndroMDA. 089 */ 090 public void run(final String configuration) 091 { 092 ExceptionUtils.checkEmpty( 093 "configuration", 094 configuration); 095 this.run(Configuration.getInstance(configuration), false, null); 096 } 097 098 /** 099 * Initializes AndroMDA without running the engine. 100 * 101 * @param configuration the configuration from which to initialize AndroMDA 102 */ 103 public void initialize(final Configuration configuration) 104 { 105 ExceptionUtils.checkNull( 106 "configuration", 107 configuration); 108 this.engine.initialize(configuration); 109 } 110 111 /** 112 * Initializes AndroMDA without running the engine. 113 * 114 * @param configurationStream the InputStream that contains the 115 * configuration contents for configuring AndroMDA. 116 */ 117 public void initialize(final InputStream configurationStream) 118 { 119 ExceptionUtils.checkNull( 120 "configurationStream", 121 configurationStream); 122 this.engine.initialize(Configuration.getInstance(configurationStream)); 123 } 124 125 /** 126 * Initializes AndroMDA without running the engine. 127 * 128 * @param configuration the String that contains the configuration contents 129 * for configuring AndroMDA. 130 */ 131 public void initialize(final String configuration) 132 { 133 ExceptionUtils.checkEmpty( 134 "configuration", 135 configuration); 136 this.engine.initialize(Configuration.getInstance(configuration)); 137 } 138 139 /** 140 * Initializes AndroMDA without running the engine. 141 * 142 * @param configurationUri the URI to the configuration file that configures 143 * AndroMDA. 144 */ 145 public void initialize(final URL configurationUri) 146 { 147 ExceptionUtils.checkNull( 148 "configurationUri", 149 configurationUri); 150 this.run(Configuration.getInstance(configurationUri), false, null); 151 } 152 153 /** 154 * Runs AndroMDA with the given configuration. Determines whether or not 155 * AndroMDA should be run in client/server mode (if the client can contact 156 * the AndroMDA server), or just stand-alone mode if the server can NOT be 157 * contacted. 158 * 159 * @param configuration the configuration instance that configures AndroMDA. 160 * @param lastModifiedCheck true=don't regenerate code if no changes made since last model update. 161 * @param historyDir Output location for model generation history file (i.e. /target/history) 162 * @return an array of model validation messages (if there have been any collected 163 * during AndroMDA execution). 164 */ 165 public ModelValidationMessage[] run(final Configuration configuration, 166 boolean lastModifiedCheck, final String historyDir) 167 { 168 ModelValidationMessage[] messages = null; 169 if (configuration != null) 170 { 171 final Client serverClient = (Client)ComponentContainer.instance().findRequiredComponent(Client.class); 172 boolean client = true; 173 174 // only attempt to run with the client, if they 175 // have a server defined in their configuration 176 if (configuration.getServer() != null) 177 { 178 try 179 { 180 serverClient.start(configuration); 181 } 182 catch (final Throwable throwable) 183 { 184 final Throwable cause = ExceptionUtils.getRootCause(throwable); 185 if (cause instanceof ConnectException || 186 cause instanceof EOFException) 187 { 188 // - if we can't connect to the server, it means 189 // we aren't running in client mode 190 client = false; 191 } 192 else 193 { 194 throw new RuntimeException(throwable); 195 } 196 } 197 } 198 else 199 { 200 client = false; 201 } 202 203 // - since we aren't running in 'client' mode, run the engine as usual 204 if (!client) 205 { 206 this.engine.initialize(configuration); 207 messages = this.engine.run(configuration, lastModifiedCheck, historyDir); 208 } 209 } 210 else 211 { 212 LOGGER.warn("AndroMDA could not run because no configuration was defined"); 213 } 214 return messages == null ? new ModelValidationMessage[0] : messages; 215 } 216 217 /** 218 * Shuts down AndroMDA. 219 */ 220 public void shutdown() 221 { 222 this.engine.shutdown(); 223 } 224}