1 package net.innig.macker.event; 2 3 import net.innig.macker.rule.RuleSet; 4 import net.innig.macker.structure.ClassInfo; 5 6 import java.io.File ; 7 import java.io.FileOutputStream ; 8 import java.io.OutputStreamWriter ; 9 import java.io.BufferedWriter ; 10 import java.io.Writer ; 11 import java.io.IOException ; 12 import java.util.LinkedList ; 13 import java.util.Iterator ; 14 15 import org.jdom.Document; 16 import org.jdom.Element; 17 import org.jdom.output.XMLOutputter; 18 19 import org.apache.commons.lang.StringUtils; 20 21 public class XmlReportingListener 22 implements MackerEventListener 23 { 24 private Writer out; 25 private String encoding; 26 27 private Document document; 28 private Element curElem; 29 private LinkedList elemStack; 30 31 public XmlReportingListener(File outFile) 32 throws ListenerException 33 { 34 try { 35 if(outFile.exists()) 36 outFile.delete(); 37 OutputStreamWriter out = new OutputStreamWriter (new FileOutputStream (outFile), "UTF-8"); 38 BufferedWriter bufferedOut = new BufferedWriter (out); 39 init(bufferedOut, "UTF-8"); 40 } 41 catch(IOException ioe) 42 { throw new ListenerException(this, "Unable to remove and re-create report file \"" + outFile + "\"", ioe); } 43 } 44 45 public XmlReportingListener(Writer out, String encoding) 46 throws ListenerException 47 { init(out, encoding); } 48 49 private void init(Writer out, String encoding) 50 throws ListenerException 51 { 52 this.out = out; 53 this.encoding = encoding; 54 55 elemStack = new LinkedList (); 56 Element topElem = new Element("macker-report"); 57 Element timestampElem = new Element("timestamp"); 58 timestampElem.setText(new java.util.Date ().toString()); topElem.addContent(timestampElem); 60 61 pushElem(topElem); 62 document = new Document(topElem); 63 } 64 65 public void flush() 66 throws ListenerException 67 { 68 try 69 { 70 XMLOutputter xmlOut = new XMLOutputter(" ", true, encoding); 71 xmlOut.output(document, out); 72 out.flush(); 73 } 74 catch(IOException ioe) 75 { throw new ListenerException(this, "Unable to write XML report", ioe); } 76 } 77 78 public void close() 79 throws ListenerException 80 { 81 try { out.close(); } 82 catch(IOException ioe) 83 { throw new ListenerException(this, "Unable to close XML report", ioe); } 84 } 85 86 public void mackerStarted(RuleSet ruleSet) 87 { 88 if(ruleSet.hasName()) 89 { 90 Element ruleSetElem = new Element("ruleset"); 91 ruleSetElem.setAttribute("name", ruleSet.getName()); 92 curElem.addContent(ruleSetElem); 93 pushElem(ruleSetElem); 94 } 95 else 96 pushElem(curElem); } 98 99 public void mackerFinished(RuleSet ruleSet) 100 throws MackerIsMadException, ListenerException 101 { popElem(); } 102 103 public void mackerAborted(RuleSet ruleSet) 104 { curElem = null; } 105 106 public void handleMackerEvent(RuleSet ruleSet, MackerEvent event) 107 throws MackerIsMadException 108 { 109 if(event instanceof MessageEvent) 110 { 111 Element messageRuleElem = new Element("message-rule"); 112 handleEventBasics(messageRuleElem, event); 113 curElem.addContent(messageRuleElem); 114 } 115 116 if(event instanceof AccessRuleViolation) 117 { 118 AccessRuleViolation violation = (AccessRuleViolation) event; 119 Element violationElem = new Element("access-rule-violation"); 120 121 handleEventBasics(violationElem, violation); 122 123 Element fromElem = new Element("from"); 124 Element toElem = new Element("to"); 125 describeClass(fromElem, violation.getFrom()); 126 describeClass( toElem, violation.getTo()); 127 violationElem.addContent(fromElem); 128 violationElem.addContent(toElem); 129 130 curElem.addContent(violationElem); 131 } 132 133 if(event instanceof ForEachStarted) 134 { 135 ForEachStarted forEachStarted = (ForEachStarted) event; 136 Element forEachElem = new Element("foreach"); 137 forEachElem.setAttribute("var", forEachStarted.getForEach().getVariableName()); 138 curElem.addContent(forEachElem); 139 pushElem(forEachElem); 140 } 141 142 if(event instanceof ForEachIterationStarted) 143 { 144 ForEachIterationStarted forEachIter = (ForEachIterationStarted) event; 145 Element iterElem = new Element("iteration"); 146 iterElem.setAttribute("value", forEachIter.getVariableValue()); 147 curElem.addContent(iterElem); 148 pushElem(iterElem); 149 } 150 151 if(event instanceof ForEachIterationFinished || event instanceof ForEachFinished) 152 popElem(); 153 } 154 155 private void handleEventBasics(Element elem, MackerEvent event) 156 { 157 elem.setAttribute("severity", event.getRule().getSeverity().getName()); 158 for(Iterator msgIter = event.getMessages().iterator(); msgIter.hasNext(); ) 159 { 160 String message = (String ) msgIter.next(); 161 Element messageElem = new Element("message"); 162 messageElem.setText(message); 163 elem.addContent(messageElem); 164 } 165 } 166 167 private void describeClass(Element classInfoElem, ClassInfo classInfo) 168 { 169 Element fullElem = new Element("full-name"); 170 Element classElem = new Element("class"); 171 Element packElem = new Element("package"); 172 fullElem.setText(classInfo.getFullName()); 173 classElem.setText(classInfo.getClassName()); 174 packElem.setText(classInfo.getPackageName()); 175 classInfoElem.addContent(fullElem); 176 classInfoElem.addContent(classElem); 177 if(!StringUtils.isEmpty(classInfo.getPackageName())) 178 classInfoElem.addContent(packElem); 179 } 180 181 private void pushElem(Element elem) 182 { 183 elemStack.addLast(curElem); 184 curElem = elem; 185 } 186 187 private void popElem() 188 { curElem = (Element) elemStack.removeLast(); } 189 190 public String toString() 191 { return "XmlReportingListener"; } 192 } 193 | Popular Tags |