1 package net.sf.tomp.xml.type;
2
3 import net.sf.tomp.xtcl.filter.XTFilterImpl;
4
5 import org.xml.sax.Attributes;
6 import org.xml.sax.SAXException;
7 import org.xml.sax.XMLReader;
8
9 /***
10 * DOCUMENT ME!
11 *
12 * @author $author$
13 * @version $Revision$
14 */
15 public class TypeDetectorFilter extends XTFilterImpl implements TypeDetector {
16 /*** DOCUMENT ME! */
17 protected boolean wasDD;
18
19 /*** DOCUMENT ME! */
20 protected String dtName;
21
22 /*** DOCUMENT ME! */
23 protected String dtPublicId;
24
25 /*** DOCUMENT ME! */
26 protected String dtSystemId;
27
28 /*** DOCUMENT ME! */
29 protected int depth;
30
31 /*** DOCUMENT ME! */
32 protected Type type;
33
34 /*** DOCUMENT ME! */
35 protected TypeDatabase typeDatabase;
36
37 /*** DOCUMENT ME! */
38 protected TypeContextImpl context;
39
40 /***
41 * Creates a new TypeDetectorFilter object.
42 */
43 public TypeDetectorFilter() {
44 super();
45 }
46
47 /***
48 * Construct an XML filter with the specified parent.
49 *
50 * @param parent DOCUMENT ME!
51 * @see #setParent
52 * @see #getParent
53 */
54 public TypeDetectorFilter(XMLReader parent) {
55 super(parent);
56 }
57
58 /***
59 * DOCUMENT ME!
60 *
61 * @param k DOCUMENT ME!
62 * @param v DOCUMENT ME!
63 */
64 public void setParameter(String k, Object v) {
65
66
67
68
69
70
71
72
73 super.setParameter(k, v);
74 }
75
76 /***
77 * DOCUMENT ME!
78 *
79 * @return DOCUMENT ME!
80 */
81 public Type getType() {
82 return type;
83 }
84
85 /***
86 * DOCUMENT ME!
87 *
88 * @return DOCUMENT ME!
89 */
90 public TypeContext getTypeContext() {
91 return context;
92 }
93
94 /***
95 * DOCUMENT ME!
96 *
97 * @return DOCUMENT ME!
98 */
99 public Type getTypeForCurrentContext() {
100 if (type == null) {
101 return null;
102 }
103
104 TypeContext tc = getTypeContext();
105
106 if (tc == null) {
107 return type;
108 }
109
110 Type t = type.getTypeForContext(tc);
111
112 return (t == null) ? type : t;
113 }
114
115 /***
116 * DOCUMENT ME!
117 *
118 * @return DOCUMENT ME!
119 */
120 public TypeDatabase getTypeDatabase() {
121 return typeDatabase;
122 }
123
124 /***
125 * DOCUMENT ME!
126 *
127 * @param td DOCUMENT ME!
128 */
129 public void setTypeDatabase(TypeDatabase td) {
130 typeDatabase = td;
131 }
132
133
134
135
136
137 /***
138 * Filter a start document event.
139 *
140 * @exception SAXException The client may throw an exception during
141 * processing.
142 */
143 public void startDocument() throws SAXException {
144
145 wasDD = false;
146 type = null;
147 depth = 0;
148 context = TypeContextImpl.ROOT;
149
150
151 }
152
153 /***
154 * DOCUMENT ME!
155 *
156 * @param ch DOCUMENT ME!
157 * @param start DOCUMENT ME!
158 * @param length DOCUMENT ME!
159 * @throws SAXException DOCUMENT ME!
160 */
161 public void comment(char[] ch, int start, int length) throws SAXException {
162
163
164
165 if (type != null) {
166 super.comment(ch, start, length);
167 }
168 }
169
170 /***
171 * Filter an end document event.
172 *
173 * @param uri DOCUMENT ME!
174 * @param localName DOCUMENT ME!
175 * @param qName DOCUMENT ME!
176 * @param atts DOCUMENT ME!
177 * @exception SAXException The client may throw an exception during
178 * processing.
179 */
180
181
182
183
184
185
186
187
188
189
190 /***
191 * Filter a start element event.
192 *
193 * @param uri The element's Namespace URI, or the empty string.
194 * @param localName The element's local name, or the empty string.
195 * @param qName The element's qualified (prefixed) name, or the empty
196 * string.
197 * @param atts The element's attributes.
198 * @exception SAXException The client may throw an exception during
199 * processing.
200 */
201 public void startElement(String uri, String localName, String qName,
202 Attributes atts) throws SAXException {
203 if ((type == null) && (depth == 0)) {
204 type = typeDatabase.getTypeForRootElement(uri, localName);
205
206 if (type == null) {
207 type = TypeImpl.UNKNOWN;
208 }
209
210 contentHandler.setDocumentLocator(locator);
211 super.startDocument();
212
213 if (wasDD) {
214 super.startDTD(dtName, dtPublicId, dtSystemId);
215 }
216 }
217
218 depth++;
219 context = new TypeContextImpl(context, qName);
220 super.startElement(uri, localName, qName, atts);
221 }
222
223 /***
224 * Filter an end element event.
225 *
226 * @param uri The element's Namespace URI, or the empty string.
227 * @param localName The element's local name, or the empty string.
228 * @param qName The element's qualified (prefixed) name, or the empty
229 * string.
230 * @exception SAXException The client may throw an exception during
231 * processing.
232 */
233 public void endElement(String uri, String localName, String qName)
234 throws SAXException {
235 super.endElement(uri, localName, qName);
236 depth--;
237 context = (TypeContextImpl) context.getParent();
238 }
239
240 /***
241 * Register the start of the DTD. Comments in the DTD are skipped because
242 * they are not part of the XPath data model
243 *
244 * @param name DOCUMENT ME!
245 * @param publicId DOCUMENT ME!
246 * @param systemId DOCUMENT ME!
247 * @throws SAXException DOCUMENT ME!
248 */
249 public void startDTD(String name, String publicId, String systemId)
250 throws SAXException {
251 if (type == null) {
252 type = typeDatabase.getTypeForDoctype(name, publicId, systemId);
253 }
254
255 wasDD = true;
256 dtName = name;
257 dtPublicId = publicId;
258 dtSystemId = systemId;
259 }
260 }
261
262
263
264
265
266
267
268
269
270
271