1 /*
2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3  */
4 /*
5  * Licensed to the Apache Software Foundation (ASF) under one or more
6  * contributor license agreements.  See the NOTICE file distributed with
7  * this work for additional information regarding copyright ownership.
8  * The ASF licenses this file to You under the Apache License, Version 2.0
9  * (the "License"); you may not use this file except in compliance with
10  * the License.  You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 /*
21  * $Id: DOMWSFilter.java,v 1.2.4.1 2005/09/06 06:14:31 pvedula Exp $
22  */
23 package com.sun.org.apache.xalan.internal.xsltc.dom;
24 
25 import com.sun.org.apache.xalan.internal.xsltc.DOM;
26 import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
27 import com.sun.org.apache.xalan.internal.xsltc.StripFilter;
28 import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
29 import com.sun.org.apache.xml.internal.dtm.DTM;
30 import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
31 import java.util.HashMap;
32 import java.util.Map;
33 
34 /**
35  * A wrapper class that adapts the
36  * {@link com.sun.org.apache.xml.internal.dtm.DTMWSFilter DTMWSFilter} interface to the XSLTC
37  * DOM {@link com.sun.org.apache.xalan.internal.xsltc.StripFilter StripFilter} interface.
38  */
39 public class DOMWSFilter implements DTMWSFilter {
40 
41     private AbstractTranslet m_translet;
42     private StripFilter m_filter;
43 
44     // The Map for DTM to mapping array
45     private Map<DTM, short[]> m_mappings;
46 
47     // Cache the DTM and mapping that are used last time
48     private DTM m_currentDTM;
49     private short[] m_currentMapping;
50 
51     /**
52      * Construct an adapter connecting the <code>DTMWSFilter</code> interface
53      * to the <code>StripFilter</code> interface.
54      *
55      * @param translet A translet that also implements the StripFilter
56      * interface.
57      *
58      * @see com.sun.org.apache.xml.internal.dtm.DTMWSFilter
59      * @see com.sun.org.apache.xalan.internal.xsltc.StripFilter
60      */
DOMWSFilter(AbstractTranslet translet)61     public DOMWSFilter(AbstractTranslet translet) {
62         m_translet = translet;
63         m_mappings = new HashMap<>();
64 
65         if (translet instanceof StripFilter) {
66             m_filter = (StripFilter) translet;
67         }
68     }
69 
70     /**
71      * Test whether whitespace-only text nodes are visible in the logical
72      * view of <code>DTM</code>. Normally, this function
73      * will be called by the implementation of <code>DTM</code>;
74      * it is not normally called directly from
75      * user code.
76      *
77      * @param node int handle of the node.
78      * @param dtm the DTM that owns this node
79      * @return one of <code>NOTSTRIP</code>, <code>STRIP</code> or
80      * <code>INHERIT</code>.
81      */
getShouldStripSpace(int node, DTM dtm)82     public short getShouldStripSpace(int node, DTM dtm) {
83         if (m_filter != null && dtm instanceof DOM) {
84             DOM dom = (DOM)dtm;
85             int type = 0;
86 
87             if (dtm instanceof DOMEnhancedForDTM) {
88                 DOMEnhancedForDTM mappableDOM = (DOMEnhancedForDTM)dtm;
89 
90                 short[] mapping;
91                 if (dtm == m_currentDTM) {
92                     mapping = m_currentMapping;
93                 }
94                 else {
95                     mapping = m_mappings.get(dtm);
96                     if (mapping == null) {
97                         mapping = mappableDOM.getMapping(
98                                      m_translet.getNamesArray(),
99                                      m_translet.getUrisArray(),
100                                      m_translet.getTypesArray());
101                         m_mappings.put(dtm, mapping);
102                         m_currentDTM = dtm;
103                         m_currentMapping = mapping;
104                     }
105                 }
106 
107                 int expType = mappableDOM.getExpandedTypeID(node);
108 
109                 // %OPT% The mapping array does not have information about all the
110                 // exptypes. However it does contain enough information about all names
111                 // in the translet's namesArray. If the expType does not fall into the
112                 // range of the mapping array, it means that the expType is not for one
113                 // of the recognized names. In this case we can just set the type to -1.
114                 if (expType >= 0 && expType < mapping.length)
115                   type = mapping[expType];
116                 else
117                   type = -1;
118 
119             }
120             else {
121                 return INHERIT;
122             }
123 
124             if (m_filter.stripSpace(dom, node, type)) {
125                 return STRIP;
126             } else {
127                 return NOTSTRIP;
128             }
129         } else {
130             return NOTSTRIP;
131         }
132     }
133 }
134