1 package pl.caltha.services.xml.validation;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Stack;
6
7 import org.dom4j.Element;
8 import org.dom4j.Node;
9 import org.xml.sax.SAXException;
10
11 import pl.caltha.services.xml.CollectingErrorHandler;
12
13 /***
14 * ErrorHandler that collects all errors.
15 *
16 * @author <a href="mailto:zwierzem@ngo.pl">Damian Gajda</a>
17 * @version $Id: DOM4JValidationErrorCollector.java,v 1.4 2005/05/20 00:46:27 rafal Exp $
18 */
19 public class DOM4JValidationErrorCollector
20 extends CollectingErrorHandler
21 implements DOM4JContentHandler, ExtendedContentHandler
22 {
23
24
25 private Stack elementStack = new Stack();
26 private Node currentNode;
27 private org.dom4j.Attribute currentAttribute;
28 private HashMap errorsByNode = new HashMap();
29 private HashMap warningsByNode = new HashMap();
30
31 /*** Getter for property errorsByNode.
32 * @return Value of property errorsByNode.
33 */
34 public HashMap getErrorsByNode()
35 {
36 return errorsByNode;
37 }
38
39 /*** Getter for property warningsByNode.
40 * @return Value of property warningsByNode.
41 */
42 public HashMap getWarningsByNode()
43 {
44 return warningsByNode;
45 }
46
47 /*** You can call this method to reuse an ErrorHandler. */
48 public void init()
49 {
50 super.init();
51 elementStack.clear();
52 errorsByNode.clear();
53 warningsByNode.clear();
54 currentNode = null;
55 currentAttribute = null;
56 }
57
58
59
60
61 public void startElementNode(Element node)
62 {
63 currentNode = node;
64 elementStack.push(node);
65 }
66
67 public void endElementNode(Element node)
68 {
69 currentNode = null;
70 elementStack.pop();
71 }
72
73 public void setCurrentNode(Node node)
74 {
75 currentNode = node;
76 }
77
78
79
80
81 /*** receives notification of the start of a document.
82 */
83 public void startDocument()
84 throws SAXException
85 {
86
87 }
88
89 /*** receives notification of the end of a document.
90 */
91 public void endDocument()
92 throws SAXException
93 {
94
95 }
96
97 /*** receives notification of the start of an element.
98 *
99 * If this element has attributes, the start/endAttribute methods are
100 * called after this method.
101 */
102 public void startElement(String namespaceURI, String localName, String qName)
103 throws SAXException
104 {
105
106 }
107
108 /*** receives notification of the start of an attribute.
109 *
110 * the value of the attribute is reported through the characterChunk method.
111 */
112 public void startAttribute(String namespaceURI, String localName, String qName)
113 throws SAXException
114 {
115 Element element = (Element)(elementStack.peek());
116 currentAttribute = element.attribute(qName);
117 }
118
119 /*** receives notification of the end of an attribute.
120 */
121 public void endAttribute(String namespaceURI, String localName, String qName)
122 throws SAXException
123 {
124 currentAttribute = null;
125 }
126
127 /*** this method is called after the start/endAttribute method are called
128 * for all attributes.
129 */
130 public void endAttributePart()
131 throws SAXException
132 {
133
134 }
135
136 /*** receives notification of the end of an element.
137 */
138 public void endElement(String namespaceURI, String localName, String qName)
139 throws SAXException
140 {
141
142 }
143
144 /*** receives notification of a string.
145 *
146 * @param literal
147 * the contents.
148 */
149 public void characterChunk(String literal)
150 throws SAXException
151 {
152
153 }
154
155
156
157 protected ErrorInfo saveError(org.xml.sax.SAXParseException spe)
158 {
159 ErrorInfo ei = super.saveError(spe);
160 return saveErrorOrWarning(ei, errorsByNode);
161 }
162
163 protected ErrorInfo saveWarning(org.xml.sax.SAXParseException spe)
164 {
165 ErrorInfo ei = super.saveWarning(spe);
166 return saveErrorOrWarning(ei, warningsByNode);
167 }
168
169 protected ErrorInfo saveErrorOrWarning(ErrorInfo ei, HashMap map)
170 {
171 Node node = null;
172 if(currentAttribute != null)
173 {
174
175 node = currentAttribute;
176 }
177 else
178 {
179
180 node = (Node)(elementStack.peek());
181 }
182
183 map.put(node, ei);
184 return ei;
185 }
186
187 /*** Dumps all errors as a String. Uses ErrorInfo.toString()
188 * @return Errors as a String.
189 */
190 public String dumpErrors()
191 {
192 return dumpErrorsOrWarnings(errorsByNode);
193 }
194
195 /*** Dumps all warnings as a String. Uses ErrorInfo.toString()
196 * @return Warnings as a String.
197 */
198 public String dumpWarnings()
199 {
200 return dumpErrorsOrWarnings(warningsByNode);
201 }
202
203 public String dumpErrorsOrWarnings(Map map)
204 {
205 StringBuilder sb = new StringBuilder();
206 for(java.util.Iterator iter = map.keySet().iterator(); iter.hasNext();)
207 {
208 Node node = (Node)(iter.next());
209 sb.append(node.getUniquePath());
210 sb.append(' ');
211 sb.append(map.get(node).toString());
212 sb.append('\n');
213 }
214 return sb.toString();
215 }
216 }