blob: 06340107a0af2c9e693d1467b389e4c3fb914614 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2007 Boeing.
* 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:
* Boeing - initial API and implementation
*******************************************************************************/
package org.eclipse.osee.framework.ui.swt;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.core.runtime.IAdaptable;
/**
* @author Robert A. Fisher
*/
public class TreeNode implements ITreeNode, Serializable {
private static final long serialVersionUID = -4932401485883022954L;
private ITreeNode parent;
protected Object[] children;
private Object backingData;
/**
* Constructor for serialization.
*/
protected TreeNode() {
}
/**
* Create a stand alone node backed by some data.
*/
public TreeNode(Object backingData) {
this(null, null, backingData);
}
/**
* @param parent
* @param children
* @param backingData
*/
public TreeNode(ITreeNode parent, Object[] children, Object backingData) {
this.parent = parent;
this.children = children;
this.backingData = backingData;
}
public Object[] getChildren() {
return children;
}
public void setChildren(Object[] objChildren) {
if (objChildren == null) {
this.children = new Object[0];
} else {
Collection<Object> newChildren = new ArrayList<Object>(objChildren.length);
for (Object obj : objChildren)
newChildren.add((obj instanceof ITreeNode) ? obj : getChild(obj));
this.children = newChildren.toArray();
}
}
public Object getBackingData() {
return backingData;
}
public ITreeNode getParent() {
return parent;
}
/**
* Subclasses should override this method so that calls to setChildren(objChildren) will result in a set of children
* that matches the subclass. The default implementation will setup the children as TreeNode's.
*
* @param backingData The data that should be placed on the child.
* @return A new node for the backing data.
*/
protected ITreeNode getChild(Object backingData) {
return new TreeNode(this, null, backingData);
}
/**
* Recursively fill a node from a content provider runnable. If an exception is thrown from the provider then it will
* be set as the child of the node.
*
* @param node
* @param provider
*/
public static void fillNode(ITreeNode node, IContentProviderRunnable provider) {
try {
node.setChildren(provider.run(node.getBackingData()));
for (Object child : node.getChildren())
fillNode((ITreeNode) child, provider);
} catch (Exception e) {
node.setChildren(new Object[] {e});
}
}
@SuppressWarnings("unchecked")
public Object getAdapter(Class adapter) {
if (adapter == null)
throw new IllegalArgumentException("adapter can not be null");
else if (backingData instanceof IAdaptable) {
return ((IAdaptable) backingData).getAdapter(adapter);
}
else if (adapter.isInstance(backingData)) {
return backingData;
}
else if (adapter.isInstance(this)) {
return this;
}
return null;
}
}