Example #1
0
 /**
  * Utility method to clone a map, preserving immutable instances
  *
  * @param <K> the map key type, which must be {@link Serializable}
  * @param <V> the map value type, which must be {@link Serializable}
  * @param map the map to copy
  * @param immutableClasses a set of classes that can be considered immutable over and above the
  *     {@link #DEFAULT_IMMUTABLE_CLASSES default set}
  */
 public static <K extends Serializable, V extends Serializable> Map<K, V> cloneMap(
     Map<K, V> map, Set<Class<?>> immutableClasses) {
   Map<K, V> copy = new HashMap<K, V>((int) (map.size() * 1.3));
   for (Map.Entry<K, V> element : map.entrySet()) {
     K key = element.getKey();
     V value = element.getValue();
     // Clone as necessary
     key = ValueProtectingMap.protectValue(key, immutableClasses);
     value = ValueProtectingMap.protectValue(value, immutableClasses);
     copy.put(key, value);
   }
   return copy;
 }
Example #2
0
  /**
   * Called by methods that need to force the map into a safe state.
   *
   * <p>This method can be called without any locks being active.
   */
  private void cloneMap() {
    readLock.lock();
    try {
      // Check that it hasn't been copied already
      if (cloned) {
        return;
      }
    } finally {
      readLock.unlock();
    }
    /*
     * Note: This space here is a window during which some code could have made
     *       a copy.  Therefore we will do a cautious double-check.
     */
    // Put in a write lock before cloning the map
    writeLock.lock();
    try {
      // Check that it hasn't been copied already
      if (cloned) {
        return;
      }

      Map<K, V> copy = ValueProtectingMap.cloneMap(map, immutableClasses);
      // Discard the original
      this.map = copy;
      this.cloned = true;
    } finally {
      writeLock.unlock();
    }
  }
Example #3
0
 @Override
 public V get(Object key) {
   readLock.lock();
   try {
     V value = map.get(key);
     return ValueProtectingMap.protectValue(value, immutableClasses);
   } finally {
     readLock.unlock();
   }
 }