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