Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2000, 2009 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: IBM Corporation - initial API and implementation /
 
 package org.eclipse.jdt.internal.core.jdom;
 
 
DOMNode provides an implementation for IDOMNode.

A node represents a document fragment. When a node is created, its contents are located in a contiguous range of a shared document. A shared document is a char array, and is shared in the sense that the contents of other document fragments may also be contained in the array.

A node maintains indicies of relevant portions of its contents in the shared document. Thus the original document and indicies create a form from which to generate the contents of the document fragment. As attributes of a node are changed, the node attempts to maintain the original formatting by only replacing relevant portions of the shared document with the value of new attributes (that is, filling in the form with replacement values).

When a node is first created, it is considered unfragmented. When any attribute of the node is altered, the node is then considered fragmented from that point on. A node is also considered fragmented if any of its descendants are fragmented. When a node is unfragmented, the contents of the node can be efficiently generated from the original shared document. When a node is fragmented, the contents of the node must be created using the original document and indicies as a form, filling in replacement values as required.

Generally, a node's contents consists of complete lines in a shared document. The contents of the node are normalized on creation to include any whitespace preceding the node on the line where the node begins, and to include and trailing whitespace up to the line where the next node begins. Any trailing // comments that begin on the line where the current node ends, are considered part of that node.

Deprecated:
The JDOM was made obsolete by the addition in 2.0 of the more powerful, fine-grained DOM/AST API found in the org.eclipse.jdt.core.dom package.
See also:
org.eclipse.jdt.core.jdom.IDOMNode
 
 public abstract class DOMNode implements IDOMNode {

The first child of this node - null when this node has no children. (Children of a node are implemented as a doubly linked list).
 
 	protected DOMNode fFirstChildnull;

The last child of this node - null when this node has no children. Used for efficient access to the last child when adding new children at the end of the linked list of children.
 
 	protected DOMNode fLastChildnull;

The sibling node following this node - null for the last node in the sibling list.
 
 	protected DOMNode fNextNodenull;

The parent of this node. A null parent indicates that this node is a root node of a document fragment.
 
 	protected DOMNode fParentnull;

The sibling node preceding this node - null for the first node in the sibling list.
 
 	protected DOMNode fPreviousNodenull;

True when this node has attributes that have been altered from their original state in the shared document, or when the attributes of a descendant have been altered. False when the contents of this node and all descendants are consistent with the content of the shared document.
 
	protected boolean fIsFragmentedfalse;

The name of this node. For efficiency, the name of a node is duplicated in this variable on creation, rather than always having to fetch the name from the shared document.
	protected String  fNamenull;

The original inclusive indicies of this node's name in the shared document. Values of -1 indiciate the name does not exist in the document.
	protected int[]	  fNameRange;

The shared document that the contents for this node are contained in. Attribute indicies are positions in this character array.
	protected char[]  fDocumentnull;

The original entire inclusive range of this node's contents within its document. Values of -1 indicate the contents of this node do not exist in the document.
	protected int[] fSourceRange;

The current state of bit masks defined by this node. Initially all bit flags are turned off. All bit masks are defined by this class to avoid overlap, although bit masks are node type specific.

	protected int fStateMask= 0;

This position is the position of the end of the last line separator before the closing brace starting position of the receiver.
	protected int fInsertionPosition;

A bit mask indicating this field has an initializer expression
	protected static final int MASK_FIELD_HAS_INITIALIZER= 0x00000001;

A bit mask indicating this field is a secondary variable declarator for a previous field declaration.
	protected static final int MASK_FIELD_IS_VARIABLE_DECLARATOR= 0x00000002;

A bit mask indicating this field's type has been altered from its original contents in the document.
	protected static final int MASK_FIELD_TYPE_ALTERED= 0x00000004;

A bit mask indicating this node's name has been altered from its original contents in the document.
	protected static final int MASK_NAME_ALTERED= 0x00000008;

A bit mask indicating this node currently has a body.
	protected static final int MASK_HAS_BODY= 0x00000010;

A bit mask indicating this node currently has a preceding comment.
	protected static final int MASK_HAS_COMMENT= 0x00000020;

A bit mask indicating this method is a constructor.
	protected static final int MASK_IS_CONSTRUCTOR= 0x00000040;

A bit mask indicating this type is a class.
	protected static final int MASK_TYPE_IS_CLASS= 0x00000080;

A bit mask indicating this type has a superclass (requires or has an 'extends' clause).
	protected static final int MASK_TYPE_HAS_SUPERCLASS= 0x00000100;

A bit mask indicating this type implements or extends some interfaces
	protected static final int MASK_TYPE_HAS_INTERFACES= 0x00000200;

A bit mask indicating this return type of this method has been altered from the original contents.
	protected static final int MASK_RETURN_TYPE_ALTERED= 0x00000400;

A bit mask indicating this node has detailed source indexes
	protected static final int MASK_DETAILED_SOURCE_INDEXES = 0x00000800;

Creates a new empty document fragment.
	this.null;
	this.null;
	this.new int[]{-1, -1};
	this.new int[]{-1, -1};
Creates a new document fragment on the given range of the document.

Parameters:
document - the document containing this node's original contents
sourceRange - a two element array of integers describing the entire inclusive source range of this node within its document. Contents start on and include the character at the first position. Contents end on and include the character at the last position. An array of -1's indicates this node's contents do not exist in the document.
name - the identifier portion of the name of this node, or null if this node does not have a name
nameRange - a two element array of integers describing the entire inclusive source range of this node's name within its document, including any array qualifiers that might immediately follow the name or -1's if this node does not have a name.
DOMNode(char[] documentint[] sourceRangeString nameint[] nameRange) {
	super();
	this.document;
	this.sourceRange;
	this.name;
	this.nameRange;
Adds the given un-parented node (document fragment) as the last child of this node.

When a child is added, this node must be considered fragmented such that the contents of this node are properly generated.

public void addChild(IDOMNode childthrows IllegalArgumentExceptionDOMException {
	// if the node is a constructor, it must also be fragmented to update the constructor's name
	if (child.getNodeType() == . && ((IDOMMethod)child).isConstructor()) {
		((DOMNode)child).fragment();
else {
	}
Appends the current contents of this document fragment to the given CharArrayBuffer.

If this node is fragmented, contents must be generated by using the original document and indicies as a form for the current attribute values of this node. If this node not fragmented, the contents can be obtained from the document.

protected void appendContents(CharArrayBuffer buffer) {
	if (isFragmented()) {
else {
		buffer.append(this.this.[0], this.[1] + 1 - this.[0]);
	}
Appends the contents of all children of this node to the given CharArrayBuffer.

This algorithm used minimizes String generation by merging adjacent unfragmented children into one substring operation.

protected void appendContentsOfChildren(CharArrayBuffer buffer) {
	DOMNode childthis.;
	DOMNode sibling;
	int start= 0, end= 0;
	if (child != null) {
		startchild.getStartPosition();
		endchild.getEndPosition();
	}
	while (child != null) {
		siblingchild.fNextNode;
		if (sibling != null) {
			if (sibling.isContentMergableWith(child)) {
				endsibling.getEndPosition();
else {
				if (child.isFragmented()) {
					child.appendContents(buffer);
else {
					buffer.append(child.getDocument(), startend + 1 - start);
				}
				startsibling.getStartPosition();
				endsibling.getEndPosition();
			}
else {
			if (child.isFragmented()) {
				child.appendContents(buffer);
else {
				buffer.append(child.getDocument(), startend + 1 - start);
			}
		}
		childsibling;
	}
Appends the contents of this node to the given CharArrayBufer, using the original document and indicies as a form for the current attribute values of this node.
protected abstract void appendFragmentedContents(CharArrayBuffer buffer);
Adds the given un-parented node (document fragment) as the last child of this node without setting this node's 'fragmented' flag. This method is only used by the DOMBuilder when creating a new DOM such that a new DOM is unfragmented.
	// verify child may be added
	if (!canHaveChildren()) {
	}
	if (child == null) {
	}
	if (!isAllowableChild(child)) {
	}
	if (child.getParent() != null) {
	}
	/* NOTE: To test if the child is an ancestor of this node, we
	 * need only test if the root of this node is the child (the child
	 * is already a root since we have just guarenteed it has no parent).
	 */
	if (child == getRoot()) {
	}
	DOMNode node= (DOMNode)child;
	// if the child is not already part of this document, localize its contents
	// before adding it to the tree
	if (node.getDocument() != getDocument()) {
	}
	// add the child last
	if (this. == null) {
		// this is the first and only child
		this.node;
else {
		this..node;
		node.fPreviousNodethis.;
	}
	this.node;
	node.fParentthis;
Generates detailed source indexes for this node if possible.

Throws:
org.eclipse.jdt.core.jdom.DOMException if unable to generate detailed source indexes for this node
protected void becomeDetailed() throws DOMException {
	if (!isDetailed()) {
		DOMNode detailedgetDetailedNode();
		if (detailed == null) {
		}
		if (detailed != this) {
			shareContents(detailed);
		}
	}
Returns true if this node is allowed to have children, otherwise false.

Default implementation of IDOMNode interface method returns false; this method must be overridden by subclasses that implement nodes that allow children.

public boolean canHaveChildren() {
	return false;
public Object clone() {
	// create a new buffer with all my contents and children contents
	int length= 0;
	char[] buffernull;
	int offsetthis.[0];
	if (offset >= 0) {
		lengththis.[1] - offset + 1;
		buffernew char[length];
		System.arraycopy(this.offsetbuffer, 0, length);
	}
	DOMNode clonenewDOMNode();
	clone.shareContents(this);
	clone.fDocument = buffer;
	if (offset > 0) {
		clone.offset(0 - offset);
	}
	// clone my children
	if (canHaveChildren()) {
		Enumeration childrengetChildren();
		while (children.hasMoreElements()) {
			DOMNode child= (DOMNode)children.nextElement();
			if (child.fDocument == this.) {
				DOMNode childClonechild.cloneSharingDocument(bufferoffset);
				clone.basicAddChild(childClone);
else {
				DOMNode childClone= (DOMNode)child.clone();
				clone.addChild(childClone);
			}
		}
	}
	return clone;
private DOMNode cloneSharingDocument(char[] documentint rootOffset) {
	DOMNode clone = newDOMNode();
	clone.shareContents(this);
	clone.fDocument = document;
	if (rootOffset > 0) {
		clone.offset(0 - rootOffset);
	}
	if (canHaveChildren()) {
		Enumeration children = getChildren();
		while (children.hasMoreElements()) {
			DOMNode child = (DOMNodechildren.nextElement();
			if (child.fDocument == this.) {
				DOMNode childClonechild.cloneSharingDocument(documentrootOffset);
				clone.basicAddChild(childClone);
else {
				DOMNode childClone= (DOMNode)child.clone();
				clone.addChild(childClone);
			}
		}
	}
	return clone;
Sets this node's fragmented flag and all ancestor fragmented flags to true. This happens when an attribute of this node or a descendant node has been altered. When a node is fragmented, its contents must be generated from its attributes and original "form" rather than from the original contents in the document.
protected void fragment() {
	if (!isFragmented()) {
		this.true;
		if (this. != null) {
		}
	}
public char[] getCharacters() {
	return buffer.getContents();
public IDOMNode getChild(String name) {
	DOMNode child = this.;
	while (child != null) {
		String n = child.getName();
		if (name == null) {
			if (n == null) {
				return child;
			}
else {
			if (name.equals(n)) {
				return child;
			}
		}
		child = child.fNextNode;
	}
	return null;
	return new SiblingEnumeration(this.);
Returns the current contents of this document fragment, or null if this node has no contents.

If this node is fragmented, contents must be generated by using the original document and indicies as a form for the current attribute values of this node. If this node not fragmented, the contents can be obtained from the document.

public String getContents() {
	return buffer.toString();
Returns a new document fragment representing this node with detailed source indexes. Subclasses that provide a detailed implementation must override this method.
protected DOMNode getDetailedNode() {
	return this;
Returns the document containing this node's original contents. The document may be shared by other nodes.
protected char[] getDocument() {
	return this.;
Returns the original position of the last character of this node's contents in its document.
public int getEndPosition() {
	return this.[1];
Returns a factory with which to create new document fragments.
protected IDOMFactory getFactory() {
	return new DOMFactory();
	return this.;
Returns the position at which the first child of this node should be inserted.
public int getInsertionPosition() {
	return this.;
Returns true if the given mask of this node's state flag is turned on, otherwise false.
protected boolean getMask(int mask) {
	return (this. & mask) > 0;
public String getName() {
	return this.;
Returns the source code to be used for this node's name.
protected char[] getNameContents() {
	if (isNameAltered()) {
		return this..toCharArray();
else {
		if (this. == null || this.[0] < 0) {
			return null;
else {
			int length = this.[1] + 1 - this.[0];
			char[] result = new char[length];
			System.arraycopy(this.this.[0], result, 0, length);
			return result;
		}
	}
public IDOMNode getNextNode() {
	return this.;
public IDOMNode getParent() {
	return this.;
Answers a source position which corresponds to the end of the parent element's declaration.
protected int getParentEndDeclaration() {
	IDOMNode parent = getParent();
	if (parent == null) {
		return 0;
else {
		if (parent instanceof IDOMCompilationUnit) {
			return 0;
else {
			return ((DOMType)parent).getOpenBodyEnd();
		}
	}
	return this.;
Returns the root node of this document fragment.
protected IDOMNode getRoot() {
	if (this. == null) {
		return this;
else {
		return this..getRoot();
	}
Returns the original position of the first character of this node's contents in its document.
public int getStartPosition() {
	return this.[0];
public void insertSibling(IDOMNode siblingthrows IllegalArgumentExceptionDOMException {
	// verify sibling may be added
	if (sibling == null) {
	}
	if (this. == null) {
	}
	if (!this..isAllowableChild(sibling)) {
	}
	if (sibling.getParent() != null) {
	}
	/* NOTE: To test if the sibling is an ancestor of this node, we
	 * need only test if the root of this node is the child (the sibling
	 * is already a root since we have just guaranteed it has no parent).
	 */
	if (sibling == getRoot()) {
	}
	DOMNode node= (DOMNode)sibling;
	// if the sibling is not already part of this document, localize its contents
	// before inserting it into the tree
	if (node.getDocument() != getDocument()) {
	}
	// insert the node
	if (this. == null) {
		this..node;
else {
	}
	node.fParentthis.;
	node.fPreviousNodethis.;
	node.fNextNodethis;
	this.node;
	// if the node is a constructor, it must also be fragmented to update the constructor's name
	if (node.getNodeType() == . && ((IDOMMethod)node).isConstructor()) {
		node.fragment();
else {
	}
public boolean isAllowableChild(IDOMNode node) {
	return false;
Returns true if the contents of this node are from the same document as the given node, the contents of this node immediately follow the contents of the given node, and neither this node or the given node are fragmented - otherwise false.
protected boolean isContentMergableWith(DOMNode node) {
	return !node.isFragmented() && !isFragmented() && node.getDocument() == getDocument() &&
		node.getEndPosition() + 1 == getStartPosition();
Returns true if this node has detailed source index information, or false if this node has limited source index information. To perform some manipulations, detailed indexes are required.
protected boolean isDetailed() {
Returns true if this node's or a descendant node's contents have been altered since this node was created. This indicates that the contents of this node are no longer consistent with the contents of this node's document.
protected boolean isFragmented() {
	return this.;
Returns true if this noed's name has been altered from the original document contents.
protected boolean isNameAltered() {

See also:
org.eclipse.jdt.core.jdom.IDOMNode.isSignatureEqual(org.eclipse.jdt.core.jdom.IDOMNode)

By default, the signatures of two nodes are equal if their type and names are equal. Node types that have other requirements for equality must override this method.

public boolean isSignatureEqual(IDOMNode node) {
	return getNodeType() == node.getNodeType() && getName().equals(node.getName());
Localizes the contents of this node and all descendant nodes, such that this node is no longer dependent on its original document in order to generate its contents. This node and all descendant nodes become unfragmented and share a new document.
protected void localizeContents() {
	DOMNode clone= (DOMNode)clone();
Returns a new empty DOMNode for this instance.
protected abstract DOMNode newDOMNode();
Normalizes this DOMNode's source positions to include whitespace preceeding the node on the line on which the node starts, and all whitespace after the node up to the next node's start
void normalize(ILineStartFinder finder) {
	if (getPreviousNode() == null)
	// Set the children's position
	if (canHaveChildren()) {
		Enumeration children = getChildren();
		while(children.hasMoreElements())
			((DOMNode)children.nextElement()).normalize(finder);
	}
Normalizes this DOMNode's end position.
	if (next == null) {
		// this node's end position includes all of the characters up
		// to the end of the enclosing node
		DOMNode parent = (DOMNodegetParent();
		if (parent == null || parent instanceof DOMCompilationUnit) {
			setSourceRangeEnd(this..length - 1);
else {
			// parent is a type
			int temp = ((DOMType)parent).getCloseBodyPosition() - 1;
			this. = Math.max(finder.getLineStart(temp + 1), getEndPosition());
		}
else {
		// this node's end position is just before the start of the next node
		int temp = next.getStartPosition() - 1;
		this. = Math.max(finder.getLineStart(temp + 1), getEndPosition());
	}
Normalizes this DOMNode's start position.
void normalizeStartPosition(int previousEndILineStartFinder finder) {
	int nodeStart = getStartPosition();
	int lineStart = finder.getLineStart(nodeStart);
	if (nodeStart > lineStart && (lineStart > previousEnd || (previousEnd == 0 && lineStart == 0)))
		setStartPosition(lineStart);
Offsets all the source indexes in this node by the given amount.
protected void offset(int offset) {
	offsetRange(this.offset);
	offsetRange(this.offset);
Offsets the source range by the given amount
protected void offsetRange(int[] rangeint offset) {
	for (int i= 0; i < range.lengthi++) {
		range[i]+=offset;
		if (range[i] < 0) {
			range[i]= -1;
		}
	}
Returns a copy of the given range.
protected int[] rangeCopy(int[] range) {
	int[] copynew int[range.length];
	for (int i= 0; i < range.lengthi++) {
		copy[i]= range[i];
	}
	return copy;
Separates this node from its parent and siblings, maintaining any ties that this node has to the underlying document fragment.

When a child is removed, its parent is fragmented such that it properly generates its contents.

public void remove() {
	if (this. != null) {
	}
	// link siblings
	if (this. != null) {
	}
	if (this. != null) {
	}
	// fix parent's pointers
	if (this. != null) {
		if (this.. == this) {
		}
		if (this.. == this) {
		}
	}
	// remove myself
	this.null;
	this.null;
	this.null;
Sets the specified mask of this node's state mask on or off based on the boolean value - true -> on, false -> off.
protected void setMask(int maskboolean on) {
	if (on) {
		this. |= mask;
else {
		this. &= ~mask;
	}
public void setName(String name) {
	this.name;
Sets the state of this node as having its name attribute altered from the original document contents.
protected void setNameAltered(boolean altered) {
Sets the original position of the last character of this node's contents in its document. This method is only used during DOM creation while normalizing the source range of each node.
protected void setSourceRangeEnd(int end) {
	this.[1]= end;
Sets the original position of the first character of this node's contents in its document. This method is only used during DOM creation while normalizing the source range of each node.
protected void setStartPosition(int start) {
	this.[0]= start;
Sets the contents of this node and descendant nodes to be the (identical) contents of the given node and its descendants. This does not effect this node's parent and sibling configuration, only the contents of this node. This is used only to localize the contents of this node.
protected void shareContents(DOMNode node) {
	this.node.fDocument;
	this.node.fIsFragmented;
	this.node.fName;
	this.rangeCopy(node.fNameRange);
	this.rangeCopy(node.fSourceRange);
	this.node.fStateMask;
	if (canHaveChildren()) {
		Enumeration myChildrengetChildren();
		Enumeration otherChildrennode.getChildren();
		DOMNode myChildotherChild;
		while (myChildren.hasMoreElements()) {
			myChild= (DOMNode)myChildren.nextElement();
			otherChild= (DOMNode)otherChildren.nextElement();
			myChild.shareContents(otherChild);
		}
	}
Returns a String representing this node - for Debug purposes only.
public abstract String toString();
New to GrepCode? Check out our FAQ X