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