001////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code for adherence to a set of rules.
003// Copyright (C) 2001-2020 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.ArrayList;
023import java.util.Collections;
024import java.util.List;
025
026import com.puppycrawl.tools.checkstyle.api.DetailAST;
027import net.sf.saxon.Configuration;
028import net.sf.saxon.event.Receiver;
029import net.sf.saxon.expr.parser.Location;
030import net.sf.saxon.om.AtomicSequence;
031import net.sf.saxon.om.NamespaceBinding;
032import net.sf.saxon.om.NodeInfo;
033import net.sf.saxon.om.TreeInfo;
034import net.sf.saxon.pattern.NodeTest;
035import net.sf.saxon.tree.iter.AxisIterator;
036import net.sf.saxon.tree.util.FastStringBuffer;
037import net.sf.saxon.tree.util.Navigator;
038import net.sf.saxon.type.SchemaType;
039
040/**
041 * Represents general class for {@code ElementNode}, {@code RootNode} and {@code AttributeNode}.
042 *
043 */
044public abstract class AbstractNode implements NodeInfo {
045
046    /** The children. */
047    private final List<AbstractNode> children = new ArrayList<>();
048
049    /** The {@code TreeInfo} object. */
050    private final TreeInfo treeInfo;
051
052    /** Depth of the node. */
053    private int depth;
054
055    /**
056     * Constructor of the abstract class {@code AbstractNode}.
057     *
058     * @param treeInfo {@code TreeInfo} object
059     */
060    protected AbstractNode(TreeInfo treeInfo) {
061        this.treeInfo = treeInfo;
062    }
063
064    /**
065     * Getter method for token type.
066     *
067     * @return token type
068     */
069    public abstract int getTokenType();
070
071    /**
072     * Returns underlying node.
073     *
074     * @return underlying node
075     */
076    public abstract DetailAST getUnderlyingNode();
077
078    /**
079     * Getter method for node depth.
080     * @return depth
081     */
082    public int getDepth() {
083        return depth;
084    }
085
086    /**
087     * Setter method for node depth.
088     * @param depth depth of node
089     */
090    public final void setDepth(int depth) {
091        this.depth = depth;
092    }
093
094    /**
095     * Getter method for children.
096     *
097     * @return children list
098     */
099    protected List<AbstractNode> getChildren() {
100        return Collections.unmodifiableList(children);
101    }
102
103    /**
104     * Add new child node to children list.
105     *
106     * @param node child node
107     */
108    protected void addChild(AbstractNode node) {
109        children.add(node);
110    }
111
112    /**
113     * Returns true if nodes are same, false otherwise.
114     *
115     * @param nodeInfo other node
116     * @return {@code TreeInfo}
117     */
118    @Override
119    public boolean isSameNodeInfo(NodeInfo nodeInfo) {
120        return this == nodeInfo;
121    }
122
123    /**
124     * Returns if implementation provides fingerprints.
125     *
126     * @return {@code boolean}
127     */
128    @Override
129    public boolean hasFingerprint() {
130        return false;
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     * Returns if current node has children.
145     *
146     * @return if current node has children
147     */
148    @Override
149    public boolean hasChildNodes() {
150        return !children.isEmpty();
151    }
152
153    /**
154     * Determines axis iteration algorithm.
155     *
156     * @param axisNumber element from {@code AxisInfo}
157     * @param nodeTest filter for iterator
158     * @return {@code AxisIterator} object
159     */
160    @Override
161    public AxisIterator iterateAxis(byte axisNumber, NodeTest nodeTest) {
162        AxisIterator axisIterator = iterateAxis(axisNumber);
163        if (nodeTest != null) {
164            axisIterator = new Navigator.AxisFilter(axisIterator, nodeTest);
165        }
166        return axisIterator;
167    }
168
169    /**
170     * Returns tree info.
171     *
172     * @return tree info
173     */
174    @Override
175    public final TreeInfo getTreeInfo() {
176        return treeInfo;
177    }
178
179    /**
180     * Returns string value. Throws {@code UnsupportedOperationException}, because no child
181     * class implements it and this method is not used for querying.
182     *
183     * @return string value
184     */
185    @Override
186    public String getStringValue() {
187        throw createUnsupportedOperationException();
188    }
189
190    /**
191     * Returns namespace array. Throws {@code UnsupportedOperationException}, because no child
192     * class implements it and this method is not used for querying.
193     *
194     * @param namespaceBindings namespace array
195     * @return namespace array
196     */
197    @Override
198    public final NamespaceBinding[] getDeclaredNamespaces(NamespaceBinding[] namespaceBindings) {
199        throw createUnsupportedOperationException();
200    }
201
202    /**
203     * Returns boolean. Throws {@code UnsupportedOperationException}, because no child
204     * class implements it and this method is not used for querying.
205     *
206     * @return boolean
207     */
208    @Override
209    public final boolean isId() {
210        throw createUnsupportedOperationException();
211    }
212
213    /**
214     * Returns boolean. Throws {@code UnsupportedOperationException}, because no child
215     * class implements it and this method is not used for querying.
216     *
217     * @return boolean
218     */
219    @Override
220    public final boolean isIdref() {
221        throw createUnsupportedOperationException();
222    }
223
224    /**
225     * Returns boolean. Throws {@code UnsupportedOperationException}, because no child
226     * class implements it and this method is not used for querying.
227     *
228     * @return boolean
229     */
230    @Override
231    public final boolean isNilled() {
232        throw createUnsupportedOperationException();
233    }
234
235    /**
236     * Returns boolean. Throws {@code UnsupportedOperationException}, because no child
237     * class implements it and this method is not used for querying.
238     *
239     * @return boolean
240     */
241    @Override
242    public final boolean isStreamed() {
243        throw createUnsupportedOperationException();
244    }
245
246    /**
247     * Returns configuration. Throws {@code UnsupportedOperationException}, because no child
248     * class implements it and this method is not used for querying.
249     *
250     * @return configuration
251     */
252    @Override
253    public final Configuration getConfiguration() {
254        throw createUnsupportedOperationException();
255    }
256
257    /**
258     * Sets system id. Throws {@code UnsupportedOperationException}, because no child
259     * class implements it and this method is not used for querying.
260     *
261     * @param systemId system id
262     */
263    @Override
264    public final void setSystemId(String systemId) {
265        throw createUnsupportedOperationException();
266    }
267
268    /**
269     * Returns system id. Throws {@code UnsupportedOperationException}, because no child
270     * class implements it and this method is not used for querying.
271     *
272     * @return system id
273     */
274    @Override
275    public final String getSystemId() {
276        throw createUnsupportedOperationException();
277    }
278
279    /**
280     * Returns public id. Throws {@code UnsupportedOperationException}, because no child
281     * class implements it and this method is not used for querying.
282     *
283     * @return public id
284     */
285    @Override
286    public final String getPublicId() {
287        throw createUnsupportedOperationException();
288    }
289
290    /**
291     * Returns base uri. Throws {@code UnsupportedOperationException}, because no child
292     * class implements it and this method is not used for querying.
293     *
294     * @return base uri
295     */
296    @Override
297    public final String getBaseURI() {
298        throw createUnsupportedOperationException();
299    }
300
301    /**
302     * Returns location. Throws {@code UnsupportedOperationException}, because no child
303     * class implements it and this method is not used for querying.
304     *
305     * @return location
306     */
307    @Override
308    public final Location saveLocation() {
309        throw createUnsupportedOperationException();
310    }
311
312    /**
313     * Returns CharSequence string value. Throws {@code UnsupportedOperationException},
314     * because no child class implements it and this method is not used for querying.
315     *
316     * @return CharSequence string value
317     */
318    @Override
319    public final CharSequence getStringValueCS() {
320        throw createUnsupportedOperationException();
321    }
322
323    /**
324     * Returns fingerprint. Throws {@code UnsupportedOperationException}, because no child
325     * class implements it and this method is not used for querying.
326     *
327     * @return fingerprint
328     */
329    @Override
330    public final int getFingerprint() {
331        throw createUnsupportedOperationException();
332    }
333
334    /**
335     * Returns display name. Throws {@code UnsupportedOperationException}, because no child
336     * class implements it and this method is not used for querying.
337     *
338     * @return display name
339     */
340    @Override
341    public final String getDisplayName() {
342        throw createUnsupportedOperationException();
343    }
344
345    /**
346     * Returns prefix. Throws {@code UnsupportedOperationException}, because no child
347     * class implements it and this method is not used for querying.
348     *
349     * @return prefix
350     */
351    @Override
352    public final String getPrefix() {
353        throw createUnsupportedOperationException();
354    }
355
356    /**
357     * Returns type of the schema. Throws {@code UnsupportedOperationException}, because no child
358     * class implements it and this method is not used for querying.
359     *
360     * @return type of the schema
361     */
362    @Override
363    public final SchemaType getSchemaType() {
364        throw createUnsupportedOperationException();
365    }
366
367    /**
368     * Returns AtomicSequence. Throws {@code UnsupportedOperationException}, because no child
369     * class implements it and this method is not used for querying.
370     *
371     * @return AtomicSequence
372     */
373    @Override
374    public final AtomicSequence atomize() {
375        throw createUnsupportedOperationException();
376    }
377
378    /**
379     * Generate id method. Throws {@code UnsupportedOperationException}, because no child
380     * class implements it and this method is not used for querying.
381     *
382     * @param fastStringBuffer fastStringBuffer
383     */
384    @Override
385    public final void generateId(FastStringBuffer fastStringBuffer) {
386        throw createUnsupportedOperationException();
387    }
388
389    /**
390     * Copy method. Throws {@code UnsupportedOperationException}, because no child
391     * class implements it and this method is not used for querying.
392     *
393     * @param receiver receiver
394     * @param index index
395     * @param location location
396     */
397    @Override
398    public final void copy(Receiver receiver, int index, Location location) {
399        throw createUnsupportedOperationException();
400    }
401
402    /**
403     * Returns UnsupportedOperationException exception. Methods which throws this exception are
404     * not supported for all nodes.
405     *
406     * @return UnsupportedOperationException exception
407     */
408    private static UnsupportedOperationException createUnsupportedOperationException() {
409        return new UnsupportedOperationException("Operation is not supported");
410    }
411
412}