1 package org.andromda.maven;
2
3 import java.io.FileNotFoundException;
4
5 import java.net.MalformedURLException;
6 import java.net.URL;
7
8 import java.util.ArrayList;
9 import java.util.Collection;
10
11 import org.andromda.core.AndroMDA;
12 import org.andromda.core.AndroMDAServer;
13 import org.andromda.core.common.ResourceUtils;
14 import org.andromda.core.configuration.Configuration;
15 import org.apache.commons.collections.CollectionUtils;
16 import org.apache.commons.jelly.JellyContext;
17 import org.apache.commons.jelly.expression.Expression;
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.commons.lang.exception.ExceptionUtils;
20 import org.apache.maven.jelly.MavenJellyContext;
21
22
23 /***
24 * This bean is used with the AndroMDA Maven plugin.
25 *
26 * @author Chad Brandon
27 * @see org.andromda.core.engine.ModelProcessor
28 */
29 public class AndroMDARunner
30 {
31 /***
32 * The URI to the configuration;
33 */
34 private String configurationUri;
35
36 /***
37 * Sets the URI to the configuration file.
38 *
39 * @param configurationUri
40 */
41 public void setConfigurationUri(final String configurationUri)
42 {
43 this.configurationUri = configurationUri;
44 }
45
46 /***
47 * Stores the search location for mapping files.
48 */
49 private String mappingsSearchLocation;
50
51 /***
52 * Sets the mappings search location.
53 *
54 * @param MappingsSearchLocation
55 */
56 public void setMappingsSearchLocation(final String mappingsSearchLocation)
57 {
58 this.mappingsSearchLocation = mappingsSearchLocation;
59 }
60
61 /***
62 * Runs AndroMDA.
63 */
64 public String run()
65 {
66
67
68
69 String message = null;
70 Thread.currentThread().setContextClassLoader(AndroMDARunner.class.getClassLoader());
71 try
72 {
73 final AndroMDA andromda = AndroMDA.newInstance();
74 andromda.run(this.getConfiguration());
75 andromda.shutdown();
76 }
77 catch (Throwable throwable)
78 {
79 final Throwable cause = ExceptionUtils.getCause(throwable);
80 if (cause != null)
81 {
82 throwable = cause;
83 }
84 if (throwable instanceof FileNotFoundException)
85 {
86 message = "No configuration could be loaded from --> '" + configurationUri + "'";
87 }
88 else if (throwable instanceof MalformedURLException)
89 {
90 message = "Configuration is not a valid URI --> '" + configurationUri + "'";
91 }
92 throwable.printStackTrace();
93 message = throwable.toString();
94 }
95 finally
96 {
97
98
99
100 Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
101 }
102 return message;
103 }
104
105 /***
106 * Creates the Configuration instance from the {@link #configurationUri}
107 * @return the configuration instance
108 * @throws MalformedURLException if the URL is invalid.
109 */
110 private Configuration getConfiguration()
111 throws MalformedURLException
112 {
113 final URL uri = ResourceUtils.toURL(this.configurationUri);;
114 final Configuration configuration =
115 Configuration.getInstance(
116 this.replaceProperties(ResourceUtils.getContents(uri)));
117 configuration.addMappingsSearchLocation(this.mappingsSearchLocation);
118 return configuration;
119 }
120
121 /***
122 * The server instance.
123 */
124 private AndroMDAServer server = AndroMDAServer.newInstance();
125
126 /***
127 * Starts the AndroMDA server instance listening
128 * for requests.
129 *
130 * @throws MalformedURLException
131 */
132 public void startServer()
133 throws MalformedURLException
134 {
135 this.server.start(this.getConfiguration());
136 }
137
138 /***
139 * Stops the AndroMDA server instance.
140 */
141 public void stopServer()
142 throws MalformedURLException
143 {
144 this.server.stop(this.getConfiguration());
145 }
146
147 /***
148 * The maven jelly context.
149 */
150 private MavenJellyContext context;
151
152 /***
153 * Sets the maven jelly context for this instance.
154 */
155 public void setContext(MavenJellyContext context)
156 {
157 this.context = context;
158 }
159
160 /***
161 * Gets all property names.
162 *
163 * @return the property names.
164 */
165 public String[] getPropertyNames()
166 {
167 final Collection properties = new ArrayList();
168 for (JellyContext context = this.context; context != null; context = context.getParent())
169 {
170 CollectionUtils.addAll(
171 properties,
172 context.getVariableNames());
173 }
174 return (String[])properties.toArray(new String[0]);
175 }
176
177 /***
178 * Replaces all properties having the style
179 * <code>${some.property}</code> with the value
180 * of the specified property if there is one.
181 *
182 * @param fileContents the fileContents to perform replacement on.
183 */
184 protected String replaceProperties(String string)
185 {
186 final String[] names = this.getPropertyNames();
187 if (names != null && names.length > 0)
188 {
189 for (int ctr = 0; ctr < names.length; ctr++)
190 {
191 String value = null;
192 final String name = names[ctr];
193 final String property = "${" + name + "}";
194 Object object = this.context.getVariable(name);
195 if (object instanceof String)
196 {
197 value = (String)object;
198 }
199 else if (object instanceof Expression)
200 {
201 value = ((Expression)object).getExpressionText();
202 }
203 if (value != null)
204 {
205 string = StringUtils.replace(string, property, value);
206 }
207 }
208 }
209
210
211 string = AndroMDAMavenUtils.removePropertyReferences(string);
212 return string;
213 }
214 }