org.apache.pivot.wtk.text.Node Maven / Gradle / Ivy
The 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.apache.pivot.wtk.text;
import org.apache.pivot.collections.Sequence;
import org.apache.pivot.util.ListenerList;
import org.apache.pivot.wtk.Span;
/**
* Abstract base class for document nodes.
*/
public abstract class Node {
private static class NodeListenerList extends ListenerList implements
NodeListener {
@Override
public void parentChanged(Node node, Element previousParent) {
for (NodeListener listener : this) {
listener.parentChanged(node, previousParent);
}
}
@Override
public void offsetChanged(Node node, int previousOffset) {
for (NodeListener listener : this) {
listener.offsetChanged(node, previousOffset);
}
}
@Override
public void nodeInserted(Node node, int offset) {
for (NodeListener listener : this) {
listener.nodeInserted(node, offset);
}
}
@Override
public void nodesRemoved(Node node, Sequence removed, int offset) {
for (NodeListener listener : this) {
listener.nodesRemoved(node, removed, offset);
}
}
@Override
public void rangeInserted(Node node, int offset, int span) {
for (NodeListener listener : this) {
listener.rangeInserted(node, offset, span);
}
}
@Override
public void rangeRemoved(Node node, int offset, int characterCount) {
for (NodeListener listener : this) {
listener.rangeRemoved(node, offset, characterCount);
}
}
}
private Element parent = null;
private int offset = 0;
private NodeListenerList nodeListeners = new NodeListenerList();
/**
* Returns the parent element of this node.
*
* @return
* The node's parent, or null if the node does not have a parent.
*/
public Element getParent() {
return parent;
}
protected void setParent(Element parent) {
Element previousParent = this.parent;
if (previousParent != parent) {
this.parent = parent;
nodeListeners.parentChanged(this, previousParent);
}
}
/**
* Returns the node's offset within its parent.
*
* @return
* The integer offset of the node's first character within its parent
* element.
*/
public int getOffset() {
return offset;
}
protected void setOffset(int offset) {
int previousOffset = this.offset;
if (previousOffset != offset) {
this.offset = offset;
nodeListeners.offsetChanged(this, previousOffset);
}
}
/**
* Returns the node's offset within the document.
*/
public int getDocumentOffset() {
return (parent == null) ? 0 : parent.getDocumentOffset() + offset;
}
/**
* @return A {@link Span} that describes the content range of this node
* relative to the whole document.
*/
public Span getDocumentSpan() {
int docOffset = getDocumentOffset();
int nodeLength = getCharacterCount();
// The "end" of a Span is inclusive, so subtract one here
return new Span(docOffset, docOffset + nodeLength - 1);
}
/**
* Inserts a range into the node. Note that the contents of the range,
* rather than the range itself, is added to the node.
*
* @param range
* @param offsetArgument
*/
public abstract void insertRange(Node range, int offsetArgument);
/**
* Removes a range from the node.
*
* @param offsetArgument
* @param characterCount
*
* @return
* The removed range. This will be a copy of the node structure relative
* to this node.
*/
public abstract Node removeRange(int offsetArgument, int characterCount);
/**
* Replaces an existing range with a new range.
*
* @param offsetArgument
* @param characterCount
* @param range
*
* @return
* The removed range. This will be a copy of the node structure relative
* to this node.
*/
public Node replaceRange(int offsetArgument, int characterCount, Node range) {
Node removed = removeRange(offsetArgument, characterCount);
insertRange(range, offsetArgument);
return removed;
}
/**
* Returns a range from the node.
*
* @param offsetArgument
* @param characterCount
*
* @return
* A node containing a copy of the node structure spanning the given range,
* relative to this node.
*/
public abstract Node getRange(int offsetArgument, int characterCount);
/**
* Returns the character at the given offset.
*
* @param offsetArgument
*/
public abstract char getCharacterAt(int offsetArgument);
/**
* Returns the number of characters in this node.
*/
public abstract int getCharacterCount();
/**
* Creates a copy of this node.
*
* @param recursive
*/
public abstract Node duplicate(boolean recursive);
/**
* Called to notify a node that a range has been inserted.
*
* @param offsetArgument
* @param characterCount
*/
protected void rangeInserted(int offsetArgument, int characterCount) {
if (parent != null) {
parent.rangeInserted(offsetArgument + this.offset, characterCount);
}
nodeListeners.rangeInserted(this, offsetArgument, characterCount);
}
/**
* Called to notify a node that a range has been removed.
*
* @param offsetArgument
* @param characterCount
*/
protected void rangeRemoved(int offsetArgument, int characterCount) {
if (parent != null) {
parent.rangeRemoved(offsetArgument + this.offset, characterCount);
}
nodeListeners.rangeRemoved(this, offsetArgument, characterCount);
}
/**
* Called to notify a node that some child nodes has been removed.
*
* @param removed
* @param offsetArgument
*/
protected void nodesRemoved(Sequence removed, int offsetArgument) {
if (parent != null) {
parent.nodesRemoved(removed, offsetArgument + this.offset);
}
nodeListeners.nodesRemoved(this, removed, offsetArgument);
}
/**
* Called to notify a node that a child node has been inserted.
*
* @param offsetArgument
*/
protected void nodeInserted(int offsetArgument) {
if (parent != null) {
parent.nodeInserted(offsetArgument + this.offset);
}
nodeListeners.nodeInserted(this, offsetArgument);
}
/**
* Returns the node listener list.
*/
public ListenerList getNodeListeners() {
return nodeListeners;
}
}