1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.onemind.commons.java.xml.digest;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.util.*;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28 import javax.xml.parsers.*;
29 import org.xml.sax.Attributes;
30 import org.xml.sax.SAXException;
31 import org.xml.sax.helpers.DefaultHandler;
32 /***
33 * The SaxDigesterHandler use digesters to digest the elements in the xml. The digesters can be added using the addDigester(). By
34 * default the sequential digester list is used.
35 * @author TiongHiang Lee (thlee@thinklient.org)
36 * @version $Id: SaxDigesterHandler.java,v 1.3 2005/01/30 06:31:37 thlee Exp $ $Name: $
37 */
38 public class SaxDigesterHandler extends DefaultHandler
39 {
40
41 /*** the logger * */
42 private static final Logger _logger = Logger.getLogger(SaxDigesterHandler.class.getName());
43
44 /*** the map contains subdigesters **/
45 private Map _digesters = new HashMap();
46
47 /*** keep track of the path for current element **/
48 private List _elementPath = new ArrayList();
49
50 /***
51 * Constructor
52 */
53 public SaxDigesterHandler()
54 {
55 }
56
57 /***
58 * Adding a digester to the root path
59 * @param dig the digester
60 */
61 public void addDigester(ElementDigester dig)
62 {
63 addDigester(null, dig);
64 }
65
66 /***
67 * Add a digester for the path
68 * @param path the path
69 * @param dig the digester
70 */
71 public void addDigester(String path, ElementDigester dig)
72 {
73 if (path == null)
74 {
75 _digesters.put(dig.getElementName(), dig);
76 } else
77 {
78 _digesters.put(path + "/" + dig.getElementName(), dig);
79 }
80 }
81
82 /***
83 * Add a subdigester to current element path
84 * @param dig the digester
85 */
86 public void addSubDigester(ElementDigester dig)
87 {
88 String path = getCurrentPath();
89 addDigester(path, dig);
90 }
91
92 /***
93 * Add a sub digester at a path of current path + prefixPath
94 * @param prefixPath the prefix path
95 * @param dig the digester
96 */
97 public void addSubDigester(String prefixPath, ElementDigester dig)
98 {
99 String path = getCurrentPath();
100 if (path == null)
101 {
102 addDigester(prefixPath, dig);
103 } else if (prefixPath == null)
104 {
105 addDigester(path, dig);
106 } else
107 {
108 addDigester(path + "/" + prefixPath, dig);
109 }
110 }
111
112 /***
113 * Append the name to the element path and return the new path string
114 * @param name the name of new element
115 * @return the new path string
116 */
117 private String appendElementPath(String name)
118 {
119 int i = _elementPath.size();
120 if (i > 0)
121 {
122 String str = (String) _elementPath.get(i - 1);
123 String newStr = str + "/" + name;
124 _elementPath.add(newStr);
125 return newStr;
126 } else
127 {
128 _elementPath.add(name);
129 return name;
130 }
131 }
132
133 /***
134 * {@inheritDoc}
135 */
136 public void characters(char[] ch, int start, int length) throws SAXException
137 {
138 ElementDigester dig = getDigester(getCurrentPath());
139 if (dig != null)
140 {
141 dig.characters(this, ch, start, length);
142 }
143 }
144
145 /***
146 * {@inheritDoc}
147 */
148 public void endDocument() throws SAXException
149 {
150
151 }
152
153 /***
154 * {@inheritDoc}
155 */
156 public void endElement(String uri, String localName, String qName) throws SAXException
157 {
158 String str = removeElementPath(qName);
159 ElementDigester dig = (ElementDigester) getDigester(str);
160 if (dig != null)
161 {
162 dig.endDigest(this);
163 }
164 }
165
166 /***
167 * Get the current element path
168 * @return the path, or null if at start of document
169 */
170 public String getCurrentPath()
171 {
172 int i = _elementPath.size();
173 if (i > 0)
174 {
175 return (String) _elementPath.get(i - 1);
176 } else
177 {
178 return null;
179 }
180 }
181
182 /***
183 * Get the digester for particular path
184 * @param path the path
185 * @return the digester, or null if there's none found
186 */
187 private ElementDigester getDigester(String path)
188 {
189 return (ElementDigester) _digesters.get(path);
190 }
191
192 /***
193 * Remove the element path
194 * @param qname the element name is being removed
195 * @return the path string before the path is removed
196 */
197 private String removeElementPath(String qname)
198 {
199 int i = _elementPath.size();
200 if (i > 0)
201 {
202 String str = (String) _elementPath.remove(i - 1);
203 return str;
204 } else
205 {
206 throw new IllegalStateException("Cannot remove element path " + qname);
207 }
208 }
209
210 /***
211 * {@inheritDoc}
212 */
213 public void startDocument() throws SAXException
214 {
215
216 }
217
218 /***
219 * Call start of particular element digester, if there's any
220 * @param attr the attribute
221 * @param path the path
222 * @throws SAXException
223 */
224 private void startDigest(String path, Attributes attr) throws SAXException
225 {
226 if (_logger.isLoggable(Level.FINEST))
227 {
228 _logger.finest("Digesting " + path);
229 }
230 ElementDigester dig = (ElementDigester) getDigester(path);
231 if (dig != null)
232 {
233 if (_logger.isLoggable(Level.FINEST))
234 {
235 _logger.finest("with " + dig);
236 }
237 dig.startDigest(this, attr);
238 }
239 }
240
241 /***
242 * {@inheritDoc}
243 */
244 public void startElement(String namespaceURI, String lName,
245 String qName,
246 Attributes attrs) throws SAXException
247 {
248 String newPath = appendElementPath(qName);
249 startDigest(newPath, attrs);
250 }
251
252 /***
253 * Parse an input
254 * @param stream the stream
255 * @throws ParserConfigurationException
256 * @throws SAXException
257 * @throws IOException
258 */
259 public synchronized void parse(InputStream stream) throws ParserConfigurationException, SAXException, IOException
260 {
261 SAXParserFactory fac = SAXParserFactory.newInstance();
262 SAXParser parser = fac.newSAXParser();
263 parser.parse(stream, this);
264 }
265 }