Author: mikedd
Date: Sat Oct  3 23:40:49 2009
New Revision: 821450

URL: http://svn.apache.org/viewvc?rev=821450&view=rev
Log:
OPENJPA-1328:
Check cacheability in ClassMetaData instead of AbstractDataCache. 
Merged patch from Jody Grassel to trunk

Modified:
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java?rev=821450&r1=821449&r2=821450&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
 Sat Oct  3 23:40:49 2009
@@ -501,42 +501,4 @@
             StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays
                 .asList(Strings.split(types, ";", 0)));
     }
-
-    /**
-     * Determine whether a provided class can be applied to this cache.
-     * 
-     * <P>
-     * The algorithm used to determine which types apply is as follows:
-     * <UL>
-     * <LI>If neither included nor excluded types are found all types will be
-     * used.</LI>
-     * <LI>If included types are specified and excluded types are not specified
-     * <b>only</b> the included types will be used.</LI>
-     * <LI>If included types are not specified and excluded types are specified
-     * all types will be used <b>except</b> those which are explicitly 
excluded.
-     * </LI>
-     * <LI>If both included types and excluded types are specified then
-     * <b>only</b> the included types will be used. If an included type is also
-     * an excluded type the <b>excluded</b> setting will take precedence (ie 
-     * the type will not be used).</LI>
-     * </UL>
-     * 
-     * @param className
-     *            A class which may be used by this plugin.
-     * @return True if the type should be used, otherwise false.
-     */
-    public boolean isCacheableType(String classname) {
-        boolean rval = true;
-        if (_includedTypes != null && ! _includedTypes.isEmpty()) { 
-            if(!_includedTypes.contains(classname)) {
-                rval = false;
-            }
-        }
-        if (_excludedTypes != null && ! _excludedTypes.isEmpty()) { 
-            if(_excludedTypes.contains(classname)) {
-                rval = false;
-            }
-        }
-        return rval;
-    }
 }

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?rev=821450&r1=821449&r2=821450&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
 Sat Oct  3 23:40:49 2009
@@ -44,12 +44,14 @@
 import org.apache.openjpa.enhance.PCRegistry;
 import org.apache.openjpa.enhance.Reflection;
 import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.lib.conf.Configurations;
 import org.apache.openjpa.lib.conf.Value;
 import org.apache.openjpa.lib.conf.ValueListener;
 import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.lib.meta.SourceTracker;
 import org.apache.openjpa.lib.util.J2DoPrivHelper;
 import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
 import org.apache.openjpa.lib.xml.Commentable;
 import org.apache.openjpa.util.BigDecimalId;
 import org.apache.openjpa.util.BigIntegerId;
@@ -212,6 +214,7 @@
     private boolean _abstract = false;
     private Boolean _hasAbstractPKField = null;
     private Boolean _hasPKFieldsFromAbstractClass = null;
+    private Boolean _isCacheable = null;
     
     /**
      * Constructor. Supply described type and repository.
@@ -2591,18 +2594,93 @@
      * 
      * @return true if the DataCache will accept this type, otherwise false.
      */
