@Override public String toString() { return "SpanList with " + children().size() + " children"; } }
/** * Returns the number of children this SpanList holds. * * @return the number of children this SpanList holds. */ public int numChildren() { return children().size(); }
@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof SpanList)) return false; if (!super.equals(o)) return false; SpanList spanList = (SpanList) o; if (children() != null ? !children().equals(spanList.children()) : spanList.children() != null) return false; return true; }
/** * Sorts children by occurrence in the text covered. * * @see SpanNode#compareTo(SpanNode) */ public void sortChildren() { Collections.sort(children()); }
private void calculateTo() { int greatestTo = Integer.MIN_VALUE; for (SpanNode n : children()) { greatestTo = Math.max(n.getTo(), greatestTo); } cachedTo = greatestTo; }
/** * Traverses all immediate children of this SpanList. The ListIterator returned support all optional operations * specified in the ListIterator interface. * * @return a ListIterator which traverses all immediate children of this SpanNode * @see java.util.ListIterator */ @Override public ListIterator<SpanNode> childIterator() { return new InvalidatingIterator(this, children().listIterator()); }
private void calculateFrom() { int smallestFrom = Integer.MAX_VALUE; for (SpanNode n : children()) { final int thisFrom = n.getFrom(); if (thisFrom != -1) { smallestFrom = Math.min(thisFrom, smallestFrom); } } if (smallestFrom == Integer.MAX_VALUE) { //all children were empty SpanLists which returned -1 smallestFrom = -1; } cachedFrom = smallestFrom; }
/** * Returns the character index where this {@link SpanNode} starts (inclusive), i.e. the smallest {@link com.yahoo.document.annotation.SpanNode#getFrom()} of all children. * * @return the lowest getFrom() of all children, or -1 if this SpanList has no children. */ @Override public int getFrom() { if (children().isEmpty()) { return -1; } if (cachedFrom == Integer.MIN_VALUE) { calculateFrom(); } return cachedFrom; }
/** * Returns the character index where this {@link SpanNode} ends (exclusive), i.e. the greatest {@link com.yahoo.document.annotation.SpanNode#getTo()} of all children. * * @return the greatest getTo() of all children, or -1 if this SpanList has no children. */ @Override public int getTo() { if (children().isEmpty()) { return -1; } if (cachedTo == Integer.MIN_VALUE) { calculateTo(); } return cachedTo; }
/** * Adds a child node to this SpanList. * * @param node the node to add. * @return this, for call chaining * @throws IllegalStateException if SpanNode.isValid() returns false. */ public SpanList add(SpanNode node) { checkValidity(node, children()); node.setParent(this); resetCachedFromAndTo(); children().add(node); return this; }
void setInvalid() { //invalidate ourselves: super.setInvalid(); //invalidate all our children: for (SpanNode node : children()) { node.setInvalid(); } }
/** * Removes and invalidates the SpanNode at the given index from this. * * @param i the index of the node to remove. * @return this, for chaining. */ public SpanList remove(int i) { SpanNode node = children().remove(i); if (node != null) { node.setParent(null); node.setInvalid(); } return this; }
/** * Recursively traverses all children (not only leaf nodes) of this SpanList, in a depth-first fashion. * The ListIterator only supports iteration forwards, and the optional operations that are implemented are * remove() and set(). add() is not supported. * * @return a ListIterator which recursively traverses all children and their children etc. of this SpanList. * @see java.util.ListIterator */ @Override public ListIterator<SpanNode> childIteratorRecursive() { return new InvalidatingIterator(this, new RecursiveNodeIterator(children().listIterator())); }
/** * Moves a child of this SpanList to another SpanList. * * @param node the node to move * @param target the SpanList to add the node to * @throws IllegalArgumentException if the given node is not a child of this SpanList */ public void move(SpanNode node, SpanList target) { boolean removed = children().remove(node); if (removed) { //we found the node node.setParent(null); resetCachedFromAndTo(); target.add(node); } else { throw new IllegalArgumentException("Node " + node + " is not a child of this SpanList, cannot move."); } }
/** * Removes and invalidates the given SpanNode from this. * * @param node the node to remove. * @return this, for chaining. */ public SpanList remove(SpanNode node) { boolean removed = children().remove(node); if (removed) { node.setParent(null); resetCachedFromAndTo(); node.setInvalid(); } return this; }
/** * Moves a child of this SpanList to another SpanList. * * @param nodeNum the index of the node to move * @param target the SpanList to add the node to * @throws IndexOutOfBoundsException if the given index is out of range */ public void move(int nodeNum, SpanList target) { SpanNode node = children().remove(nodeNum); if (node != null) { //we found the node node.setParent(null); resetCachedFromAndTo(); target.add(node); } }
/** * Moves a child of this SpanList to another SpanList. * * @param nodeNum the index of the node to move * @param target the SpanList to add the node to * @param targetSubTree the index of the subtree of the given AlternateSpanList to add the node to * @throws IndexOutOfBoundsException if the given index is out of range, or the target subtree index is out of range */ public void move(int nodeNum, AlternateSpanList target, int targetSubTree) { if (targetSubTree < 0 || targetSubTree >= target.getNumSubTrees()) { throw new IndexOutOfBoundsException(target + " has no subtree at index " + targetSubTree); } SpanNode node = children().remove(nodeNum); if (node != null) { //we found the node node.setParent(null); resetCachedFromAndTo(); target.add(targetSubTree, node); } }