/plugins/Substance/trunk/substance-6.1/substance/src/org/pushingpixels/substance/internal/utils/LazyResettableHashMap.java

# · Java · 180 lines · 72 code · 17 blank · 91 comment · 21 complexity · b502daca5502b135f37be55228d669a3 MD5 · raw file

  1. /*
  2. * Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * o Redistributions of source code must retain the above copyright notice,
  8. * this list of conditions and the following disclaimer.
  9. *
  10. * o Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. *
  14. * o Neither the name of Substance Kirill Grouchnikov nor the names of
  15. * its contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  20. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  21. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  22. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  23. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  25. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  27. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  28. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. package org.pushingpixels.substance.internal.utils;
  31. import java.util.*;
  32. import javax.swing.SwingUtilities;
  33. /**
  34. * Lazily initialized hash map for caching images. Note that this class is
  35. * <b>not</b> thread safe. In Substance, it is used only from EDT.
  36. *
  37. * @author Kirill Grouchnikov
  38. * @param <T>
  39. * Class for the stored values.
  40. */
  41. public class LazyResettableHashMap<T> {
  42. /**
  43. * List of all existing maps.
  44. */
  45. private static List<LazyResettableHashMap<?>> all;
  46. /**
  47. * The delegate cache.
  48. */
  49. private Map<HashMapKey, T> cache;
  50. /**
  51. * Display name of this hash map. Is used for tracking the statistics.
  52. */
  53. private String displayName;
  54. /**
  55. * Creates a new hash map.
  56. *
  57. * @param displayName
  58. * Display name of the new hash map.
  59. */
  60. public LazyResettableHashMap(String displayName) {
  61. this.displayName = displayName;
  62. if (all == null) {
  63. all = new LinkedList<LazyResettableHashMap<?>>();
  64. }
  65. all.add(this);
  66. }
  67. /**
  68. * Creates the delegate cache if necessary.
  69. */
  70. private void createIfNecessary() {
  71. if (this.cache == null)
  72. this.cache = new SoftHashMap<HashMapKey, T>();
  73. }
  74. /**
  75. * Puts a new key-value pair in the map.
  76. *
  77. * @param key
  78. * Pair key.
  79. * @param entry
  80. * Pair value.
  81. */
  82. public void put(HashMapKey key, T entry) {
  83. if (!SwingUtilities.isEventDispatchThread())
  84. throw new IllegalArgumentException(
  85. "Called outside Event Dispatch Thread");
  86. this.createIfNecessary();
  87. this.cache.put(key, entry);
  88. }
  89. /**
  90. * Returns the value registered for the specified key.
  91. *
  92. * @param key
  93. * Key.
  94. * @return Registered value or <code>null</code> if none.
  95. */
  96. public T get(HashMapKey key) {
  97. if (this.cache == null)
  98. return null;
  99. return this.cache.get(key);
  100. }
  101. /**
  102. * Checks whether there is a value associated with the specified key.
  103. *
  104. * @param key
  105. * Key.
  106. * @return <code>true</code> if there is an associated value,
  107. * <code>false</code> otherwise.
  108. */
  109. public boolean containsKey(HashMapKey key) {
  110. if (this.cache == null)
  111. return false;
  112. return this.cache.containsKey(key);
  113. }
  114. /**
  115. * Returns the number of key-value pairs of this hash map.
  116. *
  117. * @return The number of key-value pairs of this hash map.
  118. */
  119. public int size() {
  120. if (this.cache == null)
  121. return 0;
  122. return this.cache.size();
  123. }
  124. /**
  125. * Resets all existing hash maps.
  126. */
  127. public static void reset() {
  128. if (all != null) {
  129. for (LazyResettableHashMap<?> map : all) {
  130. if (map.cache != null)
  131. map.cache.clear();
  132. }
  133. }
  134. }
  135. /**
  136. * Returns statistical information of the existing hash maps.
  137. *
  138. * @return Statistical information of the existing hash maps.
  139. */
  140. public static List<String> getStats() {
  141. if (all != null) {
  142. List<String> result = new LinkedList<String>();
  143. Map<String, Integer> mapCounter = new TreeMap<String, Integer>();
  144. Map<String, Integer> entryCounter = new TreeMap<String, Integer>();
  145. for (LazyResettableHashMap<?> map : all) {
  146. String key = map.displayName;
  147. if (!mapCounter.containsKey(key)) {
  148. mapCounter.put(key, 0);
  149. entryCounter.put(key, 0);
  150. }
  151. mapCounter.put(key, mapCounter.get(key) + 1);
  152. entryCounter.put(key, entryCounter.get(key) + map.size());
  153. }
  154. for (Map.Entry<String, Integer> entry : mapCounter.entrySet()) {
  155. String key = entry.getKey();
  156. result.add(entry.getValue() + " " + key + " with "
  157. + entryCounter.get(key) + " entries total");
  158. }
  159. return result;
  160. }
  161. return null;
  162. }
  163. }