Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: cfe37bbf25ca8fd3b9f405d92b8084409086e1f4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
/*******************************************************************************
 * Copyright (c) 2011, 2012 Wind River Systems, Inc. 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:
 * Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.core.model;

import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.tcf.te.core.interfaces.IPropertyChangeProvider;
import org.eclipse.tcf.te.core.interfaces.IViewerInput;
import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback;
import org.eclipse.tcf.te.tcf.core.Tcf;
import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModelProvider;

/**
 * The base class of FSTreeNode and ProcessTreeNode which provides base members and methods.
 */
public abstract class AbstractTreeNode extends PlatformObject implements IPeerModelProvider{
	// The unique id of this node.
	protected final UUID uniqueId = UUID.randomUUID();

	/**
	 * The tree node name.
	 */
	public String name = null;

	/**
	 * The tree node type.
	 */
	public String type = null;

	/**
	 * The peer node the file system tree node is associated with.
	 */
	public IPeerModel peerNode = null;

	/**
	 * Flag to mark once the children of the node got queried
	 */
	public boolean childrenQueried = false;

	/**
	 * Flag to mark once the children query is running
	 */
	public boolean childrenQueryRunning = false;

	/**
	 * The tree node parent.
	 */
	protected AbstractTreeNode parent = null;

	/**
	 * The tree node children.
	 */
	protected List<AbstractTreeNode> children = Collections.synchronizedList(new ArrayList<AbstractTreeNode>());

	/*
	 * (non-Javadoc)
	 *
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public final int hashCode() {
		return uniqueId.hashCode();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public final boolean equals(Object obj) {
		if(this == obj)
			return true;
		if (obj instanceof AbstractTreeNode) {
			return uniqueId.equals(((AbstractTreeNode) obj).uniqueId);
		}
		return super.equals(obj);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		StringBuilder buffer = new StringBuilder(getClass().getSimpleName());
		buffer.append(": name=" + (name != null ? name : super.toString())); //$NON-NLS-1$
		buffer.append(", UUID=" + uniqueId.toString()); //$NON-NLS-1$
		return buffer.toString();
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModelProvider#getPeerModel()
	 */
	@Override
    public IPeerModel getPeerModel() {
	    return peerNode;
    }
	
	/**
	 * Called when the children query is done.
	 */
	public void queryDone() {
		childrenQueryRunning = false;
		childrenQueried = true;
		PropertyChangeEvent event = new PropertyChangeEvent(this, "query_done", Boolean.FALSE, Boolean.TRUE); //$NON-NLS-1$
		firePropertyChange(event);
	}
	
	/**
	 * Called when the children query is started.
	 */
	public void queryStarted() {
		childrenQueryRunning = true;
		PropertyChangeEvent event = new PropertyChangeEvent(this, "query_started", Boolean.FALSE, Boolean.TRUE); //$NON-NLS-1$
		firePropertyChange(event);
	}
	
	
	/**
	 * Fire a property change event to notify one of the node's property has changed.
	 * 
	 * @param event The property change event.
	 */
	public void firePropertyChange(PropertyChangeEvent event) {
		if(peerNode != null) {
			IViewerInput viewerInput = (IViewerInput) peerNode.getAdapter(IViewerInput.class);
			viewerInput.firePropertyChange(event);
		} else if(parent != null) {
			parent.firePropertyChange(event);
		}
    }

	/**
	 * Add the specified nodes to the children list.
	 * 
	 * @param nodes The nodes to be added.
	 */
	public void addChidren(List<? extends AbstractTreeNode> nodes) {
		children.addAll(nodes);
		PropertyChangeEvent event = new PropertyChangeEvent(this, "addChildren", null, null); //$NON-NLS-1$
		firePropertyChange(event);
    }

	/**
	 * Remove the specified nodes from the children list.
	 * 
	 * @param nodes The nodes to be removed.
	 */
	public void removeChildren(List<? extends AbstractTreeNode> nodes) {
		children.removeAll(nodes);
		PropertyChangeEvent event = new PropertyChangeEvent(this, "removeChildren", null, null); //$NON-NLS-1$
		firePropertyChange(event);
    }

