OPENJPA-1542: Adding support for openjpa.DataCache Types and ExcludedTypes configuration back into trunk. Also updating TestCacheExclusions. No doc changes required as the user manual is up to date.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@916714 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Richard G. Curtis 2010-02-26 15:23:26 +00:00
parent 06d3e4e65d
commit eca02573ba
4 changed files with 85 additions and 7 deletions

View File

@ -19,10 +19,12 @@
package org.apache.openjpa.datacache;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -37,6 +39,10 @@ import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
import org.apache.openjpa.util.GeneralException;
import org.apache.openjpa.util.OpenJPAException;
import serp.util.Strings;
/**
* Abstract {@link DataCache} implementation that provides various
@ -70,6 +76,8 @@ public abstract class AbstractDataCache extends AbstractConcurrentEventManager
private String _name = null;
private boolean _closed = false;
private String _schedule = null;
protected Set<String> _includedTypes = new HashSet<String>();
protected Set<String> _excludedTypes = new HashSet<String>();
public String getName() {
return _name;
@ -94,13 +102,29 @@ public abstract class AbstractDataCache extends AbstractConcurrentEventManager
public void setEvictionSchedule(String s) {
_schedule = s;
}
public void initialize(DataCacheManager manager) {
if (_schedule != null && !"".equals(_schedule)) {
DataCacheScheduler scheduler = manager.getDataCacheScheduler();
if (scheduler != null)
scheduler.scheduleEviction(this, _schedule);
}
// Cast here rather than add to the interface because this is a hack to support an older way of configuring
if(manager instanceof DataCacheManagerImpl){
List<String> invalidConfigured = new ArrayList<String>();
// assert that things are configured properly
if(_includedTypes!=null){
for(String s : _includedTypes){
if(_excludedTypes.contains(s)){
invalidConfigured.add(s);
}
}
if (invalidConfigured.size() > 0) {
throw new GeneralException(s_loc.get("invalid-types-excluded-types", invalidConfigured.toString()));
}
}
((DataCacheManagerImpl)manager).setTypes(_includedTypes, _excludedTypes);
}
}
public void commit(Collection<DataCachePCData> additions, Collection<DataCachePCData> newUpdates,
@ -500,4 +524,29 @@ public abstract class AbstractDataCache extends AbstractConcurrentEventManager
}
}
public Set<String> getTypes() {
return _includedTypes;
}
public Set<String> getExcludedTypes() {
return _excludedTypes;
}
public void setTypes(Set<String> types) {
_includedTypes = types;
}
public void setTypes(String types) {
_includedTypes =
StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays.asList(Strings.split(types, ";", 0)));
}
public void setExcludedTypes(Set<String> types) {
_excludedTypes = types;
}
public void setExcludedTypes(String types) {
_excludedTypes =
StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays.asList(Strings.split(types, ";", 0)));
}
}

View File

@ -20,6 +20,7 @@ package org.apache.openjpa.datacache;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.PCDataGenerator;
@ -49,6 +50,11 @@ public class DataCacheManagerImpl
private CacheDistributionPolicy _policy = new DefaultCacheDistributionPolicy();
private Map<ClassMetaData,Boolean> _cacheable = new HashMap<ClassMetaData, Boolean>();
// Properties that are configured via openjpa.DataCache but need to be used here. This is here to support the 1.2
// way of doing things with openjpa.DataCache(Types=x;y;z,ExcludedTypes=a)
private Set<String> _includedTypes;
private Set<String> _excludedTypes;
public void initialize(OpenJPAConfiguration conf, ObjectValue dataCache, ObjectValue queryCache) {
_conf = conf;
_cache = (DataCache) dataCache.instantiate(DataCache.class, conf);
@ -145,6 +151,10 @@ public class DataCacheManagerImpl
return isCachable;
}
public void setTypes(Set<String> includedTypes, Set<String> excludedTypes){
_includedTypes = includedTypes;
_excludedTypes = excludedTypes;
}
/**
* Affirms the given class is eligible to be cached according to the cache mode
* and the cache enable flag on the given metadata.
@ -165,11 +175,24 @@ public class DataCacheManagerImpl
}
/**
* Is the given type cacheable by @DataCache annotation.
* Is the given type cacheable by @DataCache annotation or openjpa.DataCache(Types/ExcludedTypes)
*
* @see ClassMetaData#getDataCacheName()
*/
private Boolean isCacheableByType(ClassMetaData meta) {
private Boolean isCacheableByType(ClassMetaData meta) {
if (_includedTypes != null && _includedTypes.size() > 0) {
return _includedTypes.contains(meta.getDescribedType().getName());
}
if (_excludedTypes != null && _excludedTypes.size() > 0) {
if (_excludedTypes.contains(meta.getDescribedType().getName())) {
return false;
} else {
// Case where Types is not set, and ExcludedTypes only has a sub set of all
// Entities.
return true;
}
}
// Check for @DataCache annotations
return meta.getDataCacheName() != null;
}
}

View File

@ -112,4 +112,6 @@ partition-cache-duplicate-partition: You have specified duplicate name "{0}" for
partition-cache-default-partition: You have specified name "{0}" for a \
partition in the configuration "{0}". The partition name matches the default \
name reserved by OpenJPA for internal use and hence can not be used.
invalid-types-excluded-types: Failed to configure openjpa.DataCache Types, ExcludedTypes. \
Types "{0}" were found in both lists, but can only appear one of the lists.

View File

@ -164,18 +164,23 @@ public class TestCacheExclusions extends AbstractCachedEMFTestCase {
}
public void testIncludePurchaseItemExcludePurchase() {
try{
getEntityManagerFactoryCacheSettings(new Class[] { Purchase.class,
Item.class }, new Class[] { Purchase.class });
populate();
fail("Shouldn't be able to create an EMF with an entity in both Types and ExcludedTypes");
StoreCache cache = emf.getStoreCache();
assertCacheContents(cache, false, false, true);
}catch(Exception e){
//expected
}
}
public OpenJPAEntityManagerFactorySPI getEntityManagerFactoryCacheSettings(
Class<?>[] includedTypes, Class<?>[] excludedTypes) {
StringBuilder includes = new StringBuilder();
if (includedTypes != null && includedTypes.length > 0) {
includes.append("IncludedTypes=");
includes.append("Types=");
for (Class<?> c : includedTypes) {
includes.append(c.getName());
includes.append(_tSep);
@ -193,7 +198,7 @@ public class TestCacheExclusions extends AbstractCachedEMFTestCase {
}
StringBuilder dataCacheSettings = new StringBuilder();
boolean hasIncludeOrExclude = includes.length() > 0 || excludes.length() > 0;
dataCacheSettings.append(hasIncludeOrExclude ? "type-based(" : "default");
dataCacheSettings.append("true" + (hasIncludeOrExclude ? "(" : ""));
if (hasIncludeOrExclude) {
dataCacheSettings.append(includes);
if (includes.length() > 0 && excludes.length() > 0)
@ -202,8 +207,7 @@ public class TestCacheExclusions extends AbstractCachedEMFTestCase {
dataCacheSettings.append(")");
}
Map<String, String> props = new HashMap<String, String>();
props.put("openjpa.CacheDistributionPolicy", dataCacheSettings.toString());
props.put("openjpa.DataCache", "true");
props.put("openjpa.DataCache", dataCacheSettings.toString());
props.put("openjpa.RemoteCommitProvider", "sjvm");
props.put("openjpa.MetaDataFactory", "jpa(Types="
+ Item.class.getName() + _tSep + Purchase.class.getName() + _tSep