Skip to content

Commit

Permalink
observing: create interface AstObserver
Browse files Browse the repository at this point in the history
  • Loading branch information
ftomassetti committed Nov 11, 2016
1 parent 5568c65 commit 263cf50
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 58 deletions.
@@ -1,14 +1,15 @@
package com.github.javaparser; package com.github.javaparser;


import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.observing.Observable;

import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;


import com.github.javaparser.ast.Node;

/** /**
* An object that has a parent node. * An object that has a parent node.
*/ */
public interface HasParentNode<T> { public interface HasParentNode<T> extends Observable {


/** /**
* Return the parent node or null, if no parent is set. * Return the parent node or null, if no parent is set.
Expand Down
23 changes: 17 additions & 6 deletions javaparser-core/src/main/java/com/github/javaparser/ast/Node.java
Expand Up @@ -27,8 +27,7 @@
import com.github.javaparser.ast.comments.BlockComment; import com.github.javaparser.ast.comments.BlockComment;
import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.comments.LineComment; import com.github.javaparser.ast.comments.LineComment;
import com.github.javaparser.ast.observing.NodeObserver; import com.github.javaparser.ast.observing.AstObserver;
import com.github.javaparser.ast.observing.Observable;
import com.github.javaparser.ast.visitor.CloneVisitor; import com.github.javaparser.ast.visitor.CloneVisitor;
import com.github.javaparser.ast.visitor.EqualsVisitor; import com.github.javaparser.ast.visitor.EqualsVisitor;
import com.github.javaparser.ast.visitor.Visitable; import com.github.javaparser.ast.visitor.Visitable;
Expand All @@ -50,7 +49,7 @@
* @author Julio Vilmar Gesser * @author Julio Vilmar Gesser
*/ */
// Use <Node> to prevent Node from becoming generic. // Use <Node> to prevent Node from becoming generic.
public abstract class Node implements Cloneable, HasParentNode<Node>, Visitable, Observable<NodeObserver> { public abstract class Node implements Cloneable, HasParentNode<Node>, Visitable {
/** /**
* This can be used to sort nodes on position. * This can be used to sort nodes on position.
*/ */
Expand All @@ -70,7 +69,7 @@ public abstract class Node implements Cloneable, HasParentNode<Node>, Visitable,


private Comment comment; private Comment comment;


private List<NodeObserver> observers = new ArrayList<>(); private List<AstObserver> observers = new ArrayList<>();


public Node(Range range) { public Node(Range range) {
this.range = range; this.range = range;
Expand Down Expand Up @@ -269,6 +268,8 @@ public List<Comment> getAllContainedComments() {
*/ */
@Override @Override
public Node setParentNode(Node parentNode) { public Node setParentNode(Node parentNode) {
observers.forEach(o -> o.parentChange(this, this.parentNode, parentNode));

// remove from old parent, if any // remove from old parent, if any
if (this.parentNode != null) { if (this.parentNode != null) {
this.parentNode.childrenNodes.remove(this); this.parentNode.childrenNodes.remove(this);
Expand Down Expand Up @@ -419,12 +420,22 @@ protected <P> void notifyPropertyChange(String propertyName, P oldValue, P newVa
} }


@Override @Override
public void unregister(NodeObserver observer) { public void unregister(AstObserver observer) {
this.observers.remove(observer); this.observers.remove(observer);
} }


@Override @Override
public void register(NodeObserver observer) { public void register(AstObserver observer) {
this.observers.add(observer); this.observers.add(observer);
} }

public void registerForSubtree(AstObserver observer) {
register(observer);
this.getChildNodes().forEach(c -> c.registerForSubtree(observer));
}

@Override
public boolean isRegistered(AstObserver observer) {
return this.observers.contains(observer);
}
} }
@@ -1,6 +1,5 @@
package com.github.javaparser.ast; package com.github.javaparser.ast;


<<<<<<< e35fb78d58750176ee0175f27ba1b2e9c9da61d6
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
Expand All @@ -15,12 +14,9 @@
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import java.util.stream.Stream; import java.util.stream.Stream;


=======
>>>>>>> observing: create separate observers for node and nodelist
import com.github.javaparser.HasParentNode; import com.github.javaparser.HasParentNode;
import com.github.javaparser.ast.observing.AstObserver;
import com.github.javaparser.ast.observing.ListChangeType; import com.github.javaparser.ast.observing.ListChangeType;
import com.github.javaparser.ast.observing.ListObserver;
import com.github.javaparser.ast.observing.Observable;
import com.github.javaparser.ast.visitor.GenericVisitor; import com.github.javaparser.ast.visitor.GenericVisitor;
import com.github.javaparser.ast.visitor.Visitable; import com.github.javaparser.ast.visitor.Visitable;
import com.github.javaparser.ast.visitor.VoidVisitor; import com.github.javaparser.ast.visitor.VoidVisitor;
Expand All @@ -33,16 +29,12 @@
* *
* @param <N> the type of nodes contained. * @param <N> the type of nodes contained.
*/ */
<<<<<<< e35fb78d58750176ee0175f27ba1b2e9c9da61d6 public class NodeList<N extends Node> implements List<N>, Iterable<N>, HasParentNode<NodeList<N>>, Visitable, Observable<ListObserver> {
public class NodeList<N extends Node> implements List<N>, Iterable<N>, HasParentNode<NodeList<N>>, Visitable {
=======
public class NodeList<N extends Node> implements Iterable<N>, HasParentNode<NodeList<N>>, Visitable, Observable<ListObserver> {
>>>>>>> observing: create separate observers for node and nodelist
private List<N> innerList = new ArrayList<>(0); private List<N> innerList = new ArrayList<>(0);


private Node parentNode; private Node parentNode;


private List<ListObserver> observers = new ArrayList<>(); private List<AstObserver> observers = new ArrayList<>();


public NodeList() { public NodeList() {
this(null); this(null);
Expand All @@ -52,13 +44,9 @@ public NodeList(Node parent) {
setParentNode(parent); setParentNode(parent);
} }


<<<<<<< e35fb78d58750176ee0175f27ba1b2e9c9da61d6
@Override @Override
public boolean add(N node) { public boolean add(N node) {
=======
public NodeList<N> add(N node) {
notifyElementAdded(innerList.size(), node); notifyElementAdded(innerList.size(), node);
>>>>>>> observing: create separate observers for node and nodelist
own(node); own(node);
return innerList.add(node); return innerList.add(node);
} }
Expand Down Expand Up @@ -132,19 +120,13 @@ public N set(int index, N element) {
return innerList.set(index, element); return innerList.set(index, element);
} }


<<<<<<< e35fb78d58750176ee0175f27ba1b2e9c9da61d6
@Override @Override
public N remove(int index) { public N remove(int index) {
notifyElementRemoved(index, innerList.get(index));
N remove = innerList.remove(index); N remove = innerList.remove(index);
if (remove != null) if (remove != null)
remove.setParentNode(null); remove.setParentNode(null);
return remove; return remove;
=======
public NodeList<N> remove(int index) {
notifyElementRemoved(index, innerList.get(index));
innerList.remove(index);
return this;
>>>>>>> observing: create separate observers for node and nodelist
} }


@Override @Override
Expand All @@ -163,13 +145,9 @@ public void addAll(NodeList<N> otherList) {
} }
} }


<<<<<<< e35fb78d58750176ee0175f27ba1b2e9c9da61d6
@Override @Override
public void add(int index, N node) { public void add(int index, N node) {
=======
public NodeList<N> add(int index, N node) {
notifyElementAdded(index, node); notifyElementAdded(index, node);
>>>>>>> observing: create separate observers for node and nodelist
own(node); own(node);
innerList.add(index, node); innerList.add(index, node);
} }
Expand Down Expand Up @@ -207,7 +185,6 @@ public <A> void accept(final VoidVisitor<A> v, final A arg) {
v.visit(this, arg); v.visit(this, arg);
} }


<<<<<<< e35fb78d58750176ee0175f27ba1b2e9c9da61d6
/** /**
* @param action * @param action
* @see java.lang.Iterable#forEach(java.util.function.Consumer) * @see java.lang.Iterable#forEach(java.util.function.Consumer)
Expand Down Expand Up @@ -438,7 +415,7 @@ public List<N> subList(int fromIndex, int toIndex) {
@Override @Override
public Spliterator<N> spliterator() { public Spliterator<N> spliterator() {
return innerList.spliterator(); return innerList.spliterator();
=======
private void notifyElementAdded(int index, Node nodeAddedOrRemoved) { private void notifyElementAdded(int index, Node nodeAddedOrRemoved) {
this.observers.forEach(o -> o.listChange(this, ListChangeType.ADDITION, index, nodeAddedOrRemoved)); this.observers.forEach(o -> o.listChange(this, ListChangeType.ADDITION, index, nodeAddedOrRemoved));
} }
Expand All @@ -448,14 +425,18 @@ private void notifyElementRemoved(int index, Node nodeAddedOrRemoved) {
} }


@Override @Override
public void unregister(ListObserver observer) { public void unregister(AstObserver observer) {
this.observers.remove(observer); this.observers.remove(observer);
} }


@Override @Override
public void register(ListObserver observer) { public void register(AstObserver observer) {
this.observers.add(observer); this.observers.add(observer);
>>>>>>> observing: create separate observers for node and nodelist }

@Override
public boolean isRegistered(AstObserver observer) {
return this.observers.contains(observer);
} }


} }
@@ -0,0 +1,10 @@
package com.github.javaparser.ast.observing;

import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;

public interface AstObserver {
void propertyChange(Node observedNode, String propertyName, Object oldValue, Object newValue);
void parentChange(Node observedNode, Node previousParent, Node newParent);
void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved);
}

This file was deleted.

This file was deleted.

@@ -1,6 +1,7 @@
package com.github.javaparser.ast.observing; package com.github.javaparser.ast.observing;


public interface Observable<O> { public interface Observable {
void register(O observer); void register(AstObserver observer);
void unregister(O observer); void unregister(AstObserver observer);
boolean isRegistered(AstObserver observer);
} }
@@ -0,0 +1,43 @@
package com.github.javaparser.ast.observing;

import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;

public abstract class PropagatingAstObserver implements AstObserver {

@Override
public void propertyChange(Node observedNode, String propertyName, Object oldValue, Object newValue) {
considerRemoving(oldValue);
considerAdding(newValue);
concretePropertyChange(observedNode, propertyName, oldValue, newValue);
}

@Override
public 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);
}

protected abstract void concretePropertyChange(Node observedNode, String propertyName, Object oldValue, Object newValue);

protected abstract void concreteListChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved);

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 Observable) {
((Observable) element).register(this);
}
}

}

0 comments on commit 263cf50

Please sign in to comment.