001    /*
002     /*
003     * Copyright 2005 John G. Wilson
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     *
017     */
018    package groovy.util.slurpersupport;
019    
020    import java.util.Iterator;
021    import java.util.Map;
022    
023    import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
024    
025    import groovy.lang.Closure;
026    
027    /**
028     * Lazy evaluated representation of nodes filtered by attributes.
029     *
030     * @author John Wilson
031     */
032    public class FilteredAttributes extends Attributes
033    {
034        private final Closure closure;
035    
036        public FilteredAttributes(final GPathResult parent, final Closure closure, final Map namespaceTagHints) {
037            super(parent, parent.name, namespaceTagHints);
038            this.closure = closure;
039        }
040    
041        public Iterator nodeIterator() {
042            return new NodeIterator(this.parent.iterator())
043            {
044                protected Object getNextNode(final Iterator iter) {
045                    while (iter.hasNext()) {
046                        final Object node = iter.next();
047                        if (DefaultTypeTransformation.castToBoolean(FilteredAttributes.this.closure.call(new Object[]{node}))) {
048                            return node;
049                        }
050                    }
051                    return null;
052                }
053            };
054        }
055    
056    }