-    private boolean isConfiguredForCaching(String candidateCacheName) {
-        boolean rval = true;
-        DataCache cache =
-            
getRepository().getConfiguration().getDataCacheManagerInstance().getDataCache(candidateCacheName);
-        if (cache != null && (cache instanceof AbstractDataCache)) {
-            AbstractDataCache adc = (AbstractDataCache) cache;
-            if (!adc.isCacheableType(getDescribedType().getName()))
-                rval = false;
+    private boolean isConfiguredForCaching() {
+        if (_isCacheable != null) {
+            return _isCacheable.booleanValue();
         }
-        return rval;
+
+        setIsCacheable(true, false);
+        return _isCacheable.booleanValue();
     }
-    
+
+    /**
+     * <p>
+     * Set whether or not the class represented by this ClassMetaData object 
should be included in the datacache. The
+     * arguments provided are *hints* as to whether the class should be 
included in the datacache, and can be overridden
+     * by the configuration set in openjpa.Datacache.
+     * </p>
+     * 
+     * <p>
+     * Rules for this determination are:
+     * </p>
+     * <ol>
+     * <li>If the class shows up in the list of excluded types, it does not 
get cached, period.</li>
+     * <li>If the class does not show up in the excluded types, but the 
included types field is set (ie, has at least
+     * one class), then:
+     * <ol>
+     * <li>If the class is listed in the include list, then it gets cached</li>
+     * <li>If the class is set as cacheable by the @Datacache annotation, it 
gets cached</li>
+     * <li>If neither a or b are true, then the class does not get cached</li>
+     * </ol>
+     * </li>
+     * <li>If neither the include or exclude lists are defined, then go along 
with the value passed into the argument,
+     * which is either the default value (true) or whatever was set with the 
@Datacache annotation</li>
+     * </ol>
+     * 
+     * @param isCacheable
+     *            Hint whether this class should be included in the datacache. 
Default behavior is yes, though the 
+     *            @Datacache annotation can specify if it should not be cached.
+     * @param annotationOverride
+     *            Whether this hint originated from the @Datacache annotation 
or whether this is the default "yes" hint.
+     *            The origination of the hint influences the decision making 
process in rule #2b.
+     */
+    public void setIsCacheable(boolean isCacheable, boolean 
annotationOverride) {
+        Options dataCacheOptions = getDataCacheOptions();
+        Set excludedTypes = 
extractDataCacheClassListing(dataCacheOptions.getProperty("ExcludedTypes", 
null));
+        Set types = 
extractDataCacheClassListing(dataCacheOptions.getProperty("Types", null));
+
+        String className = getDescribedType().getName();
+        if (excludedTypes != null && excludedTypes.contains(className)) {
+            // Rule #1
+            _isCacheable = Boolean.FALSE;
+        } else if (types != null) {
+            // Rule #2
+            if ((annotationOverride && isCacheable) || 
(types.contains(className))) {
+                _isCacheable = Boolean.TRUE;
+            } else {
+                _isCacheable = Boolean.FALSE;
+            }
+        } else {
+            // Rule #3
+            _isCacheable = isCacheable ? Boolean.TRUE : Boolean.FALSE;
+        }
+    }
+
+    /**
+     * Extract all of the DataCache plugin options from the configuration
+     */
+    private Options getDataCacheOptions() {
+        String dataCacheConfig = 
getRepository().getConfiguration().getDataCache();
+        Options dataCacheOptions = 
Configurations.parseProperties(Configurations.getProperties(dataCacheConfig));
+        return dataCacheOptions;
+    }
+
+    /**
+     * Tool to extract classes defined in the datacache include and exclude 
list into individual entries in a Set.
+     */
+    private final Set extractDataCacheClassListing(String classList) {
+        if (classList == null || classList.length() == 0)
+            return null;
+
+        HashSet returnSet = new HashSet();
+        String[] entries = classList.split(";");
+        for (int index = 0; index < entries.length; index++) {
+            returnSet.add(entries[index]);
+        }
+
+        return returnSet;
+    }
+
     private boolean isCacheable(String candidateCacheName) { 
         boolean rval;
         
switch(DataCacheMode.valueOf(_repos.getConfiguration().getDataCacheMode())) {
@@ -2635,7 +2713,7 @@
           case UNSPECIFIED:
           default:
               // behavior from previous releases. 
-              rval = isConfiguredForCaching(candidateCacheName); 
+              rval = isConfiguredForCaching(); 
       }
       return rval;
         

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=821450&r1=821449&r2=821450&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
 Sat Oct  3 23:40:49 2009
@@ -827,6 +827,7 @@
             meta.setDataCacheName(null);
             meta.setCacheEnabled(false);
         }
+        meta.setIsCacheable(cache.enabled(), true);
     }
 
     private void parseManagedInterface(ClassMetaData meta,


Reply via email to