aboutsummaryrefslogtreecommitdiff
path: root/javaparser-core/src/main/java/com/github/javaparser/ast/observer
diff options
context:
space:
mode:
Diffstat (limited to 'javaparser-core/src/main/java/com/github/javaparser/ast/observer')
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserver.java70
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserverAdapter.java48
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/observer/Observable.java44
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java298
-rw-r--r--javaparser-core/src/main/java/com/github/javaparser/ast/observer/PropagatingAstObserver.java118
5 files changed, 578 insertions, 0 deletions
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserver.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserver.java
new file mode 100644
index 000000000..6c41f4b02
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserver.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.observer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+
+/**
+ * An Observer for an AST element (either a Node or a NodeList).
+ */
+public interface AstObserver {
+
+ /**
+ * Type of change occurring on a List
+ */
+ enum ListChangeType {
+ ADDITION,
+ REMOVAL
+ }
+
+ /**
+ * The value of a property is changed
+ *
+ * @param observedNode owner of the property
+ * @param property property changed
+ * @param oldValue value of the property before the change
+ * @param newValue value of the property after the change
+ */
+ void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue);
+
+ /**
+ * The parent of a node is changed
+ *
+ * @param observedNode node of which the parent is changed
+ * @param previousParent previous parent
+ * @param newParent new parent
+ */
+ void parentChange(Node observedNode, Node previousParent, Node newParent);
+
+ /**
+ * A list is changed
+ *
+ * @param observedNode list changed
+ * @param type type of change
+ * @param index position at which the changed occurred
+ * @param nodeAddedOrRemoved element added or removed
+ */
+ void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved);
+
+ void listReplacement(NodeList observedNode, int index, Node oldNode, Node newNode);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserverAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserverAdapter.java
new file mode 100644
index 000000000..82b91949d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserverAdapter.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.observer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+
+public abstract class AstObserverAdapter implements AstObserver {
+
+ @Override
+ public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+ // do nothing
+ }
+
+ @Override
+ public void parentChange(Node observedNode, Node previousParent, Node newParent) {
+ // do nothing
+ }
+
+ @Override
+ public void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+ // do nothing
+ }
+
+ @Override
+ public void listReplacement(NodeList observedNode, int index, Node oldNode, Node newNode) {
+ // do nothing
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/Observable.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/Observable.java
new file mode 100644
index 000000000..ce0f926bf
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/Observable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.observer;
+
+/**
+ * Observable element.
+ */
+public interface Observable {
+
+ /**
+ * Register an observer.
+ */
+ void register(AstObserver observer);
+
+ /**
+ * Unregister an observer. If the given observer was not registered there are no effects.
+ */
+ void unregister(AstObserver observer);
+
+ /**
+ * Was this observer registered?
+ * Note that equals is used to determine if the given observer was registered.
+ */
+ boolean isRegistered(AstObserver observer);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java
new file mode 100644
index 000000000..d7f82f36c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.observer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.utils.Utils;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.Arrays;
+import javax.annotation.Generated;
+
+/**
+ * Properties considered by the AstObserver
+ */
+@Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+public enum ObservableProperty {
+
+ ANNOTATIONS(Type.MULTIPLE_REFERENCE),
+ ANONYMOUS_CLASS_BODY(Type.MULTIPLE_REFERENCE),
+ ARGUMENTS(Type.MULTIPLE_REFERENCE),
+ ASTERISK(Type.SINGLE_ATTRIBUTE),
+ BODY(Type.SINGLE_REFERENCE),
+ CATCH_CLAUSES(Type.MULTIPLE_REFERENCE),
+ CHECK(Type.SINGLE_REFERENCE),
+ CLASS_BODY(Type.MULTIPLE_REFERENCE),
+ CLASS_DECLARATION(Type.SINGLE_REFERENCE),
+ CLASS_EXPR(Type.SINGLE_REFERENCE),
+ COMMENT(Type.SINGLE_REFERENCE),
+ COMPARE(Type.SINGLE_REFERENCE),
+ COMPONENT_TYPE(Type.SINGLE_REFERENCE),
+ CONDITION(Type.SINGLE_REFERENCE),
+ CONTENT(Type.SINGLE_ATTRIBUTE),
+ DEFAULT_VALUE(Type.SINGLE_REFERENCE),
+ DIMENSION(Type.SINGLE_REFERENCE),
+ ELEMENTS(Type.MULTIPLE_REFERENCE),
+ ELEMENT_TYPE(Type.SINGLE_REFERENCE),
+ ELSE_EXPR(Type.SINGLE_REFERENCE),
+ ELSE_STMT(Type.SINGLE_REFERENCE),
+ ENCLOSING_PARAMETERS(Type.SINGLE_ATTRIBUTE),
+ ENTRIES(Type.MULTIPLE_REFERENCE),
+ EXPRESSION(Type.SINGLE_REFERENCE),
+ EXTENDED_TYPE(Type.SINGLE_REFERENCE),
+ EXTENDED_TYPES(Type.MULTIPLE_REFERENCE),
+ FINALLY_BLOCK(Type.SINGLE_REFERENCE),
+ IDENTIFIER(Type.SINGLE_ATTRIBUTE),
+ IMPLEMENTED_TYPES(Type.MULTIPLE_REFERENCE),
+ IMPORTS(Type.MULTIPLE_REFERENCE),
+ INDEX(Type.SINGLE_REFERENCE),
+ INITIALIZATION(Type.MULTIPLE_REFERENCE),
+ INITIALIZER(Type.SINGLE_REFERENCE),
+ INNER(Type.SINGLE_REFERENCE),
+ INTERFACE(Type.SINGLE_ATTRIBUTE),
+ ITERABLE(Type.SINGLE_REFERENCE),
+ LABEL(Type.SINGLE_REFERENCE),
+ LEFT(Type.SINGLE_REFERENCE),
+ LEVELS(Type.MULTIPLE_REFERENCE),
+ MEMBERS(Type.MULTIPLE_REFERENCE),
+ MEMBER_VALUE(Type.SINGLE_REFERENCE),
+ MESSAGE(Type.SINGLE_REFERENCE),
+ MODIFIERS(Type.MULTIPLE_ATTRIBUTE),
+ MODULE(Type.SINGLE_REFERENCE),
+ MODULE_NAMES(Type.MULTIPLE_REFERENCE),
+ MODULE_STMTS(Type.MULTIPLE_REFERENCE),
+ NAME(Type.SINGLE_REFERENCE),
+ OPEN(Type.SINGLE_ATTRIBUTE),
+ OPERATOR(Type.SINGLE_ATTRIBUTE),
+ ORIGIN(Type.SINGLE_ATTRIBUTE),
+ PACKAGE_DECLARATION(Type.SINGLE_REFERENCE),
+ PAIRS(Type.MULTIPLE_REFERENCE),
+ PARAMETER(Type.SINGLE_REFERENCE),
+ PARAMETERS(Type.MULTIPLE_REFERENCE),
+ QUALIFIER(Type.SINGLE_REFERENCE),
+ RECEIVER_PARAMETER(Type.SINGLE_REFERENCE),
+ RESOURCES(Type.MULTIPLE_REFERENCE),
+ RIGHT(Type.SINGLE_REFERENCE),
+ SCOPE(Type.SINGLE_REFERENCE),
+ SELECTOR(Type.SINGLE_REFERENCE),
+ STATEMENT(Type.SINGLE_REFERENCE),
+ STATEMENTS(Type.MULTIPLE_REFERENCE),
+ STATIC(Type.SINGLE_ATTRIBUTE),
+ SUPER_TYPE(Type.SINGLE_REFERENCE),
+ TARGET(Type.SINGLE_REFERENCE),
+ THEN_EXPR(Type.SINGLE_REFERENCE),
+ THEN_STMT(Type.SINGLE_REFERENCE),
+ THIS(Type.SINGLE_ATTRIBUTE),
+ THROWN_EXCEPTIONS(Type.MULTIPLE_REFERENCE),
+ TRY_BLOCK(Type.SINGLE_REFERENCE),
+ TYPE(Type.SINGLE_REFERENCE),
+ TYPES(Type.MULTIPLE_REFERENCE),
+ TYPE_ARGUMENTS(Type.MULTIPLE_REFERENCE),
+ TYPE_BOUND(Type.MULTIPLE_REFERENCE),
+ TYPE_PARAMETERS(Type.MULTIPLE_REFERENCE),
+ UPDATE(Type.MULTIPLE_REFERENCE),
+ VALUE(Type.SINGLE_REFERENCE),
+ VALUES(Type.MULTIPLE_REFERENCE),
+ VARIABLE(Type.SINGLE_REFERENCE),
+ VARIABLES(Type.MULTIPLE_REFERENCE),
+ VAR_ARGS(Type.SINGLE_ATTRIBUTE),
+ VAR_ARGS_ANNOTATIONS(Type.MULTIPLE_REFERENCE),
+ WITH_TYPES(Type.MULTIPLE_REFERENCE),
+ CASCADING_IF_STMT(Type.SINGLE_ATTRIBUTE, true),
+ ELSE_BLOCK(Type.SINGLE_ATTRIBUTE, true),
+ ELSE_BRANCH(Type.SINGLE_ATTRIBUTE, true),
+ EXPRESSION_BODY(Type.SINGLE_REFERENCE, true),
+ MAXIMUM_COMMON_TYPE(Type.SINGLE_REFERENCE, true),
+ POSTFIX(Type.SINGLE_ATTRIBUTE, true),
+ PREFIX(Type.SINGLE_ATTRIBUTE, true),
+ THEN_BLOCK(Type.SINGLE_ATTRIBUTE, true),
+ USING_DIAMOND_OPERATOR(Type.SINGLE_ATTRIBUTE, true),
+ RANGE,
+ COMMENTED_NODE;
+
+ enum Type {
+
+ SINGLE_ATTRIBUTE(false, false), SINGLE_REFERENCE(false, true), MULTIPLE_ATTRIBUTE(true, false), MULTIPLE_REFERENCE(true, true);
+
+ private boolean multiple;
+
+ private boolean node;
+
+ Type(boolean multiple, boolean node) {
+ this.multiple = multiple;
+ this.node = node;
+ }
+ }
+
+ private Type type;
+
+ private boolean derived;
+
+ public static ObservableProperty fromCamelCaseName(String camelCaseName) {
+ Optional<ObservableProperty> observableProperty = Arrays.stream(values()).filter(v -> v.camelCaseName().equals(camelCaseName)).findFirst();
+ if (observableProperty.isPresent()) {
+ return observableProperty.get();
+ } else {
+ throw new IllegalArgumentException("No property found with the given camel case name: " + camelCaseName);
+ }
+ }
+
+ ObservableProperty(Type type) {
+ this.type = type;
+ this.derived = false;
+ }
+
+ ObservableProperty(Type type, boolean derived) {
+ this.type = type;
+ this.derived = derived;
+ }
+
+ ObservableProperty() {
+ this(Type.SINGLE_REFERENCE, false);
+ }
+
+ public boolean isDerived() {
+ return derived;
+ }
+
+ public boolean isAboutNodes() {
+ return type.node;
+ }
+
+ public boolean isAboutValues() {
+ return !isAboutNodes();
+ }
+
+ public boolean isMultiple() {
+ return type.multiple;
+ }
+
+ public boolean isSingle() {
+ return !isMultiple();
+ }
+
+ public String camelCaseName() {
+ return Utils.screamingToCamelCase(name());
+ }
+
+ public Node getValueAsSingleReference(Node node) {
+ Object rawValue = getRawValue(node);
+ try {
+ if (rawValue instanceof Node) {
+ return (Node) rawValue;
+ } else if (rawValue instanceof Optional) {
+ Optional<Node> opt = (Optional<Node>) rawValue;
+ if (opt.isPresent()) {
+ return opt.get();
+ } else {
+ return null;
+ }
+ } else {
+ throw new RuntimeException(String.format("Property %s returned %s (%s)", this.name(), rawValue.toString(), rawValue.getClass().getCanonicalName()));
+ }
+ } catch (ClassCastException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private boolean hasMethod(Node node, String name) {
+ try {
+ node.getClass().getMethod(name);
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ public NodeList<? extends Node> getValueAsMultipleReference(Node node) {
+ Object rawValue = getRawValue(node);
+ try {
+ if (rawValue == null) {
+ return null;
+ }
+ if (rawValue instanceof NodeList) {
+ return (NodeList) rawValue;
+ } else {
+ Optional<NodeList> opt = (Optional<NodeList>) rawValue;
+ if (opt.isPresent()) {
+ return opt.get();
+ } else {
+ return null;
+ }
+ }
+ } catch (ClassCastException e) {
+ throw new RuntimeException("Unable to get list value for " + this.name() + " from " + node + " (class: " + node.getClass().getSimpleName() + ")", e);
+ }
+ }
+
+ public Collection<?> getValueAsCollection(Node node) {
+ Object rawValue = getRawValue(node);
+ try {
+ return (Collection) rawValue;
+ } catch (ClassCastException e) {
+ throw new RuntimeException("Unable to get list value for " + this.name() + " from " + node + " (class: " + node.getClass().getSimpleName() + ")", e);
+ }
+ }
+
+ public String getValueAsStringAttribute(Node node) {
+ return (String) getRawValue(node);
+ }
+
+ public Boolean getValueAsBooleanAttribute(Node node) {
+ return (Boolean) getRawValue(node);
+ }
+
+ public Object getRawValue(Node node) {
+ String getterName = "get" + Utils.capitalize(camelCaseName());
+ if (!hasMethod(node, getterName)) {
+ getterName = "is" + Utils.capitalize(camelCaseName());
+ if (!hasMethod(node, getterName)) {
+ getterName = "has" + Utils.capitalize(camelCaseName());
+ }
+ }
+ try {
+ return node.getClass().getMethod(getterName).invoke(node);
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException("Unable to get value for " + this.name() + " from " + node + " (" + node.getClass().getSimpleName() + ")", e);
+ }
+ }
+
+ public boolean isNull(Node node) {
+ return null == getRawValue(node);
+ }
+
+ public boolean isNullOrNotPresent(Node node) {
+ Object result = getRawValue(node);
+ if (result == null) {
+ return true;
+ }
+ if (result instanceof Optional) {
+ return !((Optional) result).isPresent();
+ }
+ return false;
+ }
+
+ public boolean isNullOrEmpty(Node node) {
+ return Utils.valueIsNullOrEmpty(getRawValue(node));
+ }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/PropagatingAstObserver.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/PropagatingAstObserver.java
new file mode 100644
index 000000000..1579474c3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/PropagatingAstObserver.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.observer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+
+/**
+ * This AstObserver attach itself to all new nodes added to the nodes already observed.
+ */
+public abstract class PropagatingAstObserver implements AstObserver {
+
+ /**
+ * Wrap a given observer to make it self-propagating. If the given observer is an instance of PropagatingAstObserver
+ * the observer is returned without changes.
+ */
+ public static PropagatingAstObserver transformInPropagatingObserver(final AstObserver observer) {
+ if (observer instanceof PropagatingAstObserver) {
+ return (PropagatingAstObserver) observer;
+ }
+ return new PropagatingAstObserver() {
+ @Override
+ public void concretePropertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+ observer.propertyChange(observedNode, property, oldValue, newValue);
+ }
+
+ @Override
+ public void concreteListChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+ observer.listChange(observedNode, type, index, nodeAddedOrRemoved);
+ }
+
+ @Override
+ public void parentChange(Node observedNode, Node previousParent, Node newParent) {
+ observer.parentChange(observedNode, previousParent, newParent);
+ }
+ };
+ }
+
+ @Override
+ public final void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+ considerRemoving(oldValue);
+ considerAdding(newValue);
+ concretePropertyChange(observedNode, property, oldValue, newValue);
+ }
+
+ @Override
+ public final void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+ if (type == ListChangeType.REMOVAL) {
+ considerRemoving(nodeAddedOrRemoved);
+ } else if (type == ListChangeType.ADDITION) {
+ considerAdding(nodeAddedOrRemoved);
+ }
+ concreteListChange(observedNode, type, index, nodeAddedOrRemoved);
+ }
+
+ @Override
+ public void listReplacement(NodeList observedNode, int index, Node oldNode, Node newNode) {
+ if (oldNode == newNode) {
+ return;
+ }
+ considerRemoving(oldNode);
+ considerAdding(newNode);
+ concreteListReplacement(observedNode, index, oldNode, newNode);
+ }
+
+ public void concretePropertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+ // do nothing
+ }
+
+ public void concreteListChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+ // do nothing
+ }
+
+ public void concreteListReplacement(NodeList observedNode, int index, Node oldValue, Node newValue) {
+ // do nothing
+ }
+
+ @Override
+ public void parentChange(Node observedNode, Node previousParent, Node newParent) {
+ // do nothing
+ }
+
+ private void considerRemoving(Object element) {
+ if (element instanceof Observable) {
+ if (((Observable) element).isRegistered(this)) {
+ ((Observable) element).unregister(this);
+ }
+ }
+ }
+
+ private void considerAdding(Object element) {
+ if (element instanceof Node) {
+ ((Node) element).registerForSubtree(this);
+ } else if (element instanceof Observable) {
+ ((Observable) element).register(this);
+ }
+ }
+
+}