KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > watson > ElementTreeDelta


1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.watson;
12
13 import java.util.Vector JavaDoc;
14 import org.eclipse.core.internal.dtree.*;
15 import org.eclipse.core.runtime.IPath;
16 import org.eclipse.core.runtime.Path;
17
18 /**
19  * Describes the differences between two element trees.
20  * Specifically, an ElementTreeDelta describes the changes that
21  * have been made to the tree returned by getParent() to obtain the
22  * tree returned by getElementTree().
23  *
24  * ElementTreeDeltas are meant to be treated as light-weight query structures
25  * with a relatively short lifespan. Deltas cannot be serialized.
26  *
27  * ElementTreeDeltas support pluggable logic for delta calculation. By
28  * implementing the IElementComparator interface, the client can specify
29  * the kind of change (addition, removal, etc) to any given element based
30  * on the element's data.
31  *
32  * There are two ways of navigating ElementTreeDeltas. First, one
33  * can get a handle on an ElementDelta using the getElementDelta() method.
34  * The ElementDelta can then be queried for its children, using a filter
35  * interface called IDeltaFilter. Clients can create implementations of
36  * IDeltaFilter to navigate deltas based on various characteristics of
37  * The delta elements.
38  * @see IDeltaFilter
39  * @see IElementComparator
40  *
41  * The second way of navigating element tree deltas is using the DeltaIterator.
42  * The client provides an implementation of IDeltaVisitor that specifies
43  * the code to be executed for each element of the delta.
44  * @see DeltaIterator
45  * @see IDeltaVisitor
46  *
47  * @see ElementTree#computeDeltaWith(ElementTree, IElementComparator)
48  * @see ElementTree#computeDeltaWith(ElementTree, IElementComparator, IPath)
49  */

50 public class ElementTreeDelta {
51
52     protected IElementComparator comparator;
53     protected DeltaDataTree deltaTree;
54     protected ElementTree elementTree;
55     protected ElementTree parent;
56
57     /**
58      * Path of the root of the subtree that this delta is for.
59      */

60     protected IPath rootPath;
61
62     /**
63      * Creates a delta describing the changes between the two given trees.
64      */

65     ElementTreeDelta(ElementTree parent, ElementTree elementTree, IElementComparator comparator) {
66         initialize(parent, elementTree, comparator);
67         deltaTree = elementTree.getDataTree().compareWith(parent.getDataTree(), comparator).asReverseComparisonTree(comparator);
68         rootPath = Path.ROOT;
69     }
70
71     /**
72      * Creates a delta describing the changes between the two given trees, starting
73      * at the given path.
74      */

75     ElementTreeDelta(ElementTree parent, ElementTree elementTree, IElementComparator comparator, IPath path) {
76         initialize(parent, elementTree, comparator);
77         deltaTree = parent.getDataTree().compareWith(elementTree.getDataTree(), comparator, path);
78         rootPath = path;
79     }
80
81     /**
82      * Destroys this delta and drops references to all trees deltas referenced herein.
83      */

84     public void destroy() {
85         comparator = null;
86         deltaTree = null;
87         elementTree = null;
88         parent = null;
89         rootPath = null;
90     }
91
92     /**
93      * Returns deltas describing the children of the specified element that
94      * match the given filter query. Must be called only when parentID
95      * represents a changed element, not an added or removed element.
96      */

97     protected ElementDelta[] getAffectedElements(IPath parentID, IDeltaFilter filter) {
98         IPath parentKey;
99         if (parentID == null) {
100             parentKey = deltaTree.rootKey();
101         } else {
102             parentKey = parentID;
103         }
104         Vector JavaDoc v = new Vector JavaDoc();
105         IPath[] childKeys = deltaTree.getChildren(parentKey);
106
107         for (int i = 0; i < childKeys.length; ++i) {
108             IPath key = childKeys[i];
109
110             /* return delta info based on user comparison */
111             NodeComparison nodeComparison = (NodeComparison) deltaTree.getData(key);
112             int userComparison = nodeComparison.getUserComparison();
113             if (filter.includeElement(userComparison)) {
114                 v.addElement(new ElementDelta(this, rootPath.append(key), key, nodeComparison));
115             }
116         }
117
118         ElementDelta[] result = new ElementDelta[v.size()];
119         v.copyInto(result);
120         return result;
121     }
122
123     /**
124      * Returns the delta tree
125      */

126     /*package*/DeltaDataTree getDeltaTree() {
127         return deltaTree;
128     }
129
130     /**
131      * Returns the delta for the specified element, or null if the
132      * element is not affected in this delta.
133      */

134     public ElementDelta getElementDelta(IPath key) {
135
136         if (key == null) {
137             throw new IllegalArgumentException JavaDoc();
138         }
139
140         try {
141             NodeComparison nodeComparison = (NodeComparison) deltaTree.getData(key);
142             return new ElementDelta(this, rootPath.append(key), key, nodeComparison);
143         } catch (ObjectNotFoundException e) {
144             return null;
145         }
146     }
147
148     /**
149      * Returns the element tree which this delta describes,
150      * when its changes are applied to the parent tree.
151      * It is also referred to as the 'new' tree.
152      */

153     public ElementTree getElementTree() {
154         return elementTree;
155     }
156
157     /**
158      * Returns the element tree that this delta is based on.
159      * It is also referred to as the 'old' tree.
160      */

161     public ElementTree getParent() {
162         return parent;
163     }
164
165     /**
166      * Return true if there are deltas describing affected children of the specified element.
167      * Must be called only when parentID represents a changed element, not an added or removed element.
168      */

169     protected boolean hasAffectedElements(IPath parentID, IDeltaFilter filter) {
170         IPath parentKey = parentID == null ? deltaTree.rootKey() : parentID;
171
172         IPath[] childKeys = deltaTree.getChildren(parentKey);
173         for (int i = 0; i < childKeys.length; ++i) {
174             NodeComparison nodeComparison = (NodeComparison) deltaTree.getData(childKeys[i]);
175             if (filter.includeElement(nodeComparison.getUserComparison())) {
176                 return true;
177             }
178         }
179         return false;
180     }
181
182     /**
183      * Initializes the tree delta
184      */

185     private void initialize(ElementTree parent, ElementTree elementTree, IElementComparator comparator) {
186         parent.immutable();
187         elementTree.immutable();
188         this.parent = parent;
189         this.elementTree = elementTree;
190         this.comparator = comparator;
191     }
192 }
Popular Tags