This project has retired. For details please refer to its Attic page.
AbstractGenerateMojo xref
View Javadoc

1   /*
2    * $Id: AbstractGenerateMojo.java 1656976 2015-02-04 02:27:40Z nlebas $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.tiles.autotag.plugin;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.OutputStream;
27  import java.net.URL;
28  import java.net.URLClassLoader;
29  import java.net.URLConnection;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Properties;
33  
34  import org.apache.maven.model.Resource;
35  import org.apache.maven.plugin.AbstractMojo;
36  import org.apache.maven.plugin.MojoExecutionException;
37  import org.apache.maven.plugins.annotations.Component;
38  import org.apache.maven.plugins.annotations.Parameter;
39  import org.apache.maven.project.MavenProject;
40  import org.apache.tiles.autotag.core.OutputLocator;
41  import org.apache.tiles.autotag.generate.TemplateGenerator;
42  import org.apache.tiles.autotag.generate.TemplateGeneratorFactory;
43  import org.apache.tiles.autotag.model.TemplateSuite;
44  import org.apache.velocity.app.VelocityEngine;
45  import org.sonatype.plexus.build.incremental.BuildContext;
46  
47  import com.thoughtworks.xstream.XStream;
48  import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider;
49  
50  /**
51   * Abstract class to generate boilerplate code starting from template model classes.
52   *
53   * @version $Rev: 1656976 $ $Date: 2015-02-04 03:27:40 +0100 (Wed, 04 Feb 2015) $
54   */
55  public abstract class AbstractGenerateMojo extends AbstractMojo {
56  	/**
57       * The position of the template suite XML descriptor.
58       */
59      static final String META_INF_TEMPLATE_SUITE_XML = "META-INF/template-suite.xml";
60  
61      /**
62       * The classpath elements.
63       */
64      @Parameter(property = "project.compileClasspathElements", required = true, readonly = true)
65      List<String> classpathElements;
66  
67      /**
68       * Location of the generated classes.
69       */
70  	@Parameter(defaultValue = "${project.build.directory}/autotag-classes", required = true)
71  	File classesOutputDirectory;
72  
73      /**
74       * Location of the generated resources.
75       */
76  	@Parameter(defaultValue = "${project.build.directory}/autotag-resources", required = true)
77      File resourcesOutputDirectory;
78  
79      /**
80       * Name of the request class.
81       */
82  	@Parameter(defaultValue = "org.apache.tiles.request.Request", required = true)
83      String requestClass;
84  
85      /**
86       * Name of the package.
87       */
88  	@Parameter(required = true)
89      String packageName;
90  
91  	@Component
92      MavenProject project;
93  
94  	@Component
95      BuildContext buildContext;
96      
97  	OutputLocator classesOutputLocator;
98  	OutputLocator resourcesOutputLocator;
99  	
100     /** {@inheritDoc} */
101     public void execute() throws MojoExecutionException {
102         try {
103         	TemplateSuite suite;
104         	URLConnection templateSuite = findTemplateSuiteDescriptor();
105         	long lastModified = templateSuite.getLastModified();
106         	InputStream stream = templateSuite.getInputStream();
107             try {
108 	            XStream xstream = new XStream(new Sun14ReflectionProvider());
109 	            suite = (TemplateSuite) xstream.fromXML(stream);
110             } finally {
111 	            stream.close();
112             }
113             classesOutputLocator = new MavenOutputLocator(classesOutputDirectory, lastModified);
114             resourcesOutputLocator = new MavenOutputLocator(resourcesOutputDirectory, lastModified);
115             Properties props = new Properties();
116             InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
117             props.load(propsStream);
118             propsStream.close();
119             TemplateGenerator generator = createTemplateGeneratorFactory(
120                     new VelocityEngine(props)).createTemplateGenerator();
121             generator.generate(packageName, suite, getParameters(), getRuntimeClass(), requestClass);
122             if (generator.isGeneratingResources()) {
123             	buildContext.refresh(resourcesOutputDirectory);
124                 addResourceDirectory(resourcesOutputDirectory.getAbsolutePath());
125             }
126             if (generator.isGeneratingClasses()) {
127             	buildContext.refresh(classesOutputDirectory);
128                 addCompileSourceRoot(classesOutputDirectory.getAbsolutePath());
129             }
130         } catch (IOException e) {
131             throw new MojoExecutionException("error", e);
132         } catch (RuntimeException e) {
133             throw e;
134         } catch (Exception e) {
135             throw new MojoExecutionException("error", e);
136         }
137     }
138 
139 	private void addResourceDirectory(String directory) {
140 		boolean addResource = true;
141 		@SuppressWarnings("unchecked")
142 		List<Resource> resources = project.getResources();
143 		for(Resource resource: resources) {
144 			if(directory.equals(resource.getDirectory())) {
145 				addResource = false;
146 			}
147 		}
148 		if(addResource) {
149 		    Resource resource = new Resource();
150 		    resource.setDirectory(directory);
151 		    project.addResource(resource);
152 		}
153 	}
154 
155 	private void addCompileSourceRoot(String directory) {
156 		boolean addResource = true;
157 		@SuppressWarnings("unchecked")
158 		List<String> roots = project.getCompileSourceRoots();
159 		for(String root: roots) {
160 			if(directory.equals(root)) {
161 				addResource = false;
162 			}
163 		}
164 		if(addResource) {
165 		    project.addCompileSourceRoot(directory);
166 		}
167 	}
168 
169 
170 	/**
171      * Creates a template generator factory.
172      *
173      * @param velocityEngine The Velocity engine.
174      * @return The template generator factory.
175      */
176     protected abstract TemplateGeneratorFactory createTemplateGeneratorFactory(VelocityEngine velocityEngine);
177 
178     /**
179      * Returns the map of parameters.
180      *
181      * @return The parameters.
182      */
183     protected abstract Map<String, String> getParameters();
184 
185     /**
186      * Searches for the template suite descriptor in all dependencies and sources.
187      *
188      * @return The inputstream of the identified descriptor.
189      * @throws IOException If something goes wrong.
190      */
191     private URLConnection findTemplateSuiteDescriptor() throws IOException {
192         URL[] urls = new URL[classpathElements.size()];
193         int i = 0;
194         for ( String classpathElement: classpathElements )
195         {
196             urls[i++] = new File(classpathElement).toURI().toURL();
197         }
198 
199         ClassLoader cl = new URLClassLoader( urls );
200         return cl.getResource(META_INF_TEMPLATE_SUITE_XML).openConnection();
201     }
202 
203     /**
204      * Name of the Runtime class.
205      * @return The name of the Runtime class.
206      */
207     protected abstract String getRuntimeClass();
208 
209     private final class MavenOutputLocator implements OutputLocator {
210     	
211     	private File outputDirectory;
212     	private long sourceLastModified;
213     	
214     	private MavenOutputLocator(File outputDirectory, long sourceLastModified) {
215     		this.outputDirectory = outputDirectory;
216     		this.sourceLastModified = sourceLastModified;
217     	}
218     	
219 		@Override
220 		public OutputStream getOutputStream(String resourcePath)
221 				throws IOException {
222 			File target = new File(outputDirectory, resourcePath);
223 			target.getParentFile().mkdirs();
224 			return buildContext.newFileOutputStream(target);
225 		}
226 
227 		@Override
228 		public boolean isUptodate(String resourcePath) {
229 			File target = new File(outputDirectory, resourcePath);
230 			return target.exists() && target.lastModified() > sourceLastModified;
231 		}
232 	}
233 }