View Javadoc

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.", ""); // help metaas,
194 		// this
195 		// doesn't change
196 		// anything for us
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 }