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.namespaceAware = namespaceAware;
257: eventSink.ignoreWhitespace = ignoreWhitespace;
258: eventSink.expandEntityReferences = expandEntityReferences;
259: eventSink.ignoreComments = ignoreComments;
260: eventSink.coalescing = coalescing;
261:
262: XMLReader reader = getXMLReader();
263: try
264: {
265: reader.setContentHandler(eventSink);
266: reader.setDTDHandler(eventSink);
267: reader.setProperty("http://xml.org/sax/properties/lexical-handler",
268: eventSink);
269: reader.setProperty("http://xml.org/sax/properties/declaration-handler",
270: eventSink);
271: reader.setFeature("http://xml.org/sax/features/namespaces",
272: namespaceAware);
273: reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
274: true);
275: reader.setFeature("http://xml.org/sax/features/validation",
276: validating);
277: try
278: {
279: reader.setFeature("http://xml.org/sax/features/use-attributes2",
280: true);
281: }
282: catch (SAXNotRecognizedException e)
283: {
284:
285: }
286: try
287: {
288: reader.setFeature("http://xml.org/sax/features/external-general-entities",
289: true);
290: }
291: catch (SAXNotRecognizedException e)
292: {
293:
294: }
295: reader.setEntityResolver(entityResolver);
296: reader.setErrorHandler(errorHandler);
297:
298: reader.parse(source);
299: }
300: catch (DOMException e)
301: {
302: reader = null;
303: eventSink = null;
304: throw e;
305: }
306: catch (SAXException e)
307: {
308: reader = null;
309: eventSink = null;
310: throw new DomLSException(LSException.PARSE_ERR, e);
311: }
312: catch (IOException e)
313: {
314: reader = null;
315: eventSink = null;
316: throw new DomLSException(LSException.PARSE_ERR, e);
317: }
318:
319: Document ret = eventSink.doc;
320: String systemId = input.getSystemId();
321: if (systemId != null && ret instanceof DomDocument)
322: {
323: ((DomDocument) ret).setDocumentURI(systemId);
324: }
325: eventSink = null;
326: return ret;
327: }
328:
329: private XMLReader getXMLReader()
330: throws LSException
331: {
332: if (reader == null)
333: {
334: factory.setNamespaceAware(namespaceAware);
335: factory.setValidating(validating);
336: factory.setXIncludeAware(xIncludeAware);
337: try
338: {
339: SAXParser parser = factory.newSAXParser();
340: reader = parser.getXMLReader();
341: }
342: catch (ParserConfigurationException e)
343: {
344: throw new DomLSException(LSException.PARSE_ERR, e);
345: }
346: catch (SAXException e)
347: {
348: throw new DomLSException(LSException.PARSE_ERR, e);
349: }
350: }
351: return reader;
352: }
353:
354: private InputSource getInputSource(LSInput input)
355: throws LSException
356: {
357: InputSource source = null;
358: String systemId = input.getSystemId();
359: InputStream in = input.getByteStream();
360: if (in != null)
361: {
362: source = new InputSource(in);
363: source.setSystemId(systemId);
364: }
365: if (source == null && entityResolver != null)
366: {
367: String publicId = input.getPublicId();
368: try
369: {
370: source = entityResolver.resolveEntity(publicId, systemId);
371: }
372: catch (SAXException e)
373: {
374: throw new DomLSException(LSException.PARSE_ERR, e);
375: }
376: catch (IOException e)
377: {
378: throw new DomLSException(LSException.PARSE_ERR, e);
379: }
380: }
381: if (source == null)
382: {
383: URL url = null;
384: String base = input.getBaseURI();
385: try
386: {
387: try
388: {
389: URL baseURL = (base == null) ? null : new URL(base);
390: url = (baseURL == null) ? new URL(systemId) :
391: new URL(baseURL, systemId);
392: }
393: catch (MalformedURLException e)
394: {
395: File baseFile = (base == null) ? null : new File(base);
396: url = (baseFile == null) ? new File(systemId).toURL() :
397: new File(baseFile, systemId).toURL();
398: }
399: in = url.openStream();
400: systemId = url.toString();
401: source = new InputSource(in);
402: source.setSystemId(systemId);
403: }
404: catch (IOException e)
405: {
406: throw new DomLSException(LSException.PARSE_ERR, e);
407: }
408: }
409: return source;
410: }
411:
412:
413:
414: public void setParameter(String name, Object value)
415: throws DOMException
416: {
417: name = name.toLowerCase();
418: if ("cdata-sections".equals(name))
419: {
420: coalescing = !((Boolean) value).booleanValue();
421: }
422: else if ("comments".equals(name))
423: {
424: ignoreComments = !((Boolean) value).booleanValue();
425: }
426: else if ("element-content-whitespace".equals(name))
427: {
428: ignoreWhitespace = !((Boolean) value).booleanValue();
429: }
430: else if ("namespaces".equals(name))
431: {
432: namespaceAware = ((Boolean) value).booleanValue();
433: }
434: else if ("expand-entity-references".equals(name))
435: {
436: expandEntityReferences = ((Boolean) value).booleanValue();
437: }
438: else if ("coalescing".equals(name))
439: {
440: coalescing = ((Boolean) value).booleanValue();
441: }
442: else if ("validating".equals(name))
443: {
444: validating = ((Boolean) value).booleanValue();
445: }
446: else if ("xinclude-aware".equals(name))
447: {
448: xIncludeAware = ((Boolean) value).booleanValue();
449: }
450: else if ("entity-resolver".equals(name))
451: {
452: entityResolver = (EntityResolver) value;
453: }
454: else if ("error-handler".equals(name))
455: {
456: errorHandler = (ErrorHandler) value;
457: }
458: else
459: {
460: throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
461: }
462:
463: reader = null;
464: }
465:
466: public Object getParameter(String name)
467: throws DOMException
468: {
469: name = name.toLowerCase();
470: if ("cdata-sections".equals(name))
471: {
472: return coalescing ? Boolean.FALSE : Boolean.TRUE;
473: }
474: else if ("comments".equals(name))
475: {
476: return ignoreComments ? Boolean.FALSE : Boolean.TRUE;
477: }
478: else if ("element-content-whitespace".equals(name))
479: {
480: return ignoreWhitespace ? Boolean.FALSE : Boolean.TRUE;
481: }
482: else if ("namespaces".equals(name))
483: {
484: return namespaceAware ? Boolean.TRUE : Boolean.FALSE;
485: }
486: else if ("expand-entity-references".equals(name))
487: {
488: return expandEntityReferences ? Boolean.TRUE : Boolean.FALSE;
489: }
490: else if ("coalescing".equals(name))
491: {
492: return coalescing ? Boolean.TRUE : Boolean.FALSE;
493: }
494: else if ("validating".equals(name))
495: {
496: return validating ? Boolean.TRUE : Boolean.FALSE;
497: }
498: else if ("xinclude-aware".equals(name))
499: {
500: return xIncludeAware ? Boolean.TRUE : Boolean.FALSE;
501: }
502: else if ("entity-resolver".equals(name))
503: {
504: return entityResolver;
505: }
506: else if ("error-handler".equals(name))
507: {
508: return errorHandler;
509: }
510: else
511: {
512: throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
513: }
514: }
515:
516: public boolean canSetParameter(String name, Object value)
517: {
518: return contains(name);
519: }
520:
521: public DOMStringList getParameterNames()
522: {
523: return this;
524: }
525:
526:
527:
528: public String item(int i)
529: {
530: return (String) SUPPORTED_PARAMETERS.get(i);
531: }
532:
533: public int getLength()
534: {
535: return SUPPORTED_PARAMETERS.size();
536: }
537:
538: public boolean contains(String str)
539: {
540: return SUPPORTED_PARAMETERS.contains(str);
541: }
542:
543:
544:
545: public void warning(SAXParseException e)
546: throws SAXException
547: {
548: if (errorHandler != null)
549: {
550: errorHandler.warning(e);
551: }
552: }
553:
554: public void error(SAXParseException e)
555: throws SAXException
556: {
557: if (errorHandler != null)
558: {
559: errorHandler.error(e);
560: }
561: }
562:
563: public void fatalError(SAXParseException e)
564: throws SAXException
565: {
566: if (errorHandler != null)
567: {
568: errorHandler.fatalError(e);
569: }
570: abort();
571: }
572:
573: }