~ubuntu-branches/ubuntu/wily/xslthl/wily

« back to all changes in this revision

Viewing changes to src/main/java/net/sf/xslthl/FilteredElementIterator.java

  • Committer: Package Import Robot
  • Author(s): Mathieu Malaterre
  • Date: 2013-05-16 08:59:07 UTC
  • mfrom: (4.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20130516085907-ujk9f81x8w344ch1
Tags: 2.1.0-2
Upload to sid

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * xslthl - XSLT Syntax Highlighting
 
3
 * https://sourceforge.net/projects/xslthl/
 
4
 * Copyright (C) 2005-2009 Michal Molhanec, Jirka Kosek, Michiel Hendriks
 
5
 * 
 
6
 * This software is provided 'as-is', without any express or implied
 
7
 * warranty.  In no event will the authors be held liable for any damages
 
8
 * arising from the use of this software.
 
9
 * 
 
10
 * Permission is granted to anyone to use this software for any purpose,
 
11
 * including commercial applications, and to alter it and redistribute it
 
12
 * freely, subject to the following restrictions:
 
13
 * 
 
14
 * 1. The origin of this software must not be misrepresented; you must not
 
15
 *    claim that you wrote the original software. If you use this software
 
16
 *    in a product, an acknowledgment in the product documentation would be
 
17
 *    appreciated but is not required.
 
18
 * 2. Altered source versions must be plainly marked as such, and must not be
 
19
 *    misrepresented as being the original software.
 
20
 * 3. This notice may not be removed or altered from any source distribution.
 
21
 * 
 
22
 * Michal Molhanec <mol1111 at users.sourceforge.net>
 
23
 * Jirka Kosek <kosek at users.sourceforge.net>
 
24
 * Michiel Hendriks <elmuerte at users.sourceforge.net>
 
25
 */
 
26
package net.sf.xslthl;
 
27
 
 
28
import java.util.HashSet;
 
29
import java.util.Iterator;
 
30
import java.util.NoSuchElementException;
 
31
import java.util.Set;
 
32
 
 
33
import org.w3c.dom.Element;
 
34
import org.w3c.dom.Node;
 
35
 
 
36
/**
 
37
 * An iterator over the child elements of a given element, filtered by a set of
 
38
 * element names.
 
39
 * 
 
40
 * @author Michiel Hendriks
 
41
 */
 
42
public class FilteredElementIterator implements Iterator<Element> {
 
43
 
 
44
        /**
 
45
         * Defines a filter used by this iterator
 
46
         * 
 
47
         * @author Michiel Hendriks
 
48
         */
 
49
        public interface Acceptor {
 
50
                /**
 
51
                 * Accept or reject an element
 
52
                 * 
 
53
                 * @param elm
 
54
                 *            The current element
 
55
                 * @return True if the element is accepted
 
56
                 */
 
57
                boolean accepted(Element elm);
 
58
        }
 
59
 
 
60
        /**
 
61
         * Acceptor that accepts elements based on the tag name
 
62
         */
 
63
        public static class TagNameAcceptor implements Acceptor {
 
64
                protected Set<String> names;
 
65
 
 
66
                public TagNameAcceptor(Set<String> acceptNames) {
 
67
                        if (acceptNames == null) {
 
68
                                throw new NullPointerException("Set can not be null");
 
69
                        }
 
70
                        names = new HashSet<String>(acceptNames);
 
71
                }
 
72
 
 
73
                /*
 
74
                 * (non-Javadoc)
 
75
                 * 
 
76
                 * @see
 
77
                 * net.sf.xslthl.FilteredElementIterator.Acceptor#accepted(org.w3c.dom
 
78
                 * .Element)
 
79
                 */
 
80
                public boolean accepted(Element elm) {
 
81
                        return names.contains(elm.getTagName());
 
82
                }
 
83
 
 
84
        }
 
85
 
 
86
        /**
 
87
         * The current element
 
88
         */
 
89
        protected Element base;
 
90
 
 
91
        /**
 
92
         * The current element
 
93
         */
 
94
        protected Element current;
 
95
 
 
96
        /**
 
97
         * The used acceptor for filtering
 
98
         */
 
99
        protected Acceptor acceptor;
 
100
 
 
101
        /**
 
102
         * If true a new value should be retrieved
 
103
         */
 
104
        protected boolean dirty = true;
 
105
 
 
106
        /**
 
107
         * Will be true if the search reached an end
 
108
         */
 
109
        protected boolean finished;
 
110
 
 
111
        public FilteredElementIterator(Element baseElement, Acceptor filter) {
 
112
                if (baseElement == null) {
 
113
                        throw new NullPointerException("Base Element can not be null");
 
114
                }
 
115
                if (filter == null) {
 
116
                        throw new NullPointerException("Acceptor can not be null");
 
117
                }
 
118
                acceptor = filter;
 
119
                base = baseElement;
 
120
                dirty = true;
 
121
        }
 
122
 
 
123
        /**
 
124
         * Creates a filtered element iterator that accepts elements with a given
 
125
         * tag name
 
126
         * 
 
127
         * @param baseElement
 
128
         * @param acceptTagNames
 
129
         */
 
130
        public FilteredElementIterator(Element baseElement,
 
131
                Set<String> acceptTagNames) {
 
132
                this(baseElement, new TagNameAcceptor(acceptTagNames));
 
133
        }
 
134
 
 
135
        /*
 
136
         * (non-Javadoc)
 
137
         * 
 
138
         * @see java.util.Iterator#hasNext()
 
139
         */
 
140
        public boolean hasNext() {
 
141
                if (!finished && dirty) {
 
142
                        // not finished, and the current value is dirty
 
143
                        getNextElement();
 
144
                }
 
145
                return current != null;
 
146
        }
 
147
 
 
148
        /*
 
149
         * (non-Javadoc)
 
150
         * 
 
151
         * @see java.util.Iterator#next()
 
152
         */
 
153
        public Element next() {
 
154
                if (!finished && dirty) {
 
155
                        // if dirty first get a new value
 
156
                        getNextElement();
 
157
                }
 
158
                if (finished) {
 
159
                        // no more elements
 
160
                        throw new NoSuchElementException();
 
161
                }
 
162
                dirty = true;
 
163
                return current;
 
164
        }
 
165
 
 
166
        /*
 
167
         * (non-Javadoc)
 
168
         * 
 
169
         * @see java.util.Iterator#remove()
 
170
         */
 
171
        public void remove() {
 
172
                throw new UnsupportedOperationException("Elements can not be removed");
 
173
        }
 
174
 
 
175
        /**
 
176
         * Get the next valid element
 
177
         */
 
178
        protected void getNextElement() {
 
179
                assert !finished : "Should not call getNextElements on a finished list";
 
180
                if (current == null) {
 
181
                        current = getAcceptedElement(base.getFirstChild());
 
182
                } else {
 
183
                        current = getAcceptedElement(current.getNextSibling());
 
184
                }
 
185
                // iteration is finished when the current element is null
 
186
                finished = current == null;
 
187
                dirty = false;
 
188
        }
 
189
 
 
190
        /**
 
191
         * Get the next accepted element. Will continue searching for the next
 
192
         * sibling nodes.
 
193
         * 
 
194
         * @param node
 
195
         *            The first node to test
 
196
         * @return The accepted element, or null
 
197
         */
 
198
        protected Element getAcceptedElement(Node node) {
 
199
                while (node != null) {
 
200
                        if (node.getNodeType() == Node.ELEMENT_NODE
 
201
                                && node instanceof Element) {
 
202
                                Element result = (Element) node;
 
203
                                if (acceptor.accepted(result)) {
 
204
                                        return result;
 
205
                                }
 
206
                        }
 
207
                        node = node.getNextSibling();
 
208
                }
 
209
                return null;
 
210
        }
 
211
}