View Javadoc

1   package org.appfuse.mojo;
2   
3   /*
4    * Copyright 2005 Johann Reyes.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import org.apache.maven.plugin.AbstractMojo;
20  import org.apache.maven.plugin.MojoExecutionException;
21  import org.apache.maven.plugin.MojoFailureException;
22  import org.apache.maven.project.MavenProject;
23  import org.appfuse.mojo.exporter.Component;
24  import org.codehaus.mojo.hibernate3.ExporterMojo;
25  import org.codehaus.mojo.hibernate3.HibernateUtils;
26  import org.codehaus.mojo.hibernate3.configuration.ComponentConfiguration;
27  import org.hibernate.tool.hbm2x.Exporter;
28  
29  import java.io.File;
30  import java.net.URL;
31  import java.net.URLClassLoader;
32  import java.util.ArrayList;
33  import java.util.HashMap;
34  import java.util.Iterator;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.Properties;
38  
39  /**
40   * Base class for the different appfuse goals based on the Ant tasks of hibernate tools.
41   *
42   * @author <a href="mailto:jreyes@hiberforum.org">Johann Reyes</a>
43   * @version $Id: HibernateExporterMojo.java 3535 2007-03-07 21:02:07Z jreyes $
44   * @requiresDependencyResolution test
45   */
46  public abstract class HibernateExporterMojo extends AbstractMojo implements ExporterMojo {
47      /**
48       * Parameter that holds components definitions specified by the user.
49       *
50       * @parameter
51       * @noinspection MismatchedQueryAndUpdateOfCollection
52       */
53      private List<Component> components = new ArrayList<Component>();
54  
55      /**
56       * Map holding the default component values for this goal.
57       */
58      private Map<String, Component> defaultComponents = new HashMap<String, Component>();
59  
60      /**
61       * Parameter that holds component properties defined by the user.
62       *
63       * @parameter
64       * @noinspection MismatchedQueryAndUpdateOfCollection
65       */
66      private Map<String, String> componentProperties = new HashMap<String, String>();
67  
68      /**
69       * @component role="org.codehaus.mojo.hibernate3.configuration.ComponentConfiguration"
70       * @noinspection MismatchedQueryAndUpdateOfCollection
71       */
72      private List<ComponentConfiguration> componentConfigurations = new ArrayList<ComponentConfiguration>();
73  
74      /**
75       * <i>Maven Internal</i>: Project to interact with.
76       *
77       * @parameter expression="${project}"
78       * @required
79       * @readonly
80       * @noinspection UnusedDeclaration
81       */
82      private MavenProject project;
83  
84      /**
85       * @parameter expression="${appfuse.fullSource}" default-value="false"
86       * @noinspection UnusedDeclaration
87       */
88      private boolean fullSource;
89  
90      public boolean isFullSource() {
91          return fullSource;
92      }
93  
94      // --------------------- Interface ExporterMojo ---------------------
95  
96      /**
97       * @see ExporterMojo#getComponentProperty(String)
98       */
99      public String getComponentProperty(String key) {
100         return getComponentProperty(key, null);
101     }
102 
103     /**
104      * @see ExporterMojo#getComponentProperty(String,boolean)
105      */
106     public boolean getComponentProperty(String key, boolean defaultValue) {
107         String s = getComponentProperty(key);
108         if (s == null) {
109             return defaultValue;
110         } else {
111             //noinspection UnnecessaryUnboxing
112             return Boolean.valueOf(s).booleanValue();
113         }
114     }
115 
116     /**
117      * @see ExporterMojo#getProject()
118      */
119     public MavenProject getProject() {
120         return project;
121     }
122 
123 // --------------------- Interface Mojo ---------------------
124 
125     /**
126      * @see org.apache.maven.plugin.Mojo#execute()
127      */
128     public void execute() throws MojoExecutionException, MojoFailureException {
129 
130         Thread currentThread = Thread.currentThread();
131         ClassLoader oldClassLoader = currentThread.getContextClassLoader();
132 
133         try {
134             currentThread.setContextClassLoader(getClassLoader());
135             if (getComponentProperty("skip", false)) {
136                 getLog().info("skipping plugin execution");
137             } else {
138                 doExecute();
139             }
140         }
141         finally {
142             currentThread.setContextClassLoader(oldClassLoader);
143         }
144     }
145 
146     /**
147      * Adds a default goal.
148      *
149      * @param outputDirectory Default output directory
150      * @param implementation  Default configuration implementation
151      * @param jdk5            Is this goal being setup for jdk15?
152      * @noinspection unchecked
153      */
154     public void addDefaultComponent(String outputDirectory, String implementation, boolean jdk5) {
155         Component component = new Component();
156         component.setName(getName());
157         component.setOutputDirectory(outputDirectory);
158         component.setImplementation(implementation);
159         defaultComponents.put((jdk5) ? "jdk15" : "jdk14", component);
160     }
161 
162     /**
163      * Configures the Exporter.
164      *
165      * @param exporter Exporter to configure
166      * @return Exporter
167      * @throws MojoExecutionException if there is an error configuring the exporter
168      * @noinspection unchecked
169      */
170     protected Exporter configureExporter(Exporter exporter) throws MojoExecutionException {
171         String implementation = getComponentProperty("implementation", getComponent().getImplementation());
172 
173         ComponentConfiguration componentConfiguration = getComponentConfiguration(implementation);
174         getLog().debug("using " + componentConfiguration.getName() + " task.");
175 
176         Properties properties = new Properties();
177         properties.putAll(componentProperties);
178 
179         exporter.setProperties(properties);
180         exporter.setConfiguration(componentConfiguration.getConfiguration(this));
181         exporter.setOutputDirectory(new File(getComponent().getOutputDirectory()));
182 
183         return exporter;
184     }
185 
186     /**
187      * @see ExporterMojo#getComponentProperty(String,String)
188      */
189     public String getComponentProperty(String key, String defaultValue) {
190         String value = componentProperties.get(key);
191         if (value == null || "".equals(value.trim())) {
192             return defaultValue;
193         }
194         return value;
195     }
196 
197     /**
198      * Returns the ComponentConfiguration for this maven goal.
199      *
200      * @param name Configuration task name
201      * @return ComponentConfiguration
202      * @throws MojoExecutionException if there is an error finding the ConfigurationTask
203      * @noinspection ForLoopReplaceableByForEach
204      */
205     protected ComponentConfiguration getComponentConfiguration(String name) throws MojoExecutionException {
206         for (Iterator<ComponentConfiguration> it = componentConfigurations.iterator(); it.hasNext();) {
207             ComponentConfiguration componentConfiguration = it.next();
208             if (componentConfiguration.getName().equals(name)) {
209                 return componentConfiguration;
210             }
211         }
212         throw new MojoExecutionException("Could not get ConfigurationTask.");
213     }
214 
215     /**
216      * Gets the hibernate tool exporter based on the goal that is being called.
217      *
218      * @return Goal exporter
219      */
220     protected abstract Exporter createExporter();
221 
222     /**
223      * Executes the plugin in an isolated classloader.
224      *
225      * @throws MojoExecutionException When there is an erro executing the plugin
226      */
227     protected void doExecute() throws MojoExecutionException {
228         configureExporter(createExporter()).start();
229     }
230 
231     /**
232      * Returns the an isolated classloader.
233      *
234      * @return ClassLoader
235      * @noinspection unchecked
236      */
237     private ClassLoader getClassLoader() {
238         try {
239             List classpathElements = project.getCompileClasspathElements();
240             classpathElements.add(project.getBuild().getOutputDirectory());
241             classpathElements.add(project.getBuild().getTestOutputDirectory());
242             URL urls[] = new URL[classpathElements.size()];
243             for (int i = 0; i < classpathElements.size(); ++i) {
244                 urls[i] = new File((String) classpathElements.get(i)).toURL();
245             }
246             return new URLClassLoader(urls, this.getClass().getClassLoader());
247         }
248         catch (Exception e) {
249             getLog().debug("Couldn't get the classloader.");
250             return this.getClass().getClassLoader();
251         }
252     }
253 
254     /**
255      * Returns the parsed goal to the exporter.
256      *
257      * @return Component
258      * @noinspection ForLoopReplaceableByForEach
259      */
260     protected Component getComponent() {
261         Component defaultGoal = defaultComponents.get(HibernateUtils.getJavaVersion());
262         if (!components.isEmpty()) {
263             for (Iterator<Component> it = components.iterator(); it.hasNext();) {
264                 Component component = it.next();
265                 if (getName().equals(component.getName())) {
266                     if (component.getImplementation() == null) {
267                         component.setImplementation(defaultGoal.getImplementation());
268                     }
269                     if (component.getOutputDirectory() == null) {
270                         component.setOutputDirectory(defaultGoal.getOutputDirectory());
271                     }
272                     return component;
273                 }
274             }
275         }
276         return defaultGoal;
277     }
278 
279     public Map<String, String> getComponentProperties() {
280         return componentProperties;
281     }
282 
283     // Allow setting project from tests (AbstractAppFuseMojoTestCase)
284     void setProject(MavenProject project) {
285         this.project = project;
286     }
287 }