View Javadoc

1   /*
2    * Copyright 2002 - 2007 JEuclid, http://jeuclid.sf.net
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* $Id: AbstractChangeTrackingElement.java 310 2007-05-18 20:26:36Z maxberger $ */
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   * generic implementation of Element that tries to track if a change has
30   * happened.
31   * 
32   * @author Max Berger
33   * @version $Revision: 310 $
34   */
35  public abstract class AbstractChangeTrackingElement extends
36          AbstractPartialElementImpl implements ChangeTrackingInterface {
37  
38      private final Set<ChangeTrackingInterface> listeners = new HashSet<ChangeTrackingInterface>();
39  
40      /** {@inheritDoc} */
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      /** {@inheritDoc} */
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      /** {@inheritDoc} */
56      @Override
57      public final void setTextContent(final String newTextContent) {
58          super.setTextContent(newTextContent);
59          this.fireChanged(true);
60      }
61  
62      /** {@inheritDoc} */
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      /** {@inheritDoc} */
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      /** {@inheritDoc} */
85      public void fireChangeForSubTree() {
86          this.fireChanged(false);
87          ElementListSupport.fireChangeForSubTree(ElementListSupport
88                  .createListOfChildren(this));
89      }
90  
91      /**
92       * Called on any change. Please override!
93       */
94      protected void changeHook() {
95          // Override me!
96      }
97  
98      /** {@inheritDoc} */
99      public void addListener(final ChangeTrackingInterface listener) {
100         this.listeners.add(listener);
101     }
102 
103 }