	/**
	 * Add the specified the node to the children list.
	 * 
	 * @param node The child node to be added.
	 */
	public void addChild(AbstractTreeNode node) {
		children.add(node);
		PropertyChangeEvent event = new PropertyChangeEvent(this, "addChild", null, null); //$NON-NLS-1$
		firePropertyChange(event);
    }

	/**
	 * Remove the specified child node from its children list.
	 * 
	 * @param node The child node to be removed.
	 */
	public void removeChild(AbstractTreeNode node) {
		children.remove(node);
		PropertyChangeEvent event = new PropertyChangeEvent(this, "removeChild", null, null); //$NON-NLS-1$
		firePropertyChange(event);
    }

	/**
	 * Clear the children of this folder.
	 */
	public void clearChildren() {
		children.clear();
		PropertyChangeEvent event = new PropertyChangeEvent(this, "clearChildren", null, null); //$NON-NLS-1$
		firePropertyChange(event);
    }

	/**
	 * If this node is ancestor of the specified node.
	 * @return true if it is.
	 */
	public boolean isAncestorOf(AbstractTreeNode node) {
		if (node == null) return false;
		if (node.parent == this) return true;
		return isAncestorOf(node.parent);
	}

	/**
	 * Get the parent node of this node.
	 * 
	 * @return The parent node.
	 */
	public AbstractTreeNode getParent() {
		return parent;
	}
	
	/**
	 * Set the parent node of this node.
	 * 
	 * @param parent The parent node.
	 */
	public void setParent(AbstractTreeNode parent) {
		this.parent = parent;
	}

	/**
	 * Recursively refresh the children of the given process context.
	 *
	 * @param parentNode The process context node. Must not be <code>null</code>.
	 */
	public void refresh() {
		refresh(null);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
	 */
	@SuppressWarnings("rawtypes")
    @Override
    public Object getAdapter(Class adapter) {
		if(IPropertyChangeProvider.class.equals(adapter)) {
			return peerNode.getAdapter(adapter);
		}
	    return super.getAdapter(adapter);
    }

	/**
	 * Recursively refresh the children of the given process context with a callback, which is
	 * called when whole process is finished.
	 *
	 * @param callback The callback object, or <code>null</code> when callback is not needed.
	 */
	public void refresh(ICallback callback) {
		queryStarted();
		Tcf.getChannelManager().openChannel(peerNode.getPeer(), null, doCreateRefreshDoneOpenChannel(callback));
	}

	/**
	 * Create the callback object of opening channel for refreshing itself.
	 * 
	 * @param callback The callback object.
	 * @return The callback object.
	 */
	protected abstract DoneOpenChannel doCreateRefreshDoneOpenChannel(ICallback callback);

	/**
	 * Query the children of this file system node.
	 */
	public void queryChildren() {
		queryChildren(null);
	}
	/**
	 * Query the children of this file system node.
	 */
	public void queryChildren(ICallback callback) {
		queryStarted();
		Tcf.getChannelManager().openChannel(peerNode.getPeer(), null, doCreateQueryDoneOpenChannel(callback));
	}

	/**
	 * Create the callback object of opening channel for querying children.
	 * 
	 * @return The callback object.
	 */
	protected abstract DoneOpenChannel doCreateQueryDoneOpenChannel(ICallback callback);
	
	/**
	 * Return if this node is the system root.
	 * 
	 * @return true if it is.
	 */
	public abstract boolean isSystemRoot();

	/**
	 * Get the children of this tree node.
	 * 
	 * @return The list of the children.
	 */
	public List<? extends AbstractTreeNode> getChildren() {
		return new ArrayList<AbstractTreeNode>(children);
	}

	/**
	 * Refresh the children's children.
	 */
	public abstract void refreshChildren();
}

Back to the top