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