View Javadoc

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          // - since maven doesn't fail on exceptions on this method (for some reason)
67          //   we'll save the error message and if present call ant fail from within
68          //   the plugin jelly.
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              // Set the context class loader back ot its system class loaders
98              // so that any processes running after won't be trying to use
99              // the ContextClassLoader for this class.
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         // remove any left over property references
211         string = AndroMDAMavenUtils.removePropertyReferences(string);
212         return string;
213     }
214 }