1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.jeuclid.dom;
20
21 import java.util.HashSet;
22 import java.util.Set;
23
24 import net.sourceforge.jeuclid.elements.support.ElementListSupport;
25
26 import org.w3c.dom.Node;
27
28
29
30
31
32
33
34
35 public abstract class AbstractChangeTrackingElement extends
36 AbstractPartialElementImpl implements ChangeTrackingInterface {
37
38 private final Set<ChangeTrackingInterface> listeners = new HashSet<ChangeTrackingInterface>();
39
40
41 @Override
42 public final Node appendChild(final Node newChild) {
43 final Node retVal = super.appendChild(newChild);
44 this.fireChanged(true);
45 return retVal;
46 }
47
48
49 @Override
50 public final void setAttribute(final String name, final String value) {
51 super.setAttribute(name, value);
52 this.fireChanged(true);
53 }
54
55
56 @Override
57 public final void setTextContent(final String newTextContent) {
58 super.setTextContent(newTextContent);
59 this.fireChanged(true);
60 }
61
62
63 @Override
64 public final Node replaceChild(final Node newChild, final Node oldChild) {
65 final Node retVal = super.replaceChild(newChild, oldChild);
66 this.fireChanged(true);
67 return retVal;
68 }
69
70
71 public void fireChanged(final boolean propagate) {
72 this.changeHook();
73 if (propagate) {
74 final Node superNode = this.getParentNode();
75 if (superNode instanceof ChangeTrackingInterface) {
76 ((ChangeTrackingInterface) superNode).fireChanged(propagate);
77 }
78 for (final ChangeTrackingInterface listener : this.listeners) {
79 listener.fireChanged(false);
80 }
81 }
82 }
83
84
85 public void fireChangeForSubTree() {
86 this.fireChanged(false);
87 ElementListSupport.fireChangeForSubTree(ElementListSupport
88 .createListOfChildren(this));
89 }
90
91
92
93
94 protected void changeHook() {
95
96 }
97
98
99 public void addListener(final ChangeTrackingInterface listener) {
100 this.listeners.add(listener);
101 }
102
103 }