View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.portletbridge.xsl;
17  
18  import java.util.LinkedList;
19  
20  import org.xml.sax.Attributes;
21  import org.xml.sax.ContentHandler;
22  import org.xml.sax.Locator;
23  import org.xml.sax.SAXException;
24  
25  import EDU.oswego.cs.dl.util.concurrent.Callable;
26  
27  /***
28   * @author JMcCrindle
29   */
30  public class QueuingContentHandler implements ContentHandler {
31  
32      private LinkedList events = null;
33      private ContentHandler contentHandler = null;
34      private boolean queuing = false;
35      private Object lock = new Object();
36      
37      public QueuingContentHandler(ContentHandler contentHandler) {
38          this.contentHandler = contentHandler;
39      }
40  
41      public void enqueue(Callable callable) throws SAXException {
42          synchronized(lock) {
43              if(queuing) {
44                  events.addLast(callable);
45              } else {
46                  run(callable);
47              }
48          }
49      }
50      
51      public void run(Callable callable) throws SAXException {
52          synchronized(lock) {
53              try {
54                  callable.call();
55              } catch (SAXException e) {
56                  throw e;
57              } catch (Exception e) {
58                  throw new SAXException(e);
59              }
60          }
61      }
62      
63      public void stopQueuing() throws SAXException {
64          synchronized(lock) {
65              while(events.size() > 0) {
66                  Callable callable = (Callable) events.removeFirst();
67                  run(callable);
68              }
69              queuing = false;
70          }
71      }
72      
73      public void startQueuing() throws SAXException {
74          synchronized(lock) {
75              queuing = true;
76          }
77      }
78      
79      /* (non-Javadoc)
80       * @see org.xml.sax.ContentHandler#startDocument()
81       */
82      public void startDocument() throws SAXException {
83          synchronized(lock) {
84              events = new LinkedList();
85          }
86          enqueue(new Callable() {
87              public Object call() throws Exception {
88                  contentHandler.startDocument();
89                  return null;
90              }
91          });
92      }
93  
94      /* (non-Javadoc)
95       * @see org.xml.sax.ContentHandler#endDocument()
96       */
97      public void endDocument() throws SAXException {
98          enqueue(new Callable() {
99              public Object call() throws Exception {
100                 contentHandler.endDocument();
101                 return null;
102             }
103         });
104         synchronized(lock) {
105             if(queuing) {
106                 stopQueuing();
107                 startQueuing();
108             }
109         }
110     }
111 
112     /* (non-Javadoc)
113      * @see org.xml.sax.ContentHandler#characters(char[], int, int)
114      */
115     public void characters(char[] ch, int start, final int length) throws SAXException {
116         final char[] copy = new char[length];
117         System.arraycopy(ch, start, copy, 0, length);
118         enqueue(new Callable() {
119             public Object call() throws Exception {
120                 contentHandler.characters(copy, 0, length);
121                 return null;
122             }
123         });
124     }
125 
126     /* (non-Javadoc)
127      * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
128      */
129     public void ignorableWhitespace(char[] ch, int start, final int length) throws SAXException {
130         final char[] copy = new char[length];
131         System.arraycopy(ch, start, copy, 0, length);
132         enqueue(new Callable() {
133             public Object call() throws Exception {
134                 contentHandler.ignorableWhitespace(copy, 0, length);
135                 return null;
136             }
137         });
138     }
139 
140     /* (non-Javadoc)
141      * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
142      */
143     public void endPrefixMapping(final String prefix) throws SAXException {
144         enqueue(new Callable() {
145             public Object call() throws Exception {
146                 contentHandler.endPrefixMapping(prefix);
147                 return null;
148             }
149         });
150     }
151 
152     /* (non-Javadoc)
153      * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
154      */
155     public void skippedEntity(final String name) throws SAXException {
156         enqueue(new Callable() {
157             public Object call() throws Exception {
158                 contentHandler.skippedEntity(name);
159                 return null;
160             }
161         });
162     }
163 
164     /* (non-Javadoc)
165      * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
166      */
167     public void setDocumentLocator(Locator locator) {
168         contentHandler.setDocumentLocator(locator);
169     }
170 
171     /* (non-Javadoc)
172      * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
173      */
174     public void processingInstruction(final String target, final String data) throws SAXException {
175         enqueue(new Callable() {
176             public Object call() throws Exception {
177                 contentHandler.processingInstruction(target, data);
178                 return null;
179             }
180         });
181     }
182 
183     /* (non-Javadoc)
184      * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
185      */
186     public void startPrefixMapping(final String prefix, final String uri) throws SAXException {
187         enqueue(new Callable() {
188             public Object call() throws Exception {
189                 contentHandler.startPrefixMapping(prefix, uri);
190                 return null;
191             }
192         });
193     }
194 
195     /* (non-Javadoc)
196      * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
197      */
198     public void endElement(final String namespaceURI, final String localName, final String qName) throws SAXException {
199         enqueue(new Callable() {
200             public Object call() throws Exception {
201                 contentHandler.endElement(namespaceURI, localName, qName);
202                 return null;
203             }
204         });
205     }
206 
207     /* (non-Javadoc)
208      * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
209      */
210     public void startElement(final String namespaceURI, final String localName, final String qName, final Attributes atts) throws SAXException {
211         enqueue(new Callable() {
212             public Object call() throws Exception {
213                 contentHandler.startElement(namespaceURI, localName, qName, atts);
214                 return null;
215             }
216         });
217     }
218 
219     public ContentHandler getContentHandler() {
220         return contentHandler;
221     }
222 }