View Javadoc

1   /*
2    * Copyright 2006-2012 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.maven.util.report;
17  
18  import java.io.File;
19  import java.util.List;
20  
21  import org.apache.commons.lang.StringUtils;
22  import org.apache.maven.model.ReportPlugin;
23  import org.apache.maven.plugin.logging.Log;
24  import org.apache.maven.project.MavenProject;
25  import org.codehaus.plexus.util.PathTool;
26  
27  import de.smartics.maven.util.PathUtils;
28  import de.smartics.maven.util.report.link.ExternalReport;
29  import de.smartics.maven.util.report.link.ExternalReportFactory;
30  import de.smartics.maven.util.report.link.LinkConstructorStrategy;
31  import de.smartics.maven.util.report.link.LinkConstructorStrategyConfig;
32  import de.smartics.maven.util.report.link.ReportId;
33  
34  /**
35   * Factory to create external reports within a Maven project.
36   */
37  public class MavenExternalReportFactory implements ExternalReportFactory
38  {
39    // ********************************* Fields *********************************
40  
41    // --- constants ------------------------------------------------------------
42  
43    /**
44     * The artifact ID of the surefire plugin.
45     * <p>
46     * The value of this constant is {@value}.
47     * </p>
48     */
49    public static final String MAVEN_SUREFIRE_PLUGIN =
50        "maven-surefire-report-plugin";
51  
52    /**
53     * The artifact ID of the Javadoc plugin.
54     * <p>
55     * The value of this constant is {@value}.
56     * </p>
57     */
58    public static final String MAVEN_JAVADOC_PLUGIN = "maven-javadoc-plugin";
59  
60    /**
61     * The artifact ID of the jxr plugin.
62     * <p>
63     * The value of this constant is {@value}.
64     * </p>
65     */
66    public static final String MAVEN_JXR_PLUGIN = "maven-jxr-plugin";
67  
68    /**
69     * The artifact ID of the cobertura plugin.
70     * <p>
71     * The value of this constant is {@value}.
72     * </p>
73     */
74    public static final String MAVEN_COBERTURA_PLUGIN = "maven-cobertura-plugin";
75  
76    // --- members --------------------------------------------------------------
77  
78    /**
79     * The Maven project.
80     */
81    private final MavenProject project;
82  
83    /**
84     * The Maven logger to use. May be <code>null</code> if no logging is
85     * requested.
86     */
87    private final Log log;
88  
89    /**
90     * The path up to the root directory from the report directory.
91     */
92    private final String upPath;
93  
94    // ****************************** Initializer *******************************
95  
96    // ****************************** Constructors ******************************
97  
98    /**
99     * Convenience constructor using no logging.
100    *
101    * @param project the Maven project.
102    * @param reportRelDir the project's relative path within the project.
103    * @throws IllegalArgumentException if <code>project</code> is
104    *           <code>null</code> or <code>reportRelDir</code> is
105    *           <code>null</code> or contains only whitespaces.
106    */
107   public MavenExternalReportFactory(final MavenProject project,
108       final String reportRelDir) throws IllegalArgumentException
109   {
110     this(null, project, reportRelDir);
111   }
112 
113   /**
114    * Default constructor.
115    *
116    * @param log the Maven logger to use.
117    * @param project the Maven project.
118    * @param reportRelDir the project's relative path within the project.
119    * @throws IllegalArgumentException if <code>project</code> is
120    *           <code>null</code> or <code>reportRelDir</code> is
121    *           <code>null</code> or contains only whitespaces.
122    */
123   public MavenExternalReportFactory(final Log log, final MavenProject project,
124       final String reportRelDir) throws IllegalArgumentException
125   {
126     checkArguments(project, reportRelDir);
127     this.log = log;
128     this.project = project;
129     this.upPath = PathUtils.getUpPath(reportRelDir);
130   }
131 
132   // ****************************** Inner Classes *****************************
133 
134   // ********************************* Methods ********************************
135 
136   // --- init -----------------------------------------------------------------
137 
138   private static void checkArguments(final MavenProject project,
139       final String reportRelDir) throws IllegalArgumentException
140   {
141     if (project == null)
142     {
143       throw new IllegalArgumentException("The project must not be 'null'.");
144     }
145     if (reportRelDir == null
146         || (StringUtils.isBlank(reportRelDir) && StringUtils
147             .isNotEmpty(reportRelDir)))
148     {
149       throw new IllegalArgumentException(
150           "The report relative directory within the project base"
151               + " directory must not be 'null' or contain only whitespaces.");
152     }
153   }
154 
155   // --- get&set --------------------------------------------------------------
156 
157   // --- business -------------------------------------------------------------
158 
159   private String calcRelativePath(final File reportLocation)
160   {
161     final String reportBaseDir = project.getReporting().getOutputDirectory();
162     final String reportLocationAbsolutePath = reportLocation.getAbsolutePath();
163 
164     final String relativePathBase;
165     if (reportLocationAbsolutePath.contains(".."))
166     {
167       relativePathBase = ".."; // Fix for BUG 622: Referencing Aggregate Reports
168     }
169     else
170     {
171       relativePathBase =
172           PathTool.getRelativePath(reportBaseDir, reportLocationAbsolutePath);
173     }
174     final String relativePath =
175         upPath + '/' + (getPathFragment(relativePathBase))
176             + reportLocation.getName();
177     return relativePath;
178   }
179 
180   private static String getPathFragment(final String relativePathBase)
181   {
182     return isNotCurrentDir(relativePathBase) ? relativePathBase + '/' : "";
183   }
184 
185   private static boolean isNotCurrentDir(final String relativePathBase)
186   {
187     return StringUtils.isNotEmpty(relativePathBase)
188            && !".".equals(relativePathBase);
189   }
190 
191   @SuppressWarnings("unchecked")
192   private boolean isReportPluginRegistered(final String reportArtifactId)
193   {
194     final List<ReportPlugin> reportPlugins =
195         (List<ReportPlugin>) project.getReportPlugins();
196     for (final ReportPlugin report : reportPlugins)
197     {
198       final String artifactId = report.getArtifactId();
199       if (reportArtifactId.equals(artifactId))
200       {
201         return true;
202       }
203     }
204     return false;
205   }
206 
207   /**
208    * {@inheritDoc}
209    */
210   public ExternalReport createExternalReport(final ReportId reportId,
211       final LinkConstructorStrategy strategy)
212   {
213     if (reportId == null)
214     {
215       throw new IllegalArgumentException("The report ID is required.");
216     }
217     if (strategy == null)
218     {
219       throw new IllegalArgumentException(
220           "The link construction strategy is required.");
221     }
222 
223     final String reportBasePath =
224         createRelativeReportLocationLink(reportId, strategy);
225     if (reportBasePath != null)
226     {
227       return new ExternalReport(reportId, reportBasePath, strategy);
228     }
229     else
230     {
231       return null;
232     }
233   }
234 
235   private String createRelativeReportLocationLink(final ReportId reportId,
236       final LinkConstructorStrategy strategy)
237   {
238     final LinkConstructorStrategyConfig config = strategy.getConfig();
239 
240     final File reportLocation = config.getReportLocation();
241     final String reportArtifactId = reportId.getReportArtifactId();
242 
243     final String location;
244     if (reportLocation.exists() || isReportPluginRegistered(reportArtifactId))
245     {
246       location = calcRelativePath(reportLocation);
247     }
248     else
249     {
250       location = null;
251       if (log != null && log.isWarnEnabled())
252       {
253         log.warn("Cannot locate report of '" + reportArtifactId
254                  + "'. Disabling references to that report.");
255       }
256     }
257 
258     return location;
259   }
260 
261   // --- object basics --------------------------------------------------------
262 
263 }