Skip to content

Commit

Permalink
Added get(key, type) method to Cache interface
Browse files Browse the repository at this point in the history
This new get variant not only allows for generically specifying the required value type; it also skips the ValueWrapper that the standard get method returns. Note that it is not possible to differentiate between non-existing cache entries and cached null values that way; for that purpose, the standard get variant needs to be used.

Issue: SPR-11061
  • Loading branch information
jhoeller committed Nov 4, 2013
1 parent b093b84 commit 50d3f71
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -65,6 +65,17 @@ public ValueWrapper get(Object key) {
return (element != null ? new SimpleValueWrapper(element.getObjectValue()) : null);
}

@Override
@SuppressWarnings("unchecked")
public <T> T get(Object key, Class<T> type) {
Element element = this.cache.get(key);
Object value = (element != null ? element.getObjectValue() : null);
if (type != null && !type.isInstance(value)) {
throw new IllegalStateException("Cached value is not of required type [" + type.getName() + "]: " + value);
}
return (T) value;
}

@Override
public void put(Object key, Object value) {
this.cache.put(new Element(key, value));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ public ValueWrapper get(Object key) {
return (value != null ? new SimpleValueWrapper(fromStoreValue(value)) : null);
}

@Override
@SuppressWarnings("unchecked")
public <T> T get(Object key, Class<T> type) {
Object value = fromStoreValue(this.cache.get(key));
if (type != null && !type.isInstance(value)) {
throw new IllegalStateException("Cached value is not of required type [" + type.getName() + "]: " + value);
}
return (T) value;
}

@Override
@SuppressWarnings("unchecked")
public void put(Object key, Object value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -62,6 +62,11 @@ public ValueWrapper get(Object key) {
return this.targetCache.get(key);
}

@Override
public <T> T get(Object key, Class<T> type) {
return this.targetCache.get(key, type);
}

@Override
public void put(final Object key, final Object value) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;

import org.junit.Before;
import org.junit.Test;

Expand Down Expand Up @@ -74,6 +73,9 @@ public void testCachePut() throws Exception {
assertNull(cache.get(key));
cache.put(key, value);
assertEquals(value, cache.get(key).get());
assertEquals(value, cache.get(key, String.class));
assertEquals(value, cache.get(key, Object.class));
assertEquals(value, cache.get(key, null));
}

@Test
Expand Down
30 changes: 25 additions & 5 deletions spring-context/src/main/java/org/springframework/cache/Cache.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -39,14 +39,34 @@ public interface Cache {
Object getNativeCache();

/**
* Return the value to which this cache maps the specified key. Returns
* {@code null} if the cache contains no mapping for this key.
* @param key key whose associated value is to be returned.
* Return the value to which this cache maps the specified key.
* <p>Returns {@code null} if the cache contains no mapping for this key;
* otherwise, the cached value (which may be {@code null} itself) will
* be returned in a {@link ValueWrapper}.
* @param key the key whose associated value is to be returned
* @return the value to which this cache maps the specified key,
* or {@code null} if the cache contains no mapping for this key
* contained within a {@link ValueWrapper} which may also hold
* a cached {@code null} value. A straight {@code null} being
* returned means that the cache contains no mapping for this key.
* @see #get(Object, Class)
*/
ValueWrapper get(Object key);

/**
* Return the value to which this cache maps the specified key,
* generically specifying a type that return value will be cast to.
* <p>Note: This variant of {@code get} does not allow for differentiating
* between a cached {@code null} value and no cache entry found at all.
* Use the standard {@link #get(Object)} variant for that purpose instead.
* @param key the key whose associated value is to be returned
* @param type the required type of the returned value
* @return the value to which this cache maps the specified key
* (which may be {@code null} itself), or also {@code null} if
* the cache contains no mapping for this key
* @see #get(Object)
*/
<T> T get(Object key, Class<T> type);

/**
* Associate the specified value with the specified key in this cache.
* <p>If the cache previously contained a mapping for this key, the old
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

package org.springframework.cache.concurrent;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;

import java.io.Serializable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;

/**
* Simple {@link Cache} implementation based on the core JDK
* {@code java.util.concurrent} package.
Expand Down Expand Up @@ -103,6 +103,16 @@ public ValueWrapper get(Object key) {
return (value != null ? new SimpleValueWrapper(fromStoreValue(value)) : null);
}

@Override
@SuppressWarnings("unchecked")
public <T> T get(Object key, Class<T> type) {
Object value = fromStoreValue(this.store.get(key));
if (type != null && !type.isInstance(value)) {
throw new IllegalStateException("Cached value is not of required type [" + type.getName() + "]: " + value);
}
return (T) value;
}

@Override
public void put(Object key, Object value) {
this.store.put(key, toStoreValue(value));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -93,6 +93,11 @@ public ValueWrapper get(Object key) {
return null;
}

@Override
public <T> T get(Object key, Class<T> type) {
return null;
}

@Override
public String getName() {
return this.name;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011 the original author or authors.
* Copyright 2010-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -48,6 +48,7 @@ public void testNoOpCache() throws Exception {
Object key = new Object();
cache.put(key, new Object());
assertNull(cache.get(key));
assertNull(cache.get(key, Object.class));
assertNull(cache.getNativeCache());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2012 the original author or authors.
* Copyright 2010-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -64,6 +64,9 @@ public void testCachePut() throws Exception {
assertNull(cache.get(key));
cache.put(key, value);
assertEquals(value, cache.get(key).get());
assertEquals(value, cache.get(key, String.class));
assertEquals(value, cache.get(key, Object.class));
assertEquals(value, cache.get(key, null));
}

@Test
Expand Down

0 comments on commit 50d3f71

Please sign in to comment.