package cide.gast; import java.util.ArrayList; import java.util.List; public class PropertyZeroOrMore<T extends IASTNode> extends Property { protected final ArrayList<T> valueList; /** * the indexlist keeps a list of all values including removed ones so that * the generated ID is permanent and does not change if a value is removed */ protected final List<T> indexList = new ArrayList<T>(); public PropertyZeroOrMore(String name, ArrayList<T> value) { this(name, value, PropertyType.ZEROORMORE); } protected PropertyZeroOrMore(String name, ArrayList<T> value, PropertyType type) { super(name, type); this.valueList = value; this.indexList.addAll(value); } /** * returns an unmodifiable list of values. * * do not modify this list (unmodifiable is only commented our for technical * reasons (ArrayList vs. List) * * @return */ public ArrayList<T> getValue() { return /* Collections.unmodifiableList */(valueList); } // public void addValue(T value) { // if (value != null) { // this.valueList.add(value); // this.indexList.add(value); // notifyChange(); // } // } // public boolean removeValue(IASTNode value) { // if ((value != null) && this.valueList.remove(value)) { // notifyChange(); // return true; // } // return false; // } public void setValue(int index, T value) { if ((index >= 0) && (index < valueList.size()) && (value != null)) { valueList.set(index, value); indexList.add(value); notifyChange(); } } public boolean canRemoveSubtree(IASTNode node) { return valueList.contains(node); } public void removeSubtree(IASTNode node) { this.valueList.remove(node); notifyChange(); } @Override public void replaceChild(IASTNode oldChild, IASTNode newChild) { int index = -2; if (((index = valueList.indexOf(oldChild)) >= 0) && (newChild != null)) setValue(index, (T) newChild); } void setParent(IASTNode parent) { super.setParent(parent); for (T value : valueList) value.setParentProperty(this); } String getId(IASTNode node) { return super.getId(node) + indexList.indexOf(node); } /** * after cloning the IDs might change (due to renumbering) but are again * consistent inside the AST */ Property deepCopy() { ArrayList<T> clonedList = new ArrayList<T>(valueList.size()); for (T entry : valueList) clonedList.add((T) entry.deepCopy()); return new PropertyZeroOrMore<T>(new String(name), clonedList); } public IASTNode[] getChildren() { return valueList.toArray(new IASTNode[valueList.size()]); } }