View Javadoc

1   package net.sf.mvnflexreports;
2   
3   import java.io.File;
4   import java.util.HashSet;
5   import java.util.List;
6   import java.util.Map;
7   import java.util.Set;
8   
9   import org.apache.maven.doxia.sink.Sink;
10  import org.apache.maven.plugin.logging.Log;
11  
12  import uk.co.badgersinfoil.metaas.dom.ASClassType;
13  import uk.co.badgersinfoil.metaas.dom.ASField;
14  import uk.co.badgersinfoil.metaas.dom.ASInterfaceType;
15  import uk.co.badgersinfoil.metaas.dom.ASMethod;
16  import uk.co.badgersinfoil.metaas.dom.ASType;
17  import uk.co.badgersinfoil.metaas.dom.Visibility;
18  
19  /***
20   * @author RĂ©mi Flament
21   * 
22   */
23  public class ActionScriptUMLReportGenerator extends AbstractGraphvizMavenReportGenerator {
24  
25  	private String classFillColor;
26  
27  	private String interfaceFillColor;
28  
29  	private String mxmlFillColor;
30  
31  	private boolean showAttributesAndMethods = true;
32  
33  	private boolean showAssociations = true;
34  
35  	public void setShowAssociations(boolean showAssociations) {
36  		this.showAssociations = showAssociations;
37  	}
38  
39  	public void setShowAttributesAndMethods(boolean showAttributesAndMethods) {
40  		this.showAttributesAndMethods = showAttributesAndMethods;
41  	}
42  
43  	public ActionScriptUMLReportGenerator(Sink sink) {
44  		this.sink = sink;
45  	}
46  
47  	/***
48  	 * Method that returns the title
49  	 * 
50  	 * @return a String that contains the title
51  	 */
52  	private String getTitle() {
53  		return "Actionscript UML Maven Report";
54  	}
55  
56  	/***
57  	 * Method that generates the start
58  	 */
59  	public void beginDocument() {
60  		sink.head();
61  		sink.title();
62  		sink.text(getTitle());
63  		sink.title_();
64  		sink.head_();
65  
66  		sink.body();
67  
68  		sink.section1();
69  		sink.sectionTitle1();
70  		sink.text(getTitle());
71  		sink.sectionTitle1_();
72  
73  		sink.paragraph();
74  		sink.text(this.getTitle());
75  		sink.link_();
76  		sink.paragraph_();
77  
78  	}
79  
80  	@SuppressWarnings("unchecked")
81  	private String generateGraphviz(List<ASType> asTypes) {
82  
83  		Set<String> names = new HashSet<String>();
84  
85  		for (ASType type : asTypes) {
86  			names.add(type.getName());
87  		}
88  
89  		StringBuilder builder = new StringBuilder();
90  
91  		builder.append("digraph application {\n");
92  
93  		builder.append("	rankdir=" + layout + "\n");
94  		builder.append("	fontname = \"" + fontName + "\"\n");
95  		builder.append("	fontsize = " + fontSize + "\n");
96  		builder.append("	node [\n");
97  		builder.append("		fontname = \"" + fontName + "\"\n");
98  		builder.append("		fontsize = " + fontSize + "\n");
99  		builder.append("		shape = Mrecord\n");
100 		builder.append("		color = black\n");
101 		builder.append("		style = filled\n");
102 		builder.append("		fillcolor = " + classFillColor + "\n");
103 		builder.append("	]\n");
104 		builder.append("	edge [\n");
105 		builder.append("		fontname = \"" + fontName + "\"\n");
106 		builder.append("		fontsize = " + fontSize + "\n");
107 		builder.append("	]\n");
108 
109 		for (ASType type : asTypes) {
110 			builder.append("	" + type.getName() + " [\n");
111 
112 			if (type instanceof ASInterfaceType) {
113 				builder.append("		fillcolor = " + interfaceFillColor + "\n");
114 			} else {
115 				List l = type.getMetaTagsWithName("MXML");
116 				if (l != null && l.size() > 0) {
117 					builder.append("		fillcolor = " + mxmlFillColor + "\n");
118 				}
119 			}
120 
121 			builder.append("	label = \"{");
122 			if (type instanceof ASInterfaceType) {
123 				builder.append("//<//<Interface//>//>//n");
124 			}
125 
126 			List l = type.getMetaTagsWithName("RemoteClass");
127 			if (l != null && l.size() > 0) {
128 				builder.append("//<//<RemoteClass//>//>//n");
129 			}
130 
131 			l = type.getMetaTagsWithName("MXML");
132 			if (l != null && l.size() > 0) {
133 				builder.append("//<//<MXML Component//>//>//n");
134 			}
135 
136 			builder.append(type.getName());
137 
138 			if (showAttributesAndMethods) {
139 				boolean firstMethod = true;
140 
141 				for (ASMethod method : (List<ASMethod>) type.getMethods()) {
142 					if (firstMethod) {
143 						builder.append("|");
144 						firstMethod = false;
145 					}
146 					if (method.getVisibility() == Visibility.PUBLIC) {
147 						builder.append("+ ");
148 					} else if (method.getVisibility() == Visibility.PRIVATE) {
149 						builder.append("- ");
150 					}
151 					builder.append(method.getName() + "() : " + method.getType());
152 					builder.append("//l");
153 				}
154 
155 				if (type instanceof ASClassType) {
156 					ASClassType classType = (ASClassType) type;
157 					boolean firstField = true;
158 
159 					for (ASField field : (List<ASField>) classType.getFields()) {
160 						if (firstField) {
161 							builder.append("|");
162 							firstField = false;
163 						}
164 
165 						if (field.getVisibility() == Visibility.PUBLIC) {
166 							builder.append("+ ");
167 						} else if (field.getVisibility() == Visibility.PRIVATE) {
168 							builder.append("- ");
169 						}
170 						builder.append(field.getName() + " : " + field.getType());
171 						builder.append("//l");
172 					}
173 
174 				}
175 			}
176 
177 			builder.append("}\"\n");
178 			builder.append("	]\n");
179 			if (type instanceof ASClassType) {
180 				ASClassType classType = (ASClassType) type;
181 				if (classType.getSuperclass() != null) {
182 					builder.append("	" + classType.getName() + " -> " + classType.getSuperclass() + " [arrowhead = \"empty\"];\n\n");
183 				}
184 
185 				if (classType.getImplementedInterfaces() != null) {
186 					for (String string : (List<String>) classType.getImplementedInterfaces()) {
187 						builder.append("	" + classType.getName() + " -> " + string + " [arrowhead = \"empty\"];\n\n");
188 					}
189 				}
190 				if (showAssociations) {
191 					List<ASField> fields = classType.getFields();
192 					for (ASField field : fields) {
193 
194 						if (names.contains(field.getType())) {
195 							builder.append("	" + field.getType() + " -> " + type.getName() + " [arrowhead = \"none\" taillabel = \"0..1\"];\n");
196 						}
197 					}
198 				}
199 			}
200 
201 		}
202 
203 		builder.append("}\n");
204 		return builder.toString();
205 	}
206 
207 	/***
208 	 * Method that generates the contents
209 	 * 
210 	 */
211 	public void generate(File root, Map<String, List<ASType>> asTypes, List<ActionScriptParseError> actionScriptParseErrors, File outputDirectory, Log log) throws Exception {
212 		beginDocument();
213 
214 		try {
215 			sink.section2();
216 			sink.sectionTitle2();
217 			sink.text("Graphical view");
218 			sink.sectionTitle2_();
219 			sink.section2_();
220 
221 			for (Map.Entry<String, List<ASType>> entry : asTypes.entrySet()) {
222 				sink.section3();
223 				sink.sectionTitle3();
224 				sink.text(entry.getKey().equals("") == false ? "Package " + entry.getKey() : "Root package");
225 				sink.sectionTitle3_();
226 				sink.section3_();
227 				String text = this.generateGraphviz(entry.getValue());
228 				invokeDot(text, "asuml-" + entry.getKey(), outputDirectory.getAbsolutePath(), log);
229 				sink.lineBreak();
230 				sink.rawText("<img src='images/asuml-" + entry.getKey() + ".png' />");
231 				sink.lineBreak();
232 			}
233 
234 		} catch (Exception e) {
235 			log.error("Cannot generate graphical view !", e);
236 		}
237 
238 		if (actionScriptParseErrors != null && actionScriptParseErrors.size() > 0) {
239 			sink.section2();
240 			sink.sectionTitle2();
241 			sink.text("Parsing errors");
242 			sink.sectionTitle2_();
243 			sink.section2_();
244 
245 			sink.paragraph();
246 			sink.table();
247 			sink.tableRow();
248 			sink.tableHeaderCell();
249 			sink.text("Filename");
250 			sink.tableHeaderCell_();
251 			sink.tableHeaderCell();
252 			sink.text("Error");
253 			sink.tableHeaderCell_();
254 
255 			for (ActionScriptParseError actionScriptParseError : actionScriptParseErrors) {
256 
257 				sink.tableRow();
258 				sink.tableCell();
259 				sink.text(actionScriptParseError.getSourceFile().getPath().substring(root.getAbsolutePath().length() + 1));
260 				sink.tableCell_();
261 				sink.tableCell();
262 				sink.text(actionScriptParseError.getError());
263 				sink.tableCell_();
264 				sink.tableRow_();
265 
266 			}
267 			sink.table_();
268 			sink.paragraph_();
269 		}
270 		sink.body_();
271 		sink.flush();
272 		sink.close();
273 	}
274 
275 	public String getClassFillColor() {
276 		return classFillColor;
277 	}
278 
279 	public void setClassFillColor(String classFillColor) {
280 		this.classFillColor = classFillColor;
281 	}
282 
283 	public String getInterfaceFillColor() {
284 		return interfaceFillColor;
285 	}
286 
287 	public void setInterfaceFillColor(String interfaceFillColor) {
288 		this.interfaceFillColor = interfaceFillColor;
289 	}
290 
291 	public void setMxmlFillColor(String mxmlFillColor) {
292 		this.mxmlFillColor = mxmlFillColor;
293 	}
294 
295 }