1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xalan.internal.xsltc.dom;
  23 
  24 import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary;
  25 import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
  26 import com.sun.org.apache.xml.internal.dtm.DTMFilter;
  27 import com.sun.org.apache.xml.internal.dtm.DTMIterator;
  28 import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIteratorBase;
  29 
  30 /**
  31  * Similar to a CurrentNodeListIterator except that the filter has a
  32  * simpler interface (only needs the node, no position, last, etc.)
  33  * It takes a source iterator and a Filter object and returns nodes
  34  * from the source after filtering them by calling filter.test(node).
  35  * @author Jacek Ambroziak
  36  * @author Santiago Pericas-Geertsen
  37  */
  38 public final class FilterIterator extends DTMAxisIteratorBase {
  39 
  40     /**
  41      * Reference to source iterator.
  42      */
  43     private DTMAxisIterator _source;
  44 
  45     /**
  46      * Reference to a filter object that to be applied to each node.
  47      */
  48     private final DTMFilter _filter;
  49 
  50     /**
  51      * A flag indicating if position is reversed.
  52      */
  53     private final boolean _isReverse;
  54 
  55     public FilterIterator(DTMAxisIterator source, DTMFilter filter) {
  56         _source = source;
  57 // System.out.println("FI souce = " + source + " this = " + this);
  58         _filter = filter;
  59         _isReverse = source.isReverse();
  60     }
  61 
  62     public boolean isReverse() {
  63         return _isReverse;
  64     }
  65 
  66 
  67     public void setRestartable(boolean isRestartable) {
  68         _isRestartable = isRestartable;
  69         _source.setRestartable(isRestartable);
  70     }
  71 
  72     public DTMAxisIterator cloneIterator() {
  73 
  74         try {
  75             final FilterIterator clone = (FilterIterator) super.clone();
  76             clone._source = _source.cloneIterator();
  77             clone._isRestartable = false;
  78             return clone.reset();
  79         }
  80         catch (CloneNotSupportedException e) {
  81             BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  82                                       e.toString());
  83             return null;
  84         }
  85     }
  86 
  87     public DTMAxisIterator reset() {
  88         _source.reset();
  89         return resetPosition();
  90     }
  91 
  92     public int next() {
  93         int node;
  94         while ((node = _source.next()) != END) {
  95             if (_filter.acceptNode(node, DTMFilter.SHOW_ALL) == DTMIterator.FILTER_ACCEPT) {
  96                 return returnNode(node);
  97             }
  98         }
  99         return END;
 100     }
 101 
 102     public DTMAxisIterator setStartNode(int node) {
 103         if (_isRestartable) {
 104             _source.setStartNode(_startNode = node);
 105             return resetPosition();
 106         }
 107         return this;
 108     }
 109 
 110     public void setMark() {
 111         _source.setMark();
 112     }
 113 
 114     public void gotoMark() {
 115         _source.gotoMark();
 116     }
 117 
 118 }