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 }