View Javadoc

1   /*
2    * Copyright 2005 John G. Wilson
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  package groovy.util.slurpersupport;
18  
19  import java.util.Iterator;
20  import java.util.Map;
21  
22  import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
23  
24  import groovy.lang.Closure;
25  
26  /***
27   * @author John Wilson
28   */
29  
30  public class FilteredNodeChildren extends NodeChildren {
31      private final Closure closure;
32  
33      public FilteredNodeChildren(final GPathResult parent, final Closure closure, final Map namespaceTagHints) {
34          super(parent, parent.name, namespaceTagHints);
35          this.closure = closure;
36      }
37  
38      public Iterator iterator() {
39          return new Iterator() {
40          final Iterator iter = FilteredNodeChildren.this.parent.iterator();
41          Object next = null;
42  
43              public boolean hasNext() {
44                  while (this.iter.hasNext()) {
45                  final Object childNode = this.iter.next();
46                  
47                      if (closureYieldsTrueForNode(childNode)) {
48                          this.next = childNode;
49                          return true;
50                      }
51                  }
52                  
53                  return false;
54              }
55  
56              public Object next() {
57                  return this.next;
58              }
59  
60              public void remove() {
61                  throw new UnsupportedOperationException();
62              }
63          };
64      }
65  
66      public Iterator nodeIterator() {
67          return new NodeIterator(this.parent.nodeIterator()) {
68              protected Object getNextNode(final Iterator iter) {
69                  while (iter.hasNext()) {
70                  final Object node = iter.next();
71                  
72                      if (closureYieldsTrueForNode(new NodeChild((Node) node, FilteredNodeChildren.this.parent, FilteredNodeChildren.this.namespaceTagHints))) {
73                          return node;
74                      }
75                  }
76                  return null;
77              }
78          };
79      }
80  
81      private boolean closureYieldsTrueForNode(Object childNode) {
82          return DefaultTypeTransformation.castToBoolean(FilteredNodeChildren.this.closure.call(new Object[]{childNode}));
83      }
84  
85  }