View Javadoc
1   package org.nuiton.config;
2   
3   /*
4    * #%L
5    * Maven Report Plugin
6    * %%
7    * Copyright (C) 2012 - 2016 CodeLutin, Tony Chemit
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as 
11   * published by the Free Software Foundation, either version 3 of the 
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Lesser Public 
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * #L%
23   */
24  
25  import org.apache.maven.doxia.siterenderer.Renderer;
26  import org.apache.maven.plugins.annotations.Component;
27  import org.apache.maven.plugins.annotations.Parameter;
28  import org.apache.maven.project.MavenProject;
29  import org.apache.maven.reporting.AbstractMavenReport;
30  import org.apache.maven.reporting.MavenReportException;
31  import org.codehaus.plexus.i18n.I18N;
32  import org.codehaus.plexus.util.StringUtils;
33  import org.nuiton.i18n.I18n;
34  import org.nuiton.i18n.init.ClassPathI18nInitializer;
35  import org.nuiton.i18n.init.DefaultI18nInitializer;
36  import org.nuiton.i18n.init.I18nInitializer;
37  
38  import java.io.File;
39  import java.net.MalformedURLException;
40  import java.net.URL;
41  import java.net.URLClassLoader;
42  import java.util.Arrays;
43  import java.util.HashSet;
44  import java.util.Locale;
45  import java.util.Set;
46  
47  /**
48   * Abstract application config report used by normal and aggregate report.
49   *
50   * @author Tony - chemit@codelutin.com
51   * @since 2.6.10
52   */
53  public abstract class AbstractApplicationConfigReport extends AbstractMavenReport {
54  
55      /**
56       * Report output directory. Note that this parameter is only relevant if the goal is run from the command line or
57       * from the default build lifecycle. If the goal is run indirectly as part of a site generation, the output
58       * directory configured in the Maven Site Plugin is used instead.
59       *
60       * @since 2.6.10
61       */
62      @Parameter(property = "config.outputDirectory",
63                 defaultValue = "${project.reporting.outputDirectory}",
64                 required = true)
65      protected File outputDirectory;
66  
67      /**
68       * Report output encoding. Note that this parameter is only relevant if the goal is run from the command line or
69       * from the default build lifecycle. If the goal is run indirectly as part of a site generation, the output
70       * encoding configured in the Maven Site Plugin is used instead.
71       *
72       * @since 2.6.10
73       */
74      @Parameter(property = "config.outputEncoding",
75                 defaultValue = "${project.reporting.outputEncoding}",
76                 required = true)
77      protected String outputEncoding;
78  
79      /**
80       * Optional i18n bundle name as used by the nuiton I18n system to init his
81       * files.
82       *
83       * If not given, will look at all i18n files in all over class-path (which
84       * could be costy if many dependencies), otherwise will init I18n system
85       * usinga {@link DefaultI18nInitializer} with this bundle name.
86       *
87       * @since 2.6.10
88       */
89      @Parameter(property = "config.i18nBundleName")
90      protected String i18nBundleName;
91  
92      /**
93       * List of application config to include in report (separated by comma).
94       *
95       * <strong>Note:</strong> If not filled then will use all config
96       * found in class-path.
97       *
98       * @since 2.6.10
99       */
100     @Parameter(property = "config.include")
101     protected String include;
102 
103     /**
104      * List of application config to exclude from report (separated by comma).
105      *
106      * <strong>Note:</strong> If not filled no config will be exclude.
107      *
108      * @since 2.6.10
109      */
110     @Parameter(property = "config.exclude")
111     protected String exclude;
112 
113     /**
114      * Flag to activate verbose mode.
115      *
116      * <b>Note:</b> Verbose mode is always on if you starts a debug maven instance
117      * (says via {@code -X}).
118      *
119      * @since 2.6.10
120      */
121     @Parameter(property = "config.verbose", defaultValue = "${maven.verbose}")
122     protected boolean verbose;
123 
124     /**
125      * Flag to render option in detail (add a section for each option).
126      *
127      * @since 2.6.10
128      */
129     @Parameter(property = "config.showOptionDetail", defaultValue = "true")
130     protected boolean showOptionDetail;
131 
132     /**
133      * Skip to generate the report.
134      *
135      * @since 2.6.10
136      */
137     @Parameter(property = "config.skip")
138     protected boolean skip;
139 
140     /**
141      * The Maven Project.
142      *
143      * @since 2.6.10
144      */
145     @Parameter(defaultValue = "${project}", required = true)
146     protected MavenProject project;
147 
148 
149     /**
150      * Doxia Site Renderer component.
151      *
152      * @since 2.6.10
153      */
154     @Component
155     protected Renderer siteRenderer;
156 
157     /**
158      * Internationalization component.
159      *
160      * @since 2.6.10
161      */
162     @Component
163     protected I18N i18n;
164 
165     /**
166      * Class loader with all compile dependencies of the module in class-path
167      * (used to init i18n) and obtain config provider over compile class-path.
168      *
169      * @since 2.6.10
170      */
171     protected ClassLoader newClassLoader;
172 
173     /**
174      * Set of ApplicationconfigProvider detected from configuration.
175      *
176      * @since 2.6.10
177      */
178     protected Set<ApplicationConfigProvider> configProviders;
179 
180     @Override
181     public String getOutputName() {
182         return "config-report";
183     }
184 
185     public String getDescription(Locale locale) {
186         return i18n.getString(getOutputName(), locale, "report.description");
187     }
188 
189     public String getName(Locale locale) {
190         return i18n.getString(getOutputName(), locale, "report.title");
191     }
192 
193     @Override
194     public String getCategoryName() {
195         return CATEGORY_PROJECT_REPORTS;
196     }
197 
198     @Override
199     public boolean canGenerateReport() {
200         return !skip;
201     }
202 
203     @Override
204     protected Renderer getSiteRenderer() {
205         return siteRenderer;
206     }
207 
208     @Override
209     protected String getOutputDirectory() {
210         return outputDirectory.getAbsolutePath();
211     }
212 
213     @Override
214     protected MavenProject getProject() {
215         return project;
216     }
217 
218     protected abstract ClassLoader createClassLoader() throws MavenReportException;
219 
220     @Override
221     protected void executeReport(Locale locale) throws MavenReportException {
222 
223         if (newClassLoader == null) {
224 
225             // not init
226             init(locale);
227         } else {
228 
229             // just change init language
230             I18n.setDefaultLocale(locale);
231         }
232         ApplicationConfigReportRenderer renderer =
233                 new ApplicationConfigReportRenderer(getSink(),
234                                                     i18n,
235                                                     locale,
236                                                     getOutputName(),
237                                                     getOutputName(),
238                                                     configProviders,
239                                                     showOptionDetail);
240         renderer.render();
241     }
242 
243     protected void init(Locale locale) throws MavenReportException {
244         if (getLog().isDebugEnabled()) {
245 
246             // debug mode set verbose flag to true
247             verbose = true;
248         }
249 
250         if (newClassLoader == null) {
251 
252             newClassLoader = createClassLoader();
253         }
254 
255         // get i18n initializer
256         I18nInitializer initializer;
257         if (StringUtils.isNotEmpty(i18nBundleName)) {
258             initializer = new DefaultI18nInitializer(i18nBundleName,
259                                                      newClassLoader);
260         } else {
261             initializer = new ClassPathI18nInitializer(newClassLoader);
262         }
263         // init i18n
264         I18n.init(initializer, locale);
265 
266         if (configProviders == null) {
267 
268             Set<String> includes = null;
269             if (StringUtils.isNotEmpty(include)) {
270                 includes = new HashSet<String>(Arrays.asList(include.split("\\s*,\\s*")));
271                 if (verbose) {
272                     getLog().info("config - includes : " + includes);
273                 }
274             }
275 
276             Set<String> excludes = null;
277             if (StringUtils.isNotEmpty(exclude)) {
278                 excludes = new HashSet<String>(Arrays.asList(exclude.split("\\s*,\\s*")));
279                 if (verbose) {
280                     getLog().info("config - excludes : " + excludes);
281                 }
282             }
283 
284             configProviders = ApplicationConfigHelper.getProviders(
285                     newClassLoader,
286                     includes,
287                     excludes,
288                     verbose
289             );
290         }
291     }
292 
293     protected ClassLoader createClassLoader(Set<String> paths) {
294 
295         Set<URL> urls = new HashSet<URL>();
296 
297         for (String fileName : paths) {
298             File pathElem = new File(fileName);
299             try {
300                 URL url = pathElem.toURI().toURL();
301                 urls.add(url);
302                 getLog().debug("Added classpathElement URL " + url);
303             } catch (MalformedURLException e) {
304                 throw new RuntimeException(
305                         "Error in adding the classpath " + pathElem, e);
306             }
307         }
308 
309         return new URLClassLoader(
310                 urls.toArray(new URL[urls.size()]),
311                 Thread.currentThread().getContextClassLoader());
312     }
313 }