org.eclipse.core.internal.watson
Class ElementTree

java.lang.Object
  extended by org.eclipse.core.internal.watson.ElementTree

public class ElementTree
extends java.lang.Object

An ElementTree can be viewed as a generic rooted tree that stores a hierarchy of elements. An element in the tree consists of a (name, data, children) 3-tuple. The name can be any String, and the data can be any Object. The children are a collection of zero or more elements that logically fall below their parent in the tree. The implementation makes no guarantees about the ordering of children. Elements in the tree are referenced by a key that consists of the names of all elements on the path from the root to that element in the tree. For example, if root node "a" has child "b", which has child "c", element "c" can be referenced in the tree using the key (/a/b/c). Keys are represented using IPath objects, where the Paths are relative to the root element of the tree.

See Also:
Each ElementTree has a single root element that is created implicitly and is always present in any tree. This root corresponds to the key (/), or the singleton Path.ROOT. The root element cannot be created or deleted, and its data and name cannot be set. The root element's children however can be modified (added, deleted, etc). The root path can be obtained using the getRoot() method. ElementTrees are modified in generations. The method newEmptyDelta() returns a new tree generation that can be modified arbitrarily by the user. For the purpose of explanation, we call such a tree "active". When the method immutable() is called, that tree generation is frozen, and can never again be modified. A tree must be immutable before a new tree generation can start. Since all ancestor trees are immutable, different active trees can have ancestors in common without fear of thread corruption problems. Internally, any single tree generation is simply stored as the set of changes between itself and its most recent ancestor (its parent). This compact delta representation allows chains of element trees to be created at relatively low cost. Clients of the ElementTree can instantaneously "undo" sets of changes by navigating up to the parent tree using the getParent() method. Although the delta representation is compact, extremely long delta chains make for a large structure that is potentially slow to query. For this reason, the client is encouraged to minimize delta chain lengths using the collapsing(int) and makeComplete() methods. The getDeltaDepth() method can be used to discover the length of the delta chain. The entire delta chain can also be re-oriented in terms of the current element tree using the reroot() operation. Classes are also available for tree serialization and navigation., ElementTreeReader, ElementTreeWriter, Finally, why are ElementTrees in a package called "watson"? - "It's ElementTree my dear Watson, ElementTree."

Constructor Summary
ElementTree()
          Creates a new empty element tree.
 
Method Summary
 ElementTree collapseTo(ElementTree parent)
          Collapses this tree so that the given ancestor becomes its immediate parent.
 void createElement(org.eclipse.core.runtime.IPath key, java.lang.Object data)
          Creates the indicated element and sets its element info.
 void createSubtree(org.eclipse.core.runtime.IPath key, ElementTree subtree)
          Creates or replaces the subtree below the given path with the given tree.
 void deleteElement(org.eclipse.core.runtime.IPath key)
          Deletes the indicated element and its descendents.
static int findOldest(ElementTree[] trees)
          Given an array of element trees, returns the index of the oldest tree.
 int getChildCount(org.eclipse.core.runtime.IPath key)
          Returns the number of children of the element specified by the given path.
 org.eclipse.core.runtime.IPath[] getChildren(org.eclipse.core.runtime.IPath key)
          Returns the paths of the children of the element specified by the given path.
 DeltaDataTree getDataTree()
          Returns the internal data tree.
 java.lang.Object getElementData(org.eclipse.core.runtime.IPath key)
          Returns the element data for the given element identifier.
 java.lang.Object getElementDataIgnoreCase(org.eclipse.core.runtime.IPath key)
          Returns the element data for the given element identifier.
 java.lang.String[] getNamesOfChildren(org.eclipse.core.runtime.IPath key)
          Returns the names of the children of the specified element.
 ElementTree getParent()
          Returns the parent tree, or null if there is no parent.
 org.eclipse.core.runtime.IPath getRoot()
          Returns the root node of this tree.
 ElementTree getSubtree(org.eclipse.core.runtime.IPath key)
          Returns the subtree rooted at the given key.
 IElementTreeData getTreeData()
          Returns the user data associated with this tree.
static boolean hasChanges(ElementTree newLayer, ElementTree oldLayer, IElementComparator comparator, boolean inclusive)
          Returns true if there have been changes in the tree between the two given layers.
 void immutable()
          Makes this tree immutable (read-only); ignored if it is already immutable.
 boolean includes(org.eclipse.core.runtime.IPath key)
          Returns true if this element tree includes an element with the given key, false otherwise.
 boolean includesIgnoreCase(org.eclipse.core.runtime.IPath key)
          Returns true if this element tree includes an element with the given key, ignoring the case of the key, and false otherwise.
 boolean isImmutable()
          Returns whether this tree is immutable.
 ElementTree mergeDeltaChain(org.eclipse.core.runtime.IPath path, ElementTree[] trees)
          Merges a chain of deltas for a certain subtree to this tree.
 ElementTree newEmptyDelta()
          Creates a new element tree which is represented as a delta on this one.
 java.lang.Object openElementData(org.eclipse.core.runtime.IPath key)
          Returns a mutable copy of the element data for the given path.
 void setElementData(org.eclipse.core.runtime.IPath key, java.lang.Object data)
          Sets the element for the given element identifier.
 void setTreeData(IElementTreeData data)
          Sets the user data associated with this tree.
 void shareStrings(StringPool set)
           
 java.lang.String toDebugString()
          Returns a string representation of this element tree's structure suitable for debug purposes.
 java.lang.String toString()
           
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

ElementTree

public ElementTree()
Creates a new empty element tree.

