1 package net.logAnalyzer.reports;
2
3 import java.text.SimpleDateFormat;
4 import java.util.Date;
5
6 import javax.xml.parsers.DocumentBuilder;
7 import javax.xml.parsers.DocumentBuilderFactory;
8 import javax.xml.parsers.ParserConfigurationException;
9
10 import net.logAnalyzer.analysis.AnalyzerException;
11 import net.logAnalyzer.analysis.LAAnalysis;
12 import net.logAnalyzer.analysis.LAAnalyzer;
13 import net.logAnalyzer.analysis.MultiValuesAnalysis;
14 import net.logAnalyzer.analysis.SingleValueAnalysis;
15 import net.logAnalyzer.utils.XMLUtils;
16
17 import org.w3c.dom.Document;
18 import org.w3c.dom.Element;
19
20 /***
21 * This renderer generates an XML report from analyzers results. Each analysis
22 * is serialized in XML format according to the class of its result.
23 * <p>
24 * The report returned by {@link #render()} is an XML document of class
25 * {@link org.w3c.dom.Document} wrapped in a
26 * {@link net.logAnalyzer.reports.XMLReport}.
27 * </p>
28 *
29 * @author Karim REFEYTON
30 * @version 0.1
31 */
32 public class XMLReportRenderer implements LAReportRenderer {
33 /***
34 * LAReportRenderer definition.
35 */
36 private RendererDefinition definition = null;
37
38 /***
39 * Analyzers to include in the report.
40 */
41 private LAAnalyzer[] analyzers = null;
42
43 /***
44 * Creates a new report for specified analyzers.
45 *
46 * @param definition
47 * Renderer definition.
48 * @param analyzers
49 * Analyzers to include in the report.
50 */
51 public XMLReportRenderer(RendererDefinition definition,
52 LAAnalyzer[] analyzers) {
53 this.definition = definition;
54 this.analyzers = analyzers;
55 }
56
57 /***
58 * Creates a new XML document.
59 * <p>
60 * The new XML document has a root node as :<br>
61 * <br>
62 * <tt><analyzer:report class="<i>analyzerClassName</i>"/></tt>.<br>
63 * and children as :
64 * <tt><analyzer:report class="<i>analyzerClassName</i>"/></tt>.
65 * </p>
66 * <p>
67 * The children of each analyzer node are specific to the analyzer result
68 * class (see {@link LAAnalysis}).
69 * </p>
70 *
71 * @return New XML document.
72 * @throws AnalyzerException
73 * If anay parsing error.
74 */
75 protected Document createNewXMLDocument() throws ReportException {
76
77 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
78 factory.setCoalescing(false);
79 factory.setExpandEntityReferences(false);
80 factory.setIgnoringComments(true);
81 factory.setIgnoringElementContentWhitespace(true);
82 factory.setNamespaceAware(true);
83 factory.setValidating(false);
84 Document document = null;
85 try {
86 DocumentBuilder builder = factory.newDocumentBuilder();
87
88 document = builder.newDocument();
89 Element root = (Element) document.createElement("report");
90 document.appendChild(root);
91 XMLUtils.addAttribute(document, root, "created",
92 (new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"))
93 .format(new Date()));
94 document.getDocumentElement().normalize();
95 } catch (ParserConfigurationException pce) {
96 throw new ReportException(pce.getMessage(), pce);
97 }
98 return document;
99 }
100
101 /***
102 * Returns the name of the analyzer.
103 *
104 * @return LAAnalyzer name.
105 * @see LAReportRenderer#getName()
106 */
107 public String getName() {
108 return definition.getName();
109 }
110
111 /***
112 * Render the report. The report is a {@link XMLReport} wrapping a XML
113 * {@link Document} representation of all anlyzers results.
114 *
115 * @return Generated report.
116 * @throws ReportException
117 * @see LAReportRenderer#render()
118 */
119 public LAReport[] render() throws ReportException {
120 Document report = createNewXMLDocument();
121 if (analyzers != null && analyzers.length > 0) {
122 for (int i = 0; i < analyzers.length; i++) {
123 renderAnalysis(report, analyzers[i].getAnalysis());
124 }
125 }
126
127 LAReport[] reports = new LAReport[1];
128 reports[0] = new XMLReport("FullReport", report);
129 return reports;
130 }
131
132 /***
133 * Empty method to avoid loops on unsupported analysis.
134 *
135 * @param report
136 * Report.
137 * @param analysis
138 * Analyze to render.
139 */
140 protected void renderAnalysis(Document report, LAAnalysis analysis) {
141 if (analysis instanceof SingleValueAnalysis) {
142 renderAnalysis(report, (SingleValueAnalysis) analysis);
143 } else if (analysis instanceof MultiValuesAnalysis) {
144 renderAnalysis(report, (MultiValuesAnalysis) analysis);
145 }
146 }
147
148 /***
149 * Renders a key values result. Element format:
150 *
151 * <pre>
152 * <analyzerName label="analyzer.getLabel()">
153 * <item valueName="value[1]">key[1]</item>
154 * <item valueName="value[2]">key[2]</item>
155 * ...
156 * </analyzerName>
157 * </pre>
158 *
159 * @param report
160 * Report.
161 * @param analysis
162 * Analyze to render.
163 */
164 protected void renderAnalysis(Document report, SingleValueAnalysis analysis) {
165
166 Element newElement = XMLUtils.addElement(report, analysis.getAnalyzer()
167 .getName());
168
169 XMLUtils.addAttribute(report, newElement, "label", analysis
170 .getAnalyzer().getLabel());
171
172 for (int i = 0; i < analysis.size(); i++) {
173
174 Element newItem = XMLUtils.addElement(report, newElement, "item",
175 analysis.getStringKey(i), false);
176
177 XMLUtils.addAttribute(report, newItem, analysis.getName(), analysis
178 .getString(i));
179 }
180 }
181
182 /***
183 * Renders a multi values result. Element format:
184 *
185 * <pre>
186 * <analyzerName label="analyzer.getLabel()">
187 * <item valueName1="value1[1]" valueName2="value2[1]" ...>key[1]</item>
188 * <item valueName1="value1[2]" valueName2="value2[2]" ...>key[2]</item>
189 * ...
190 * </analyzerName>
191 * </pre>
192 *
193 * @param report
194 * Report.
195 * @param analysis
196 * Analyze to render.
197 */
198 protected void renderAnalysis(Document report, MultiValuesAnalysis analysis) {
199
200 Element newElement = XMLUtils.addElement(report, analysis.getAnalyzer()
201 .getName());
202
203 XMLUtils.addAttribute(report, newElement, "label", analysis
204 .getAnalyzer().getLabel());
205
206 String[] valuesNames = analysis.getNames();
207 for (int i = 0; i < analysis.size(); i++) {
208
209 Comparable key = analysis.getKey(i);
210 Element newItem = XMLUtils.addElement(report, newElement, "item",
211 analysis.getStringKey(i), false);
212
213 for (int j = 0; j < valuesNames.length; j++) {
214 String valueName = valuesNames[j];
215 valueName = valueName.replace(' ', '_');
216 XMLUtils.addAttribute(report, newItem, valueName, analysis
217 .getString(key, j));
218 }
219 }
220 }
221 }