Coverage Report - org.dishevelled.observable.graph.AbstractObservableGraph
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractObservableGraph
98%
57/58
100%
10/10
1.2
 
 1  
 /*
 2  
 
 3  
     dsh-observable-graph  Observable decorators for graph interfaces.
 4  
     Copyright (c) 2008-2013 held jointly by the individual authors.
 5  
 
 6  
     This library is free software; you can redistribute it and/or modify it
 7  
     under the terms of the GNU Lesser General Public License as published
 8  
     by the Free Software Foundation; either version 3 of the License, or (at
 9  
     your option) any later version.
 10  
 
 11  
     This library is distributed in the hope that it will be useful, but WITHOUT
 12  
     ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
 13  
     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 14  
     License for more details.
 15  
 
 16  
     You should have received a copy of the GNU Lesser General Public License
 17  
     along with this library;  if not, write to the Free Software Foundation,
 18  
     Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
 19  
 
 20  
     > http://www.fsf.org/licensing/licenses/lgpl.html
 21  
     > http://www.opensource.org/licenses/lgpl-license.php
 22  
 
 23  
 */
 24  
 package org.dishevelled.observable.graph;
 25  
 
 26  
 import org.dishevelled.graph.Edge;
 27  
 import org.dishevelled.graph.Graph;
 28  
 import org.dishevelled.graph.Node;
 29  
 
 30  
 import org.dishevelled.graph.impl.AbstractGraphDecorator;
 31  
 
 32  
 import org.dishevelled.observable.graph.event.GraphChangeListener;
 33  
 import org.dishevelled.observable.graph.event.GraphChangeVetoException;
 34  
 import org.dishevelled.observable.graph.event.ObservableGraphChangeSupport;
 35  
 import org.dishevelled.observable.graph.event.VetoableGraphChangeListener;
 36  
 
 37  
 /**
 38  
  * Abstract implementation of an observable graph that decorates an
 39  
  * instance of <code>Graph</code>.
 40  
  *
 41  
  * @param <N> node value type
 42  
  * @param <E> edge value type
 43  
  * @author  Michael Heuer
 44  
  * @version $Revision$ $Date$
 45  
  */
 46  
 public abstract class AbstractObservableGraph<N, E>
 47  
     extends AbstractGraphDecorator<N, E>
 48  
     implements ObservableGraph<N, E>
 49  
 {
 50  
     /** Observable graph change support. */
 51  
     private final ObservableGraphChangeSupport<N, E> support;
 52  
 
 53  
 
 54  
     /**
 55  
      * Create a new abstract observable graph that
 56  
      * decorates the specified graph.
 57  
      *
 58  
      * @param graph graph to decorate
 59  
      */
 60  
     protected AbstractObservableGraph(final Graph<N, E> graph)
 61  
     {
 62  134
         super(graph);
 63  133
         support = new ObservableGraphChangeSupport<N, E>(this);
 64  133
     }
 65  
 
 66  
 
 67  
     /**
 68  
      * Return the <code>ObservableGraphChangeSupport</code>
 69  
      * class backing this abstract observable graph.
 70  
      *
 71  
      * @return the <code>ObservableGraphChangeSupport</code>
 72  
      *    class backing this abstract observable graph
 73  
      */
 74  
     protected final ObservableGraphChangeSupport<N, E> getObservableGraphChangeSupport()
 75  
     {
 76  0
         return support;
 77  
     }
 78  
 
 79  
     /** {@inheritDoc} */
 80  
     public final void addGraphChangeListener(final GraphChangeListener<N, E> l)
 81  
     {
 82  12
         support.addGraphChangeListener(l);
 83  12
     }
 84  
 
 85  
     /** {@inheritDoc} */
 86  
     public final void removeGraphChangeListener(final GraphChangeListener<N, E> l)
 87  
     {
 88  12
         support.removeGraphChangeListener(l);
 89  12
     }
 90  
 
 91  
     /** {@inheritDoc} */
 92  
     public final void addVetoableGraphChangeListener(final VetoableGraphChangeListener<N, E> l)
 93  
     {
 94  22
         support.addVetoableGraphChangeListener(l);
 95  22
     }
 96  
 
 97  
     /** {@inheritDoc} */
 98  
     public final void removeVetoableGraphChangeListener(final VetoableGraphChangeListener<N, E> l)
 99  
     {
 100  22
         support.removeVetoableGraphChangeListener(l);
 101  22
     }
 102  
 
 103  
     /** {@inheritDoc} */
 104  
     public final GraphChangeListener<N, E>[] getGraphChangeListeners()
 105  
     {
 106  10
         return support.getGraphChangeListeners();
 107  
     }
 108  
 
 109  
     /** {@inheritDoc} */
 110  
     public final int getGraphChangeListenerCount()
 111  
     {
 112  4
         return support.getGraphChangeListenerCount();
 113  
     }
 114  
 
 115  
     /** {@inheritDoc} */
 116  
     public final VetoableGraphChangeListener<N, E>[] getVetoableGraphChangeListeners()
 117  
     {
 118  10
         return support.getVetoableGraphChangeListeners();
 119  
     }
 120  
 
 121  
     /** {@inheritDoc} */
 122  
     public final int getVetoableGraphChangeListenerCount()
 123  
     {
 124  4
         return support.getVetoableGraphChangeListenerCount();
 125  
     }
 126  
 
 127  
     /**
 128  
      * Fire a will clear change event to all registered
 129  
      * <code>VetoableGraphChangeListener</code>s.
 130  
      *
 131  
      * @throws GraphChangeVetoException if any of the listeners veto the change
 132  
      */
 133  
     protected void fireWillClear()
 134  
         throws GraphChangeVetoException
 135  
     {
 136  4
         support.fireWillClear();
 137  2
     }
 138  
 
 139  
     /**
 140  
      * Fire a cleared change event to all registered <code>GraphChangeListener</code>s.
 141  
      */
 142  
     protected void fireCleared()
 143  
     {
 144  1
         support.fireCleared();
 145  1
     }
 146  
 
 147  
     /**
 148  
      * Fire a will create node change event to all registered
 149  
      * <code>VetoableGraphChangeListener</code>s.
 150  
      *
 151  
      * @param nodeValue node value for an about to be created node
 152  
      * @throws GraphChangeVetoException if any of the listeners veto the change
 153  
      */
 154  
     protected void fireWillCreateNode(final N nodeValue)
 155  
         throws GraphChangeVetoException
 156  
     {
 157  23
         support.fireWillCreateNode(nodeValue);
 158  17
     }
 159  
 
 160  
     /**
 161  
      * Fire a will create edge change event to all registered
 162  
      * <code>VetoableGraphChangeListener</code>s.
 163  
      *
 164  
      * @param sourceNode source node for an about to be created edge
 165  
      * @param targetNode target node for an about to be created edge
 166  
      * @param edgeValue edge value for an about to be created edge
 167  
      * @throws GraphChangeVetoException if any of the listeners veto the change
 168  
      */
 169  
     protected void fireWillCreateEdge(final Node<N, E> sourceNode,
 170  
            final Node<N, E> targetNode,
 171  
            final E edgeValue)
 172  
         throws GraphChangeVetoException
 173  
     {
 174  5
         support.fireWillCreateEdge(sourceNode, targetNode, edgeValue);
 175  3
     }
 176  
 
 177  
     /**
 178  
      * Fire a will remove node change event to all registered
 179  
      * <code>VetoableGraphChangeListener</code>s.
 180  
      *
 181  
      * @param node node about to be removed
 182  
      * @throws GraphChangeVetoException if any of the listeners veto the change
 183  
      */
 184  
     protected void fireWillRemoveNode(final Node<N, E> node)
 185  
         throws GraphChangeVetoException
 186  
     {
 187  4
         support.fireWillRemoveNode(node);
 188  2
     }
 189  
 
 190  
     /**
 191  
      * Fire a will remove edge change event to all registered
 192  
      * <code>VetoableGraphChangeListener</code>s.
 193  
      *
 194  
      * @param edge edge about to be removed
 195  
      * @throws GraphChangeVetoException if any of the listeners veto the change
 196  
      */
 197  
     protected void fireWillRemoveEdge(final Edge<N, E> edge)
 198  
         throws GraphChangeVetoException
 199  
     {
 200  4
         support.fireWillRemoveEdge(edge);
 201  2
     }
 202  
 
 203  
     /**
 204  
      * Fire a node created change event to all registered <code>GraphChangeListener</code>s.
 205  
      *
 206  
      * @param node newly created node
 207  
      */
 208  
     protected void fireNodeCreated(final Node<N, E> node)
 209  
     {
 210  15
         support.fireNodeCreated(node);
 211  15
     }
 212  
 
 213  
     /**
 214  
      * Fire a node removed change event to all registered <code>GraphChangeListener</code>s.
 215  
      *
 216  
      * @param node removed node
 217  
      */
 218  
     protected void fireNodeRemoved(final Node<N, E> node)
 219  
     {
 220  1
         support.fireNodeRemoved(node);
 221  1
     }
 222  
 
 223  
     /**
 224  
      * Fire an edge created change event to all registered <code>GraphChangeListener</code>s.
 225  
      *
 226  
      * @param edge newly created edge
 227  
      */
 228  
     protected void fireEdgeCreated(final Edge<N, E> edge)
 229  
     {
 230  3
         support.fireEdgeCreated(edge);
 231  3
     }
 232  
 
 233  
     /**
 234  
      * Fire an edge removed change event to all registered <code>GraphChangeListener</code>s.
 235  
      *
 236  
      * @param edge removed edge
 237  
      */
 238  
     protected void fireEdgeRemoved(final Edge<N, E> edge)
 239  
     {
 240  1
         support.fireEdgeRemoved(edge);
 241  1
     }
 242  
 
 243  
     /**
 244  
      * Notify subclasses the <code>clear</code> method is about to
 245  
      * be called on the wrapped graph.
 246  
      * Return <code>true</code> to proceed with the change.
 247  
      *
 248  
      * @return true to proceed with the change
 249  
      */
 250  
     protected abstract boolean preClear();
 251  
 
 252  
     /**
 253  
      * Notify subclasses the <code>clear</code> method has just been
 254  
      * called on the wrapped graph.
 255  
      */
 256  
     protected abstract void postClear();
 257  
 
 258  
     /**
 259  
      * Notify subclasses the <code>createNode</code> method is about to
 260  
      * be called on the wrapped graph with the specified parameter.
 261  
      * Return <code>true</code> to proceed with the change.
 262  
      *
 263  
      * @param value <code>createNode</code> method parameter
 264  
      * @return true to proceed with the change
 265  
      */
 266  
     protected abstract boolean preCreateNode(N value);
 267  
 
 268  
     /**
 269  
      * Notify subclasses the <code>createNode</code> method has just been
 270  
      * called on the wrapped graph with the specified parameter.
 271  
      *
 272  
      * @param value <code>createNode</code> method parameter
 273  
      * @param node newly created node
 274  
      */
 275  
     protected abstract void postCreateNode(N value, Node<N, E> node);
 276  
 
 277  
     /**
 278  
      * Notify subclasses the <code>remove(Node&lt;N, E&gt;)</code> method is about to
 279  
      * be called on the wrapped graph with the specified parameter.
 280  
      * Return <code>true</code> to proceed with the change.
 281  
      *
 282  
      * @param node <code>remove(Node&lt;N, E&gt;)</code> method parameter
 283  
      * @return true to proceed with the change
 284  
      */
 285  
     protected abstract boolean preRemove(Node<N, E> node);
 286  
 
 287  
     /**
 288  
      * Notify subclasses the <code>remove(Node&lt;N, E&gt;)</code> method has just been
 289  
      * called on the wrapped graph with the specified parameter.
 290  
      *
 291  
      * @param node <code>remove(Node&lt;N, E&gt;)</code> method parameter
 292  
      */
 293  
     protected abstract void postRemove(Node<N, E> node);
 294  
 
 295  
     /**
 296  
      * Notify subclasses the <code>createEdge</code> method is about to
 297  
      * be called on the wrapped graph with the specified parameters.
 298  
      * Return <code>true</code> to proceed with the change.
 299  
      *
 300  
      * @param source <code>createEdge</code> method parameter
 301  
      * @param target <code>createEdge</code> method parameter
 302  
      * @param value <code>createEdge</code> method parameter
 303  
      * @return true to proceed with the change
 304  
      */
 305  
     protected abstract boolean preCreateEdge(Node<N, E> source, Node<N, E> target, E value);
 306  
 
 307  
     /**
 308  
      * Notify subclasses the <code>createEdge</code> method has just been
 309  
      * called on the wrapped graph with the specified parameters.
 310  
      *
 311  
      * @param source <code>createEdge</code> method parameter
 312  
      * @param target <code>createEdge</code> method parameter
 313  
      * @param value <code>createEdge</code> method parameter
 314  
      * @param edge newly created edge
 315  
      */
 316  
     protected abstract void postCreateEdge(Node<N, E> source, Node<N, E> target, E value, Edge<N, E> edge);
 317  
 
 318  
     /**
 319  
      * Notify subclasses the <code>remove(Edge&lt;N, E&gt;)</code> method is about to
 320  
      * be called on the wrapped graph with the specified parameter.
 321  
      * Return <code>true</code> to proceed with the change.
 322  
      *
 323  
      * @param edge <code>remove(Edge&lt;N, E&gt;)</code> method parameter
 324  
      * @return true to proceed with the change
 325  
      */
 326  
     protected abstract boolean preRemove(Edge<N, E> edge);
 327  
 
 328  
     /**
 329  
      * Notify subclasses the <code>remove(Edge&lt;N, E&gt;)</code> method has just been
 330  
      * called on the wrapped graph with the specified parameter.
 331  
      *
 332  
      * @param edge <code>remove(Edge&lt;N, E&gt;)</code> method parameter
 333  
      */
 334  
     protected abstract void postRemove(Edge<N, E> edge);
 335  
 
 336  
     /** {@inheritDoc} */
 337  
     public void clear()
 338  
     {
 339  4
         if (preClear())
 340  
         {
 341  2
             super.clear();
 342  1
             postClear();
 343  
         }
 344  3
     }
 345  
 
 346  
     /** {@inheritDoc} */
 347  
     public Node<N, E> createNode(final N value)
 348  
     {
 349  23
         if (preCreateNode(value))
 350  
         {
 351  17
             Node<N, E> node = super.createNode(value);
 352  15
             postCreateNode(value, node);
 353  15
             return node;
 354  
         }
 355  
         // TODO:  explicitly document this behaviour
 356  6
         return null;
 357  
     }
 358  
 
 359  
     /** {@inheritDoc} */
 360  
     public void remove(final Node<N, E> node)
 361  
     {
 362  4
         if (preRemove(node))
 363  
         {
 364  2
             super.remove(node);
 365  1
             postRemove(node);
 366  
         }
 367  3
     }
 368  
 
 369  
     /** {@inheritDoc} */
 370  
     public Edge<N, E> createEdge(final Node<N, E> source, final Node<N, E> target, final E value)
 371  
     {
 372  5
         if (preCreateEdge(source, target, value))
 373  
         {
 374  3
             Edge<N, E> edge = super.createEdge(source, target, value);
 375  3
             postCreateEdge(source, target, value, edge);
 376  3
             return edge;
 377  
         }
 378  
         // TODO:  explicitly document this behaviour
 379  2
         return null;
 380  
     }
 381  
 
 382  
     /** {@inheritDoc} */
 383  
     public void remove(final Edge<N, E> edge)
 384  
     {
 385  4
         if (preRemove(edge))
 386  
         {
 387  2
             super.remove(edge);
 388  1
             postRemove(edge);
 389  
         }
 390  3
     }
 391  
 }