Coverage Report - org.apache.tiles.autotag.plugin.AbstractGenerateMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractGenerateMojo
79%
46/58
44%
8/18
2.6
AbstractGenerateMojo$1
N/A
N/A
2.6
AbstractGenerateMojo$MavenOutputLocator
50%
5/10
0%
0/4
2.6
 
 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  6
 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  1
                 URLConnection templateSuite = findTemplateSuiteDescriptor();
 105  1
                 long lastModified = templateSuite.getLastModified();
 106  1
                 InputStream stream = templateSuite.getInputStream();
 107  
             try {
 108  1
                     XStream xstream = new XStream(new Sun14ReflectionProvider());
 109  1
                     suite = (TemplateSuite) xstream.fromXML(stream);
 110  
             } finally {
 111  1
                     stream.close();
 112  1
             }
 113  1
             classesOutputLocator = new MavenOutputLocator(classesOutputDirectory, lastModified);
 114  1
             resourcesOutputLocator = new MavenOutputLocator(resourcesOutputDirectory, lastModified);
 115  1
             Properties props = new Properties();
 116  1
             InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
 117  1
             props.load(propsStream);
 118  1
             propsStream.close();
 119  1
             TemplateGenerator generator = createTemplateGeneratorFactory(
 120  
                     new VelocityEngine(props)).createTemplateGenerator();
 121  1
             generator.generate(packageName, suite, getParameters(), getRuntimeClass(), requestClass);
 122  1
             if (generator.isGeneratingResources()) {
 123  1
                     buildContext.refresh(resourcesOutputDirectory);
 124  1
                 addResourceDirectory(resourcesOutputDirectory.getAbsolutePath());
 125  
             }
 126  1
             if (generator.isGeneratingClasses()) {
 127  1
                     buildContext.refresh(classesOutputDirectory);
 128  1
                 addCompileSourceRoot(classesOutputDirectory.getAbsolutePath());
 129  
             }
 130  0
         } catch (IOException e) {
 131  0
             throw new MojoExecutionException("error", e);
 132  0
         } catch (RuntimeException e) {
 133  0
             throw e;
 134  0
         } catch (Exception e) {
 135  0
             throw new MojoExecutionException("error", e);
 136  1
         }
 137  1
     }
 138  
 
 139  
         private void addResourceDirectory(String directory) {
 140  1
                 boolean addResource = true;
 141  
                 @SuppressWarnings("unchecked")
 142  1
                 List<Resource> resources = project.getResources();
 143  1
                 for(Resource resource: resources) {
 144  0
                         if(directory.equals(resource.getDirectory())) {
 145  0
                                 addResource = false;
 146  
                         }
 147  0
                 }
 148  1
                 if(addResource) {
 149  1
                     Resource resource = new Resource();
 150  1
                     resource.setDirectory(directory);
 151  1
                     project.addResource(resource);
 152  
                 }
 153  1
         }
 154  
 
 155  
         private void addCompileSourceRoot(String directory) {
 156  1
                 boolean addResource = true;
 157  
                 @SuppressWarnings("unchecked")
 158  1
                 List<String> roots = project.getCompileSourceRoots();
 159  1
                 for(String root: roots) {
 160  0
                         if(directory.equals(root)) {
 161  0
                                 addResource = false;
 162  
                         }
 163  0
                 }
 164  1
                 if(addResource) {
 165  1
                     project.addCompileSourceRoot(directory);
 166  
                 }
 167  1
         }
 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  1
         URL[] urls = new URL[classpathElements.size()];
 193  1
         int i = 0;
 194  1
         for ( String classpathElement: classpathElements )
 195  
         {
 196  1
             urls[i++] = new File(classpathElement).toURI().toURL();
 197  1
         }
 198  
 
 199  1
         ClassLoader cl = new URLClassLoader( urls );
 200  1
         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  2
     private final class MavenOutputLocator implements OutputLocator {
 210  
             
 211  
             private File outputDirectory;
 212  
             private long sourceLastModified;
 213  
             
 214  2
             private MavenOutputLocator(File outputDirectory, long sourceLastModified) {
 215  2
                     this.outputDirectory = outputDirectory;
 216  2
                     this.sourceLastModified = sourceLastModified;
 217  2
             }
 218  
             
 219  
                 @Override
 220  
                 public OutputStream getOutputStream(String resourcePath)
 221  
                                 throws IOException {
 222  0
                         File target = new File(outputDirectory, resourcePath);
 223  0
                         target.getParentFile().mkdirs();
 224  0
                         return buildContext.newFileOutputStream(target);
 225  
                 }
 226  
 
 227  
                 @Override
 228  
                 public boolean isUptodate(String resourcePath) {
 229  0
                         File target = new File(outputDirectory, resourcePath);
 230  0
                         return target.exists() && target.lastModified() > sourceLastModified;
 231  
                 }
 232  
         }
 233  
 }