1. /*
  2. * @(#)DigraphNode.java 1.7 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.imageio.spi;
  8. import java.io.Serializable;
  9. import java.util.HashSet;
  10. import java.util.Iterator;
  11. import java.util.Set;
  12. /**
  13. * A node in a directed graph. In addition to an arbitrary
  14. * <code>Object</code> containing user data associated with the node,
  15. * each node maintains a <code>Set</code>s of nodes which are pointed
  16. * to by the current node (available from <code>getOutNodes</code>).
  17. * The in-degree of the node (that is, number of nodes that point to
  18. * the current node) may be queried.
  19. *
  20. * @version 0.5
  21. */
  22. class DigraphNode implements Cloneable, Serializable {
  23. /** The data associated with this node. */
  24. protected Object data;
  25. /**
  26. * A <code>Set</code> of neighboring nodes pointed to by this
  27. * node.
  28. */
  29. protected Set outNodes = new HashSet();
  30. /** The in-degree of the node. */
  31. protected int inDegree = 0;
  32. /**
  33. * A <code>Set</code> of neighboring nodes that point to this
  34. * node.
  35. */
  36. private Set inNodes = new HashSet();
  37. public DigraphNode(Object data) {
  38. this.data = data;
  39. }
  40. /** Returns the <code>Object</code> referenced by this node. */
  41. public Object getData() {
  42. return data;
  43. }
  44. /**
  45. * Returns an <code>Iterator</code> containing the nodes pointed
  46. * to by this node.
  47. */
  48. public Iterator getOutNodes() {
  49. return outNodes.iterator();
  50. }
  51. /**
  52. * Adds a directed edge to the graph. The outNodes list of this
  53. * node is updated and the in-degree of the other node is incremented.
  54. *
  55. * @param node a <code>DigraphNode</code>.
  56. *
  57. * @return <code>true</code> if the node was not previously the
  58. * target of an edge.
  59. */
  60. public boolean addEdge(DigraphNode node) {
  61. if (outNodes.contains(node)) {
  62. return false;
  63. }
  64. outNodes.add(node);
  65. node.inNodes.add(this);
  66. node.incrementInDegree();
  67. return true;
  68. }
  69. /**
  70. * Returns <code>true</code> if an edge exists between this node
  71. * and the given node.
  72. *
  73. * @param node a <code>DigraphNode</code>.
  74. *
  75. * @return <code>true</code> if the node is the target of an edge.
  76. */
  77. public boolean hasEdge(DigraphNode node) {
  78. return outNodes.contains(node);
  79. }
  80. /**
  81. * Removes a directed edge from the graph. The outNodes list of this
  82. * node is updated and the in-degree of the other node is decremented.
  83. *
  84. * @return <code>true</code> if the node was previously the target
  85. * of an edge.
  86. */
  87. public boolean removeEdge(DigraphNode node) {
  88. if (!outNodes.contains(node)) {
  89. return false;
  90. }
  91. outNodes.remove(node);
  92. node.inNodes.remove(this);
  93. node.decrementInDegree();
  94. return true;
  95. }
  96. /**
  97. * Removes this node from the graph, updating neighboring nodes
  98. * appropriately.
  99. */
  100. public void dispose() {
  101. Iterator inIter = inNodes.iterator();
  102. while (inIter.hasNext()) {
  103. DigraphNode node = (DigraphNode)inIter.next();
  104. node.removeEdge(this);
  105. }
  106. Iterator outIter = outNodes.iterator();
  107. while (outIter.hasNext()) {
  108. DigraphNode node = (DigraphNode)outIter.next();
  109. removeEdge(node);
  110. }
  111. }
  112. /** Returns the in-degree of this node. */
  113. public int getInDegree() {
  114. return inDegree;
  115. }
  116. /** Increments the in-degree of this node. */
  117. private void incrementInDegree() {
  118. ++inDegree;
  119. }
  120. /** Decrements the in-degree of this node. */
  121. private void decrementInDegree() {
  122. --inDegree;
  123. }
  124. }