1 /* 2 * Copyright (C) 2007-2010 Júlio Vilmar Gesser. 3 * Copyright (C) 2011, 2013-2016 The JavaParser Team. 4 * 5 * This file is part of JavaParser. 6 * 7 * JavaParser can be used either under the terms of 8 * a) the GNU Lesser General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * b) the terms of the Apache License 12 * 13 * You should have received a copy of both licenses in LICENCE.LGPL and 14 * LICENCE.APACHE. Please refer to those files for details. 15 * 16 * JavaParser is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Lesser General Public License for more details. 20 */ 21 22 package com.github.javaparser.ast.observer; 23 24 import com.github.javaparser.ast.Node; 25 import com.github.javaparser.ast.NodeList; 26 27 /** 28 * This AstObserver attach itself to all new nodes added to the nodes already observed. 29 */ 30 public abstract class PropagatingAstObserver implements AstObserver { 31 32 /** 33 * Wrap a given observer to make it self-propagating. If the given observer is an instance of PropagatingAstObserver 34 * the observer is returned without changes. 35 */ transformInPropagatingObserver(final AstObserver observer)36 public static PropagatingAstObserver transformInPropagatingObserver(final AstObserver observer) { 37 if (observer instanceof PropagatingAstObserver) { 38 return (PropagatingAstObserver) observer; 39 } 40 return new PropagatingAstObserver() { 41 @Override 42 public void concretePropertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) { 43 observer.propertyChange(observedNode, property, oldValue, newValue); 44 } 45 46 @Override 47 public void concreteListChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) { 48 observer.listChange(observedNode, type, index, nodeAddedOrRemoved); 49 } 50 51 @Override 52 public void parentChange(Node observedNode, Node previousParent, Node newParent) { 53 observer.parentChange(observedNode, previousParent, newParent); 54 } 55 }; 56 } 57 58 @Override 59 public final void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) { 60 considerRemoving(oldValue); 61 considerAdding(newValue); 62 concretePropertyChange(observedNode, property, oldValue, newValue); 63 } 64 65 @Override 66 public final void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) { 67 if (type == ListChangeType.REMOVAL) { 68 considerRemoving(nodeAddedOrRemoved); 69 } else if (type == ListChangeType.ADDITION) { 70 considerAdding(nodeAddedOrRemoved); 71 } 72 concreteListChange(observedNode, type, index, nodeAddedOrRemoved); 73 } 74 75 @Override 76 public void listReplacement(NodeList observedNode, int index, Node oldNode, Node newNode) { 77 if (oldNode == newNode) { 78 return; 79 } 80 considerRemoving(oldNode); 81 considerAdding(newNode); 82 concreteListReplacement(observedNode, index, oldNode, newNode); 83 } 84 85 public void concretePropertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) { 86 // do nothing 87 } 88 89 public void concreteListChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) { 90 // do nothing 91 } 92 93 public void concreteListReplacement(NodeList observedNode, int index, Node oldValue, Node newValue) { 94 // do nothing 95 } 96 97 @Override 98 public void parentChange(Node observedNode, Node previousParent, Node newParent) { 99 // do nothing 100 } 101 102 private void considerRemoving(Object element) { 103 if (element instanceof Observable) { 104 if (((Observable) element).isRegistered(this)) { 105 ((Observable) element).unregister(this); 106 } 107 } 108 } 109 110 private void considerAdding(Object element) { 111 if (element instanceof Node) { 112 ((Node) element).registerForSubtree(this); 113 } else if (element instanceof Observable) { 114 ((Observable) element).register(this); 115 } 116 } 117 118 } 119