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: DOMAdapter.java 468651 2006-10-28 07:04:25Z minchau $
020     */
021    
022    package org.apache.xalan.xsltc.dom;
023    
024    import org.apache.xalan.xsltc.DOM;
025    import org.apache.xalan.xsltc.DOMEnhancedForDTM;
026    import org.apache.xalan.xsltc.StripFilter;
027    import org.apache.xalan.xsltc.TransletException;
028    import org.apache.xalan.xsltc.runtime.Hashtable;
029    import org.apache.xml.dtm.DTM;
030    import org.apache.xml.dtm.DTMAxisIterator;
031    import org.apache.xml.serializer.SerializationHandler;
032    
033    import org.w3c.dom.Node;
034    import org.w3c.dom.NodeList;
035    
036    /**
037     * @author Jacek Ambroziak
038     * @author Morten Jorgensen
039     */
040    public final class DOMAdapter implements DOM {
041    
042        // Mutually exclusive casting of DOM interface to known implementations
043        private DOMEnhancedForDTM _enhancedDOM;
044    
045        private DOM _dom;
046    
047        private String[] _namesArray;
048        private String[] _urisArray;
049        private int[]    _typesArray;
050        private String[] _namespaceArray;
051    
052        // Cached mappings
053        private short[] _mapping = null;
054        private int[]   _reverse = null;
055        private short[] _NSmapping = null;
056        private short[] _NSreverse = null;
057    
058        private StripFilter _filter = null;
059    
060        private int _multiDOMMask;
061        
062        public DOMAdapter(DOM dom,
063                          String[] namesArray,
064                          String[] urisArray,
065                          int[] typesArray,
066                          String[] namespaceArray) {
067            if (dom instanceof DOMEnhancedForDTM){
068                _enhancedDOM = (DOMEnhancedForDTM) dom;
069            }
070    
071            _dom = dom;
072            _namesArray = namesArray;
073            _urisArray = urisArray;
074            _typesArray = typesArray;
075            _namespaceArray = namespaceArray;
076        }
077    
078        public void setupMapping(String[] names, String[] urisArray,
079                                 int[] typesArray, String[] namespaces) {
080            _namesArray = names;
081            _urisArray = urisArray;
082            _typesArray = typesArray;
083            _namespaceArray = namespaces;
084        }
085        
086        public String[] getNamesArray() {
087            return _namesArray;
088        }
089        
090        public String[] getUrisArray() {
091            return _urisArray;
092        }
093        
094        public int[] getTypesArray() {
095            return _typesArray;
096        }
097        
098        public String[] getNamespaceArray() {
099            return _namespaceArray;
100        }
101        
102        public DOM getDOMImpl() {
103            return _dom;
104        }
105    
106        private short[] getMapping() {
107            if (_mapping == null) {
108                if (_enhancedDOM != null) {
109                    _mapping = _enhancedDOM.getMapping(_namesArray, _urisArray,
110                                                       _typesArray);
111                } 
112            }
113            return _mapping;
114        }
115    
116        private int[] getReverse() {
117            if (_reverse == null) {
118                if (_enhancedDOM != null) {
119                    _reverse = _enhancedDOM.getReverseMapping(_namesArray,
120                                                              _urisArray,
121                                                              _typesArray);
122                }
123            }
124            return _reverse;
125        }
126    
127        private short[] getNSMapping() {
128            if (_NSmapping == null) {
129                if (_enhancedDOM != null) {
130                    _NSmapping = _enhancedDOM.getNamespaceMapping(_namespaceArray);
131                }
132            }
133            return _NSmapping;
134        }
135    
136        private short[] getNSReverse() {
137            if (_NSreverse == null) {
138                if (_enhancedDOM != null) {
139                    _NSreverse = _enhancedDOM
140                                      .getReverseNamespaceMapping(_namespaceArray);
141                }
142            }
143            return _NSreverse;
144        }
145    
146        /** 
147          * Returns singleton iterator containg the document root 
148          */
149        public DTMAxisIterator getIterator() {
150            return _dom.getIterator();
151        }
152        
153        public String getStringValue() {
154            return _dom.getStringValue();
155        }
156        
157        public DTMAxisIterator getChildren(final int node) {
158            if (_enhancedDOM != null) {
159                return _enhancedDOM.getChildren(node);
160            }
161            else {
162                DTMAxisIterator iterator = _dom.getChildren(node);
163                return iterator.setStartNode(node);
164            }
165        }
166    
167        public void setFilter(StripFilter filter) {
168            _filter = filter;
169        }
170    
171        public DTMAxisIterator getTypedChildren(final int type) {
172            final int[] reverse = getReverse();
173    
174            if (_enhancedDOM != null) {
175                return _enhancedDOM.getTypedChildren(reverse[type]);
176            }
177            else {
178                return _dom.getTypedChildren(type);
179            }      
180        }
181    
182        public DTMAxisIterator getNamespaceAxisIterator(final int axis,
183                                                        final int ns) {
184            return _dom.getNamespaceAxisIterator(axis, getNSReverse()[ns]);
185        }
186    
187        public DTMAxisIterator getAxisIterator(final int axis) {
188            if (_enhancedDOM != null) {
189                return _enhancedDOM.getAxisIterator(axis);
190            }
191            else {
192                return _dom.getAxisIterator(axis);
193            }        
194        }
195        
196        public DTMAxisIterator getTypedAxisIterator(final int axis,
197                                                    final int type) {
198            final int[] reverse = getReverse();
199            if (_enhancedDOM != null) {
200                return _enhancedDOM.getTypedAxisIterator(axis, reverse[type]);
201            } else {
202                return _dom.getTypedAxisIterator(axis, type);
203            }      
204        }
205            
206        public int getMultiDOMMask() {
207            return _multiDOMMask;
208        }
209    
210        public void setMultiDOMMask(int mask) {
211            _multiDOMMask = mask;
212        }
213    
214        public DTMAxisIterator getNthDescendant(int type, int n,
215                                                boolean includeself) {
216            return _dom.getNthDescendant(getReverse()[type], n, includeself);
217        }
218    
219        public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iterator,
220                                                    int type, String value,
221                                                    boolean op) {
222            return _dom.getNodeValueIterator(iterator, type, value, op);
223        }
224    
225        public DTMAxisIterator orderNodes(DTMAxisIterator source, int node) {
226            return _dom.orderNodes(source, node);
227        }
228        
229        public int getExpandedTypeID(final int node) {
230            final short[] mapping = getMapping();
231            final int type;
232            if (_enhancedDOM != null) {
233                type = mapping[_enhancedDOM.getExpandedTypeID2(node)];
234            }
235            else {
236                    if(null != mapping)
237                    {
238                    type = mapping[_dom.getExpandedTypeID(node)];
239                    }
240                    else
241                    {
242                            type = _dom.getExpandedTypeID(node);
243                    }
244            }
245            return type;
246        }
247    
248        public int getNamespaceType(final int node) {
249            return getNSMapping()[_dom.getNSType(node)];
250        }
251    
252        public int getNSType(int node) {
253            return _dom.getNSType(node);
254        }
255        
256        public int getParent(final int node) {
257            return _dom.getParent(node);
258        }
259    
260        public int getAttributeNode(final int type, final int element) {
261            return _dom.getAttributeNode(getReverse()[type], element);
262        }
263        
264        public String getNodeName(final int node) {
265            if (node == DTM.NULL) {
266                return "";
267            }
268            return _dom.getNodeName(node);
269        }
270        
271        public String getNodeNameX(final int node) 
272        {
273            if (node == DTM.NULL) {
274                return "";
275            }
276            return _dom.getNodeNameX(node);
277        }
278    
279        public String getNamespaceName(final int node) 
280        {
281            if (node == DTM.NULL) {
282                return "";
283            }
284            return _dom.getNamespaceName(node);
285        }
286        
287        public String getStringValueX(final int node) 
288        {           
289            if (_enhancedDOM != null) {
290                return _enhancedDOM.getStringValueX(node);
291            }
292            else {
293                if (node == DTM.NULL) {
294                    return "";
295                }
296                return _dom.getStringValueX(node);
297            }
298        }
299        
300        public void copy(final int node, SerializationHandler handler)
301            throws TransletException 
302        {
303            _dom.copy(node, handler);
304        }
305        
306        public void copy(DTMAxisIterator nodes,SerializationHandler handler)
307            throws TransletException 
308        {
309            _dom.copy(nodes, handler);
310        }
311    
312        public String shallowCopy(final int node, SerializationHandler handler)
313            throws TransletException 
314        {
315            if (_enhancedDOM != null) {
316                return _enhancedDOM.shallowCopy(node, handler);
317            }
318            else {
319                return _dom.shallowCopy(node, handler);
320            }
321        }
322        
323        public boolean lessThan(final int node1, final int node2) 
324        {
325            return _dom.lessThan(node1, node2);
326        }
327        
328        public void characters(final int textNode, SerializationHandler handler)
329          throws TransletException 
330        {
331            if (_enhancedDOM != null) {
332                _enhancedDOM.characters(textNode, handler);
333            }
334            else {
335                _dom.characters(textNode, handler);
336            }
337        }
338    
339        public Node makeNode(int index) 
340        {
341            return _dom.makeNode(index);
342        }
343    
344        public Node makeNode(DTMAxisIterator iter) 
345        {
346            return _dom.makeNode(iter);
347        }
348    
349        public NodeList makeNodeList(int index) 
350        {
351            return _dom.makeNodeList(index);
352        }
353    
354        public NodeList makeNodeList(DTMAxisIterator iter) 
355        {
356            return _dom.makeNodeList(iter);
357        }
358    
359        public String getLanguage(int node) 
360        {
361            return _dom.getLanguage(node);
362        }
363    
364        public int getSize() 
365        {
366            return _dom.getSize();
367        }
368    
369        public void setDocumentURI(String uri) 
370        {
371            if (_enhancedDOM != null) {
372                _enhancedDOM.setDocumentURI(uri);
373            }
374        }
375    
376        public String getDocumentURI()
377        {
378            if (_enhancedDOM != null) {
379                return _enhancedDOM.getDocumentURI();
380            }
381            else {
382                return "";
383            }
384        }
385    
386        public String getDocumentURI(int node) 
387        {
388            return _dom.getDocumentURI(node);
389        }
390    
391        public int getDocument() 
392        {
393            return _dom.getDocument();
394        }
395    
396        public boolean isElement(final int node) 
397        {
398            return(_dom.isElement(node));
399        }
400    
401        public boolean isAttribute(final int node) 
402        {
403            return(_dom.isAttribute(node));
404        }
405        
406        public int getNodeIdent(int nodeHandle)
407        {
408            return _dom.getNodeIdent(nodeHandle);
409        }
410        
411        public int getNodeHandle(int nodeId)
412        {
413            return _dom.getNodeHandle(nodeId);
414        }
415        
416        /**
417         * Return a instance of a DOM class to be used as an RTF
418         */ 
419        public DOM getResultTreeFrag(int initSize, int rtfType)
420        {
421            if (_enhancedDOM != null) {
422                return _enhancedDOM.getResultTreeFrag(initSize, rtfType);
423            }
424            else {
425                return _dom.getResultTreeFrag(initSize, rtfType);
426            }
427        }
428        
429        /**
430         * Return a instance of a DOM class to be used as an RTF
431         */ 
432        public DOM getResultTreeFrag(int initSize, int rtfType,
433                                     boolean addToManager)
434        {
435            if (_enhancedDOM != null) {
436                return _enhancedDOM.getResultTreeFrag(initSize, rtfType,
437                                                      addToManager);
438            }
439            else {
440                return _dom.getResultTreeFrag(initSize, rtfType, addToManager);
441            }
442        }
443      
444        
445        /**
446         * Returns a SerializationHandler class wrapped in a SAX adapter.
447         */
448        public SerializationHandler getOutputDomBuilder()
449        {
450            return _dom.getOutputDomBuilder();
451        }
452    
453        public String lookupNamespace(int node, String prefix) 
454            throws TransletException 
455        {
456            return _dom.lookupNamespace(node, prefix);
457        }
458    
459        public String getUnparsedEntityURI(String entity) {
460            return _dom.getUnparsedEntityURI(entity);
461        }
462    
463        public Hashtable getElementsWithIDs() {
464            return _dom.getElementsWithIDs();
465        }
466    }