summaryrefslogtreecommitdiff
path: root/israfil-foundation-cache/src/main/java/net/israfil/foundation/caching/GenericFetcherCache.java
diff options
context:
space:
mode:
Diffstat (limited to 'israfil-foundation-cache/src/main/java/net/israfil/foundation/caching/GenericFetcherCache.java')
-rw-r--r--israfil-foundation-cache/src/main/java/net/israfil/foundation/caching/GenericFetcherCache.java124
1 files changed, 124 insertions, 0 deletions
diff --git a/israfil-foundation-cache/src/main/java/net/israfil/foundation/caching/GenericFetcherCache.java b/israfil-foundation-cache/src/main/java/net/israfil/foundation/caching/GenericFetcherCache.java
new file mode 100644
index 0000000..ce42bc2
--- /dev/null
+++ b/israfil-foundation-cache/src/main/java/net/israfil/foundation/caching/GenericFetcherCache.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2006 Israfil Consulting Services Corporation
+ * Copyright (c) 2006 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: GenericCache.java 129 2006-12-31 23:20:02Z cgruber $
+ */
+package net.israfil.foundation.caching;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * A non-thread-safe cache object
+ *
+ * @author <a href="mailto:cgruber@israfil.net">Christian Edward Gruber</a>
+ */
+public class GenericFetcherCache implements FetcherCache {
+
+ private Map<String,Object> _caches = new HashMap<String,Object>();
+
+ /**
+ * Retrieves an object from a path in the cache
+ * @param cacheName A string identifying from which cache the object will be retrieved
+ * @param An array of path items identifying the path through the map keys.
+ */
+ public Object get(Fetcher fetcher, String cacheName, String itemKey, String ... path) {
+
+ // Fetch the map containing the item.
+ Map<String,Object> cache = _getLocationInMap(_caches,new ArrayList<String>(_prepPathList(cacheName,path)));
+
+ // Get the item from the map
+ Object o = cache.get((itemKey==null) ? "__NULL__" : itemKey);
+ if (o == null) {
+ // Item doesn't exist, so try to fetch, then retrieve again.
+ fetcher.fetch();
+ o = cache.get((itemKey==null) ? "__NULL__" : itemKey);
+ }
+ return o;
+ }
+
+
+ /**
+ * A method to set values within the cache, to be used by Fetcher implementations
+ * in setting up the cache when they fetch.
+ */
+ public void set(String cacheName, String itemKey, Object value, String ... path) {
+ List<String> pathList = _prepPathList(cacheName,path);
+ Map<String,Object> cache = _getLocationInMap(_caches,new ArrayList<String>(pathList));
+ cache.put(itemKey,value);
+ }
+
+ /**
+ * Creates a List that contains the pathelements, starting from the
+ * cache name down to the bottom, but excluding the actual final path
+ * item.
+ */
+ static List<String> _prepPathList(String cacheName,String[] pathElements) {
+ List<String> pathList;
+ if (pathElements == null || pathElements.length < 1) {
+ pathList = new ArrayList<String>();
+ } else {
+ // Need to make this explicitly an arrayList, so that
+ // add(index,value) will work.
+ pathList = new ArrayList<String>(Arrays.asList(pathElements));
+ }
+ pathList.add(0,cacheName);
+ return pathList;
+ }
+
+ /**
+ * Recursively traverses the cache map, creating maps at path locations
+ * where they do not already exist.
+ */
+ @SuppressWarnings("unchecked")
+ static Map<String, Object> _getLocationInMap(
+ Map<String, Object> currentMap, List<String> cachePath) {
+ if (cachePath == null || cachePath.size() < 1) return currentMap;
+ String cacheName = (String)cachePath.remove(0); // pull the first one
+
+ Object cacheObject = (Map<String,Object>)currentMap.get(cacheName);
+ if (cacheObject == null) {
+ cacheObject = new HashMap<String,Object>();
+ currentMap.put(cacheName,cacheObject);
+ }
+ if (! (cacheObject instanceof Map))
+ throw new IllegalArgumentException("Attempted to find a map at location ("+cachePath+") in cache ("+cacheName+"), but found a " + cacheObject.getClass().getName() + ".");
+ Map<String,Object> cache = (Map<String,Object>)cacheObject;
+
+ return _getLocationInMap(cache,cachePath);
+ }
+
+
+}