1 package net.sf.mvnflexreports; 2 3 import java.io.File; 4 import java.util.Map; 5 import java.util.Set; 6 7 import org.apache.maven.doxia.sink.Sink; 8 import org.apache.maven.plugin.logging.Log; 9 10 /*** 11 * @author RĂ©mi Flament 12 * 13 */ 14 public class RemoteObjectReportGenerator extends AbstractGraphvizMavenReportGenerator { 15 16 /*** 17 * The fill color for remote objects in the graphical report 18 * 19 */ 20 private String remoteObjectColor; 21 22 /*** 23 * The fill color for mxml components in the graphical report 24 * 25 */ 26 private String mxmlComponentColor; 27 28 public RemoteObjectReportGenerator(Sink sink) { 29 this.sink = sink; 30 } 31 32 /*** 33 * Method that returns the title 34 * 35 * @return a String that contains the title 36 */ 37 private String getTitle() { 38 return "Flex Remote Object Maven Report"; 39 } 40 41 /*** 42 * Method that generates the start 43 */ 44 public void beginDocument() { 45 sink.head(); 46 sink.title(); 47 sink.text(getTitle()); 48 sink.title_(); 49 sink.head_(); 50 51 sink.body(); 52 53 sink.section1(); 54 sink.sectionTitle1(); 55 sink.text(getTitle()); 56 sink.sectionTitle1_(); 57 58 sink.paragraph(); 59 sink.text(this.getTitle()); 60 sink.link_(); 61 sink.paragraph_(); 62 63 } 64 65 private String generateGraphviz(Iterable<RemoteObject> remoteObjects, Iterable<MXMLComponent> components) { 66 StringBuilder builder = new StringBuilder(); 67 68 builder.append("digraph application {\n"); 69 70 builder.append(" rankdir=" + layout + "\n"); 71 builder.append(" fontname = \"" + fontName + "\"\n"); 72 builder.append(" fontsize = " + fontSize + "\n"); 73 builder.append(" node [\n"); 74 builder.append(" fontname = \"" + fontName + "\"\n"); 75 builder.append(" fontsize = " + fontSize + "\n"); 76 builder.append(" shape = \"Mrecord\"\n"); 77 builder.append(" color = black\n"); 78 builder.append(" style = filled\n"); 79 builder.append(" fillcolor = " + remoteObjectColor + "\n"); 80 builder.append(" ]\n"); 81 builder.append(" edge [\n"); 82 builder.append(" fontname = \"" + fontName + "\"\n"); 83 builder.append(" fontsize = " + fontSize + "\n"); 84 builder.append(" ]\n"); 85 86 for (RemoteObject remoteObject : remoteObjects) { 87 builder.append(" \"__ro__" + remoteObject.getDestination() + "\" [label=\"{<f0> Remote Object " + remoteObject.getDestination()+"|"); 88 89 Map<String, RemoteObjectMethod> methods = remoteObject.getMethods(); 90 91 for (RemoteObjectMethod remoteObjectMethod : methods.values()) { 92 builder.append(remoteObjectMethod.getName() + "()//l"); 93 } 94 95 builder.append("}\" ];\n"); 96 } 97 98 for (MXMLComponent component : components) { 99 if (component.getUsedRemoteObjects().size() > 0) { 100 builder.append(" \"__co__" + component.getFilename() + "\" [style=filled shape=ellipse label=\"" + component.getFilename() + "\" fillcolor=" + mxmlComponentColor + "];\n"); 101 102 Map<String, RemoteObjectUse> usedRemoteObjects = component.getUsedRemoteObjects(); 103 104 for (RemoteObjectUse remoteObjectUse : usedRemoteObjects.values()) { 105 builder.append(" \"__co__" + component.getFilename() + "\" -> \"__ro__" + remoteObjectUse.getRemoteObject().getDestination() + "\":f0 [ label = \"" + remoteObjectUse.getId() 106 + "\" ];\n"); 107 } 108 109 } 110 } 111 112 builder.append("}\n"); 113 return builder.toString(); 114 } 115 116 /*** 117 * Method that generates the contents 118 * 119 * @param remoteObjects 120 * @param components 121 * @param log 122 * @throws Exception 123 */ 124 public void generate(Iterable<RemoteObject> remoteObjects, Iterable<MXMLComponent> components, File outputDirectory, Log log) throws Exception { 125 beginDocument(); 126 127 try { 128 sink.section2(); 129 sink.sectionTitle2(); 130 sink.text("Graphical view"); 131 sink.sectionTitle2_(); 132 sink.section2_(); 133 String text = this.generateGraphviz(remoteObjects, components); 134 invokeDot(text, "remoteobjects", outputDirectory.getAbsolutePath(), log); 135 sink.lineBreak(); 136 sink.rawText("<img src='images/remoteobjects.png' />"); 137 sink.lineBreak(); 138 } catch (Exception e) { 139 log.error("Cannot generate graphical view !", e); 140 } 141 142 sink.paragraph(); 143 sink.section2(); 144 sink.sectionTitle2(); 145 sink.text("Global Summary"); 146 sink.sectionTitle2_(); 147 sink.section2_(); 148 149 sink.table(); 150 sink.tableRow(); 151 sink.tableHeaderCell("50%"); 152 sink.text("Remote Objects"); 153 sink.tableHeaderCell_(); 154 sink.tableHeaderCell(); 155 sink.text("Declaration count"); 156 sink.tableHeaderCell_(); 157 sink.tableRow_(); 158 159 for (RemoteObject remoteObject : remoteObjects) { 160 161 sink.tableRow(); 162 sink.tableCell(); 163 sink.text(remoteObject.getDestination()); 164 sink.tableCell_(); 165 sink.tableCell(); 166 sink.text(remoteObject.getCount() + ""); 167 sink.tableCell_(); 168 sink.tableRow_(); 169 170 } 171 sink.table_(); 172 sink.paragraph_(); 173 174 sink.section2(); 175 sink.sectionTitle2(); 176 sink.text("Remote Objects"); 177 sink.sectionTitle2_(); 178 sink.section2_(); 179 180 for (RemoteObject remoteObject : remoteObjects) { 181 182 sink.paragraph(); 183 sink.table(); 184 sink.tableRow(); 185 sink.tableHeaderCell("50%"); 186 sink.text("Remote Object " + remoteObject.getDestination()); 187 sink.tableHeaderCell_(); 188 sink.tableHeaderCell(); 189 sink.text("Declaration count"); 190 sink.tableHeaderCell_(); 191 192 Map<String, RemoteObjectMethod> methods = remoteObject.getMethods(); 193 for (RemoteObjectMethod method : methods.values()) { 194 sink.tableRow(); 195 sink.tableCell(); 196 sink.text(method.getName()); 197 sink.tableCell_(); 198 sink.tableCell(); 199 sink.text(method.getCount() + ""); 200 sink.tableCell_(); 201 sink.tableRow_(); 202 } 203 sink.table_(); 204 sink.paragraph_(); 205 } 206 207 sink.section2(); 208 sink.sectionTitle2(); 209 sink.text("MXML Components"); 210 sink.sectionTitle2_(); 211 sink.section2_(); 212 213 for (MXMLComponent component : components) { 214 if (component.getUsedRemoteObjects().size() > 0) { 215 sink.paragraph(); 216 217 sink.section3(); 218 sink.sectionTitle3(); 219 sink.text(component.getFilename()); 220 sink.sectionTitle3_(); 221 sink.section3_(); 222 223 sink.table(); 224 sink.tableRow(); 225 sink.tableHeaderCell("25%"); 226 sink.text("Remote Object Destination"); 227 sink.tableHeaderCell_(); 228 sink.tableHeaderCell("25%"); 229 sink.text("Remote Object Id"); 230 sink.tableHeaderCell_(); 231 sink.tableHeaderCell("25%"); 232 sink.text("Type"); 233 sink.tableHeaderCell_(); 234 sink.tableHeaderCell("25%"); 235 sink.text("Method used"); 236 sink.tableHeaderCell_(); 237 238 Map<String, RemoteObjectUse> uses = component.getUsedRemoteObjects(); 239 240 for (RemoteObjectUse use : uses.values()) { 241 242 Set<RemoteObjectMethod> methods = use.getUsedMethods(); 243 for (RemoteObjectMethod remoteObjectMethod : methods) { 244 sink.tableRow(); 245 sink.tableCell(); 246 sink.text(use.getDestination()); 247 sink.tableCell_(); 248 sink.tableCell(); 249 sink.text(use.getId()); 250 sink.tableCell_(); 251 sink.tableCell(); 252 sink.text(use.getRemoteObjectType()); 253 sink.tableCell_(); 254 sink.tableCell(); 255 sink.text(remoteObjectMethod.getName()); 256 sink.tableCell_(); 257 sink.tableRow_(); 258 } 259 260 } 261 sink.table_(); 262 sink.paragraph_(); 263 } 264 } 265 266 sink.body_(); 267 sink.flush(); 268 sink.close(); 269 } 270 271 public String getRemoteObjectColor() { 272 return remoteObjectColor; 273 } 274 275 public void setRemoteObjectColor(String remoteObjectColor) { 276 this.remoteObjectColor = remoteObjectColor; 277 } 278 279 public String getMxmlComponentColor() { 280 return mxmlComponentColor; 281 } 282 283 public void setMxmlComponentColor(String mxmlComponentColor) { 284 this.mxmlComponentColor = mxmlComponentColor; 285 } 286 287 }