Method Detail

collapseTo

public ElementTree collapseTo(ElementTree parent)
Collapses this tree so that the given ancestor becomes its immediate parent. Afterwards, this tree will still have exactly the same contents, but its internal structure will be compressed.

This operation should be used to collapse chains of element trees created by newEmptyDelta()/immutable().

This element tree must be immutable at the start of this operation, and will be immutable afterwards.

Returns:
this tree.

createElement

public void createElement(org.eclipse.core.runtime.IPath key,
                          java.lang.Object data)
Creates the indicated element and sets its element info. The parent element must be present, otherwise an IllegalArgumentException is thrown. If the indicated element is already present in the tree, its element info is replaced and any existing children are deleted.

Parameters:
key - element key
data - element data, or null

createSubtree

public void createSubtree(org.eclipse.core.runtime.IPath key,
                          ElementTree subtree)
Creates or replaces the subtree below the given path with the given tree. The subtree can only have one child below the root, which will become the node specified by the given key in this tree.

Parameters:
key - The path of the new subtree in this tree.
See Also:
getSubtree(IPath)

deleteElement

public void deleteElement(org.eclipse.core.runtime.IPath key)
Deletes the indicated element and its descendents. The element must be present.


findOldest

public static int findOldest(ElementTree[] trees)
Given an array of element trees, returns the index of the oldest tree. The oldest tree is the tree such that no other tree in the array is a descendent of that tree. Note that this counter-intuitive concept of oldest is based on the ElementTree orientation such that the complete tree is always the newest tree.


getChildCount

public int getChildCount(org.eclipse.core.runtime.IPath key)
Returns the number of children of the element specified by the given path. The given element must be present in this tree.


getChildren

public org.eclipse.core.runtime.IPath[] getChildren(org.eclipse.core.runtime.IPath key)
Returns the paths of the children of the element specified by the given path. The given element must be present in this tree.


getDataTree

public DeltaDataTree getDataTree()
Returns the internal data tree.


getElementData

public java.lang.Object getElementData(org.eclipse.core.runtime.IPath key)
Returns the element data for the given element identifier. The given element must be present in this tree.


getElementDataIgnoreCase

public java.lang.Object getElementDataIgnoreCase(org.eclipse.core.runtime.IPath key)
Returns the element data for the given element identifier. The given element must be present in this tree.


getNamesOfChildren

public java.lang.String[] getNamesOfChildren(org.eclipse.core.runtime.IPath key)
Returns the names of the children of the specified element. The specified element must exist in the tree. If the specified element is null, returns the root element path.


getParent

public ElementTree getParent()
Returns the parent tree, or null if there is no parent.


getRoot

public org.eclipse.core.runtime.IPath getRoot()
Returns the root node of this tree.


getSubtree

public ElementTree getSubtree(org.eclipse.core.runtime.IPath key)
Returns the subtree rooted at the given key. In the resulting tree, the implicit root node (designated by Path.ROOT), has a single child, which is the node specified by the given key in this tree. The subtree must be present in this tree.

See Also:
createSubtree(IPath, ElementTree)

getTreeData

public IElementTreeData getTreeData()
Returns the user data associated with this tree.


hasChanges

public static boolean hasChanges(ElementTree newLayer,
                                 ElementTree oldLayer,
                                 IElementComparator comparator,
                                 boolean inclusive)
Returns true if there have been changes in the tree between the two given layers. The two must be related and new must be newer than old. That is, new must be an ancestor of old.


immutable

public void immutable()
Makes this tree immutable (read-only); ignored if it is already immutable.


includes

public boolean includes(org.eclipse.core.runtime.IPath key)
Returns true if this element tree includes an element with the given key, false otherwise.


includesIgnoreCase

public boolean includesIgnoreCase(org.eclipse.core.runtime.IPath key)
Returns true if this element tree includes an element with the given key, ignoring the case of the key, and false otherwise.


isImmutable

public boolean isImmutable()
Returns whether this tree is immutable.


mergeDeltaChain

public ElementTree mergeDeltaChain(org.eclipse.core.runtime.IPath path,
                                   ElementTree[] trees)
Merges a chain of deltas for a certain subtree to this tree. If this tree has any data in the specified subtree, it will be overwritten. The receiver tree must be open, and it will be made immutable during the merge operation. The trees in the provided array will be replaced by new trees that have been merged into the receiver's delta chain.

Parameters:
path - The path of the subtree chain to merge
trees - The chain of trees to merge. The trees can be in any order, but they must all form a simple ancestral chain.
Returns:
A new open tree with the delta chain merged in.

newEmptyDelta

public ElementTree newEmptyDelta()
Creates a new element tree which is represented as a delta on this one. Initially they have the same content. Subsequent changes to the new tree will not affect this one.


openElementData

public java.lang.Object openElementData(org.eclipse.core.runtime.IPath key)
Returns a mutable copy of the element data for the given path. This copy will be held onto in the most recent delta. ElementTree data MUST implement the IElementTreeData interface for this method to work. If the data does not define that interface this method will fail.


setElementData

public void setElementData(org.eclipse.core.runtime.IPath key,
                           java.lang.Object data)
Sets the element for the given element identifier. The given element must be present in this tree.

Parameters:
key - element identifier
data - element info, or null

setTreeData

public void setTreeData(IElementTreeData data)
Sets the user data associated with this tree.


shareStrings

public void shareStrings(StringPool set)

toDebugString

public java.lang.String toDebugString()
Returns a string representation of this element tree's structure suitable for debug purposes.


toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object