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