public IRedefinable getChild(String key) { if (childrenByKey == null) { childrenByKey = new HashMap<String, IRedefinable>(); for (IRedefinable child : children) { childrenByKey.put(child.key(), child); } } return childrenByKey.get(key); }
/** * Returns the ancestors of this {@link IRedefinable}, as a list. Lower index = closer ancestor. * * @return */ protected List<IRedefinable> getAncestors() { ArrayList<IRedefinable> result = new ArrayList<IRedefinable>(); IRedefinable parent = this.parent; while (parent != null) { result.add(parent); parent = parent.getParent(); } return result; }
public <T extends IRedefinable> T getParent(Class<T> parentType) { IRedefinable parent = this.parent; while (parent != null) { if (parentType.isAssignableFrom(parent.getClass())) { return (T) parent; } parent = parent.getParent(); } return null; }
/** * The default implementation redefines all children as well, delegating to the {@link * #redefineAdded(IRedefinable, IRedefiner)} method if the replacement has a child not present in * this {@link IRedefinable}. */ @Override public void redefine(IRedefinable replacement, IRedefiner redefiner) { if (replacement != null && !Util.equals(replacement.key(), key())) { throw new IllegalArgumentException("Internal error: key mismatch"); } if (redefiner != null) { redefiner.changed(this, replacement); } HashSet<String> redefined = new HashSet(); for (IRedefinable originalChild : getChildren()) { String key = originalChild.key(); IRedefinable replacementChild = replacement.getChild(key); if (replacementChild != null) { replacementChild.redefine(originalChild, redefiner); redefined.add(key); } else { redefiner.deleted(originalChild); } } for (IRedefinable replaceChild : replacement.getChildren()) { if (!redefined.contains(replaceChild.key())) { redefiner.added(replaceChild); } } }
protected AbstractRedefinable(IRedefinable parent, ISourceSupport source) { this.parent = parent; this.source = source; if (parent != null) { parent.addChild(this); } }
/** * Replaces a child with another. This method uses the key of the replacement to find the child to * replace. If no such child exists, the replacement is added. * * @param replacement */ public void replaceChild(IRedefinable replacement) { if (replacement == null) { return; } boolean wasReplaced = false; for (int i = 0; i < children.size(); i++) { IRedefinable child = children.get(i); if (replacement.key().equals(child.key())) { children.set(i, replacement); wasReplaced = true; } } if (!wasReplaced) { addChild(replacement); } childrenByKey = null; }
public String constructKey(String subkey) { String parentKey = parent == null ? "" : parent.key(); return parentKey + "/" + subkey; }