/******************************************************************************* * Copyright (c) 2005, 2007 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.simantics.browsing.ui; import java.util.Arrays; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IAdaptable; /** * A {@link GraphExplorer} tree {@link NodeContext} path denotes a model element * in a tree viewer. Tree path objects have value semantics. A model element is * represented by a path of elements in the tree from the root element to the * leaf element. *
* Clients may instantiate this class. Not intended to be subclassed. *
* *
* Directly imitated for the Simantics browsing framework from JFace
* org.eclipse.jface.viewer.TreePath
class.
*
null
if this
* path has no segments.
*
* @return the first element in this path
*/
public NodeContext getFirstSegment() {
if (segments.length == 0) {
return null;
}
return segments[0];
}
/**
* Returns the last element in this path, or null
if this
* path has no segments.
*
* @return the last element in this path
*/
public NodeContext getLastSegment() {
if (segments.length == 0) {
return null;
}
return segments[segments.length - 1];
}
/**
* @return all the segments in the path as an array
*/
public NodeContext[] getSegments() {
if (segments.length == 0)
return segments;
return Arrays.copyOf(segments, segments.length);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object other) {
if (!(other instanceof NodeContextPath)) {
return false;
}
return equals((NodeContextPath) other);
}
/**
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
if (hash == 0) {
hash = hashCode0();
}
return hash;
}
/**
* Returns a hash code computed from the hash codes of the segments, using
* the given comparer to compute the hash codes of the segments.
*
* @param comparer
* comparer to use or null
if the segments' hash
* codes should be computed by calling their hashCode() methods.
* @return the computed hash code
*/
private int hashCode0() {
int result = 0;
for (int i = 0; i < segments.length; i++) {
result += segments[i].hashCode();
}
return result;
}
/**
* Returns whether this path is equivalent to the given path using the
* specified comparer to compare individual elements.
*
* @param otherPath
* tree path to compare to
* @param comparer
* comparator to use or null
if segments should be
* compared using equals()
* @return whether the paths are equal
*/
public boolean equals(NodeContextPath otherPath) {
if (otherPath == null) {
return false;
}
if (segments.length != otherPath.segments.length) {
return false;
}
for (int i = 0; i < segments.length; i++) {
if (!segments[i].equals(otherPath.segments[i])) {
return false;
}
}
return true;
}
/**
* Returns whether this path starts with the same segments as the given
* path, using the given comparer to compare segments.
*
* @param treePath
* path to compare to
* @param comparer
* the comparer to use, or null
if equals() should
* be used to compare segments
* @return whether the given path is a prefix of this path, or the same as
* this path
*/
public boolean startsWith(NodeContextPath treePath) {
int thisSegmentCount = getSegmentCount();
int otherSegmentCount = treePath.getSegmentCount();
if (otherSegmentCount == thisSegmentCount) {
return equals(treePath);
}
if (otherSegmentCount > thisSegmentCount) {
return false;
}
for (int i = 0; i < otherSegmentCount; i++) {
Object otherSegment = treePath.getSegment(i);
if (!otherSegment.equals(segments[i])) {
return false;
}
}
return true;
}
/**
* Returns a copy of this tree path with one segment removed from the end,
* or null
if this tree path has no segments.
* @return a tree path
*/
public NodeContextPath getParentPath() {
int segmentCount = getSegmentCount();
if (segmentCount < 1) {
return null;
} else if (segmentCount == 1) {
return EMPTY;
}
NodeContext[] parentSegments = new NodeContext[segmentCount - 1];
System.arraycopy(segments, 0, parentSegments, 0, segmentCount - 1);
return new NodeContextPath(parentSegments);
}
/**
* Returns a copy of this tree path with the given segment added at the end.
* @param newSegment
* @return a tree path
*/
public NodeContextPath createChildPath(NodeContext newSegment) {
int segmentCount = getSegmentCount();
NodeContext[] childSegments = new NodeContext[segmentCount + 1];
if(segmentCount>0) {
System.arraycopy(segments, 0, childSegments, 0, segmentCount);
}
childSegments[segmentCount] = newSegment;
return new NodeContextPath(childSegments);
}
@SuppressWarnings("unchecked")
@Override
public