1 package net.sf.mvnflexreports;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.InputStreamReader;
7 import java.io.StringReader;
8 import java.util.ArrayList;
9 import java.util.List;
10 import java.util.Locale;
11 import java.util.Map;
12 import java.util.ResourceBundle;
13 import java.util.TreeMap;
14
15 import javax.xml.stream.XMLInputFactory;
16 import javax.xml.stream.XMLStreamConstants;
17 import javax.xml.stream.XMLStreamReader;
18
19 import org.apache.maven.doxia.siterenderer.Renderer;
20 import org.apache.maven.project.MavenProject;
21 import org.apache.maven.reporting.MavenReportException;
22
23 import uk.co.badgersinfoil.metaas.ActionScriptFactory;
24 import uk.co.badgersinfoil.metaas.ActionScriptParser;
25 import uk.co.badgersinfoil.metaas.dom.ASClassType;
26 import uk.co.badgersinfoil.metaas.dom.ASCompilationUnit;
27 import uk.co.badgersinfoil.metaas.dom.ASPackage;
28 import uk.co.badgersinfoil.metaas.dom.ASType;
29
30 /***
31 * @author RĂ©mi Flament
32 * @goal asuml-maven-report
33 * @phase site
34 *
35 */
36 public class ActionScriptUMLMavenReport extends AbstractGraphvizMavenReport {
37
38 /***
39 * The output directory for the final HTML report. Note that this parameter
40 * is only evaluated if the goal is run directly from the command line or
41 * during the default lifecycle. If the goal is run indirectly as part of a
42 * site generation, the output directory configured in the Maven Site Plugin
43 * is used instead.
44 *
45 * @parameter expression="${project.reporting.outputDirectory}"
46 * @required
47 */
48 protected File outputDirectory;
49
50 /***
51 * The fill color for classes in the graphical report
52 *
53 * @parameter expression="cornflowerblue"
54 */
55 protected String classFillColor;
56
57 /***
58 * The fill color for interfaces in the graphical report
59 *
60 * @parameter expression="firebrick1"
61 */
62 protected String interfaceFillColor;
63
64 /***
65 * The fill color for mxmls in the graphical report
66 *
67 * @parameter expression="cadetblue3"
68 */
69 protected String mxmlFillColor;
70
71 /***
72 * The layout to use. This parameter will be used as the rankdir parameter.
73 *
74 * @parameter expression="BT"
75 */
76 protected String actionScriptUMLLayout;
77
78 /***
79 * The project to analyse.
80 *
81 * @parameter expression="${project}"
82 * @required
83 * @readonly
84 */
85 protected MavenProject project;
86
87 /***
88 * The directory containing source code to parse.
89 *
90 * @parameter expression="${basedir}/src/main/flex"
91 * @required
92 */
93 private File sourceDir;
94
95 /***
96 * Show attributes and methods in the uml report.
97 *
98 * @parameter expression="true"
99 */
100 private boolean showAttributesAndMethods;
101
102 /***
103 * Show associations between classes in the uml report.
104 *
105 * @parameter expression="true"
106 */
107 private boolean showAssociations;
108
109 /***
110 * Site rendering component for generating the HTML report.
111 *
112 * @component
113 */
114 private Renderer siteRenderer;
115
116 private ActionScriptParser parser = new ActionScriptFactory().newParser();
117
118 @Override
119 protected void executeReport(Locale locale) throws MavenReportException {
120
121 List<File> files = new ArrayList<File>();
122
123 ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
124
125 List<ActionScriptParseError> unparseables = new ArrayList<ActionScriptParseError>();
126 Map<String, List<ASType>> asTypes = new TreeMap<String, List<ASType>>();
127
128 try {
129 getFiles(sourceDir.getAbsoluteFile(), files, ".as", ".mxml");
130 Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
131 for (File sourceFile : files) {
132 getLog().debug("Processing flex source file " + sourceFile.getCanonicalPath());
133 try {
134 ASPackage pack = null;
135
136 if (sourceFile.getAbsolutePath().endsWith(".as")) {
137 pack = parseAsFile(sourceFile);
138 } else if (sourceFile.getAbsolutePath().endsWith(".mxml")) {
139 pack = parseMxmlFile(sourceDir.getAbsoluteFile(), sourceFile);
140 }
141
142 if (pack != null) {
143
144 List<ASType> list = asTypes.get(pack.getName() != null ? pack.getName() : "");
145
146 if (list == null) {
147 list = new ArrayList<ASType>();
148 asTypes.put(pack.getName() != null ? pack.getName() : "", list);
149 }
150
151 list.add(pack.getType());
152 }
153
154 } catch (Exception e) {
155 ActionScriptParseError actionScriptParseError = new ActionScriptParseError();
156 actionScriptParseError.setSourceFile(sourceFile);
157 actionScriptParseError.setError(e.getMessage());
158 unparseables.add(actionScriptParseError);
159 getLog().warn("Error while parsing source file " + sourceFile.getCanonicalPath(), e);
160 }
161 }
162
163 ActionScriptUMLReportGenerator generator = new ActionScriptUMLReportGenerator(getSink());
164 getLog().debug("classFillColor = " + classFillColor);
165 getLog().debug("interfaceFillColor = " + interfaceFillColor);
166 generator.setClassFillColor(classFillColor);
167 generator.setInterfaceFillColor(interfaceFillColor);
168 generator.setMxmlFillColor(mxmlFillColor);
169 generator.setShowAttributesAndMethods(showAttributesAndMethods);
170 generator.setShowAssociations(showAssociations);
171 generator.setFontName(fontName);
172 generator.setFontSize(fontSize);
173 generator.setProgramName(programName);
174 generator.setLayout(actionScriptUMLLayout);
175 generator.generate(sourceDir, asTypes, unparseables, this.getReportOutputDirectory(), getLog());
176
177 } catch (Exception e) {
178 throw new MavenReportException(e.getMessage(), e);
179 } finally {
180 Thread.currentThread().setContextClassLoader(origLoader);
181 }
182
183 }
184
185 private String readFileContent(File file) throws Exception {
186 StringBuilder content = new StringBuilder();
187
188 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
189 String line;
190 while ((line = bufferedReader.readLine()) != null) {
191 content.append(line + "\n");
192 }
193 return content.toString().replace("super.", "");
194
195
196
197 }
198
199 private ASPackage parseAsFile(File sourceFile) throws Exception {
200 StringReader reader = new StringReader(readFileContent(sourceFile));
201 ASCompilationUnit unit = parser.parse(reader);
202
203 ASPackage pkg = unit.getPackage();
204
205 return pkg;
206
207 }
208
209 private ASPackage parseMxmlFile(File sourceDir, File sourceFile) throws Exception {
210
211 XMLInputFactory factory = XMLInputFactory.newInstance();
212 XMLStreamReader p = factory.createXMLStreamReader(new FileInputStream(sourceFile));
213
214 String className = sourceFile.getName().substring(0, sourceFile.getName().indexOf('.'));
215 String packageName = sourceFile.getParent().replace(sourceDir.getAbsolutePath(), "").replace(File.separatorChar, '.');
216 if (packageName.startsWith("."))
217 packageName = packageName.substring(1);
218
219 String firstElement = null;
220 while (true) {
221 int event = p.next();
222 if (event == XMLStreamConstants.END_DOCUMENT) {
223 p.close();
224 break;
225 }
226 if (event == XMLStreamConstants.START_ELEMENT) {
227
228 if (firstElement == null) {
229 firstElement = p.getLocalName();
230 }
231
232 if (p.getLocalName().equals("Script")) {
233
234 String source = "package " + packageName + " {\npublic class " + className + " {\n" + p.getElementText() + "\n}}";
235
236 StringReader reader = new StringReader(source);
237 ASCompilationUnit unit = parser.parse(reader);
238
239 ASPackage pkg = unit.getPackage();
240 ASType type = pkg.getType();
241
242 type.newMetaTag("MXML");
243
244 ASClassType c = (ASClassType) type;
245 c.setSuperclass(firstElement);
246
247 return pkg;
248
249 }
250 }
251 }
252
253 return null;
254
255 }
256
257 public String getOutputName() {
258 return "asuml-maven-report";
259 }
260
261 /***
262 * @return Returns the sourceDir.
263 */
264 public File getSourceDir() {
265 return sourceDir;
266 }
267
268 /***
269 * @param sourceDir
270 * The sourceDir to set.
271 */
272 public void setSourceDir(File sourceDir) {
273 this.sourceDir = sourceDir;
274 }
275
276 protected String getOutputDirectory() {
277 return outputDirectory.getAbsolutePath();
278
279 }
280
281 protected MavenProject getProject() {
282 return project;
283 }
284
285 public String getDescription(Locale locale) {
286 return getBundle(locale).getString("report.asuml-maven-report.name");
287
288 }
289
290 public String getName(Locale locale) {
291 return getBundle(locale).getString("report.asuml-maven-report.name");
292
293 }
294
295 private static ResourceBundle getBundle(Locale locale) {
296 return ResourceBundle.getBundle("asuml-maven-report", locale, ActionScriptUMLReportGenerator.class.getClassLoader());
297 }
298
299 public String getClassFillColor() {
300 return classFillColor;
301 }
302
303 public void setClassFillColor(String classFillColor) {
304 this.classFillColor = classFillColor;
305 }
306
307 public String getInterfaceFillColor() {
308 return interfaceFillColor;
309 }
310
311 public void setInterfaceFillColor(String interfaceFillColor) {
312 this.interfaceFillColor = interfaceFillColor;
313 }
314
315 public boolean isShowAttributesAndMethods() {
316 return showAttributesAndMethods;
317 }
318
319 public void setShowAttributesAndMethods(boolean showAttributesAndMethods) {
320 this.showAttributesAndMethods = showAttributesAndMethods;
321 }
322
323 @Override
324 protected Renderer getSiteRenderer() {
325 return siteRenderer;
326 }
327
328 public boolean isShowAssociations() {
329 return showAssociations;
330 }
331
332 public void setShowAssociations(boolean showAssociations) {
333 this.showAssociations = showAssociations;
334 }
335
336 public String getActionScriptUMLLayout() {
337 return actionScriptUMLLayout;
338 }
339
340 public void setActionScriptUMLLayout(String actionScriptUMLLayout) {
341 this.actionScriptUMLLayout = actionScriptUMLLayout;
342 }
343
344 public void setMxmlFillColor(String mxmlFillColor) {
345 this.mxmlFillColor = mxmlFillColor;
346 }
347
348 }