001    /*
002    * Copyright (c) 2003-2004 Yrjö Kari-Koskinen, Taavi Hupponen
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    package fi.iki.hsivonen.xml;
023    
024    import gnu.xml.pipeline.EventConsumer;
025    import gnu.xml.pipeline.EventFilter;
026    
027    import java.util.Arrays;
028    
029    import org.xml.sax.Attributes;
030    import org.xml.sax.SAXException;
031    
032    /**
033     * SAX-filtteri, jolla voi jättää pois halutut elementit
034     * (elementNames-taulukossa) tai sisällyttää vain halutut elementit. 
035     * Toiminta määräytyy boolean drop -parametrin perusteella.
036     *
037     * 
038     * 
039     * MUISTA ETTÄ ARRAYN TÄYTYY OLLA JÄRJESTETTY!
040     * 
041     *
042     * @author ykk@kallio.tky.hut.fi
043     */
044    public class ElementDropper extends EventFilter {
045    
046        /** 
047         * Jos drop on true, jätetään elementNames-taulukon elementit
048         * pois. Jos drop on false, sisällytetään vain
049         * elementNames-taulukon elementit ja kaikki muut jätetään pois.
050         */
051        private boolean drop;
052    
053        /**
054         * Tarkistetaanko onko namespace xhtml-namespace.
055         */
056        private boolean checkNS;
057    
058        /** 
059         * Sisällytettävät tai poisjätettävät elementtinimet, esim "body"
060         * ja "title".
061         */
062        private String[] elementNames;
063    
064        /**
065         * Luo uuden ElementDropperin. Jos haluat pudottaa body-elementin,
066         * niin luo uusi filtteri näin: <pre> new ElementDropper(nextFilter,
067         * new String[] { "body" }, true); </pre>
068         * @param next seuraava filtteri
069             * @param elementNames sisällytettävät tai poisjätettävät
070             * elementtinimet, esim "body" ja "title".
071             * @param drop määrää, pudotetaanko (true) elementNamesin
072             * elementit vai sisällytetäänkö ne (false)
073             */
074        public ElementDropper(EventConsumer next, String[] elementNames, boolean drop) {
075            this(next, elementNames, drop, true);
076        }
077    
078        /**
079             * Luo uuden ElementDropperin. Jos haluat pudottaa body-elementin,
080             * niin luo uusi filtteri näin: <pre> new ElementDropper(nextFilter,
081             * new String[] { "body" }, true); </pre>
082             * @param next seuraava filtteri
083             * @param elementNames sisällytettävät tai poisjätettävät
084             * elementtinimet, esim "body" ja "title".
085             * @param drop määrää, pudotetaanko (true) elementNamesin
086             * elementit vai sisällytetäänkö ne (false)
087             * @param checkNS tarkistetaanko pudotettavien elementtien NS
088             * 
089             * 
090             */
091        public ElementDropper(EventConsumer next, String[] elementNames, boolean drop, boolean checkNS) {
092            super(next);
093            setContentHandler(this);
094            this.elementNames = elementNames;
095            this.drop = drop;
096            this.checkNS = checkNS;
097            setContentHandler(this);
098        }
099    
100        public void endElement(String uri, String local, String qname) throws SAXException {
101    
102            if ((!checkNS || "http://www.w3.org/1999/xhtml".equals(uri))
103                && ((drop && Arrays.binarySearch(elementNames, local) < 0)
104                    || (!drop && Arrays.binarySearch(elementNames, local) >= 0))) {
105                super.endElement(uri, local, qname);
106            }
107        }
108    
109        public void startElement(String uri, String local, String qname, Attributes attributes) throws SAXException {
110    
111            if ((!checkNS || "http://www.w3.org/1999/xhtml".equals(uri))
112                && ((drop && Arrays.binarySearch(elementNames, local) < 0)
113                    || (!drop && Arrays.binarySearch(elementNames, local) >= 0))) {
114                super.startElement(uri, local, qname, attributes);
115            }
116        }
117    }