001///////////////////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code and other text files for adherence to a set of rules.
003// Copyright (C) 2001-2026 the original author or authors.
004//
005// This library is free software; you can redistribute it and/or
006// modify it under the terms of the GNU Lesser General Public
007// License as published by the Free Software Foundation; either
008// version 2.1 of the License, or (at your option) any later version.
009//
010// This library is distributed in the hope that it will be useful,
011// but WITHOUT ANY WARRANTY; without even the implied warranty of
012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013// Lesser General Public License for more details.
014//
015// You should have received a copy of the GNU Lesser General Public
016// License along with this library; if not, write to the Free Software
017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018///////////////////////////////////////////////////////////////////////////////////////////////
019
020package com.puppycrawl.tools.checkstyle.xpath;
021
022import java.util.Collections;
023import java.util.List;
024
025import net.sf.saxon.Configuration;
026import net.sf.saxon.event.Receiver;
027import net.sf.saxon.om.AtomicSequence;
028import net.sf.saxon.om.NamespaceBinding;
029import net.sf.saxon.om.NamespaceMap;
030import net.sf.saxon.om.NamespaceUri;
031import net.sf.saxon.om.NodeInfo;
032import net.sf.saxon.om.SequenceIterator;
033import net.sf.saxon.om.TreeInfo;
034import net.sf.saxon.pattern.nodetest.NodePredicate;
035import net.sf.saxon.s9api.Location;
036import net.sf.saxon.str.UnicodeString;
037import net.sf.saxon.tree.util.Navigator;
038import net.sf.saxon.type.SchemaType;
039import net.sf.saxon.type.Untyped;
040
041/**
042 * Represents general class for {@code ElementNode}, {@code RootNode} and {@code AttributeNode}.
043 */
044public abstract class AbstractNode implements NodeInfo {
045
046    /** The {@code TreeInfo} object. */
047    private final TreeInfo treeInfo;
048
049    /** The children. */
050    private List<AbstractNode> children;
051
052    /**
053     * Constructor of the abstract class {@code AbstractNode}.
054     *
055     * @param treeInfo {@code TreeInfo} object
056     */
057    protected AbstractNode(TreeInfo treeInfo) {
058        this.treeInfo = treeInfo;
059    }
060
061    /**
062     * Getter method for token type.
063     *
064     * @return token type
065     */
066    public abstract int getTokenType();
067
068    /**
069     * Returns underlying node.
070     *
071     * @return underlying node
072     */
073    public abstract Object getUnderlyingNode();
074
075    /**
076     * Getter method for node depth.
077     *
078     * @return depth
079     */
080    public abstract int getDepth();
081
082    /**
083     * Creates nodes for children.
084     *
085     * @return children list
086     */
087    protected abstract List<AbstractNode> createChildren();
088
089    /**
090     * Getter method for children.
091     *
092     * @return children list
093     */
094    protected List<AbstractNode> getChildren() {
095        if (children == null) {
096            children = createChildren();
097        }
098        return Collections.unmodifiableList(children);
099    }
100
101    /**
102     * Returns true if nodes are same, false otherwise.
103     *
104     * @param nodeInfo other node
105     * @return {@code TreeInfo}
106     */
107    @Override
108    @SuppressWarnings("ReferenceEquality")
109    public boolean isSameNodeInfo(NodeInfo nodeInfo) {
110        return this == nodeInfo;
111    }
112
113    /**
114     * Returns if implementation provides fingerprints.
115     *
116     * @return {@code boolean}
117     */
118    @Override
119    public boolean hasFingerprint() {
120        return false;
121    }
122
123    /**
124     * Get the URI part of the name of this node.
125     *
126     * @return The URI of the namespace of this node.
127     */
128    @Override
129    public NamespaceUri getNamespaceUri() {
130        return NamespaceUri.NULL;
131    }
132
133    /**
134     * Returns uri of the namespace for the current node.
135     *
136     * @return uri
137     */
138    @Override
139    public String getURI() {
140        return "";
141    }
142
143    /**
144     * Applies the node predicate to the given axis iterator, if a predicate is provided.
145     *
146     * @param iterator axis iterator
147     * @param predicate filter for the iterator, may be null
148     * @return filtered iterator, or the same iterator if there is no predicate
149     */
150    protected static SequenceIterator filter(SequenceIterator iterator,
151                                             NodePredicate predicate) {
152        final SequenceIterator result;
153        if (predicate == null) {
154            result = iterator;
155        }
156        else {
157            result = Navigator.filter(iterator, predicate);
158        }
159        return result;
160    }
161
162    /**
163     * Returns tree info.
164     *
165     * @return tree info
166     */
167    @Override
168    public final TreeInfo getTreeInfo() {
169        return treeInfo;
170    }
171
172    /**
173     * Returns string value. Throws {@code UnsupportedOperationException}, because no child class
174     * implements it and this method is not used for querying.
175     *
176     * @return string value
177     */
178    @Override
179    public String getStringValue() {
180        throw createUnsupportedOperationException();
181    }
182
183    /**
184     * Returns namespace array. Throws {@code UnsupportedOperationException}, because no child class
185     * implements it and this method is not used for querying.
186     *
187     * @param namespaceBindings namespace array
188     * @return namespace array
189     */
190    @Override
191    public final NamespaceBinding[] getDeclaredNamespaces(NamespaceBinding[] namespaceBindings) {
192        throw createUnsupportedOperationException();
193    }
194
195    /**
196     * Returns namespace array. Throws {@code UnsupportedOperationException}, because no child class
197     * implements it and this method is not used for querying.
198     *
199     * @return namespace map
200     */
201    @Override
202    public NamespaceMap getAllNamespaces() {
203        throw createUnsupportedOperationException();
204    }
205
206    /**
207     * Returns boolean. Throws {@code UnsupportedOperationException}, because no child class
208     * implements it and this method is not used for querying.
209     *
210     * @return boolean
211     */
212    @Override
213    public final boolean isId() {
214        throw createUnsupportedOperationException();
215    }
216
217    /**
218     * Returns boolean. Throws {@code UnsupportedOperationException}, because no child class
219     * implements it and this method is not used for querying.
220     *
221     * @return boolean
222     */
223    @Override
224    public final boolean isIdref() {
225        throw createUnsupportedOperationException();
226    }
227
228    /**
229     * Returns boolean. Throws {@code UnsupportedOperationException}, because no child class
230     * implements it and this method is not used for querying.
231     *
232     * @return boolean
233     */
234    @Override
235    public final boolean isNilled() {
236        throw createUnsupportedOperationException();
237    }
238
239    /**
240     * Returns boolean. Throws {@code UnsupportedOperationException}, because no child class
241     * implements it and this method is not used for querying.
242     *
243     * @return boolean
244     */
245    @Override
246    public final boolean isStreamed() {
247        throw createUnsupportedOperationException();
248    }
249
250    /**
251     * Returns configuration. Throws {@code UnsupportedOperationException}, because no child class
252     * implements it and this method is not used for querying.
253     *
254     * @return configuration
255     */
256    @Override
257    public final Configuration getConfiguration() {
258        throw createUnsupportedOperationException();
259    }
260
261    /**
262     * Sets system id. Throws {@code UnsupportedOperationException}, because no child class
263     * implements it and this method is not used for querying.
264     *
265     * @param systemId system id
266     */
267    @Override
268    public final void setSystemId(String systemId) {
269        throw createUnsupportedOperationException();
270    }
271
272    /**
273     * Returns system id. Throws {@code UnsupportedOperationException}, because no child class
274     * implements it and this method is not used for querying.
275     *
276     * @return system id
277     */
278    @Override
279    public final String getSystemId() {
280        throw createUnsupportedOperationException();
281    }
282
283    /**
284     * Returns public id. Throws {@code UnsupportedOperationException}, because no child class
285     * implements it and this method is not used for querying.
286     *
287     * @return public id
288     */
289    @Override
290    public final String getPublicId() {
291        throw createUnsupportedOperationException();
292    }
293
294    /**
295     * Returns base uri. Throws {@code UnsupportedOperationException}, because no child class
296     * implements it and this method is not used for querying.
297     *
298     * @return base uri
299     */
300    @Override
301    public final String getBaseURI() {
302        throw createUnsupportedOperationException();
303    }
304
305    /**
306     * Returns location. Throws {@code UnsupportedOperationException}, because no child class
307     * implements it and this method is not used for querying.
308     *
309     * @return location
310     */
311    @Override
312    public final Location saveLocation() {
313        throw createUnsupportedOperationException();
314    }
315
316    /**
317     * Returns the value of the item as a Unicode string.
318     * Throws {@code UnsupportedOperationException}, because no child class implements it and this
319     * method is not used for querying.
320     *
321     * @return CharSequence string value
322     */
323    @Override
324    public final UnicodeString getUnicodeStringValue() {
325        throw createUnsupportedOperationException();
326    }
327
328    /**
329     * Returns fingerprint. Throws {@code UnsupportedOperationException}, because no child class
330     * implements it and this method is not used for querying.
331     *
332     * @return fingerprint
333     */
334    @Override
335    public final int getFingerprint() {
336        throw createUnsupportedOperationException();
337    }
338
339    /**
340     * Returns display name. Throws {@code UnsupportedOperationException}, because no child class
341     * implements it and this method is not used for querying.
342     *
343     * @return display name
344     */
345    @Override
346    public final String getDisplayName() {
347        throw createUnsupportedOperationException();
348    }
349
350    /**
351     * Returns prefix. Nodes of the xpath tree are never in a namespace,
352     * so the prefix is always empty.
353     *
354     * @return empty string
355     */
356    @Override
357    public String getPrefix() {
358        return "";
359    }
360
361    /**
362     * Returns type of the schema. Nodes of the xpath tree are never schema-validated,
363     * so they are always untyped.
364     *
365     * @return untyped schema type
366     */
367    @Override
368    public SchemaType getSchemaType() {
369        return Untyped.getInstance();
370    }
371
372    /**
373     * Returns AtomicSequence. Throws {@code UnsupportedOperationException}, because no child class
374     * implements it and this method is not used for querying.
375     *
376     * @return AtomicSequence
377     */
378    @Override
379    public AtomicSequence atomize() {
380        throw createUnsupportedOperationException();
381    }
382
383    /**
384     * Generate id method. Throws {@code UnsupportedOperationException}, because no child class
385     * implements it and this method is not used for querying.
386     *
387     * @param buffer buffer
388     */
389    @Override
390    public final void generateId(StringBuilder buffer) {
391        throw createUnsupportedOperationException();
392    }
393
394    /**
395     * Copy method. Throws {@code UnsupportedOperationException}, because no child class implements
396     * it and this method is not used for querying.
397     *
398     * @param receiver receiver
399     * @param index index
400     * @param location location
401     */
402    @Override
403    public final void copy(Receiver receiver, int index, Location location) {
404        throw createUnsupportedOperationException();
405    }
406
407    /**
408     * Returns UnsupportedOperationException exception. Methods which throws this exception are not
409     * supported for all nodes.
410     *
411     * @return UnsupportedOperationException exception
412     */
413    private static UnsupportedOperationException createUnsupportedOperationException() {
414        return new UnsupportedOperationException("Operation is not supported");
415    }
416
417}