OSDN Git Service

* external/w3c_dom/Makefile.am: New file.
[pf3gnuchains/gcc-fork.git] / libjava / gnu / xml / dom / ls / FilteredSAXEventSink.java
1 /* FilteredSAXEventSink.java -- 
2    Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 package gnu.xml.dom.ls;
39
40 import java.util.LinkedList;
41 import org.w3c.dom.Attr;
42 import org.w3c.dom.Element;
43 import org.w3c.dom.Node;
44 import org.w3c.dom.Text;
45 import org.w3c.dom.ls.LSParserFilter;
46 import org.w3c.dom.traversal.NodeFilter;
47 import org.xml.sax.Attributes;
48 import org.xml.sax.SAXException;
49
50 /**
51  * A SAX event sink that calls out to a parser filter in order to decide
52  * whether to insert nodes into the tree.
53  *
54  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
55  */
56 class FilteredSAXEventSink
57   extends SAXEventSink
58 {
59
60   final LSParserFilter filter;
61   final int whatToShow;
62
63   /**
64    * Stack of elements to insert.
65    */
66   LinkedList nodes;
67   
68   /**
69    * Corresponding stack of filter decisions about the nodes.
70    */
71   LinkedList decisions;
72
73   /**
74    * True when rejecting child nodes.
75    */
76   boolean rejecting;
77
78   FilteredSAXEventSink(LSParserFilter filter)
79   {
80     this.filter = filter;
81     whatToShow = filter.getWhatToShow();
82   }
83
84   public void startDocument()
85     throws SAXException
86   {
87     if (interrupted)
88       {
89         return;
90       }
91     nodes = new LinkedList();
92     decisions = new LinkedList();
93     
94     super.startDocument();
95   }
96
97   public void endDocument()
98     throws SAXException
99   {
100     if (interrupted)
101       {
102         return;
103       }
104     super.endDocument();
105
106     switch (getDecision(ctx, false))
107       {
108       case LSParserFilter.FILTER_REJECT:
109         ctx = null;
110         doc = null;
111         break;
112       }
113     
114     nodes = null;
115     decisions = null;
116   }
117
118   public void startElement(String uri, String localName, String qName,
119                            Attributes atts)
120     throws SAXException
121   {
122     if (rejecting || interrupted)
123       {
124         return;
125       }
126     Element element = createElement(uri, localName, qName, atts);
127     ctx = element;
128     
129     short decision = getDecision(element, true);
130     nodes.addLast(element);
131     decisions.addLast(new Short(decision));
132
133     switch (decision)
134       {
135       case LSParserFilter.FILTER_REJECT:
136         rejecting = true;
137         break;
138       case LSParserFilter.FILTER_INTERRUPT:
139         interrupted = true;
140         break;
141       }
142   }
143
144   protected Attr createAttr(Attributes atts, int index)
145   {
146     Attr attr = super.createAttr(atts, index);
147     short decision = getDecision(attr, false);
148     switch (decision)
149       {
150       case LSParserFilter.FILTER_REJECT:
151         return null;
152       case LSParserFilter.FILTER_INTERRUPT:
153         interrupted = true;
154         return null;
155       }
156     return attr;
157   }
158
159   public void endElement(String uri, String localName, String qName)
160     throws SAXException
161   {
162     if (rejecting || interrupted)
163       {
164         return;
165       }
166     super.endElement(uri, localName, qName);
167     
168     Element element = (Element) nodes.removeLast();
169     Node parent = nodes.isEmpty() ? doc : (Node) nodes.getLast();
170     ctx = parent;
171     short decision = ((Short) decisions.removeLast()).shortValue();
172     switch (decision)
173       {
174       case LSParserFilter.FILTER_SKIP:
175         // Add all children of element to parent
176         for (Node child = element.getFirstChild(); child != null;
177              child = child.getNextSibling())
178           {
179             parent.insertBefore(child, element);
180           }
181         return;
182       case LSParserFilter.FILTER_REJECT:
183         rejecting = false;
184         break;
185       }
186     decision = getDecision(element, false);
187     switch (decision)
188       {
189       case LSParserFilter.FILTER_ACCEPT:
190         parent.appendChild(element);
191         break;
192       case LSParserFilter.FILTER_INTERRUPT:
193         interrupted = true;
194         break;
195       }
196   }
197
198   public void characters(char[] c, int off, int len)
199     throws SAXException
200   {
201     if (rejecting || interrupted)
202       {
203         return;
204       }
205     Text text = createText(c, off, len);
206     short decision = getDecision(text, false);
207     switch (decision)
208       {
209       case LSParserFilter.FILTER_ACCEPT:
210         ctx.appendChild(text);
211         break;
212       case LSParserFilter.FILTER_INTERRUPT:
213         interrupted = true;
214         break;
215       }
216   }
217
218   public void processingInstruction(String target, String data)
219     throws SAXException
220   {
221     if (rejecting || interrupted || inDTD)
222       {
223         return;
224       }
225     Node pi = createProcessingInstruction(target, data);
226     short decision = getDecision(pi, false);
227     switch (decision)
228       {
229       case LSParserFilter.FILTER_ACCEPT:
230         ctx.appendChild(pi);
231         break;
232       case LSParserFilter.FILTER_INTERRUPT:
233         interrupted = true;
234         break;
235       }
236   }
237
238   public void startDTD(String name, String publicId, String systemId)
239     throws SAXException
240   {
241     if (interrupted)
242       {
243         return;
244       }
245     Node doctype = createDocumentType(name, publicId, systemId);
246     ctx = doctype;
247     inDTD = true;
248     nodes.addLast(doctype);
249     decisions.addLast(new Short(LSParserFilter.FILTER_ACCEPT));
250   }
251
252   public void endDTD()
253     throws SAXException
254   {
255     if (interrupted)
256       {
257         return;
258       }
259     Node doctype = (Node) nodes.removeLast();
260     decisions.removeLast();
261     inDTD = false;
262     ctx = doc;
263     short decision = getDecision(doctype, false);
264     switch (decision)
265       {
266       case LSParserFilter.FILTER_ACCEPT:
267         ctx.appendChild(doctype);
268         break;
269       case LSParserFilter.FILTER_INTERRUPT:
270         interrupted = true;
271         break;
272       }
273   }
274
275   public void comment(char[] c, int off, int len)
276     throws SAXException
277   {
278     if (rejecting || interrupted || inDTD)
279       {
280         return;
281       }
282     Node comment = createComment(c, off, len);
283     short decision = getDecision(comment, false);
284     switch (decision)
285       {
286       case LSParserFilter.FILTER_ACCEPT:
287         ctx.appendChild(comment);
288         break;
289       case LSParserFilter.FILTER_INTERRUPT:
290         interrupted = true;
291         break;
292       }
293   }
294
295   // TODO declarations
296
297   short getDecision(Node node, boolean start)
298   {
299     boolean show = (whatToShow == NodeFilter.SHOW_ALL);
300     if (!show)
301       {
302         switch (node.getNodeType())
303           {
304           case Node.ATTRIBUTE_NODE:
305             show = ((whatToShow & NodeFilter.SHOW_ATTRIBUTE) != 0);
306             break;     
307           case Node.TEXT_NODE:
308             show = ((whatToShow & NodeFilter.SHOW_TEXT) != 0);
309             break;     
310           case Node.CDATA_SECTION_NODE:
311             show = ((whatToShow & NodeFilter.SHOW_CDATA_SECTION) != 0);
312             break;     
313           case Node.ELEMENT_NODE:
314             show = ((whatToShow & NodeFilter.SHOW_ELEMENT) != 0);
315             break;     
316           case Node.COMMENT_NODE:
317             show = ((whatToShow & NodeFilter.SHOW_COMMENT) != 0);
318             break;     
319           case Node.DOCUMENT_NODE:
320             show = ((whatToShow & NodeFilter.SHOW_DOCUMENT) != 0);
321             break;     
322           case Node.PROCESSING_INSTRUCTION_NODE:
323             show = ((whatToShow & NodeFilter.SHOW_PROCESSING_INSTRUCTION) != 0);
324             break;     
325           case Node.DOCUMENT_FRAGMENT_NODE:
326             show = ((whatToShow & NodeFilter.SHOW_DOCUMENT_FRAGMENT) != 0);
327             break;     
328           case Node.DOCUMENT_TYPE_NODE:
329             show = ((whatToShow & NodeFilter.SHOW_DOCUMENT_TYPE) != 0);
330             break;     
331           case Node.ENTITY_REFERENCE_NODE:
332             show = ((whatToShow & NodeFilter.SHOW_ENTITY_REFERENCE) != 0);
333             break;     
334           case Node.ENTITY_NODE:
335             show = ((whatToShow & NodeFilter.SHOW_ENTITY) != 0);
336             break;     
337           case Node.NOTATION_NODE:
338             show = ((whatToShow & NodeFilter.SHOW_NOTATION) != 0);
339             break;     
340           }
341       }
342     if (!show)
343       {
344         return LSParserFilter.FILTER_ACCEPT;
345       }
346     if (start)
347       {
348         return filter.startElement((Element) node);
349       }
350     return filter.acceptNode(node);
351   }
352
353 }
354