org.apache.xmlgraphics.image.loader.util.SoftMapCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xmlgraphics-commons Show documentation
Show all versions of xmlgraphics-commons Show documentation
Apache XML Graphics Commons is a library that consists of several reusable
components used by Apache Batik and Apache FOP. Many of these components
can easily be used separately outside the domains of SVG and XSL-FO.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: SoftMapCache.java 750418 2009-03-05 11:03:54Z vhennebert $ */
package org.apache.xmlgraphics.image.loader.util;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.Collections;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Provides a simple cache using soft references and storing the values in a Map. The keys into
* the Map are hard references, the values are referenced through soft references. The collected
* values are cleaned up through a ReferenceQueue.
*/
public class SoftMapCache {
/** logger */
private static Log log = LogFactory.getLog(SoftMapCache.class);
private Map map;
private ReferenceQueue refQueue = new ReferenceQueue();
/**
* Creates a new soft cache.
* @param synched true if the Map containing the values should by synchronized
*/
public SoftMapCache(boolean synched) {
this.map = new java.util.HashMap();
if (synched) {
this.map = Collections.synchronizedMap(this.map);
}
}
/**
* Returns the value associated with the given key. If the value is not found or the value
* has been collected, null is returned.
* @param key the key
* @return the requested value or null
*/
public Object get(Object key) {
Reference ref = (Reference)map.get(key);
return getReference(key, ref);
}
/**
* Removed the value associated with the given key. The value that is removed is returned
* as the methods result. If the value is not found or the value has been collected,
* null is returned.
* @param key the key
* @return the requested value or null
*/
public Object remove(Object key) {
Reference ref = (Reference)map.remove(key);
return getReference(key, ref);
}
private Object getReference(Object key, Reference ref) {
Object value = null;
if (ref != null) {
value = ref.get();
if (value == null) {
//Remove key if its value has been garbage collected
if (log.isTraceEnabled()) {
log.trace("Image has been collected: " + key);
}
checkReferenceQueue();
}
}
return value;
}
/**
* Put a new value in the cache overwriting any existing value with the same key.
* @param key The key
* @param value the value
*/
public void put(Object key, Object value) {
map.put(key, wrapInReference(value, key));
}
/**
* Clears the cache.
*/
public void clear() {
map.clear();
}
/**
* Triggers some house-keeping, i.e. processes any pending objects in the reference queue.
*/
public void doHouseKeeping() {
checkReferenceQueue();
}
private Reference wrapInReference(Object obj, Object key) {
return new SoftReferenceWithKey(obj, key, refQueue);
}
/**
* Checks the reference queue if any references have been cleared and removes them from the
* cache.
*/
private void checkReferenceQueue() {
SoftReferenceWithKey ref;
while ((ref = (SoftReferenceWithKey)refQueue.poll()) != null) {
if (log.isTraceEnabled()) {
log.trace("Removing ImageInfo from ref queue: " + ref.getKey());
}
map.remove(ref.getKey());
}
}
}