1:
37:
38: package ;
39:
40: import ;
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50:
51:
92: public class NSFilter extends EventFilter
93: {
94: private NamespaceSupport nsStack = new NamespaceSupport ();
95: private Stack elementStack = new Stack ();
96:
97: private boolean pushedContext;
98: private String nsTemp [] = new String [3];
99: private AttributesImpl attributes = new AttributesImpl ();
100: private boolean usedDefault;
101:
102:
103: private static final String prefixRoot = "prefix-";
104:
105:
106:
112:
113: public NSFilter (EventConsumer next)
114: {
115: super (next);
116:
117: setContentHandler (this);
118: }
119:
120: private void fatalError (String message)
121: throws SAXException
122: {
123: SAXParseException e;
124: ErrorHandler handler = getErrorHandler ();
125: Locator locator = getDocumentLocator ();
126:
127: if (locator == null)
128: e = new SAXParseException (message, null, null, -1, -1);
129: else
130: e = new SAXParseException (message, locator);
131: if (handler != null)
132: handler.fatalError (e);
133: throw e;
134: }
135:
136:
137: public void startDocument () throws SAXException
138: {
139: elementStack.removeAllElements ();
140: nsStack.reset ();
141: pushedContext = false;
142: super.startDocument ();
143: }
144:
145:
151: public void startPrefixMapping (String prefix, String uri)
152: throws SAXException
153: {
154: if (pushedContext == false) {
155: nsStack.pushContext ();
156: pushedContext = true;
157: }
158:
159:
160: for (Enumeration e = nsStack.getDeclaredPrefixes ();
161: e.hasMoreElements ();
162: ) {
163: String declared = (String) e.nextElement ();
164:
165: if (!declared.equals (prefix))
166: continue;
167: if (uri.equals (nsStack.getURI (prefix)))
168: return;
169: fatalError ("inconsistent binding for prefix '" + prefix
170: + "' ... " + uri + " (was " + nsStack.getURI (prefix) + ")");
171: }
172:
173: if (!nsStack.declarePrefix (prefix, uri))
174: fatalError ("illegal prefix declared: " + prefix);
175: }
176:
177: private String fixName (String ns, String l, String name, boolean isAttr)
178: throws SAXException
179: {
180: if ("".equals (name) || name == null) {
181: name = l;
182: if ("".equals (name) || name == null)
183: fatalError ("empty/null name");
184: }
185:
186:
187:
188: if (nsStack.processName (name, nsTemp, isAttr) != null
189: && nsTemp [0].equals (ns)
190: ) {
191: return nsTemp [2];
192: }
193:
194:
195: int temp;
196:
197:
198: if ((temp = name.indexOf (':')) >= 0) {
199: name = name.substring (temp + 1);
200:
201:
202: if (!isAttr && nsStack.processName (name, nsTemp, false) != null
203: && nsTemp [0].equals (ns)
204: ) {
205: return nsTemp [2];
206: }
207: }
208:
209:
210: if ("".equals (ns)) {
211: if (isAttr)
212: fatalError ("processName bug");
213: if (attributes.getIndex ("xmlns") != -1)
214: fatalError ("need to undefine default NS, but it's bound: "
215: + attributes.getValue ("xmlns"));
216:
217: nsStack.declarePrefix ("", "");
218: attributes.addAttribute ("", "", "xmlns", "CDATA", "");
219: return name;
220: }
221:
222:
223: for (Enumeration e = nsStack.getDeclaredPrefixes ();
224: e.hasMoreElements ();
225: ) {
226: String prefix = (String) e.nextElement ();
227: String uri = nsStack.getURI (prefix);
228:
229: if (uri == null || !uri.equals (ns))
230: continue;
231: return prefix + ":" + name;
232: }
233:
234:
235: for (temp = 0; temp >= 0; temp++) {
236: String prefix = prefixRoot + temp;
237:
238: if (nsStack.getURI (prefix) == null) {
239: nsStack.declarePrefix (prefix, ns);
240: attributes.addAttribute ("", "", "xmlns:" + prefix,
241: "CDATA", ns);
242: return prefix + ":" + name;
243: }
244: }
245: fatalError ("too many prefixes genned");
246:
247: return null;
248: }
249:
250: public void startElement (
251: String uri, String localName,
252: String qName, Attributes atts
253: ) throws SAXException
254: {
255: if (!pushedContext)
256: nsStack.pushContext ();
257: pushedContext = false;
258:
259:
260: int length = atts.getLength ();
261:
262: for (int i = 0; i < length; i++) {
263: String aName = atts.getQName (i);
264:
265: if (!aName.startsWith ("xmlns"))
266: continue;
267:
268: String prefix;
269:
270: if ("xmlns".equals (aName))
271: prefix = "";
272: else if (aName.indexOf (':') == 5)
273: prefix = aName.substring (6);
274: else
275: continue;
276: startPrefixMapping (prefix, atts.getValue (i));
277: }
278:
279:
280: attributes.clear ();
281: for (Enumeration e = nsStack.getDeclaredPrefixes ();
282: e.hasMoreElements ();
283: ) {
284: String prefix = (String) e.nextElement ();
285:
286: attributes.addAttribute ("", "",
287: ("".equals (prefix)
288: ? "xmlns"
289: : "xmlns:" + prefix),
290: "CDATA",
291: nsStack.getURI (prefix));
292: }
293:
294:
295:
296:
297: qName = fixName (uri, localName, qName, false);
298:
299: for (int i = 0; i < length; i++) {
300: String aName = atts.getQName (i);
301: String aNS = atts.getURI (i);
302: String aLocal = atts.getLocalName (i);
303: String aType = atts.getType (i);
304: String aValue = atts.getValue (i);
305:
306: if (aName.startsWith ("xmlns"))
307: continue;
308: aName = fixName (aNS, aLocal, aName, true);
309: attributes.addAttribute (aNS, aLocal, aName, aType, aValue);
310: }
311:
312: elementStack.push (qName);
313:
314:
315: super.startElement (uri, localName, qName, attributes);
316: }
317:
318: public void endElement (String uri, String localName, String qName)
319: throws SAXException
320: {
321: nsStack.popContext ();
322: qName = (String) elementStack.pop ();
323: super.endElement (uri, localName, qName);
324: }
325:
326:
331: public void endPrefixMapping (String prefix)
332: throws SAXException
333: { }
334:
335: public void endDocument () throws SAXException
336: {
337: elementStack.removeAllElements ();
338: nsStack.reset ();
339: super.endDocument ();
340: }
341: }