/* Open Source Java Caching Service
* Copyright (C) 2002 Frank Karlstr�m
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author can be contacted by email: fjankk@users.sourceforge.net
*/
package org.fjank.jcache;
import java.io.File;
import java.io.Serializable;
import java.util.Iterator;
import javax.util.jcache.Attributes;
import javax.util.jcache.CacheException;
import javax.util.jcache.CacheFullException;
import javax.util.jcache.CacheLoader;
import javax.util.jcache.CacheLogger;
import javax.util.jcache.DiskCacheException;
import javax.util.jcache.NotARetrievableObjectException;
import javax.util.jcache.ObjectNotFoundException;
import org.fjank.jcache.persistence.DiskCache;
/**
* An optimized implementation of CacheAccess.
* No exceptions is thrown excpet in really exceptional situations.
* The Map interface uses this class directly,
* while the old CacheAccessImpl interface should be reprogrammed
* to work with this class.
*/
public final class CacheAccessImpl2 {
/** a boolean indication wether this obejct is valid or not. */
private boolean valid = true;
/** the current region this CacheAccess applies to. */
private CacheRegion region;
private Class lastException;
private String lastMessage;
/**
* Creates a new CacheAccessImpl object.
*
* @param aCache the the cahce the region belopngs to.
* @param aRegion the region to get an CacheAccessImpl to.
*/
CacheAccessImpl2(final CacheRegion aRegion) {
this.region = aRegion;
}
/**
* terminates the request for a reply from the previous invalidate or
* update. If a response was requested, the either cancelResponse or
* waitForResponse should be called to terminate the request and free up
* related structures. If the waitForResponse method times out,
* cancelResponse should be called. All response associated with the
* CacheAccess object are canceled. If the object is local or a reply has
* not been requested, this call returns immediantely.
* @todo Implement me.
*/
public void cancelResponse() {
if (!isValid()) {
return;
}
}
/**
* Will check if close() has been called.
* @return <code>true</code> if this CacheAccess is valid, <code>false</code>
* otherwise.
*/
private boolean isValid() {
if (this.valid) {
return true;
}
return false;
}
/**
* will return the CacheAccess object to the cache. Any attempt to use a
* CacheAccess object after it has been closed will be ignored.
*/
public void close() {
if (!isValid()) {
return;
}
region = null;
this.valid = false;
}
/**
* Is used to create a new group object. The attributes of the region or
* group the new group is associated with are used.
*
* @param name the name of the new group.
*/
public void defineGroup(final String name) {
if (!isValid()) {
return;
}
defineGroupImpl(name, null, null);
}
/**
* Is used to create a new group object. The attrbutes-parameter are used as
* the attributes for the new group.
* @param name the group the new group should be associated with.
* @param attributes the attributes of the new group.
*
*/
public void defineGroup(final String name, final Attributes attributes) {
if (!isValid()) {
return;
}
defineGroupImpl(name, null, attributes);
}
/**
* Is used to create a new group which belongs to another group.
* The attributes of the group the new group is attached to are used
* as the attrbutes for the new group.
* @param name the name of the new group.
* @param group the group the new group should be associated with.
*
*/
public void defineGroup(final String name, final String group) {
if (!isValid()) {
return;
}
defineGroupImpl(name, group, null);
}
/**
* Is used to create a new group which belongs to another group.
* The attrbutes-parameter are used as
* the attributes for the new group.
* @param name the name of the new group.
* @param groupName the group the new group should be associated with.
* @param attributes the attributes of the new group.
*/
public void defineGroup(final String name, final String groupName, final Attributes attributes) {
if (!isValid()) {
return;
}
defineGroupImpl(name, groupName, attributes);
}
/**
* The actual implementation of defineGroup.
* @param name the name of the group to define.
* @param groupName the groupName the group should belong to.
* @param attributes the attributes of the new group.
*/
private void defineGroupImpl(final String name, final String groupName, final Attributes attributes) {
if (name == null) {
return;
}
if (name.equals("")) {
return;
}
CacheGroup group;
if (groupName == null) {
group = region;
} else {
group = region.getGroup(groupName);
if (group == null) {
return;
}
}
group.put(new CacheGroup(name, new AttributesImpl(attributes)));
}
/**
* is used to specify the attributes to associate with an object when it is
* loaded. This can include the loader object, cache event handlers, and
* spesific attributes for the object such as distribute, spool, etc.
* Attributes (with the exception of the CacheLoader object itself) can also
* be specified within the load method of the CacheLoader object using the
* setAttributes method, if the attributes for an object are not defined,
* the attributes of the region will be used.
*
* @param name the name of the object to associate the attributes with.
* @param attributes the attributes to associate.
*
*/
public void defineObject(final Object name, final Attributes attributes) {
if (!isValid()) {
return;
}
putImpl(name, null, attributes, NullObject.getInstance());
}
/**
* See defineObject(Object, Attributes)
*
* @param name the name of the object to associate the attributes with.
* @param group the group the object to associate the attributes with is
* contained in.
* @param attributes the attributes to associate.
*
*/
public void defineObject(final Object name, final String group, final Attributes attributes) {
if (!isValid()) {
return;
}
putImpl(name, group, attributes, NullObject.getInstance());
}
/**
* Will invalidate all objects within the region for this CacheAccess
* object, and the region itself. All references to the objects and any
* loaders registered will be destroyed. This object is unusable after this
* operation, will be closed and returned to the cache pool.
*
*/
public void destroy() {
if (!isValid()) {
return;
}
if (region.getName() != null) {
destroy(region.getName());
} else {
region.destroy();
}
close();
}
/**
* Will invalidate all objects in the named region and the named region.
*
* @param name the name of the region to destroy.
*
*
* @see #destroy()
*/
public void destroy(final Object name) {
if (!isValid()) {
return;
}
CacheImpl.getCache(true).destroyRegion(name);
}
/**
* Returns a reference to the object accosiated with the specified name. If
* the object is a streamAccess object, an {@link java.io.InputStream}is
* returned, if the object is a disk object, a {@link java.lang.String}
* containg the full path to the object is returned. The name parameter must
* override the {@link java.lang.Object#equals(Object)}and {@link
* java.lang.Object#hashCode()} methods. If a loader object has not been
* registered for the object the default load method will do a netSearch for
* the object. A CacheAccess will only maintain a reference to one cached
* object at any gived time. If get is called multiple times, the object
* accessed previously, will be released.
*
* @param name the name of the object to get.
*
* @return a reference to a shared object. Will always return the latest
* version of the object.
*
*/
public Object get(final Object name) {
if (!isValid()) {
return null;
}
return getImpl(name, null, null);
}
/**
* Gets the object from the cache. If the object is not currently in the
* cache and a loader object has been registered, the object will be loaded
* into the cache with the arguments specified.
*
* @param name the name of the object to get.
* @param arguments the arguments wich is passed to the load method of the
* CacheLoader, if registered.
*
* @return a reference to a shared object. Will always return the latest
* version of the object.
* @see #get(Object)
*/
public Object get(final Object name, final Object arguments) {
if (!isValid()) {
return null;
}
return getImpl(name, null, arguments);
}
/**Gets an object from the cache.
* @param name the name of the object to get
* @param arguments the arguments to send to the loader, if any.
* @return the object which is stored in the cache.
*/
private Object getImpl(final Object name, final String group, final Object arguments) {
CacheObject objHandle = getCacheObject(name, group);
if (objHandle == null) {
return null;
}
return getTrueObject(objHandle, arguments);
}
private Object getTrueObject(final CacheObject objHandle, final Object arguments) {
if (objHandle.needsLoading(arguments)) {
Attributes attribs = objHandle.getAttributes();
CacheLoader loader = attribs.getLoader();
Object retrievedObject;
try {
retrievedObject = loader.load(objHandle, arguments);
if (retrievedObject == null) {
throw new ObjectNotFoundException("The returned object from the CacheLoader " + loader.getClass().getName() + " was null.");
}
if (retrievedObject instanceof CacheOutputStream) {
/*
* a CacheLoader has created an OutputStream, and loaded the
* object. Get the owner object for the stream, and return
* the corresponding InputStream. The StreamObjects are
* created in the CacheLoader, but the regular memory
* objects are created below, is this correct? And a double
* creation is also done... once before the load, and once
* further down, but this is not called as we have multiple
* return points in this method.... well, if it works, dont
* touch it! Refactor when we are moving towards a
* production release.
*
*/
return ((CacheOutputStream) retrievedObject).getStreamObject().getInputStream();
} else if (retrievedObject instanceof File) {
/*
* The object was a DiskObject, return the path to the
* diskfile.
*/
return ((File) retrievedObject).getAbsolutePath();
}
attribs.setCreateTime(System.currentTimeMillis());
} catch (CacheException e) {
this.lastException = e.getClass();
this.lastMessage = e.getMessage();
return null;
}
CacheGroup group = objHandle.getGroup();
CacheObject newRef = new CacheObject(objHandle.getKey(), retrievedObject, group, region, CacheImpl.getCache().getReferenceQueue());
group.replace(objHandle.getKey(), newRef);
return newRef.get();
}
return objHandle.get();
}
/**
* gets a cacheobject from the cache.
* @param name the name of the object to get.
* @param group the group to get the object from.
* @return an cacheobject.
*
*/
private CacheObject getCacheObject(final Object name, final String group) {
Object object = null;
//first check the memory cache
CacheGroup parentCacheObject = region;
if (group != null) {
parentCacheObject = region.getGroup(group);
if (parentCacheObject == null) {
return null;
}
}
if (parentCacheObject.contains(name)) {
object = parentCacheObject.get(name);
} else if (name instanceof Serializable) {
//second, check the disk cache.
try {
DiskCache diskCache = CacheImpl.getCache().getDiskCache();
if (diskCache != null) {
object = diskCache.getObject((Serializable) name);
if (object == null) {
return null;
}
}
} catch (DiskCacheException e) {
this.lastException = DiskCacheException.class;
this.lastMessage = e.getMessage();
return null;
}
}
if (object == null) {
return null;
}
if (object instanceof CacheGroup) {
this.lastException = NotARetrievableObjectException.class;
this.lastMessage = ("This object is a group and cannot be retrieved.");
return null;
}
CacheObject objHandle = (CacheObject) object;
return objHandle;
}
/**
* Gets the object from the specified group. If the object is not currently
* in the cache, and a loader object has been registered, the object will be
* loaded into the cache and accosiated with the specified group.
*
* @param name the name of the object to get.
* @param group The group the Object is associated with.
* @param arguments the arguments wich is passed to the load method of the
* CacheLoader, if registered.
*
* @return a reference to a shared object. Will always return the latest
* version of the object.
*
* @see #get(Object)
*/
public Object get(final Object name, final String group, final Object arguments) {
if (!isValid()) {
return null;
}
return getImpl(name, group, arguments);
}
/**
* Will return an attribute object describing the current attributes
* associated for the region for this CacheAccess.
*
* @return an Attributes object for the region of this CacheAccess.
*
*/
public Attributes getAttributes() {
if (!isValid()) {
return null;
}
return region.getAttributes();
}
/**
* will return an attribute object describing the current attributes
* associated with the object name.
*
* @param name the name of the object to get the attributes for.
*
* @return an Attributes object for the named object.
*
*/
public Attributes getAttributes(final Object name) {
if (!isValid()) {
return null;
}
if (name == null) {
return null;
}
Object obj = region.get(name);
if (obj == null) {
return null;
}
if (obj instanceof CacheObject) {
return ((CacheObject) obj).getAttributes();
} else if (obj instanceof CacheGroup) {
return ((CacheGroup) obj).getAttributes();
}
this.lastException = CacheException.class;
this.lastMessage = "The object " + name + " is not valid. (" + obj.getClass().getName() + ')';
return null;
}
/**
* will claim ownership for the named object for this instance of
* CacheAccess. If ownership is not available, this method will block for
* the specified timeout. The local cache is checked first, if the local
* cache does not hold ownership of the object, a message is sent to all
* other caches in the system. Ownership is only relevant for synchronized
* objects. Ownership is maintained until an update or invalidation
* completes (this includes the reciept of replies when applicable) or until
* ownership is explicitly released with a call to releaseOwnership(). An
* instance of CacheAccess con only hold ownership of one object at a time.
* Ownership only applies to individual objects, it is not available on
* groups.
*
* @param name the name of the object to claim ownership for.
* @param timeout number of milliseconds to wait for the ownership claim.
*
* @return true if ownership was obtained, false otherwise.
*
*
*
* @todo not implemented.
*/
public boolean getOwnership(final Object name, final int timeout) {
if (!isValid()) {
return false;
}
return false;
}
/**
* Will mark all objects in the region as invalid.
* @todo distribution of this event
*/
public void invalidate() {
if (!isValid()) {
return;
}
region.invalidate();
// TODO: distribution of this event
}
/**
* Will mark all objects withing the scope of the specified name as invalid.
* If the name refers to a group object, the invalidate will cascade to all
* objects associated with the group or any subgroups. Invalidate does not
* "unregister" an object. The loader object will remain associated with the
* object name. To completely remove any knowledge of an object from the
* cache, destroy must be called.
*
* @param name the name of the object to invalidate.
*
*
*/
public void invalidate(final Object name) {
if (!isValid()) {
return;
}
invalidateWithoutDistribution(name);
if (CacheImpl.getCache().isDistributed()) {
CacheImpl.getCache().getDistributionEngine().cacheObjectInvalidated(getRegionName(), (Serializable) name);
}
}
private void invalidateWithoutDistribution(final Object name) {
if (!region.contains(name)) {
return;
}
Object object = region.get(name);
if (object == null) {
return;
}
if (object instanceof CacheGroup) {
CacheGroup group = (CacheGroup) object;
group.invalidate();
} else {
// 2004/09-FB
if (object instanceof CacheObject) {
CacheObject obj = (CacheObject) object;
obj.invalidate();
}
}
}
/**
* Check the existence of a valid copy of the named object in the region
* associated with this CacheAccess object.
*
* @param name the name of the object to check the existence for.
*
* @return true if a valid copy was found, false otherwise.
*/
public boolean isPresent(final Object name) {
if (!isValid()) {
return false;
}
return region.contains(name);
}
/**
* This method allows for asynchronous loading of object into the cache.
* This method will schedule a background task to the registered load
* method, then return. Any exception that occur during the load, will be
* written to the log, if logging is on and a log is available.
*
* @param name the name of the object to load.
*
*
*/
public void preLoad(final Object name) {
if (!isValid()) {
return;
}
preLoad(name, null);
}
/**
* See {@link #preLoad(Object)}.
*
* @param name the name of the object to load.
* @param arguments these arguments will be passed to the load method of the
* loader object.
*/
public void preLoad(final Object name, final Object arguments) {
if (!isValid()) {
return;
}
preLoad(name, null, arguments);
}
/**
* See {@link #preLoad(Object)}.
*
* @param name the name of the object to load.
* @param group the group the new object will be associated with.
* @param arguments these arguments will be passed to the load method of the
* loader object.
*
*
*/
public void preLoad(final Object name, final String group, final Object arguments) {
if (!isValid()) {
return;
}
if (name == null) {
//log this, and silently return.
return;
}
final CacheLogger logger = CacheImpl.getCache().getAttributes().getLogger();
try {
final CacheObject obj = getCacheObject(name, group);
final CacheLoader loader = obj.getAttributes().getLoader();
if (loader == null) {
throw new ObjectNotFoundException("The object has no CacheLoader associated with it.");
}
Runnable runnable = new Runnable() {
public void run() {
try {
loader.load(obj, arguments);
} catch (CacheException e) {
if (logger != null) {
logger.log("The object was not found in the cache.", e);
}
}
}
};
CacheImpl.getCache().getExecPool().execute(runnable);
} catch (ObjectNotFoundException e) {
if (logger != null) {
logger.log("The object was not found in the cache.", e);
}
} catch (InterruptedException e) {
if (logger != null) {
logger.log("Some strange concurrency issue have occured.", e);
}
}
}
/**
* See {@link #put(Object, Object)}
*
* @param name the name associated with the object.
* @param attributes the attributes to associate with the object put into
* the cache,
* @param object the object wich is put in the cache.
*
*
*
* @see #put(Object,Object)
*/
public void put(final Object name, final Attributes attributes, final Object object) {
if (!isValid()) {
return;
}
putImpl(name, null, attributes, object);
}
/**
* See {@link #put(Object, Object)}
*
* @param name the name associated with the object.
* @param group The group associated with the object.
* @param attributes the attributes to associate with the object put into
* the cache,
* @param object the object wich is put in the cache.
*
*
* @see #put(Object,Object)
*/
public void put(final Object name, final String group, final Attributes attributes, final Object object) {
putImpl(name, group, attributes, object);
}
/**Gets the current number of objects in the cache.
* @return The current number of objects in the cache.
*/
private int getCurrentObjectCount() {
int count = 0;
count += CacheImpl.getCache().getRegion().getObjectCount();
Iterator regions = CacheImpl.getCache().userRegionNames();
while (regions.hasNext()) {
count += CacheImpl.getCache().getRegion(regions.next()).getObjectCount();
}
return count;
}
/**
* Will return the last exception which occured.
* If no exception has occured, this will return null.
*
* @param cached if <code>true</code>, a cached exception is returned. The stacktrace of this exception
* will not be correct. Otherwise a new CacheException will be created. if you use <code>false</code> as the cache
* parameter, be adviced that this will be detrimental for performance.
* @return the last CacheException which occured.
*/
public CacheException getException(boolean cached) {
if (lastException == null) {
return null;
}
try {
CacheException ex = (CacheException) lastException.newInstance();
ex.setMessage(lastMessage);
this.lastException = null;
this.lastMessage = null;
return ex;
} catch (InstantiationException e) {
throw new IllegalStateException(e.getMessage() + ":" + lastMessage);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e.getMessage() + ":" + lastMessage);
}
}
/**
* puts an object into the cache without distribution.
* @param name the name of the object
* @param group the group to put the object into.
* @param attributes the attributoes belonging to the object
* @param object the actual object to put into the cache,.
* @return returns a boolean indicating wether the return was successfull or not. To get the errortype
* and errormessage you can call
*/
private boolean putImpl(final Object name, final String group, final Attributes attributes, final Object object) {
CacheGroup objGr = region;
if (group != null) {
objGr = region.getGroup(group);
if (objGr == null) {
this.lastException = ObjectNotFoundException.class;
this.lastMessage = "The object " + group + " is not present in this cache.";
return false;
}
}
CacheObject o = new CacheObject(name, object, objGr, region, CacheImpl.getCache().getReferenceQueue());
o.setAttributes(attributes);
int maxObjects = CacheImpl.getCache().getAttributes().getMaxObjects();
int currentObjectCount = getCurrentObjectCount();
if (currentObjectCount >= maxObjects) {
DiskCache diskCache = CacheImpl.getCache().getDiskCache();
if (diskCache == null) {
//no disk, and memory is full.
this.lastException = CacheFullException.class;
this.lastMessage = "The maximum number of objects in the cache has been reached.";
return false;
}
boolean updated = diskCache.update(o);
if (!updated) {
this.lastException = CacheFullException.class;
this.lastMessage = "The maximum size for the diskCache has been reached.";
}
return updated;
}
if ((attributes != null) && (attributes.getSize() != 0)) {
if ((region.getCurrentSize() + attributes.getSize()) > (CacheImpl.getCache().getAttributes().getMemoryCacheSize() * 1024 * 1024)) {
DiskCache diskCache = CacheImpl.getCache().getDiskCache();
if (diskCache == null) {
//no disk, and memory is full.
this.lastException = CacheFullException.class;
this.lastMessage = "The maximum size for the memory cache has been reached.";
return false;
}
boolean updated = diskCache.update(o);
if (!updated) {
this.lastException = CacheFullException.class;
this.lastMessage = "The maximum size for the diskCache has been reached.";
}
return updated;
}
}
objGr.put(name, o, object);
return true;
}
/**
* inserts the specified object into the cache, and associates it with the
* specified name. Names are scoped to a region, so they must be unique
* within the region they are placed. This method is intended for very
* simple caching situations. In general it is better to create a
* CacheLoader object and allow the cache to manage the creation and loading
* of objects. Default attributes are assumed.
*
* @param name the name associated with the object.
* @param object the object wich is put in the cache.
*
*
*/
public boolean put(final Object name, final Object object) {
if (!isValid()) {
return false;
}
return putImpl(name, null, null, object);
}
/**
* See {@link #put(Object, Object)}
*
* @param name the name associated with the object.
* @param group The group associated with the object.
* @param object the object wich is put in the cache.
*
*
*
* @see #put(Object, Object)
*/
public void put(Object name, String group, Object object) {
if (!isValid()) {
return;
}
putImpl(name, group, null, object);
}
/**
* Is called to explicitly give up ownership for an object. Ownership is
* only relevant for synchronized objects. If ownership is not held,
* releaseOwnership is ignored.
*
*
*/
public void releaseOwnership() {
if (!isValid()) {
return;
}
}
/**
* Will create a new version of the object indentified by the name,
* replacing the current version with the object specified. If the object
* doesn't exist in the cache, replace is equivalent to a put. The
* attributes will be inherited from the existing object or if no object
* exists, from the group or region the object associated with. Names are in
* the scope of a region so they must be unique within the region they are
* placed. This method is not valid on a disk, StreamAccess or Group Object.
*
* @param name the name of the object to replace.
* @param object The new object to be put in the cache.
*
* @return a reference to the newly replaced object.
*
*/
public Object replace(Object name, Object object) {
if (!isValid()) {
return null;
}
if (name == null)
return null;
if (object == null)
return null;
Object replacedObject = replaceWithoutDistribution(name, object);
if (CacheImpl.getCache().isDistributed()) {
CacheImpl.getCache().getDistributionEngine().cacheObjectUpdated(getRegionName(), null, (Serializable) name, (Serializable) object);
}
return replacedObject;
}
/**
* @todo refactor me to another place. I really do not belong here, and I do not want to be public!
*
*/
public Object replaceWithoutDistribution(Object name, Object object) {
if (!isValid()) {
return null;
}
return region.replace(name, new CacheObject(name, object, region, region, CacheImpl.getCache().getReferenceQueue()));
}
/**
* See replace(Object, Object)
*
* @param name the name of the object to replace.
* @param group the group the object is associated with.
* @param object The new object to be put in the cache.
*
* @return a reference to the newly replaced object.
*
*/
public Object replace(Object name, String group, Object object) {
if (!isValid()) {
return null;
}
if (name == null)
return null;
if (object == null)
return null;
if (group == null)
return null;
Object replacedObject = replaceWithoutDistribution(name, group, object);
if (CacheImpl.getCache().isDistributed()) {
CacheImpl.getCache().getDistributionEngine().cacheObjectUpdated(getRegionName(), group, (Serializable) name, (Serializable) object);
}
return replacedObject;
}
/**
* @todo refactor me to another place. I really do not belong here, and I do not want to be public!
*
*/
public Object replaceWithoutDistribution(Object name, String group, Object object) {
if (!isValid()) {
return null;
}
CacheGroup cachegroup = (CacheGroup) region.get(group);
if (cachegroup == null)
return null;
return cachegroup.replace(name, new CacheObject(name, object, region, region, CacheImpl.getCache().getReferenceQueue()));
}
/**
* allows for some attributes of a region to be reset. The attributes are
* expiration time attributes, time to live, default time to live, idle time
* and event handlers. The cacheloader and attributes explicitly set can't
* be reset with this method. To do this the object must be destroyed and
* redefined change those parameters. Changing the default settings on
* groups and regions will not affect existing objects. Only objects loaded
* after the reset will use the new defaults.
*
* @param attributes The new attributes to append to the region.
*
*/
public void resetAttributes(Attributes attributes) {
if (!isValid()) {
return;
}
Attributes att = region.getAttributes();
att.reset();
att.applyAttributes(attributes);
}
/**
* See {@link #resetAttributes(Attributes)}.
*
* @param name the name of the region to reset the attributes for.
* @param attributes the new attributes for the named region.
*
*/
public void resetAttributes(Object name, Attributes attributes) {
if (!isValid()) {
return;
}
Attributes att = CacheImpl.getCache(true).getRegion(name).getAttributes();
att.reset();
att.applyAttributes(attributes);
}
/**
* Will cause all objects within the region of this CacheAccess to be saved
* to the disk cache. All exceptions encountered will be logged if logging
* is on. Local objects will be saved in the process specific cache,
* distributed objects will be saved in the machine global disk cache.
*
*
*/
public void save() {
if (!isValid()) {
return;
}
saveImpl(region);
}
/**
* Implements the stuff mentioned in save().
* This method does not throws any exceptions, cause all exceptions should be logged instead.
* @see CacheAccessImpl2#save()
* @todo Implement me.
* @param region the region to save.
*/
private void saveImpl(CacheRegion region) {
}
/**
* See {@link #save()}. If the name refers to a specific object and that
* object does not implement the {@link java.io.Serializable}interface, a
* {@link CacheException}will be logged. If the name referenced a group or
* a region, all objects not implementing {@link java.io.Serializable}is
* ignored.
*
* @param name the name of the object to save.
*
*/
public void save(Object name) {
if (!isValid()) {
return;
}
saveImpl(CacheImpl.getCache().getRegion(name));
}
/**
* May be used to wait for replies returned from invalidates or updates when
* a reply is requested. This method will block the calling thread until all
* the responses associated with the CacheAccess object have been retrieved
* or the time indicated in the timeout variable has expired. If this method
* times out and the caller does not intend to call waitForResponse again on
* this object, cancelResponse should be called. If the object is local or a
* reply has not been requested, this call return immediately.
*
* @param timeout the maximum number of milliseconds to wait for remote
* caches to reply.
*
*/
public void waitForResponse(int timeout) {
if (!isValid()) {
return;
}
}
/**
* Gets the region this access applies to.
*
* @return the region this access applies to.
*/
public CacheRegion getRegion() {
return region;
}
private String getRegionName() {
return region.getName() == null ? null : region.getName().toString();
}
}