All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.htmlunit.xpath.axes.LocPathIterator Maven / Gradle / Ivy

There is a newer version: 4.7.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.htmlunit.xpath.axes;

import org.htmlunit.xpath.XPathContext;
import org.htmlunit.xpath.XPathVisitor;
import org.htmlunit.xpath.objects.XNodeSet;
import org.htmlunit.xpath.objects.XObject;
import org.htmlunit.xpath.res.XPATHErrorResources;
import org.htmlunit.xpath.res.XPATHMessages;
import org.htmlunit.xpath.xml.dtm.DTM;
import org.htmlunit.xpath.xml.dtm.DTMFilter;
import org.htmlunit.xpath.xml.dtm.DTMIterator;
import org.htmlunit.xpath.xml.dtm.DTMManager;
import org.htmlunit.xpath.xml.utils.PrefixResolver;

/**
 * This class extends NodeSetDTM, which implements NodeIterator, and fetches nodes one at a time in
 * document order based on a XPath.
* * @see = 0) ? getProximityPosition() : m_pos; final LocPathIterator clone; try { clone = (LocPathIterator) clone(); } catch (final CloneNotSupportedException cnse) { return -1; } // We want to clip off the last predicate, but only if we are a sub // context node list, NOT if we are a context list. See pos68 test, // also test against bug4638. if (predCount > 0 && isPredicateTest) { // Don't call setPredicateCount, because it clones and is slower. clone.m_predCount = m_predicateIndex; // The line above used to be: // clone.m_predCount = predCount - 1; // ...which looks like a dumb bug to me. -sb } while (DTM.NULL != clone.nextNode()) { pos++; } if (isPredicateTest && m_predicateIndex < 1) { m_length = pos; } return pos; } /** {@inheritDoc} */ @Override public boolean isFresh() { return m_pos == 0; } /** {@inheritDoc} */ @Override public int previousNode() { throw new RuntimeException( XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_NODESETDTM_CANNOT_ITERATE, null)); } /** {@inheritDoc} */ @Override public int getWhatToShow() { // TODO: ?? return DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE; } /** {@inheritDoc} */ @Override public int getRoot() { return m_context; } /** {@inheritDoc} */ @Override public boolean getExpandEntityReferences() { return true; } /** {@inheritDoc} */ @Override public void detach() { // sb: allow reusing of cached nodes when possible? // m_cachedNodes = null; m_execContext = null; // m_prefixResolver = null; sb: Why would this ever want to be null? m_cdtm = null; m_length = -1; m_pos = 0; m_lastFetched = DTM.NULL; m_context = DTM.NULL; m_currentContextNode = DTM.NULL; m_clones.freeInstance(this); } /** {@inheritDoc} */ @Override public void reset() { assertion(false, "This iterator can not reset!"); } /** {@inheritDoc} */ @Override public DTMIterator cloneWithReset() throws CloneNotSupportedException { final LocPathIterator clone; // clone = (LocPathIterator) clone(); clone = (LocPathIterator) m_clones.getInstanceOrThrow(); clone.m_execContext = m_execContext; clone.m_cdtm = m_cdtm; clone.m_context = m_context; clone.m_currentContextNode = m_currentContextNode; clone.m_stackFrame = m_stackFrame; // clone.reset(); return clone; } /** {@inheritDoc} */ @Override public abstract int nextNode(); /** * Bottleneck the return of a next node, to make returns easier from nextNode(). * * @param nextNode The next node found, may be null. * @return The same node that was passed as an argument. */ protected int returnNextNode(final int nextNode) { if (DTM.NULL != nextNode) { m_pos++; } m_lastFetched = nextNode; if (DTM.NULL == nextNode) { m_foundLast = true; } return nextNode; } /** {@inheritDoc} */ @Override public int getCurrentNode() { return m_lastFetched; } /** {@inheritDoc} */ @Override public void runTo(final int index) { if (m_foundLast || ((index >= 0) && (index <= getCurrentPos()))) { return; } if (-1 == index) { while (DTM.NULL != nextNode()) { ; } } else { while (DTM.NULL != nextNode()) { if (getCurrentPos() >= index) { break; } } } } /** * The XPath execution context we are operating on. * * @return XPath execution context this iterator is operating on, or null if setRoot has not been * called. */ public final XPathContext getXPathContext() { return m_execContext; } /** * Return the saved reference to the prefix resolver that was in effect when this iterator was * created. * * @return The prefix resolver or this iterator, which may be null. */ public final PrefixResolver getPrefixResolver() { if (null == m_prefixResolver) { m_prefixResolver = (PrefixResolver) getExpressionOwner(); } return m_prefixResolver; } /** {@inheritDoc} */ @Override public void callVisitors(final XPathVisitor visitor) { if (visitor.visitLocationPath()) { visitor.visitStep(); callPredicateVisitors(visitor); } } // ============= State Data ============= /** * The pool for cloned iterators. Iterators need to be cloned because the hold running state, and * thus the original iterator expression from the stylesheet pool can not be used. */ protected final transient IteratorPool m_clones = new IteratorPool(this); /** * The dtm of the context node. Careful about using this... it may not be the dtm of the current * node. */ protected transient DTM m_cdtm; /** The stack frame index for this iterator. */ transient int m_stackFrame = -1; /** * Value determined at compile time, indicates that this is an iterator at the top level of the * expression, rather than inside a predicate. * * @serial */ private boolean m_isTopLevel = false; /** The last node that was fetched, usually by nextNode. */ public transient int m_lastFetched = DTM.NULL; /** * The context node for this iterator, which doesn't change through the course of the iteration. */ protected transient int m_context = DTM.NULL; /** * The node context from where the expression is being executed from (i.e. for current() support). * Different from m_context in that this is the context for the entire expression, rather than the * context for the subexpression. */ protected transient int m_currentContextNode = DTM.NULL; /** The current position of the context node. */ protected transient int m_pos = 0; protected transient int m_length = -1; /** * Fast access to the current prefix resolver. It isn't really clear that this is needed. * * @serial */ private PrefixResolver m_prefixResolver; /** The XPathContext reference, needed for execution of many operations. */ protected transient XPathContext m_execContext; /** {@inheritDoc} */ @Override public boolean isDocOrdered() { return true; } /** {@inheritDoc} */ @Override public int getAxis() { return -1; } /** {@inheritDoc} */ @Override public int getLastPos(final XPathContext xctxt) { return getLength(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy