001    /*
002     * Copyright (c) 2007 Mozilla Foundation
003     *
004     * Permission is hereby granted, free of charge, to any person obtaining a 
005     * copy of this software and associated documentation files (the "Software"), 
006     * to deal in the Software without restriction, including without limitation 
007     * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
008     * and/or sell copies of the Software, and to permit persons to whom the 
009     * Software is furnished to do so, subject to the following conditions:
010     *
011     * The above copyright notice and this permission notice shall be included in 
012     * all copies or substantial portions of the Software.
013     *
014     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
015     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
016     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
017     * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
018     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
019     * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
020     * DEALINGS IN THE SOFTWARE.
021     */
022    
023    package nu.validator.xml;
024    
025    import java.io.IOException;
026    
027    import org.xml.sax.ContentHandler;
028    import org.xml.sax.DTDHandler;
029    import org.xml.sax.EntityResolver;
030    import org.xml.sax.ErrorHandler;
031    import org.xml.sax.InputSource;
032    import org.xml.sax.SAXException;
033    import org.xml.sax.SAXNotRecognizedException;
034    import org.xml.sax.SAXNotSupportedException;
035    import org.xml.sax.XMLReader;
036    import org.xml.sax.ext.LexicalHandler;
037    
038    public class WiretapXMLReaderWrapper implements XMLReader {
039    
040        private final XMLReader wrappedReader;
041    
042        private ContentHandler contentHandler;
043    
044        private ContentHandler wiretapContentHander;
045    
046        private LexicalHandler lexicalHandler;
047    
048        private LexicalHandler wiretapLexicalHandler;
049    
050        /**
051         * @param wrappedReader
052         */
053        public WiretapXMLReaderWrapper(final XMLReader wrappedReader) {
054            this.wrappedReader = wrappedReader;
055            contentHandler = wrappedReader.getContentHandler();
056            try {
057                lexicalHandler = (LexicalHandler) wrappedReader.getProperty("http://xml.org/sax/properties/lexical-handler");
058            } catch (SAXNotRecognizedException e) {
059            } catch (SAXNotSupportedException e) {
060            }
061        }
062    
063        /**
064         * Sets the wiretapContentHander.
065         * 
066         * @param wiretapContentHander
067         *            the wiretapContentHander to set
068         */
069        public void setWiretapContentHander(ContentHandler wiretapContentHander) {
070            this.wiretapContentHander = wiretapContentHander;
071            updateWiretap();
072        }
073    
074        /**
075         * Sets the wiretapLexicalHandler.
076         * 
077         * @param wiretapLexicalHandler
078         *            the wiretapLexicalHandler to set
079         */
080        public void setWiretapLexicalHandler(LexicalHandler wiretapLexicalHandler) {
081            this.wiretapLexicalHandler = wiretapLexicalHandler;
082            updateWiretap();
083        }
084    
085        /**
086         * @return
087         * @see org.xml.sax.XMLReader#getContentHandler()
088         */
089        public ContentHandler getContentHandler() {
090            return contentHandler;
091        }
092    
093        /**
094         * @return
095         * @see org.xml.sax.XMLReader#getDTDHandler()
096         */
097        public DTDHandler getDTDHandler() {
098            return wrappedReader.getDTDHandler();
099        }
100    
101        /**
102         * @return
103         * @see org.xml.sax.XMLReader#getEntityResolver()
104         */
105        public EntityResolver getEntityResolver() {
106            return wrappedReader.getEntityResolver();
107        }
108    
109        /**
110         * @return
111         * @see org.xml.sax.XMLReader#getErrorHandler()
112         */
113        public ErrorHandler getErrorHandler() {
114            return wrappedReader.getErrorHandler();
115        }
116    
117        /**
118         * @param arg0
119         * @return
120         * @throws SAXNotRecognizedException
121         * @throws SAXNotSupportedException
122         * @see org.xml.sax.XMLReader#getFeature(java.lang.String)
123         */
124        public boolean getFeature(String arg0) throws SAXNotRecognizedException,
125                SAXNotSupportedException {
126            return wrappedReader.getFeature(arg0);
127        }
128    
129        /**
130         * @param name
131         * @return
132         * @throws SAXNotRecognizedException
133         * @throws SAXNotSupportedException
134         * @see org.xml.sax.XMLReader#getProperty(java.lang.String)
135         */
136        public Object getProperty(String name) throws SAXNotRecognizedException,
137                SAXNotSupportedException {
138            if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
139                return lexicalHandler;
140            } else {
141                return wrappedReader.getProperty(name);
142            }
143        }
144    
145        /**
146         * @param arg0
147         * @throws IOException
148         * @throws SAXException
149         * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
150         */
151        public void parse(InputSource arg0) throws IOException, SAXException {
152            wrappedReader.parse(arg0);
153        }
154    
155        /**
156         * @param arg0
157         * @throws IOException
158         * @throws SAXException
159         * @see org.xml.sax.XMLReader#parse(java.lang.String)
160         */
161        public void parse(String arg0) throws IOException, SAXException {
162            wrappedReader.parse(arg0);
163        }
164    
165        /**
166         * @param arg0
167         * @see org.xml.sax.XMLReader#setContentHandler(org.xml.sax.ContentHandler)
168         */
169        public void setContentHandler(ContentHandler contentHandler) {
170            this.contentHandler = contentHandler;
171            updateWiretap();
172        }
173    
174        /**
175         * @param arg0
176         * @see org.xml.sax.XMLReader#setDTDHandler(org.xml.sax.DTDHandler)
177         */
178        public void setDTDHandler(DTDHandler arg0) {
179            wrappedReader.setDTDHandler(arg0);
180        }
181    
182        /**
183         * @param arg0
184         * @see org.xml.sax.XMLReader#setEntityResolver(org.xml.sax.EntityResolver)
185         */
186        public void setEntityResolver(EntityResolver arg0) {
187            wrappedReader.setEntityResolver(arg0);
188        }
189    
190        /**
191         * @param arg0
192         * @see org.xml.sax.XMLReader#setErrorHandler(org.xml.sax.ErrorHandler)
193         */
194        public void setErrorHandler(ErrorHandler arg0) {
195            wrappedReader.setErrorHandler(arg0);
196        }
197    
198        /**
199         * @param arg0
200         * @param arg1
201         * @throws SAXNotRecognizedException
202         * @throws SAXNotSupportedException
203         * @see org.xml.sax.XMLReader#setFeature(java.lang.String, boolean)
204         */
205        public void setFeature(String arg0, boolean arg1)
206                throws SAXNotRecognizedException, SAXNotSupportedException {
207            wrappedReader.setFeature(arg0, arg1);
208        }
209    
210        /**
211         * @param name
212         * @param value
213         * @throws SAXNotRecognizedException
214         * @throws SAXNotSupportedException
215         * @see org.xml.sax.XMLReader#setProperty(java.lang.String,
216         *      java.lang.Object)
217         */
218        public void setProperty(String name, Object value)
219                throws SAXNotRecognizedException, SAXNotSupportedException {
220            if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
221                lexicalHandler = (LexicalHandler) value;
222                updateWiretap();
223            } else {
224                wrappedReader.setProperty(name, value);
225            }
226        }
227    
228        private void updateWiretap() {
229            if (contentHandler != null) {
230                if (wiretapContentHander != null) {
231                    wrappedReader.setContentHandler(new CombineContentHandler(
232                            wiretapContentHander, contentHandler));
233                } else {
234                    wrappedReader.setContentHandler(contentHandler);
235                }
236            } else {
237                wrappedReader.setContentHandler(wiretapContentHander);
238            }
239    
240            try {
241                if (lexicalHandler != null) {
242                    if (wiretapLexicalHandler != null) {
243                        wrappedReader.setProperty(
244                                "http://xml.org/sax/properties/lexical-handler",
245                                new CombineLexicalHandler(wiretapLexicalHandler,
246                                        lexicalHandler));
247                    } else {
248                        wrappedReader.setProperty(
249                                "http://xml.org/sax/properties/lexical-handler",
250                                lexicalHandler);
251                    }
252                } else {
253                    wrappedReader.setProperty(
254                            "http://xml.org/sax/properties/lexical-handler",
255                            wiretapLexicalHandler);
256                }
257            } catch (SAXNotRecognizedException e) {
258            } catch (SAXNotSupportedException e) {
259            }
260        }
261    
262    }