blob: 3c97f0974174616767fa6d3da0af8c919ff4132d [file] [log] [blame]
package org.eclipse.cdt.internal.core.model;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.io.File;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.core.resources.IResource;
/**
* Holds cached structure and properties for a C element.
* Subclassed to carry properties for specific kinds of elements.
*/
class CElementInfo {
protected CElement element;
/**
* Collection of handles of immediate children of this
* object. This is an empty array if this element has
* no children.
*/
protected ICElement[] fChildren;
/**
* Shared empty collection used for efficiency.
*/
protected static ICElement[] fgEmptyChildren = new ICElement[]{};
/**
* Is the structure of this element known
* @see ICElement.isStructureKnown()
*/
protected boolean fIsStructureKnown = false;
protected long modificationStamp = 0;
protected CElementInfo(CElement element) {
this.element = element;
fChildren = fgEmptyChildren;
}
protected CElement getElement() {
return element;
}
protected void addChild(ICElement child) {
if (fChildren == fgEmptyChildren) {
setChildren(new ICElement[] {child});
} else {
if (!includesChild(child)) {
setChildren(growAndAddToArray(fChildren, child));
}
}
}
protected ICElement[] getChildren() {
return fChildren;
}
/**
* Adds the new element to a new array that contains all of the elements of the old array.
* Returns the new array.
*/
protected ICElement[] growAndAddToArray(ICElement[] array, ICElement addition) {
ICElement[] old = array;
array = new ICElement[old.length + 1];
System.arraycopy(old, 0, array, 0, old.length);
array[old.length] = addition;
return array;
}
/**
* Returns <code>true</code> if this child is in my children collection
*/
protected boolean includesChild(ICElement child) {
for (int i= 0; i < fChildren.length; i++) {
if (fChildren[i].equals(child)) {
return true;
}
}
return false;
}
/**
* @see ICElement.isStructureKnown()
*/
protected boolean isStructureKnown() {
return fIsStructureKnown;
}
/**
* Returns an array with all the same elements as the specified array except for
* the element to remove. Assumes that the deletion is contained in the array.
*/
protected ICElement[] removeAndShrinkArray(ICElement[] array, ICElement deletion) {
ICElement[] old = array;
array = new ICElement[old.length - 1];
int j = 0;
for (int i = 0; i < old.length; i++) {
if (!old[i].equals(deletion)) {
array[j] = old[i];
} else {
System.arraycopy(old, i + 1, array, j, old.length - (i + 1));
return array;
}
j++;
}
return array;
}
protected void removeChild(ICElement child) {
if (includesChild(child)) {
setChildren(removeAndShrinkArray(fChildren, child));
}
}
protected void removeChildren () {
fChildren = fgEmptyChildren;
}
protected void setChildren(ICElement[] children) {
fChildren = children;
}
protected boolean hasChildren() {
return fChildren.length > 0;
}
protected void setChanged() {
modificationStamp = 0;
}
protected boolean hasChanged () {
IResource r = null;
boolean b = false;
r = getElement().getUnderlyingResource();
if (r != null && r.exists()) {
long modif = 0;
switch(r.getType()) {
// Adding/Removing does not count as changing, in Eclipse
// Ask the underlying file system
case IResource.FOLDER:
case IResource.PROJECT:
case IResource.ROOT:
File file = r.getLocation().toFile();
modif = file.lastModified();
break;
case IResource.FILE:
modif = r.getModificationStamp();
break;
}
b = (modif != modificationStamp);
modificationStamp = modif;
}
return b;
}
/**
* Sets whether the structure of this element known
* @see ICElement.isStructureKnown()
*/
protected void setIsStructureKnown(boolean newIsStructureKnown) {
fIsStructureKnown = newIsStructureKnown;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new Error();
}
}
}