001: package org.andromda.maven;
002:
003: import java.io.FileNotFoundException;
004:
005: import java.net.MalformedURLException;
006: import java.net.URL;
007:
008: import java.util.ArrayList;
009: import java.util.Collection;
010:
011: import org.andromda.core.AndroMDA;
012: import org.andromda.core.AndroMDAServer;
013: import org.andromda.core.common.ResourceUtils;
014: import org.andromda.core.configuration.Configuration;
015: import org.apache.commons.collections.CollectionUtils;
016: import org.apache.commons.jelly.JellyContext;
017: import org.apache.commons.jelly.expression.Expression;
018: import org.apache.commons.lang.StringUtils;
019: import org.apache.commons.lang.exception.ExceptionUtils;
020: import org.apache.maven.jelly.MavenJellyContext;
021:
022: /**
023: * This bean is used with the AndroMDA Maven plugin.
024: *
025: * @author Chad Brandon
026: * @see org.andromda.core.engine.ModelProcessor
027: */
028: public class AndroMDARunner {
029: /**
030: * The URI to the configuration;
031: */
032: private String configurationUri;
033:
034: /**
035: * Sets the URI to the configuration file.
036: *
037: * @param configurationUri
038: */
039: public void setConfigurationUri(final String configurationUri) {
040: this .configurationUri = configurationUri;
041: }
042:
043: /**
044: * Stores the search location for mapping files.
045: */
046: private String mappingsSearchLocation;
047:
048: /**
049: * Sets the mappings search location.
050: *
051: * @param MappingsSearchLocation
052: */
053: public void setMappingsSearchLocation(
054: final String mappingsSearchLocation) {
055: this .mappingsSearchLocation = mappingsSearchLocation;
056: }
057:
058: /**
059: * Runs AndroMDA.
060: */
061: public String run() {
062: // - since maven doesn't fail on exceptions on this method (for some reason)
063: // we'll save the error message and if present call ant fail from within
064: // the plugin jelly.
065: String message = null;
066: Thread.currentThread().setContextClassLoader(
067: AndroMDARunner.class.getClassLoader());
068: try {
069: final AndroMDA andromda = AndroMDA.newInstance();
070: andromda.run(this .getConfiguration());
071: andromda.shutdown();
072: } catch (Throwable throwable) {
073: final Throwable cause = ExceptionUtils.getCause(throwable);
074: if (cause != null) {
075: throwable = cause;
076: }
077: if (throwable instanceof FileNotFoundException) {
078: message = "No configuration could be loaded from --> '"
079: + configurationUri + "'";
080: } else if (throwable instanceof MalformedURLException) {
081: message = "Configuration is not a valid URI --> '"
082: + configurationUri + "'";
083: }
084: throwable.printStackTrace();
085: message = throwable.toString();
086: } finally {
087: // Set the context class loader back ot its system class loaders
088: // so that any processes running after won't be trying to use
089: // the ContextClassLoader for this class.
090: Thread.currentThread().setContextClassLoader(
091: ClassLoader.getSystemClassLoader());
092: }
093: return message;
094: }
095:
096: /**
097: * Creates the Configuration instance from the {@link #configurationUri}
098: * @return the configuration instance
099: * @throws MalformedURLException if the URL is invalid.
100: */
101: private Configuration getConfiguration()
102: throws MalformedURLException {
103: final URL uri = ResourceUtils.toURL(this .configurationUri);
104: ;
105: final Configuration configuration = Configuration
106: .getInstance(this .replaceProperties(ResourceUtils
107: .getContents(uri)));
108: configuration
109: .addMappingsSearchLocation(this .mappingsSearchLocation);
110: return configuration;
111: }
112:
113: /**
114: * The server instance.
115: */
116: private AndroMDAServer server = AndroMDAServer.newInstance();
117:
118: /**
119: * Starts the AndroMDA server instance listening
120: * for requests.
121: *
122: * @throws MalformedURLException
123: */
124: public void startServer() throws MalformedURLException {
125: this .server.start(this .getConfiguration());
126: }
127:
128: /**
129: * Stops the AndroMDA server instance.
130: */
131: public void stopServer() throws MalformedURLException {
132: this .server.stop(this .getConfiguration());
133: }
134:
135: /**
136: * The maven jelly context.
137: */
138: private MavenJellyContext context;
139:
140: /**
141: * Sets the maven jelly context for this instance.
142: */
143: public void setContext(MavenJellyContext context) {
144: this .context = context;
145: }
146:
147: /**
148: * Gets all property names.
149: *
150: * @return the property names.
151: */
152: public String[] getPropertyNames() {
153: final Collection properties = new ArrayList();
154: for (JellyContext context = this .context; context != null; context = context
155: .getParent()) {
156: CollectionUtils.addAll(properties, context
157: .getVariableNames());
158: }
159: return (String[]) properties.toArray(new String[0]);
160: }
161:
162: /**
163: * Replaces all properties having the style
164: * <code>${some.property}</code> with the value
165: * of the specified property if there is one.
166: *
167: * @param fileContents the fileContents to perform replacement on.
168: */
169: protected String replaceProperties(String string) {
170: final String[] names = this .getPropertyNames();
171: if (names != null && names.length > 0) {
172: for (int ctr = 0; ctr < names.length; ctr++) {
173: String value = null;
174: final String name = names[ctr];
175: final String property = "${" + name + "}";
176: Object object = this .context.getVariable(name);
177: if (object instanceof String) {
178: value = (String) object;
179: } else if (object instanceof Expression) {
180: value = ((Expression) object).getExpressionText();
181: }
182: if (value != null) {
183: string = StringUtils.replace(string, property,
184: value);
185: }
186: }
187: }
188:
189: // remove any left over property references
190: string = AndroMDAMavenUtils.removePropertyReferences(string);
191: return string;
192: }
193: }
|