1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69:
70:
75: public class DomLSParser
76: implements LSParser, DOMConfiguration, DOMStringList, ErrorHandler
77: {
78:
79: private static final List SUPPORTED_PARAMETERS
80: = Arrays.asList(new String[] { "cdata-sections",
81: "comments",
82: "element-content-whitespace",
83: "namespaces",
84: "expand-entity-references",
85: "coalescing",
86: "validating",
87: "xinclude-aware",
88: "entity-resolver",
89: "error-handler" });
90:
91: private LSParserFilter filter;
92: private final boolean async;
93: private String schemaType;
94: private SAXEventSink eventSink;
95: private SAXParserFactory factory;
96: private XMLReader reader;
97:
98: private boolean namespaceAware = true;
99: private boolean ignoreWhitespace;
100: private boolean expandEntityReferences;
101: private boolean ignoreComments;
102: private boolean coalescing;
103: private boolean validating;
104: private boolean xIncludeAware;
105: private EntityResolver entityResolver;
106: private ErrorHandler errorHandler;
107:
108: public DomLSParser(short mode, String schemaType)
109: throws DOMException
110: {
111: switch (mode)
112: {
113: case DOMImplementationLS.MODE_ASYNCHRONOUS:
114: async = true;
115: break;
116: case DOMImplementationLS.MODE_SYNCHRONOUS:
117: async = false;
118: break;
119: default:
120: throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
121: }
122:
123: this.schemaType = schemaType;
124: factory = SAXParserFactory.newInstance();
125: }
126:
127:
128:
129: public DOMConfiguration getDomConfig()
130: {
131: return this;
132: }
133:
134: public LSParserFilter getFilter()
135: {
136: return filter;
137: }
138:
139: public void setFilter(LSParserFilter filter)
140: {
141: this.filter = filter;
142: }
143:
144: public boolean getAsync()
145: {
146: return async;
147: }
148:
149: public boolean getBusy()
150: {
151: return eventSink != null;
152: }
153:
154: public Document parse(LSInput input)
155: throws DOMException, LSException
156: {
157: if (async)
158: {
159: return doParse(input);
160: }
161: else
162: {
163: synchronized (this)
164: {
165: return doParse(input);
166: }
167: }
168: }
169:
170: public Document parseURI(String uri)
171: throws DOMException, LSException
172: {
173: LSInput input = new DomLSInput();
174: input.setSystemId(uri);
175: return parse(input);
176: }
177:
178: public Node parseWithContext(LSInput input, Node context, short action)
179: throws DOMException, LSException
180: {
181: Document doc = (context.getNodeType() == Node.DOCUMENT_NODE) ?
182: (Document) context : context.getOwnerDocument();
183: input.setBaseURI(doc.getDocumentURI());
184:
185: Document ret = parse(input);
186: Node root = ret.getDocumentElement();
187: root = doc.adoptNode(root);
188: switch (action)
189: {
190: case ACTION_APPEND_AS_CHILDREN:
191: context.appendChild(root);
192: break;
193: case ACTION_REPLACE_CHILDREN:
194: Node c1 = context.getFirstChild();
195: while (c1 != null)
196: {
197: Node next = c1.getNextSibling();
198: context.removeChild(c1);
199: c1 = next;
200: }
201: context.appendChild(root);
202: break;
203: case ACTION_INSERT_BEFORE:
204: Node p1 = context.getParentNode();
205: p1.insertBefore(root, context);
206: break;
207: case ACTION_INSERT_AFTER:
208: Node p2 = context.getParentNode();
209: Node r1 = context.getNextSibling();
210: if (r1 == null)
211: {
212: p2.appendChild(root);
213: }
214: else
215: {
216: p2.insertBefore(root, r1);
217: }
218: break;
219: case ACTION_REPLACE:
220: Node p3 = context.getParentNode();
221: Node r2 = context.getNextSibling();
222: p3.removeChild(context);
223: if (r2 == null)
224: {
225: p3.appendChild(root);
226: }
227: else
228: {
229: p3.insertBefore(root, r2);
230: }
231: break;
232: }
233: return root;
234: }
235:
236: public void abort()
237: {
238: if (eventSink != null)
239: {
240: eventSink.interrupt();
241: }
242: }
243:
244: private Document doParse(LSInput input)
245: throws DOMException, LSException
246: {
247:
248: if (eventSink != null)
249: {
250: throw new LSException(LSException.PARSE_ERR, "parse in progress");
251: }
252: InputSource source = getInputSource(input);
253: eventSink = (filter == null) ? new SAXEventSink() :
254: new FilteredSAXEventSink(filter);
255:
256: eventSink.setNamespaceAware(namespaceAware);
257: eventSink.ignoreWhitespace = ignoreWhitespace;
258: eventSink.expandEntityReferences = expandEntityReferences;
259: eventSink.ignoreComments = ignoreComments;
260: eventSink.coalescing = coalescing;
261:
262: XMLReader reader = getXMLReader();
263: eventSink.reader = reader;
264: try
265: {
266: reader.setContentHandler(eventSink);
267: reader.setDTDHandler(eventSink);
268: reader.setProperty("http://xml.org/sax/properties/lexical-handler",
269: eventSink);
270: reader.setProperty("http://xml.org/sax/properties/declaration-handler",
271: eventSink);
272: reader.setFeature("http://xml.org/sax/features/namespaces",
273: namespaceAware);
274: reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
275: true);
276: reader.setFeature("http://xml.org/sax/features/validation",
277: validating);
278: try
279: {
280: reader.setFeature("http://gnu.org/sax/features/coalescing",
281: coalescing);
282: }
283: catch (SAXNotRecognizedException e)
284: {
285:
286: }
287: try
288: {
289: reader.setFeature("http://xml.org/sax/features/use-attributes2",
290: true);
291: }
292: catch (SAXNotRecognizedException e)
293: {
294:
295: }
296: try
297: {
298: reader.setFeature("http://xml.org/sax/features/external-general-entities",
299: true);
300: }
301: catch (SAXNotRecognizedException e)
302: {
303:
304: }
305: reader.setEntityResolver(entityResolver);
306: reader.setErrorHandler(errorHandler);
307:
308: reader.parse(source);
309: }
310: catch (DOMException e)
311: {
312: reader = null;
313: eventSink = null;
314: throw e;
315: }
316: catch (SAXException e)
317: {
318: reader = null;
319: eventSink = null;
320: throw new DomLSException(LSException.PARSE_ERR, e);
321: }
322: catch (IOException e)
323: {
324: reader = null;
325: eventSink = null;
326: throw new DomLSException(LSException.PARSE_ERR, e);
327: }
328:
329: Document ret = eventSink.doc;
330: String systemId = input.getSystemId();
331: if (systemId != null && ret instanceof DomDocument)
332: {
333: ((DomDocument) ret).setDocumentURI(systemId);
334: }
335: eventSink = null;
336: return ret;
337: }
338:
339: private XMLReader getXMLReader()
340: throws LSException
341: {
342: if (reader == null)
343: {
344: factory.setNamespaceAware(namespaceAware);
345: factory.setValidating(validating);
346: factory.setXIncludeAware(xIncludeAware);
347: try
348: {
349: SAXParser parser = factory.newSAXParser();
350: reader = parser.getXMLReader();
351: }
352: catch (ParserConfigurationException e)
353: {
354: throw new DomLSException(LSException.PARSE_ERR, e);
355: }
356: catch (SAXException e)
357: {
358: throw new DomLSException(LSException.PARSE_ERR, e);
359: }
360: }
361: return reader;
362: }
363:
364: private InputSource getInputSource(LSInput input)
365: throws LSException
366: {
367: InputSource source = null;
368: String systemId = input.getSystemId();
369: InputStream in = input.getByteStream();
370: if (in != null)
371: {
372: source = new InputSource(in);
373: source.setSystemId(systemId);
374: }
375: if (source == null)
376: {
377: URL url = null;
378: String base = input.getBaseURI();
379: try
380: {
381: try
382: {
383: URL baseURL = (base == null) ? null : new URL(base);
384: url = (baseURL == null) ? new URL(systemId) :
385: new URL(baseURL, systemId);
386: }
387: catch (MalformedURLException e)
388: {
389: File baseFile = (base == null) ? null : new File(base);
390: url = (baseFile == null) ? new File(systemId).toURL() :
391: new File(baseFile, systemId).toURL();
392: }
393: in = url.openStream();
394: systemId = url.toString();
395: source = new InputSource(in);
396: source.setSystemId(systemId);
397: }
398: catch (IOException e)
399: {
400: throw new DomLSException(LSException.PARSE_ERR, e);
401: }
402: }
403: return source;
404: }
405:
406:
407:
408: public void setParameter(String name, Object value)
409: throws DOMException
410: {
411: name = name.toLowerCase();
412: if ("cdata-sections".equals(name))
413: {
414: coalescing = !((Boolean) value).booleanValue();
415: }
416: else if ("comments".equals(name))
417: {
418: ignoreComments = !((Boolean) value).booleanValue();
419: }
420: else if ("element-content-whitespace".equals(name))
421: {
422: ignoreWhitespace = !((Boolean) value).booleanValue();
423: }
424: else if ("namespaces".equals(name))
425: {
426: namespaceAware = ((Boolean) value).booleanValue();
427: }
428: else if ("expand-entity-references".equals(name))
429: {
430: expandEntityReferences = ((Boolean) value).booleanValue();
431: }
432: else if ("coalescing".equals(name))
433: {
434: coalescing = ((Boolean) value).booleanValue();
435: }
436: else if ("validating".equals(name))
437: {
438: validating = ((Boolean) value).booleanValue();
439: }
440: else if ("xinclude-aware".equals(name))
441: {
442: xIncludeAware = ((Boolean) value).booleanValue();
443: }
444: else if ("entity-resolver".equals(name))
445: {
446: entityResolver = (EntityResolver) value;
447: }
448: else if ("error-handler".equals(name))
449: {
450: errorHandler = (ErrorHandler) value;
451: }
452: else
453: {
454: throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
455: }
456:
457: reader = null;
458: }
459:
460: public Object getParameter(String name)
461: throws DOMException
462: {
463: name = name.toLowerCase();
464: if ("cdata-sections".equals(name))
465: {
466: return coalescing ? Boolean.FALSE : Boolean.TRUE;
467: }
468: else if ("comments".equals(name))
469: {
470: return ignoreComments ? Boolean.FALSE : Boolean.TRUE;
471: }
472: else if ("element-content-whitespace".equals(name))
473: {
474: return ignoreWhitespace ? Boolean.FALSE : Boolean.TRUE;
475: }
476: else if ("namespaces".equals(name))
477: {
478: return namespaceAware ? Boolean.TRUE : Boolean.FALSE;
479: }
480: else if ("expand-entity-references".equals(name))
481: {
482: return expandEntityReferences ? Boolean.TRUE : Boolean.FALSE;
483: }
484: else if ("coalescing".equals(name))
485: {
486: return coalescing ? Boolean.TRUE : Boolean.FALSE;
487: }
488: else if ("validating".equals(name))
489: {
490: return validating ? Boolean.TRUE : Boolean.FALSE;
491: }
492: else if ("xinclude-aware".equals(name))
493: {
494: return xIncludeAware ? Boolean.TRUE : Boolean.FALSE;
495: }
496: else if ("entity-resolver".equals(name))
497: {
498: return entityResolver;
499: }
500: else if ("error-handler".equals(name))
501: {
502: return errorHandler;
503: }
504: else
505: {
506: throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
507: }
508: }
509:
510: public boolean canSetParameter(String name, Object value)
511: {
512: return contains(name);
513: }
514:
515: public DOMStringList getParameterNames()
516: {
517: return this;
518: }
519:
520:
521:
522: public String item(int i)
523: {
524: return (String) SUPPORTED_PARAMETERS.get(i);
525: }
526:
527: public int getLength()
528: {
529: return SUPPORTED_PARAMETERS.size();
530: }
531:
532: public boolean contains(String str)
533: {
534: return SUPPORTED_PARAMETERS.contains(str);
535: }
536:
537:
538:
539: public void warning(SAXParseException e)
540: throws SAXException
541: {
542: if (errorHandler != null)
543: {
544: errorHandler.warning(e);
545: }
546: }
547:
548: public void error(SAXParseException e)
549: throws SAXException
550: {
551: if (errorHandler != null)
552: {
553: errorHandler.error(e);
554: }
555: }
556:
557: public void fatalError(SAXParseException e)
558: throws SAXException
559: {
560: if (errorHandler != null)
561: {
562: errorHandler.fatalError(e);
563: }
564: abort();
565: }
566:
567: }