1 package org.andromda.core;
2
3 import java.io.EOFException;
4 import java.io.InputStream;
5 import java.net.ConnectException;
6 import java.net.URL;
7 import org.andromda.core.common.AndroMDALogger;
8 import org.andromda.core.common.ComponentContainer;
9 import org.andromda.core.common.ExceptionUtils;
10 import org.andromda.core.configuration.Configuration;
11 import org.andromda.core.engine.Engine;
12 import org.andromda.core.metafacade.ModelValidationMessage;
13 import org.andromda.core.server.Client;
14 import org.apache.log4j.Logger;
15
16 /**
17 * The main entry point to the framework. Handles the processing of models.
18 * Facilitates Model Driven Architecture by enabling the generation of source
19 * code, configuration files, and other such artifacts from a single or multiple
20 * models.
21 *
22 * @see Engine
23 * @author Chad Brandon
24 */
25 public final class AndroMDA
26 {
27 /**
28 * The logger instance.
29 */
30 private static final Logger LOGGER = Logger.getLogger(AndroMDA.class);
31
32 /**
33 * The AndroMDA engine instance.
34 */
35 private Engine engine;
36
37 /**
38 * Gets a new instance of AndroMDA.
39 *
40 * @return the new instance of AndroMDA.
41 */
42 public static AndroMDA newInstance()
43 {
44 return new AndroMDA();
45 }
46
47 /**
48 * Hidden constructor.
49 */
50 private AndroMDA()
51 {
52 AndroMDALogger.initialize();
53 this.engine = Engine.newInstance();
54 }
55
56 /**
57 * Runs AndroMDA with the given configuration.
58 *
59 * @param configurationUri the URI to the configuration file that configures
60 * AndroMDA.
61 */
62 public void run(final URL configurationUri)
63 {
64 ExceptionUtils.checkNull(
65 "configurationUri",
66 configurationUri);
67 this.run(Configuration.getInstance(configurationUri), false, null);
68 }
69
70 /**
71 * Runs AndroMDA with the given configuration.
72 *
73 * @param configurationStream the InputStream that contains the
74 * configuration contents for configuring AndroMDA.
75 */
76 public void run(final InputStream configurationStream)
77 {
78 ExceptionUtils.checkNull(
79 "configurationStream",
80 configurationStream);
81 this.run(Configuration.getInstance(configurationStream), false, null);
82 }
83
84 /**
85 * Runs AndroMDA with the given configuration.
86 *
87 * @param configuration the String that contains the configuration contents
88 * for configuring AndroMDA.
89 */
90 public void run(final String configuration)
91 {
92 ExceptionUtils.checkEmpty(
93 "configuration",
94 configuration);
95 this.run(Configuration.getInstance(configuration), false, null);
96 }
97
98 /**
99 * 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 }