View Javadoc

1   /*
2    * Copyright 2012-2013 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.properties.report;
17  
18  import java.io.File;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.List;
22  
23  import javax.annotation.concurrent.NotThreadSafe;
24  
25  import com.thoughtworks.qdox.JavaProjectBuilder;
26  import com.thoughtworks.qdox.library.ErrorHandler;
27  import com.thoughtworks.qdox.model.JavaClass;
28  import com.thoughtworks.qdox.parser.ParseException;
29  
30  import de.smartics.properties.report.data.PropertyReport;
31  import de.smartics.properties.report.data.ReportProblem;
32  import de.smartics.properties.report.qdox.PropertyDescriptorSearcher;
33  import de.smartics.properties.utils.RuntimeUtils;
34  import de.smartics.util.lang.Arg;
35  import de.smartics.util.lang.NullArgumentException;
36  
37  /**
38   * Builder of reports on smartics properties.
39   */
40  @NotThreadSafe
41  public final class ReportBuilder
42  {
43    // ********************************* Fields *********************************
44  
45    // --- constants ------------------------------------------------------------
46  
47    // --- members --------------------------------------------------------------
48  
49    /**
50     * The configuration to control the generation of the report.
51     */
52    private final ReportConfiguration configuration;
53  
54    /**
55     * The parser of the Java sources.
56     */
57    private final JavaProjectBuilder javaProjectBuilder;
58  
59    /**
60     * The error handler to log parsing problems.
61     */
62    private final ErrorHandler errorHandler = new ErrorHandler()
63    {
64      @Override
65      public void handle(final ParseException parseException)
66      {
67        problems.add(new ReportProblem("Parse error", parseException));
68      }
69    };
70  
71    /**
72     * The list of problems encountered while parsing sources and fetching report
73     * information.
74     */
75    private final List<ReportProblem> problems = new ArrayList<ReportProblem>();
76  
77    /**
78     * Helper to instantiate classes.
79     */
80    private final RuntimeUtils runtimeUtils;
81  
82    // ****************************** Initializer *******************************
83  
84    // ****************************** Constructors ******************************
85  
86    private ReportBuilder(final ReportConfiguration configuration)
87    {
88      this.configuration = configuration;
89  
90      javaProjectBuilder = createJavaProjectBuilder(configuration, errorHandler);
91      runtimeUtils = createRuntimeUtils(configuration);
92    }
93  
94    // ****************************** Inner Classes *****************************
95  
96    // ********************************* Methods ********************************
97  
98    // --- init -----------------------------------------------------------------
99  
100   private static JavaProjectBuilder createJavaProjectBuilder(
101       final ReportConfiguration configuration, final ErrorHandler errorHandler)
102   {
103     final JavaProjectBuilder builder = new JavaProjectBuilder();
104 
105     builder.setEncoding(configuration.getEncoding());
106     builder.setErrorHandler(errorHandler);
107 
108     for (final File sourceTree : configuration.getSourceTrees())
109     {
110       builder.addSourceTree(sourceTree);
111     }
112 
113     return builder;
114   }
115 
116   private RuntimeUtils createRuntimeUtils(
117       final ReportConfiguration configuration)
118   {
119     final ClassLoader classLoader = configuration.getProjectClassLoader();
120     return new RuntimeUtils(classLoader);
121   }
122 
123   // --- create ---------------------------------------------------------------
124 
125   /**
126    * Factory method to create an instance of a report builder.
127    *
128    * @param configuration the configuration to control the generation of the
129    *          report.
130    * @return the configured report builder.
131    */
132   public static ReportBuilder create(final ReportConfiguration configuration)
133   {
134     return new ReportBuilder(configuration);
135   }
136 
137   // --- get&set --------------------------------------------------------------
138 
139   /**
140    * Returns the configuration to control the generation of the report.
141    *
142    * @return the configuration to control the generation of the report.
143    */
144   public ReportConfiguration getConfiguration()
145   {
146     return configuration;
147   }
148 
149   // --- business -------------------------------------------------------------
150 
151   /**
152    * Runs the report process and writes to the given report.
153    *
154    * @param report the report to write to.
155    * @throws NullArgumentException if {@code report} is <code>null</code>.
156    */
157   public void reportTo(final PropertyReport report)
158     throws NullArgumentException
159   {
160     Arg.checkNotNull("report", report);
161 
162     notifyOfParseProblems(report);
163 
164     final PropertyDescriptorSearcher searcher =
165         new PropertyDescriptorSearcher();
166     final Collection<JavaClass> propertyDescriptorTypes =
167         javaProjectBuilder.search(searcher);
168     for (final JavaClass propertyDescriptorType : propertyDescriptorTypes)
169     {
170       try
171       {
172         final AddReportItemHelper helper =
173             new AddReportItemHelper(runtimeUtils, javaProjectBuilder,
174                 propertyDescriptorType);
175         helper.addReportItems(report);
176       }
177       catch (final Exception e)
178       {
179         report.addProblem(new ReportProblem("Cannot add report item.", e));
180       }
181     }
182   }
183 
184   private void notifyOfParseProblems(final PropertyReport report)
185   {
186     if (!problems.isEmpty())
187     {
188       for (final ReportProblem problem : problems)
189       {
190         report.addProblem(problem);
191       }
192     }
193   }
194 
195   // --- object basics --------------------------------------------------------
196 
197 }