View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  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,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.creadur.whisker.out.velocity;
20  
21  import java.io.Writer;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.List;
25  
26  import org.apache.commons.io.IOUtils;
27  import org.apache.commons.logging.Log;
28  import org.apache.creadur.whisker.app.Configuration;
29  import org.apache.creadur.whisker.app.ResultWriterFactory;
30  import org.apache.creadur.whisker.app.analysis.LicenseAnalyst;
31  import org.apache.creadur.whisker.model.Descriptor;
32  import org.apache.creadur.whisker.scan.Directory;
33  import org.apache.velocity.VelocityContext;
34  import org.apache.velocity.app.VelocityEngine;
35  
36  /**
37   * Wraps velocity engine.
38   */
39  public class VelocityReports {
40      /** XML generation template. */
41      private static final Product[] PRODUCTS_THAT_GENERATE_TEMPLATES
42          = {Product.XML_TEMPLATE};
43      /** Missing license report. */
44      private static final Product[] PRODUCTS_THAT_VALIDATE
45          = {Product.MISSING_LICENSE_REPORT_TEMPLATE};
46      /** Directories report. */
47      private static final Product[] PRODUCTS_THAT_REPORT_ON_DIRECTORIES
48          = {Product.DIRECTORIES_REPORT_TEMPLATE};
49      /** Legal documents. */
50      private static final Product[] PRODUCTS_THAT_GENERATE_LICENSING_MATERIALS
51          = {Product.LICENSE, Product.NOTICE};
52  
53      /** Makes writes, not null. */
54      private final ResultWriterFactory writerFactory;
55      /** Merges templates, not null. */
56      private final VelocityEngine engine;
57      /** Logs messages, not null. */
58      private final Log log;
59  
60      /**
61       * Constructs a reporter using Apache Velocity.
62       * @param writerFactory not null
63       * @param log not null
64       */
65      public VelocityReports(
66              final ResultWriterFactory writerFactory, final Log log) {
67          this.writerFactory = writerFactory;
68          this.log = log;
69          engine = new VelocityEngine();
70          engine.setProperty(VelocityEngine.RESOURCE_LOADER, "classpath");
71          engine.setProperty("classpath.resource.loader.class",
72              "org.apache.velocity.runtime.resource.loader."
73                  + "ClasspathResourceLoader");
74          engine.init();
75      }
76  
77      /**
78       * Reports on work.
79       * @param work not null
80       * @param configuration not null
81       * @throws Exception when generation fails
82       */
83      public final void generate(final Descriptor work,
84              final Configuration configuration) throws Exception {
85          final List<Product> products = new ArrayList<Product>();
86          for (Product product: PRODUCTS_THAT_GENERATE_LICENSING_MATERIALS) {
87              switch (product) {
88                  case NOTICE:
89                      if (!work.isNoticeRequired()) {
90                          break;
91                      }
92                  default:
93                      products.add(product);
94              }
95  
96  
97          }
98          final Product[] pruductArray = new Product[products.size()];
99          merge(products.toArray(pruductArray), context(work, configuration));
100     }
101 
102     /**
103      * Merges context with product templates, and writes results.
104      * @param products not null
105      * @param context not null
106      * @throws Exception when merger fails
107      */
108     private void merge(final Product[] products,
109             final VelocityContext context) throws Exception {
110         for (final Product product : products) {
111             merge(product, context);
112         }
113     }
114 
115     /**
116      * Merges context with product template, and writes results.
117      * @param product not null
118      * @param context not null
119      * @throws Exception when generate fails
120      */
121     private void merge(
122             final Product product, final VelocityContext context)
123                 throws Exception {
124         final Writer writer = product.writerFrom(writerFactory);
125         engine.getTemplate(
126                 template(product.getTemplate())).merge(context, writer);
127         IOUtils.closeQuietly(writer);
128     }
129 
130     /**
131      * Creates a context, and loads it for descriptor work.
132      * @param work not null
133      * @param configuration not null
134      * @return not null
135      */
136     private VelocityContext context(final Descriptor work,
137             final Configuration configuration) {
138         final VelocityContext context = new VelocityContext();
139         context.put("work", work);
140         context.put("indent", new Indentation());
141         context.put("helper", new RenderingHelper(work, configuration));
142         return context;
143     }
144 
145 
146     /**
147      * Returns the full template path.
148      * @param name not null
149      * @return not null
150      */
151     private String template(final String name) {
152         return "org/apache/creadur/whisker/template/velocity/"
153                 + name.toLowerCase() + ".vm";
154     }
155 
156     /**
157      * Generates a directory report.
158      * @param directories not null
159      * @throws Exception when reporting fails
160      */
161     public final void report(
162             final Collection<Directory> directories) throws Exception {
163         merge(PRODUCTS_THAT_REPORT_ON_DIRECTORIES, context(directories));
164     }
165 
166     /**
167      * Creates a content, and loads it with the directories.
168      * @param directories not null
169      * @return not null
170      */
171     private VelocityContext context(
172             final Collection<Directory> directories) {
173         final VelocityContext context = new VelocityContext();
174         context.put("dirs", directories);
175         return context;
176     }
177 
178     /**
179      * Reports on analysis.
180      * @param analyst not null
181      * @throws Exception when validation fails
182      */
183     public final void validate(
184             final LicenseAnalyst analyst) throws Exception {
185         merge(PRODUCTS_THAT_VALIDATE, context(analyst));
186     }
187 
188     /**
189      * Creates a context, and loads it with the analyst.
190      * @param analyst not null
191      * @return not null
192      */
193     private VelocityContext context(final LicenseAnalyst analyst) {
194         final VelocityContext context = new VelocityContext();
195         context.put("analyst", analyst);
196         return context;
197     }
198 
199     /**
200      * Generates template.
201      * @param withBase not null
202      * @throws Exception when generation fails
203      */
204     public final void generateTemplate(
205             final Collection<Directory> withBase) throws Exception {
206         merge(PRODUCTS_THAT_GENERATE_TEMPLATES, context(withBase));
207     }
208 }