blob: 5862e49ce63ed2396be0f2dfc7af871cd158786b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2012 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.bpel.ui.details.providers;
import org.eclipse.bpel.ui.details.tree.ITreeNode;
import org.eclipse.jface.viewers.Viewer;
/**
* A content provider for a tree of ITreeNode objects representing some expansion of
* the underlying graph of model objects. CachedTreeContentProvider keeps track of the
* parent relationships so the ITreeNode objects don't have to; however, the ITreeNode
* objects *must have unique parents*, so our model objects can't represent themselves
* directly. After all, our model is a graph, not a tree. Another reason to wrap our
* model objects in ITreeNode objects is that there may be different tree expansions
* of a particular model object in different contexts (e.g. variable/property versus
* variable/part/query).
*
* To programatically expose a particular branch of the tree, you must first walk down
* the content provider from the root to the ITreeNode you want to expose (causing the
* necessary ITreeNode objects to be created). Then, you call viewer.expandToLevel()
* on this ITreeNode. Using this content provider, the TreeViewer will walk up from
* the given node to the deepest already-expanded item, then back down again expanding
* the remaining items.
*/
public class ModelTreeContentProvider extends CachedTreeContentProvider {
protected boolean isCondensed;
public ModelTreeContentProvider(boolean isCondensed) {
super();
this.isCondensed = isCondensed;
}
public boolean isCondensed() { return isCondensed; }
@Override
protected Object[] primGetChildren(Object node) {
if (!(node instanceof ITreeNode)) return EMPTY_ARRAY;
return ((ITreeNode)node).getChildren();
}
@Override
protected Object[] primGetElements(Object node) {
return primGetChildren(node);
}
@Override
protected boolean primHasChildren(Object node) {
if (!(node instanceof ITreeNode)) return false;
return ((ITreeNode)node).hasChildren();
}
/**
* Searches each of the nodes in the given array to find the node representing a
* particular modelObject.
*
* If subtreeDepth > 0, the children of each node in the given array are recursively
* searched to a depth of subtreeDepth-1.
*
* Values larger than 1 or 2 should be avoided whenever possible, because all of the
* nodes in the subtree up to subtreeDepth have to be created and cached. The most
* efficient subtreeDepth is 0.
*/
public ITreeNode findModelNode(Object[] nodes, Object modelObject, int subtreeDepth) {
for (int i = 0; i<nodes.length; i++) {
if (!(nodes[i] instanceof ITreeNode)) continue;
ITreeNode treeNode = (ITreeNode)nodes[i];
if (treeNode.getModelObject().equals(modelObject)) return treeNode;
}
ITreeNode result = null;
if (subtreeDepth > 0) {
for (int i = 0; result==null && i<nodes.length; i++) {
result = findModelNode(getChildren(nodes[i]), modelObject, subtreeDepth-1);
}
}
return result;
}
/* IContentProvider */
@Override
public void dispose() {
super.dispose();
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
super.inputChanged(viewer, oldInput, newInput);
// TODO: hook model listener?
}
}