001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: DOMWSFilter.java 468651 2006-10-28 07:04:25Z minchau $
020     */
021    package org.apache.xalan.xsltc.dom;
022    
023    import org.apache.xalan.xsltc.DOM;
024    import org.apache.xalan.xsltc.DOMEnhancedForDTM;
025    import org.apache.xalan.xsltc.StripFilter;
026    import org.apache.xalan.xsltc.runtime.AbstractTranslet;
027    import org.apache.xalan.xsltc.runtime.Hashtable;
028    import org.apache.xml.dtm.DTM;
029    import org.apache.xml.dtm.DTMWSFilter;
030    
031    /**
032     * A wrapper class that adapts the
033     * {@link org.apache.xml.dtm.DTMWSFilter DTMWSFilter} interface to the XSLTC
034     * DOM {@link org.apache.xalan.xsltc.StripFilter StripFilter} interface.
035     */
036    public class DOMWSFilter implements DTMWSFilter {
037    
038        private AbstractTranslet m_translet;
039        private StripFilter m_filter;
040        
041        // The Hashtable for DTM to mapping array
042        private Hashtable m_mappings;
043        
044        // Cache the DTM and mapping that are used last time
045        private DTM m_currentDTM;
046        private short[] m_currentMapping;
047    
048        /**
049         * Construct an adapter connecting the <code>DTMWSFilter</code> interface
050         * to the <code>StripFilter</code> interface.
051         *
052         * @param translet A translet that also implements the StripFilter
053         * interface.
054         *
055         * @see org.apache.xml.dtm.DTMWSFilter
056         * @see org.apache.xalan.xsltc.StripFilter
057         */
058        public DOMWSFilter(AbstractTranslet translet) {
059            m_translet = translet;
060            m_mappings = new Hashtable();
061    
062            if (translet instanceof StripFilter) {
063                m_filter = (StripFilter) translet;
064            }
065        }
066    
067        /**
068         * Test whether whitespace-only text nodes are visible in the logical
069         * view of <code>DTM</code>. Normally, this function
070         * will be called by the implementation of <code>DTM</code>;
071         * it is not normally called directly from
072         * user code.
073         *
074         * @param node int handle of the node.
075         * @param dtm the DTM that owns this node
076         * @return one of <code>NOTSTRIP</code>, <code>STRIP</code> or
077         * <code>INHERIT</code>.
078         */
079        public short getShouldStripSpace(int node, DTM dtm) {
080            if (m_filter != null && dtm instanceof DOM) {
081                DOM dom = (DOM)dtm;
082                int type = 0;
083    
084                if (dtm instanceof DOMEnhancedForDTM) {
085                    DOMEnhancedForDTM mappableDOM = (DOMEnhancedForDTM)dtm;
086                    
087                    short[] mapping;
088                    if (dtm == m_currentDTM) {
089                        mapping = m_currentMapping;
090                    }
091                    else {  
092                        mapping = (short[])m_mappings.get(dtm);
093                        if (mapping == null) {
094                            mapping = mappableDOM.getMapping(
095                                         m_translet.getNamesArray(),
096                                         m_translet.getUrisArray(),
097                                         m_translet.getTypesArray());
098                            m_mappings.put(dtm, mapping);
099                            m_currentDTM = dtm;
100                            m_currentMapping = mapping;
101                        }
102                    }
103                    
104                    int expType = mappableDOM.getExpandedTypeID(node);
105                    
106                    // %OPT% The mapping array does not have information about all the
107                    // exptypes. However it does contain enough information about all names
108                    // in the translet's namesArray. If the expType does not fall into the
109                    // range of the mapping array, it means that the expType is not for one
110                    // of the recognized names. In this case we can just set the type to -1.
111                    if (expType >= 0 && expType < mapping.length)
112                      type = mapping[expType];
113                    else
114                      type = -1;
115                    
116                } 
117                else {
118                    return INHERIT;
119                }
120    
121                if (m_filter.stripSpace(dom, node, type)) {
122                    return STRIP;
123                } else {
124                    return NOTSTRIP;
125                }
126            } else {
127                return NOTSTRIP;
128            }
129        }
130    }