View Javadoc

1   package net.sf.mvnflexreports;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.FileNotFoundException;
6   import java.util.ArrayList;
7   import java.util.HashSet;
8   import java.util.List;
9   import java.util.Locale;
10  import java.util.Map;
11  import java.util.ResourceBundle;
12  import java.util.Set;
13  import java.util.TreeMap;
14  
15  import javax.xml.namespace.QName;
16  import javax.xml.stream.XMLInputFactory;
17  import javax.xml.stream.XMLStreamConstants;
18  import javax.xml.stream.XMLStreamException;
19  import javax.xml.stream.XMLStreamReader;
20  
21  import org.apache.maven.doxia.siterenderer.Renderer;
22  import org.apache.maven.project.MavenProject;
23  import org.apache.maven.reporting.MavenReportException;
24  
25  /***
26   * @author RĂ©mi Flament
27   * @goal remoteobject-maven-report
28   * @phase site
29   */
30  public class RemoteObjectMavenReport extends AbstractGraphvizMavenReport {
31  
32  	/***
33  	 * The output directory for the final HTML report. Note that this parameter
34  	 * is only evaluated if the goal is run directly from the command line or
35  	 * during the default lifecycle. If the goal is run indirectly as part of a
36  	 * site generation, the output directory configured in the Maven Site Plugin
37  	 * is used instead.
38  	 * 
39  	 * @parameter expression="${project.reporting.outputDirectory}"
40  	 * @required
41  	 */
42  	protected File outputDirectory;
43  
44  	/***
45  	 * The project to analyse.
46  	 * 
47  	 * @parameter expression="${project}"
48  	 * @required
49  	 * @readonly
50  	 */
51  	protected MavenProject project;
52  
53  	/***
54  	 * The directory containing source code to parse.
55  	 * 
56  	 * @parameter expression="${basedir}/src/main/flex"
57  	 * @required
58  	 */
59  	private File sourceDir;
60  	
61  	/***
62  	 * The layout to use. This parameter will be used as the rankdir parameter.
63  	 * 
64  	 * @parameter expression="TB"
65  	 */
66  	protected String remoteObjectLayout;
67  
68  	/***
69  	 * @parameter
70  	 */
71  	private Set<String> remoteObjectPatterns;
72  
73  	/***
74  	 * @parameter
75  	 */
76  	private Set<String> remoteMethodPatterns;
77  
78  	/***
79  	 * The fill color for remote objects in the graphical report
80  	 * 
81  	 * @parameter expression="cornflowerblue"
82  	 */
83  	private String remoteObjectColor;
84  
85  	/***
86  	 * The fill color for mxml components in the graphical report
87  	 * 
88  	 * @parameter expression="firebrick1"
89  	 */
90  	private String mxmlComponentColor;
91  
92  	/***
93  	 * Site rendering component for generating the HTML report.
94  	 * 
95  	 * @component
96  	 */
97  	private Renderer siteRenderer;
98  
99  	protected void executeReport(Locale locale) throws MavenReportException {
100 
101 		if (remoteObjectPatterns == null) {
102 			remoteObjectPatterns = new HashSet<String>();
103 		}
104 
105 		if (remoteMethodPatterns == null) {
106 			remoteMethodPatterns = new HashSet<String>();
107 		}
108 
109 		if (remoteObjectPatterns.size() == 0) {
110 			remoteObjectPatterns.add("RemoteObject");
111 		}
112 
113 		if (remoteMethodPatterns.size() == 0) {
114 			remoteMethodPatterns.add("method");
115 		}
116 
117 		List<File> files = new ArrayList<File>();
118 		getFiles(sourceDir.getAbsoluteFile(), files, ".as", ".mxml");
119 		ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
120 
121 		try {
122 			Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
123 			Map<String, RemoteObject> remoteObjects = new TreeMap<String, RemoteObject>();
124 			Map<String, MXMLComponent> components = new TreeMap<String, MXMLComponent>();
125 			for (File sourceFile : files) {
126 				getLog().debug("Processing flex source file " + sourceFile.getCanonicalPath());
127 				findRemoteObjects(sourceFile, remoteObjects, components);
128 			}
129 
130 			RemoteObjectReportGenerator generator = new RemoteObjectReportGenerator(getSink());
131 			generator.setMxmlComponentColor(mxmlComponentColor);
132 			generator.setRemoteObjectColor(remoteObjectColor);
133 			generator.setFontName(fontName);
134 			generator.setFontSize(fontSize);
135 			generator.setProgramName(programName);
136 			generator.setLayout(remoteObjectLayout);
137 			getLog().debug("mxmlComponentColor = " + mxmlComponentColor);
138 			getLog().debug("remoteObjectColor = " + remoteObjectColor);
139 			generator.generate(remoteObjects.values(), components.values(), this.getReportOutputDirectory(), getLog());
140 
141 		} catch (Exception e) {
142 			throw new MavenReportException(e.getMessage(), e);
143 		} finally {
144 			Thread.currentThread().setContextClassLoader(origLoader);
145 		}
146 
147 	}
148 
149 	private void findRemoteObjects(File file, Map<String, RemoteObject> remoteObjects, Map<String, MXMLComponent> components) throws FileNotFoundException, XMLStreamException {
150 
151 		getLog().debug("getUsedRemoteObjects() for file " + file.getAbsolutePath());
152 
153 		MXMLComponent currentComponent = null;
154 
155 		if (file.getName().toLowerCase().endsWith(".mxml")) {
156 
157 			currentComponent = components.get(file.getName());
158 			if (currentComponent == null) {
159 				currentComponent = new MXMLComponent();
160 				currentComponent.setFilename(file.getName());
161 				components.put(file.getName(), currentComponent);
162 			}
163 
164 			XMLInputFactory factory = XMLInputFactory.newInstance();
165 			XMLStreamReader parser = factory.createXMLStreamReader(new FileInputStream(file));
166 
167 			RemoteObject currentRemoteObject = null;
168 			RemoteObjectUse currentRemoteObjectUse = null;
169 			while (true) {
170 				int event = parser.next();
171 				if (event == XMLStreamConstants.END_DOCUMENT) {
172 					parser.close();
173 					break;
174 				}
175 				if (event == XMLStreamConstants.START_ELEMENT) {
176 
177 					if (remoteObjectPatterns.contains(parser.getLocalName())) {
178 
179 						String destination = null;
180 						String id = null;
181 						String type = parser.getLocalName();
182 						for (int i = 0; i < parser.getAttributeCount(); i++) {
183 							QName localName = parser.getAttributeName(i);
184 							if (localName.getLocalPart().equals("destination")) {
185 
186 								destination = parser.getAttributeValue(i);
187 								getLog().debug(file.getAbsolutePath() + " uses remote object " + destination);
188 
189 								currentRemoteObject = remoteObjects.get(destination);
190 								if (currentRemoteObject == null) {
191 									currentRemoteObject = new RemoteObject();
192 									currentRemoteObject.setDestination(destination);
193 
194 									remoteObjects.put(destination, currentRemoteObject);
195 								}
196 								currentRemoteObject.increment();
197 
198 							}
199 
200 							if (localName.getLocalPart().equals("id")) {
201 								id = parser.getAttributeValue(i);
202 							}
203 
204 						}
205 
206 						if (id != null && destination != null) {
207 							currentRemoteObjectUse = currentComponent.getUsedRemoteObjects().get(destination + "#" + id);
208 							if (currentRemoteObjectUse == null) {
209 								currentRemoteObjectUse = new RemoteObjectUse();
210 								currentRemoteObjectUse.setDestination(destination);
211 								currentRemoteObjectUse.setRemoteObject(currentRemoteObject);
212 								currentRemoteObjectUse.setId(id);
213 								currentRemoteObjectUse.setRemoteObjectType(type);
214 								currentComponent.getUsedRemoteObjects().put(destination + "#" + id, currentRemoteObjectUse);
215 							}
216 							currentRemoteObjectUse.setComponent(currentComponent);
217 						}
218 
219 					} else if (remoteMethodPatterns.contains(parser.getLocalName()) && currentRemoteObject != null) {
220 						for (int i = 0; i < parser.getAttributeCount(); i++) {
221 							QName localName = parser.getAttributeName(i);
222 							if (localName.getLocalPart().equals("name")) {
223 
224 								String methodName = parser.getAttributeValue(i);
225 								getLog().debug(file.getAbsolutePath() + " uses method " + methodName + " on remote object " + currentRemoteObject.getDestination());
226 								RemoteObjectMethod method = currentRemoteObject.getMethods().get(methodName);
227 								if (method == null) {
228 									method = new RemoteObjectMethod();
229 									method.setName(methodName);
230 
231 									currentRemoteObject.getMethods().put(methodName, method);
232 								}
233 
234 								method.increment();
235 								if (currentRemoteObjectUse != null) {
236 									currentRemoteObjectUse.getUsedMethods().add(method);
237 								}
238 							}
239 						}
240 					}
241 				}
242 
243 			}
244 
245 		} else if (file.getName().toLowerCase().endsWith(".as")) {
246 			getLog().debug("ignoring " + file.getAbsolutePath() + " : not implemented yet");
247 		} else {
248 			getLog().info("ignoring " + file.getAbsolutePath() + " because we don't know how to search remote objects in it.");
249 		}
250 
251 	}
252 
253 	/***
254 	 * @return Returns the sourceDir.
255 	 */
256 	public File getSourceDir() {
257 		return sourceDir;
258 	}
259 
260 	/***
261 	 * @param sourceDir
262 	 *            The sourceDir to set.
263 	 */
264 	public void setSourceDir(File sourceDir) {
265 		this.sourceDir = sourceDir;
266 	}
267 
268 	protected String getOutputDirectory() {
269 		return outputDirectory.getAbsolutePath();
270 
271 	}
272 
273 	protected MavenProject getProject() {
274 		return project;
275 	}
276 
277 	protected Renderer getSiteRenderer() {
278 		return siteRenderer;
279 	}
280 
281 	public String getDescription(Locale locale) {
282 		return getBundle(locale).getString("report.remoteobject-flex-maven.name");
283 
284 	}
285 
286 	public String getName(Locale locale) {
287 		return getBundle(locale).getString("report.remoteobject-flex-maven.name");
288 
289 	}
290 
291 	private static ResourceBundle getBundle(Locale locale) {
292 		return ResourceBundle.getBundle("remoteobject-maven-report", locale, RemoteObjectMavenReport.class.getClassLoader());
293 	}
294 
295 	public String getOutputName() {
296 		return "remoteobject-maven-report";
297 	}
298 
299 	public Set<String> getRemoteObjectPatterns() {
300 		return remoteObjectPatterns;
301 	}
302 
303 	public void setRemoteObjectPatterns(Set<String> remoteObjectPatterns) {
304 		this.remoteObjectPatterns = remoteObjectPatterns;
305 	}
306 
307 	public Set<String> getRemoteMethodPatterns() {
308 		return remoteMethodPatterns;
309 	}
310 
311 	public void setRemoteMethodPatterns(Set<String> remoteMethodPatterns) {
312 		this.remoteMethodPatterns = remoteMethodPatterns;
313 	}
314 
315 	public String getRemoteObjectColor() {
316 		return remoteObjectColor;
317 	}
318 
319 	public void setRemoteObjectColor(String remoteObjectColor) {
320 		this.remoteObjectColor = remoteObjectColor;
321 	}
322 
323 	public String getMxmlComponentColor() {
324 		return mxmlComponentColor;
325 	}
326 
327 	public void setMxmlComponentColor(String mxmlComponentColor) {
328 		this.mxmlComponentColor = mxmlComponentColor;
329 	}
330 
331 	public String getRemoteObjectLayout() {
332 		return remoteObjectLayout;
333 	}
334 
335 	public void setRemoteObjectLayout(String remoteObjectLayout) {
336 		this.remoteObjectLayout = remoteObjectLayout;
337 	}
338 
339 }