1. /*
  2. * @(#)CircularIdentityList.java 1.5 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.gtk;
  8. import java.util.*;
  9. /**
  10. * An circular linked list like data structure that uses identity for equality
  11. * testing.
  12. *
  13. * @version 1.5, 12/19/03
  14. * @author Scott Violet
  15. */
  16. class CircularIdentityList implements Cloneable {
  17. private Property property;
  18. /**
  19. * Sets a particular value.
  20. */
  21. public synchronized void set(Object key, Object value) {
  22. if (property == null) {
  23. property = new Property(key, value, null);
  24. }
  25. else {
  26. Property p = property;
  27. Property last = p;
  28. do {
  29. if (p.key == key) {
  30. p.value = value;
  31. property = p;
  32. return;
  33. }
  34. last = p;
  35. p = p.next;
  36. } while (p != property && p != null);
  37. // not defined
  38. if (value != null) {
  39. if (p == null) {
  40. // Only one element
  41. p = property;
  42. }
  43. property = new Property(key, value, p);
  44. last.next = property;
  45. }
  46. }
  47. }
  48. /**
  49. * Returns the value currently being referenced.
  50. */
  51. public synchronized Object get() {
  52. if (property == null) {
  53. return null;
  54. }
  55. return property.value;
  56. }
  57. /**
  58. * Returns the value for a specific key.
  59. */
  60. public synchronized Object get(Object key) {
  61. if (property == null) {
  62. return null;
  63. }
  64. Property p = property;
  65. do {
  66. if (p.key == key) {
  67. return p.value;
  68. }
  69. p = p.next;
  70. } while (p != property && p != null);
  71. return null;
  72. }
  73. /**
  74. * Advanced the list returning the next key. This will only return
  75. * null if the list is empty.
  76. */
  77. public synchronized Object next() {
  78. if (property == null) {
  79. return null;
  80. }
  81. if (property.next == null) {
  82. return property.key;
  83. }
  84. property = property.next;
  85. return property.key;
  86. }
  87. public synchronized Object clone() {
  88. try {
  89. CircularIdentityList list = (CircularIdentityList)super.clone();
  90. if (property != null) {
  91. list.property = (Property)property.clone();
  92. Property last = list.property;
  93. while (last.next != null && last.next != property) {
  94. last.next = (Property)last.next.clone();
  95. last = last.next;
  96. }
  97. last.next = list.property;
  98. }
  99. return list;
  100. } catch (CloneNotSupportedException cnse) {
  101. }
  102. return null;
  103. }
  104. static class Property implements Cloneable {
  105. Object key;
  106. Object value;
  107. Property next;
  108. Property(Object key, Object value, Property next) {
  109. this.key = key;
  110. this.value = value;
  111. this.next = next;
  112. }
  113. public Object clone() {
  114. try {
  115. return super.clone();
  116. } catch (CloneNotSupportedException cnse) {
  117. }
  118. return null;
  119. }
  120. }
  121. }