KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > fjank > jcache > CacheAccessImpl2


1 /* Open Source Java Caching Service
2  * Copyright (C) 2002 Frank Karlstrøm
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * The author can be contacted by email: fjankk@users.sourceforge.net
18  */

19 package org.fjank.jcache;
20
21 import java.io.File JavaDoc;
22 import java.io.Serializable JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import javax.util.jcache.Attributes;
25 import javax.util.jcache.CacheException;
26 import javax.util.jcache.CacheFullException;
27 import javax.util.jcache.CacheLoader;
28 import javax.util.jcache.CacheLogger;
29 import javax.util.jcache.DiskCacheException;
30 import javax.util.jcache.NotARetrievableObjectException;
31 import javax.util.jcache.ObjectNotFoundException;
32 import org.fjank.jcache.persistence.DiskCache;
33
34
35 /**
36  * An optimized implementation of CacheAccess.
37  * No exceptions is thrown excpet in really exceptional situations.
38  * The Map interface uses this class directly,
39  * while the old CacheAccessImpl interface should be reprogrammed
40  * to work with this class.
41  */

42 public final class CacheAccessImpl2 {
43     /** a boolean indication wether this obejct is valid or not. */
44     private boolean valid = true;
45     /** the current region this CacheAccess applies to. */
46     private CacheRegion region;
47     private Class JavaDoc lastException;
48     private String JavaDoc lastMessage;
49
50     /**
51      * Creates a new CacheAccessImpl object.
52      *
53      * @param aCache the the cahce the region belopngs to.
54      * @param aRegion the region to get an CacheAccessImpl to.
55      */

56     CacheAccessImpl2(final CacheRegion aRegion) {
57         this.region = aRegion;
58     }
59
60     /**
61      * terminates the request for a reply from the previous invalidate or
62      * update. If a response was requested, the either cancelResponse or
63      * waitForResponse should be called to terminate the request and free up
64      * related structures. If the waitForResponse method times out,
65      * cancelResponse should be called. All response associated with the
66      * CacheAccess object are canceled. If the object is local or a reply has
67      * not been requested, this call returns immediantely.
68      * @todo Implement me.
69      */

70     public void cancelResponse() {
71         if (!isValid()) {
72             return;
73         }
74     }
75
76     /**
77      * Will check if close() has been called.
78      * @return <code>true</code> if this CacheAccess is valid, <code>false</code>
79      * otherwise.
80      */

81     private boolean isValid() {
82         if (this.valid) {
83             return true;
84         }
85         return false;
86     }
87
88     /**
89      * will return the CacheAccess object to the cache. Any attempt to use a
90      * CacheAccess object after it has been closed will be ignored.
91      */

92     public void close() {
93         if (!isValid()) {
94             return;
95         }
96         region = null;
97         this.valid = false;
98     }
99
100     /**
101      * Is used to create a new group object. The attributes of the region or
102      * group the new group is associated with are used.
103      *
104      * @param name the name of the new group.
105      */

106     public void defineGroup(final String JavaDoc name) {
107         if (!isValid()) {
108             return;
109         }
110         defineGroupImpl(name, null, null);
111     }
112
113     /**
114      * Is used to create a new group object. The attrbutes-parameter are used as
115      * the attributes for the new group.
116      * @param name the group the new group should be associated with.
117      * @param attributes the attributes of the new group.
118      *
119      */

120     public void defineGroup(final String JavaDoc name, final Attributes attributes) {
121         if (!isValid()) {
122             return;
123         }
124         defineGroupImpl(name, null, attributes);
125     }
126
127     /**
128      * Is used to create a new group which belongs to another group.
129      * The attributes of the group the new group is attached to are used
130      * as the attrbutes for the new group.
131      * @param name the name of the new group.
132      * @param group the group the new group should be associated with.
133      *
134      */

135     public void defineGroup(final String JavaDoc name, final String JavaDoc group) {
136         if (!isValid()) {
137             return;
138         }
139         defineGroupImpl(name, group, null);
140     }
141
142     /**
143      * Is used to create a new group which belongs to another group.
144      * The attrbutes-parameter are used as
145      * the attributes for the new group.
146      * @param name the name of the new group.
147      * @param groupName the group the new group should be associated with.
148      * @param attributes the attributes of the new group.
149      */

150     public void defineGroup(final String JavaDoc name, final String JavaDoc groupName, final Attributes attributes) {
151         if (!isValid()) {
152             return;
153         }
154         defineGroupImpl(name, groupName, attributes);
155     }
156
157     /**
158      * The actual implementation of defineGroup.
159      * @param name the name of the group to define.
160      * @param groupName the groupName the group should belong to.
161      * @param attributes the attributes of the new group.
162      */

163     private void defineGroupImpl(final String JavaDoc name, final String JavaDoc groupName, final Attributes attributes) {
164         if (name == null) {
165             return;
166         }
167         if (name.equals("")) {
168             return;
169         }
170         CacheGroup group;
171         if (groupName == null) {
172             group = region;
173         } else {
174             group = region.getGroup(groupName);
175             if (group == null) {
176                 return;
177             }
178         }
179         group.put(new CacheGroup(name, new AttributesImpl(attributes)));
180     }
181
182     /**
183      * is used to specify the attributes to associate with an object when it is
184      * loaded. This can include the loader object, cache event handlers, and
185      * spesific attributes for the object such as distribute, spool, etc.
186      * Attributes (with the exception of the CacheLoader object itself) can also
187      * be specified within the load method of the CacheLoader object using the
188      * setAttributes method, if the attributes for an object are not defined,
189      * the attributes of the region will be used.
190      *
191      * @param name the name of the object to associate the attributes with.
192      * @param attributes the attributes to associate.
193      *
194      */

195     public void defineObject(final Object JavaDoc name, final Attributes attributes) {
196         if (!isValid()) {
197             return;
198         }
199         putImpl(name, null, attributes, NullObject.getInstance());
200     }
201
202     /**
203      * See defineObject(Object, Attributes)
204      *
205      * @param name the name of the object to associate the attributes with.
206      * @param group the group the object to associate the attributes with is
207      * contained in.
208      * @param attributes the attributes to associate.
209      *
210      */

211     public void defineObject(final Object JavaDoc name, final String JavaDoc group, final Attributes attributes) {
212         if (!isValid()) {
213             return;
214         }
215         putImpl(name, group, attributes, NullObject.getInstance());
216     }
217
218     /**
219      * Will invalidate all objects within the region for this CacheAccess
220      * object, and the region itself. All references to the objects and any
221      * loaders registered will be destroyed. This object is unusable after this
222      * operation, will be closed and returned to the cache pool.
223      *
224      */

225     public void destroy() {
226         if (!isValid()) {
227             return;
228         }
229         if (region.getName() != null) {
230             destroy(region.getName());
231         } else {
232             region.destroy();
233         }
234         close();
235     }
236
237     /**
238      * Will invalidate all objects in the named region and the named region.
239      *
240      * @param name the name of the region to destroy.
241      *
242      *
243      * @see #destroy()
244      */

245     public void destroy(final Object JavaDoc name) {
246         if (!isValid()) {
247             return;
248         }
249         CacheImpl.getCache(true).destroyRegion(name);
250     }
251
252     /**
253      * Returns a reference to the object accosiated with the specified name. If
254      * the object is a streamAccess object, an {@link java.io.InputStream}is
255      * returned, if the object is a disk object, a {@link java.lang.String}
256      * containg the full path to the object is returned. The name parameter must
257      * override the {@link java.lang.Object#equals(Object)}and {@link
258      * java.lang.Object#hashCode()} methods. If a loader object has not been
259      * registered for the object the default load method will do a netSearch for
260      * the object. A CacheAccess will only maintain a reference to one cached
261      * object at any gived time. If get is called multiple times, the object
262      * accessed previously, will be released.
263      *
264      * @param name the name of the object to get.
265      *
266      * @return a reference to a shared object. Will always return the latest
267      * version of the object.
268      *
269      */

270     public Object JavaDoc get(final Object JavaDoc name) {
271         if (!isValid()) {
272             return null;
273         }
274         return getImpl(name, null, null);
275     }
276
277     /**
278      * Gets the object from the cache. If the object is not currently in the
279      * cache and a loader object has been registered, the object will be loaded
280      * into the cache with the arguments specified.
281      *
282      * @param name the name of the object to get.
283      * @param arguments the arguments wich is passed to the load method of the
284      * CacheLoader, if registered.
285      *
286      * @return a reference to a shared object. Will always return the latest
287      * version of the object.
288      * @see #get(Object)
289      */

290     public Object JavaDoc get(final Object JavaDoc name, final Object JavaDoc arguments) {
291         if (!isValid()) {
292             return null;
293         }
294         return getImpl(name, null, arguments);
295     }
296
297     /**Gets an object from the cache.
298      * @param name the name of the object to get
299      * @param arguments the arguments to send to the loader, if any.
300      * @return the object which is stored in the cache.
301      */

302     private Object JavaDoc getImpl(final Object JavaDoc name, final String JavaDoc group, final Object JavaDoc arguments) {
303         CacheObject objHandle = getCacheObject(name, group);
304         if (objHandle == null) {
305             return null;
306         }
307         return getTrueObject(objHandle, arguments);
308     }
309
310     private Object JavaDoc getTrueObject(final CacheObject objHandle, final Object JavaDoc arguments) {
311         if (objHandle.needsLoading(arguments)) {
312             Attributes attribs = objHandle.getAttributes();
313             CacheLoader loader = attribs.getLoader();
314             Object JavaDoc retrievedObject;
315             try {
316                 retrievedObject = loader.load(objHandle, arguments);
317                 if (retrievedObject == null) {
318                     throw new ObjectNotFoundException("The returned object from the CacheLoader " + loader.getClass().getName() + " was null.");
319                 }
320                 if (retrievedObject instanceof CacheOutputStream) {
321                     /*
322                      * a CacheLoader has created an OutputStream, and loaded the
323                      * object. Get the owner object for the stream, and return
324                      * the corresponding InputStream. The StreamObjects are
325                      * created in the CacheLoader, but the regular memory
326                      * objects are created below, is this correct? And a double
327                      * creation is also done... once before the load, and once
328                      * further down, but this is not called as we have multiple
329                      * return points in this method.... well, if it works, dont
330                      * touch it! Refactor when we are moving towards a
331                      * production release.
332                      *
333                      */

334                     return ((CacheOutputStream) retrievedObject).getStreamObject().getInputStream();
335                 } else if (retrievedObject instanceof File JavaDoc) {
336                     /*
337                      * The object was a DiskObject, return the path to the
338                      * diskfile.
339                      */

340                     return ((File JavaDoc) retrievedObject).getAbsolutePath();
341                 }
342                 attribs.setCreateTime(System.currentTimeMillis());
343             } catch (CacheException e) {
344                 this.lastException = e.getClass();
345                 this.lastMessage = e.getMessage();
346                 return null;
347             }
348             CacheGroup group = objHandle.getGroup();
349             CacheObject newRef = new CacheObject(objHandle.getKey(), retrievedObject, group, region, CacheImpl.getCache().getReferenceQueue());
350             group.replace(objHandle.getKey(), newRef);
351             return newRef.get();
352         }
353         return objHandle.get();
354     }
355
356     /**
357      * gets a cacheobject from the cache.
358      * @param name the name of the object to get.
359      * @param group the group to get the object from.
360      * @return an cacheobject.
361      *
362      */

363     private CacheObject getCacheObject(final Object JavaDoc name, final String JavaDoc group) {
364         Object JavaDoc object = null;
365         //first check the memory cache
366
CacheGroup parentCacheObject = region;
367         if (group != null) {
368             parentCacheObject = region.getGroup(group);
369             if (parentCacheObject == null) {
370                 return null;
371             }
372         }
373         if (parentCacheObject.contains(name)) {
374             object = parentCacheObject.get(name);
375         } else if (name instanceof Serializable JavaDoc) {
376             //second, check the disk cache.
377
try {
378                 DiskCache diskCache = CacheImpl.getCache().getDiskCache();
379                 if (diskCache != null) {
380                     object = diskCache.getObject((Serializable JavaDoc) name);
381                     if (object == null) {
382                         return null;
383                     }
384                 }
385             } catch (DiskCacheException e) {
386                 this.lastException = DiskCacheException.class;
387                 this.lastMessage = e.getMessage();
388                 return null;
389             }
390         }
391         if (object == null) {
392             return null;
393         }
394         if (object instanceof CacheGroup) {
395             this.lastException = NotARetrievableObjectException.class;
396             this.lastMessage = ("This object is a group and cannot be retrieved.");
397             return null;
398         }
399         CacheObject objHandle = (CacheObject) object;
400         return objHandle;
401     }
402
403     /**
404      * Gets the object from the specified group. If the object is not currently
405      * in the cache, and a loader object has been registered, the object will be
406      * loaded into the cache and accosiated with the specified group.
407      *
408      * @param name the name of the object to get.
409      * @param group The group the Object is associated with.
410      * @param arguments the arguments wich is passed to the load method of the
411      * CacheLoader, if registered.
412      *
413      * @return a reference to a shared object. Will always return the latest
414      * version of the object.
415      *
416      * @see #get(Object)
417      */

418     public Object JavaDoc get(final Object JavaDoc name, final String JavaDoc group, final Object JavaDoc arguments) {
419         if (!isValid()) {
420             return null;
421         }
422         return getImpl(name, group, arguments);
423     }
424
425     /**
426      * Will return an attribute object describing the current attributes
427      * associated for the region for this CacheAccess.
428      *
429      * @return an Attributes object for the region of this CacheAccess.
430      *
431      */

432     public Attributes getAttributes() {
433         if (!isValid()) {
434             return null;
435         }
436         return region.getAttributes();
437     }
438
439     /**
440      * will return an attribute object describing the current attributes
441      * associated with the object name.
442      *
443      * @param name the name of the object to get the attributes for.
444      *
445      * @return an Attributes object for the named object.
446      *
447      */

448     public Attributes getAttributes(final Object JavaDoc name) {
449         if (!isValid()) {
450             return null;
451         }
452         if (name == null) {
453             return null;
454         }
455         Object JavaDoc obj = region.get(name);
456         if (obj == null) {
457             return null;
458         }
459         if (obj instanceof CacheObject) {
460             return ((CacheObject) obj).getAttributes();
461         } else if (obj instanceof CacheGroup) {
462             return ((CacheGroup) obj).getAttributes();
463         }
464         this.lastException = CacheException.class;
465         this.lastMessage = "The object " + name + " is not valid. (" + obj.getClass().getName() + ')';
466         return null;
467     }
468
469     /**
470      * will claim ownership for the named object for this instance of
471      * CacheAccess. If ownership is not available, this method will block for
472      * the specified timeout. The local cache is checked first, if the local
473      * cache does not hold ownership of the object, a message is sent to all
474      * other caches in the system. Ownership is only relevant for synchronized
475      * objects. Ownership is maintained until an update or invalidation
476      * completes (this includes the reciept of replies when applicable) or until
477      * ownership is explicitly released with a call to releaseOwnership(). An
478      * instance of CacheAccess con only hold ownership of one object at a time.
479      * Ownership only applies to individual objects, it is not available on
480      * groups.
481      *
482      * @param name the name of the object to claim ownership for.
483      * @param timeout number of milliseconds to wait for the ownership claim.
484      *
485      * @return true if ownership was obtained, false otherwise.
486      *
487      *
488      *
489      * @todo not implemented.
490      */

491     public boolean getOwnership(final Object JavaDoc name, final int timeout) {
492         if (!isValid()) {
493             return false;
494         }
495         return false;
496     }
497
498     /**
499      * Will mark all objects in the region as invalid.
500      * @todo distribution of this event
501      */

502     public void invalidate() {
503         if (!isValid()) {
504             return;
505         }
506         region.invalidate();
507         // TODO: distribution of this event
508
}
509
510     /**
511      * Will mark all objects withing the scope of the specified name as invalid.
512      * If the name refers to a group object, the invalidate will cascade to all
513      * objects associated with the group or any subgroups. Invalidate does not
514      * "unregister" an object. The loader object will remain associated with the
515      * object name. To completely remove any knowledge of an object from the
516      * cache, destroy must be called.
517      *
518      * @param name the name of the object to invalidate.
519      *
520      *
521      */

522     public void invalidate(final Object JavaDoc name) {
523         if (!isValid()) {
524             return;
525         }
526         invalidateWithoutDistribution(name);
527         if (CacheImpl.getCache().isDistributed()) {
528             CacheImpl.getCache().getDistributionEngine().cacheObjectInvalidated(getRegionName(), (Serializable JavaDoc) name);
529         }
530     }
531
532     private void invalidateWithoutDistribution(final Object JavaDoc name) {
533         if (!region.contains(name)) {
534             return;
535         }
536         Object JavaDoc object = region.get(name);
537         if (object == null) {
538             return;
539         }
540         if (object instanceof CacheGroup) {
541             CacheGroup group = (CacheGroup) object;
542             group.invalidate();
543         } else {
544             // 2004/09-FB
545
if (object instanceof CacheObject) {
546                 CacheObject obj = (CacheObject) object;
547                 obj.invalidate();
548             }
549         }
550     }
551
552     /**
553      * Check the existence of a valid copy of the named object in the region
554      * associated with this CacheAccess object.
555      *
556      * @param name the name of the object to check the existence for.
557      *
558      * @return true if a valid copy was found, false otherwise.
559      */

560     public boolean isPresent(final Object JavaDoc name) {
561         if (!isValid()) {
562             return false;
563         }
564         return region.contains(name);
565     }
566
567     /**
568      * This method allows for asynchronous loading of object into the cache.
569      * This method will schedule a background task to the registered load
570      * method, then return. Any exception that occur during the load, will be
571      * written to the log, if logging is on and a log is available.
572      *
573      * @param name the name of the object to load.
574      *
575      *
576      */

577     public void preLoad(final Object JavaDoc name) {
578         if (!isValid()) {
579             return;
580         }
581         preLoad(name, null);
582     }
583
584     /**
585      * See {@link #preLoad(Object)}.
586      *
587      * @param name the name of the object to load.
588      * @param arguments these arguments will be passed to the load method of the
589      * loader object.
590
591      */

592     public void preLoad(final Object JavaDoc name, final Object JavaDoc arguments) {
593         if (!isValid()) {
594             return;
595         }
596         preLoad(name, null, arguments);
597     }
598
599     /**
600      * See {@link #preLoad(Object)}.
601      *
602      * @param name the name of the object to load.
603      * @param group the group the new object will be associated with.
604      * @param arguments these arguments will be passed to the load method of the
605      * loader object.
606      *
607      *
608      */

609     public void preLoad(final Object JavaDoc name, final String JavaDoc group, final Object JavaDoc arguments) {
610         if (!isValid()) {
611             return;
612         }
613         if (name == null) {
614             //log this, and silently return.
615
return;
616         }
617         final CacheLogger logger = CacheImpl.getCache().getAttributes().getLogger();
618         try {
619             final CacheObject obj = getCacheObject(name, group);
620             final CacheLoader loader = obj.getAttributes().getLoader();
621             if (loader == null) {
622                 throw new ObjectNotFoundException("The object has no CacheLoader associated with it.");
623             }
624             Runnable JavaDoc runnable = new Runnable JavaDoc() {
625                 public void run() {
626                     try {
627                         loader.load(obj, arguments);
628                     } catch (CacheException e) {
629                         if (logger != null) {
630                             logger.log("The object was not found in the cache.", e);
631                         }
632                     }
633                 }
634             };
635             CacheImpl.getCache().getExecPool().execute(runnable);
636         } catch (ObjectNotFoundException e) {
637             if (logger != null) {
638                 logger.log("The object was not found in the cache.", e);
639             }
640         } catch (InterruptedException JavaDoc e) {
641             if (logger != null) {
642                 logger.log("Some strange concurrency issue have occured.", e);
643             }
644         }
645     }
646
647     /**
648      * See {@link #put(Object, Object)}
649      *
650      * @param name the name associated with the object.
651      * @param attributes the attributes to associate with the object put into
652      * the cache,
653      * @param object the object wich is put in the cache.
654      *
655      *
656      *
657      * @see #put(Object,Object)
658      */

659     public void put(final Object JavaDoc name, final Attributes attributes, final Object JavaDoc object) {
660         if (!isValid()) {
661             return;
662         }
663         putImpl(name, null, attributes, object);
664     }
665
666     /**
667      * See {@link #put(Object, Object)}
668      *
669      * @param name the name associated with the object.
670      * @param group The group associated with the object.
671      * @param attributes the attributes to associate with the object put into
672      * the cache,
673      * @param object the object wich is put in the cache.
674      *
675      *
676      * @see #put(Object,Object)
677      */

678     public void put(final Object JavaDoc name, final String JavaDoc group, final Attributes attributes, final Object JavaDoc object) {
679         putImpl(name, group, attributes, object);
680     }
681
682     /**Gets the current number of objects in the cache.
683      * @return The current number of objects in the cache.
684      */

685     private int getCurrentObjectCount() {
686         int count = 0;
687         count += CacheImpl.getCache().getRegion().getObjectCount();
688         Iterator JavaDoc regions = CacheImpl.getCache().userRegionNames();
689         while (regions.hasNext()) {
690             count += CacheImpl.getCache().getRegion(regions.next()).getObjectCount();
691         }
692         return count;
693     }
694
695     /**
696      * Will return the last exception which occured.
697      * If no exception has occured, this will return null.
698      *
699      * @param cached if <code>true</code>, a cached exception is returned. The stacktrace of this exception
700      * will not be correct. Otherwise a new CacheException will be created. if you use <code>false</code> as the cache
701      * parameter, be adviced that this will be detrimental for performance.
702      * @return the last CacheException which occured.
703      */

704     public CacheException getException(boolean cached) {
705         if (lastException == null) {
706             return null;
707         }
708         try {
709             CacheException ex = (CacheException) lastException.newInstance();
710             ex.setMessage(lastMessage);
711             this.lastException = null;
712             this.lastMessage = null;
713             return ex;
714         } catch (InstantiationException JavaDoc e) {
715             throw new IllegalStateException JavaDoc(e.getMessage() + ":" + lastMessage);
716         } catch (IllegalAccessException JavaDoc e) {
717             throw new IllegalStateException JavaDoc(e.getMessage() + ":" + lastMessage);
718         }
719     }
720
721     /**
722      * puts an object into the cache without distribution.
723      * @param name the name of the object
724      * @param group the group to put the object into.
725      * @param attributes the attributoes belonging to the object
726      * @param object the actual object to put into the cache,.
727      * @return returns a boolean indicating wether the return was successfull or not. To get the errortype
728      * and errormessage you can call
729      */

730     private boolean putImpl(final Object JavaDoc name, final String JavaDoc group, final Attributes attributes, final Object JavaDoc object) {
731         CacheGroup objGr = region;
732         if (group != null) {
733             objGr = region.getGroup(group);
734             if (objGr == null) {
735                 this.lastException = ObjectNotFoundException.class;
736                 this.lastMessage = "The object " + group + " is not present in this cache.";
737                 return false;
738             }
739         }
740         CacheObject o = new CacheObject(name, object, objGr, region, CacheImpl.getCache().getReferenceQueue());
741         o.setAttributes(attributes);
742         int maxObjects = CacheImpl.getCache().getAttributes().getMaxObjects();
743         int currentObjectCount = getCurrentObjectCount();
744         if (currentObjectCount >= maxObjects) {
745             DiskCache diskCache = CacheImpl.getCache().getDiskCache();
746             if (diskCache == null) {
747                 //no disk, and memory is full.
748
this.lastException = CacheFullException.class;
749                 this.lastMessage = "The maximum number of objects in the cache has been reached.";
750                 return false;
751             }
752             boolean updated = diskCache.update(o);
753             if (!updated) {
754                 this.lastException = CacheFullException.class;
755                 this.lastMessage = "The maximum size for the diskCache has been reached.";
756             }
757             return updated;
758         }
759         if ((attributes != null) && (attributes.getSize() != 0)) {
760             if ((region.getCurrentSize() + attributes.getSize()) > (CacheImpl.getCache().getAttributes().getMemoryCacheSize() * 1024 * 1024)) {
761                 DiskCache diskCache = CacheImpl.getCache().getDiskCache();
762                 if (diskCache == null) {
763                     //no disk, and memory is full.
764
this.lastException = CacheFullException.class;
765                     this.lastMessage = "The maximum size for the memory cache has been reached.";
766                     return false;
767                 }
768                 boolean updated = diskCache.update(o);
769                 if (!updated) {
770                     this.lastException = CacheFullException.class;
771                     this.lastMessage = "The maximum size for the diskCache has been reached.";
772                 }
773                 return updated;
774             }
775         }
776         objGr.put(name, o, object);
777         return true;
778     }
779
780     /**
781      * inserts the specified object into the cache, and associates it with the
782      * specified name. Names are scoped to a region, so they must be unique
783      * within the region they are placed. This method is intended for very
784      * simple caching situations. In general it is better to create a
785      * CacheLoader object and allow the cache to manage the creation and loading
786      * of objects. Default attributes are assumed.
787      *
788      * @param name the name associated with the object.
789      * @param object the object wich is put in the cache.
790      *
791      *
792      */

793     public boolean put(final Object JavaDoc name, final Object JavaDoc object) {
794         if (!isValid()) {
795             return false;
796         }
797         return putImpl(name, null, null, object);
798     }
799
800     /**
801      * See {@link #put(Object, Object)}
802      *
803      * @param name the name associated with the object.
804      * @param group The group associated with the object.
805      * @param object the object wich is put in the cache.
806      *
807      *
808      *
809      * @see #put(Object, Object)
810      */

811     public void put(Object JavaDoc name, String JavaDoc group, Object JavaDoc object) {
812         if (!isValid()) {
813             return;
814         }
815         putImpl(name, group, null, object);
816     }
817
818     /**
819      * Is called to explicitly give up ownership for an object. Ownership is
820      * only relevant for synchronized objects. If ownership is not held,
821      * releaseOwnership is ignored.
822      *
823      *
824      */

825     public void releaseOwnership() {
826         if (!isValid()) {
827             return;
828         }
829     }
830
831     /**
832      * Will create a new version of the object indentified by the name,
833      * replacing the current version with the object specified. If the object
834      * doesn't exist in the cache, replace is equivalent to a put. The
835      * attributes will be inherited from the existing object or if no object
836      * exists, from the group or region the object associated with. Names are in
837      * the scope of a region so they must be unique within the region they are
838      * placed. This method is not valid on a disk, StreamAccess or Group Object.
839      *
840      * @param name the name of the object to replace.
841      * @param object The new object to be put in the cache.
842      *
843      * @return a reference to the newly replaced object.
844      *
845      */

846     public Object JavaDoc replace(Object JavaDoc name, Object JavaDoc object) {
847         if (!isValid()) {
848             return null;
849         }
850         if (name == null)
851             return null;
852         if (object == null)
853             return null;
854         Object JavaDoc replacedObject = replaceWithoutDistribution(name, object);
855         if (CacheImpl.getCache().isDistributed()) {
856             CacheImpl.getCache().getDistributionEngine().cacheObjectUpdated(getRegionName(), null, (Serializable JavaDoc) name, (Serializable JavaDoc) object);
857         }
858         return replacedObject;
859     }
860
861     /**
862      * @todo refactor me to another place. I really do not belong here, and I do not want to be public!
863      *
864      */

865     public Object JavaDoc replaceWithoutDistribution(Object JavaDoc name, Object JavaDoc object) {
866         if (!isValid()) {
867             return null;
868         }
869         return region.replace(name, new CacheObject(name, object, region, region, CacheImpl.getCache().getReferenceQueue()));
870     }
871
872     /**
873      * See replace(Object, Object)
874      *
875      * @param name the name of the object to replace.
876      * @param group the group the object is associated with.
877      * @param object The new object to be put in the cache.
878      *
879      * @return a reference to the newly replaced object.
880      *
881      */

882     public Object JavaDoc replace(Object JavaDoc name, String JavaDoc group, Object JavaDoc object) {
883         if (!isValid()) {
884             return null;
885         }
886         if (name == null)
887             return null;
888         if (object == null)
889             return null;
890         if (group == null)
891             return null;
892         Object JavaDoc replacedObject = replaceWithoutDistribution(name, group, object);
893         if (CacheImpl.getCache().isDistributed()) {
894             CacheImpl.getCache().getDistributionEngine().cacheObjectUpdated(getRegionName(), group, (Serializable JavaDoc) name, (Serializable JavaDoc) object);
895         }
896         return replacedObject;
897     }
898
899     /**
900      * @todo refactor me to another place. I really do not belong here, and I do not want to be public!
901      *
902      */

903     public Object JavaDoc replaceWithoutDistribution(Object JavaDoc name, String JavaDoc group, Object JavaDoc object) {
904         if (!isValid()) {
905             return null;
906         }
907         CacheGroup cachegroup = (CacheGroup) region.get(group);
908         if (cachegroup == null)
909             return null;
910         return cachegroup.replace(name, new CacheObject(name, object, region, region, CacheImpl.getCache().getReferenceQueue()));
911     }
912
913     /**
914      * allows for some attributes of a region to be reset. The attributes are
915      * expiration time attributes, time to live, default time to live, idle time
916      * and event handlers. The cacheloader and attributes explicitly set can't
917      * be reset with this method. To do this the object must be destroyed and
918      * redefined change those parameters. Changing the default settings on
919      * groups and regions will not affect existing objects. Only objects loaded
920      * after the reset will use the new defaults.
921      *
922      * @param attributes The new attributes to append to the region.
923      *
924      */

925     public void resetAttributes(Attributes attributes) {
926         if (!isValid()) {
927             return;
928         }
929         Attributes att = region.getAttributes();
930         att.reset();
931         att.applyAttributes(attributes);
932     }
933
934     /**
935      * See {@link #resetAttributes(Attributes)}.
936      *
937      * @param name the name of the region to reset the attributes for.
938      * @param attributes the new attributes for the named region.
939      *
940      */

941     public void resetAttributes(Object JavaDoc name, Attributes attributes) {
942         if (!isValid()) {
943             return;
944         }
945         Attributes att = CacheImpl.getCache(true).getRegion(name).getAttributes();
946         att.reset();
947         att.applyAttributes(attributes);
948     }
949
950     /**
951      * Will cause all objects within the region of this CacheAccess to be saved
952      * to the disk cache. All exceptions encountered will be logged if logging
953      * is on. Local objects will be saved in the process specific cache,
954      * distributed objects will be saved in the machine global disk cache.
955      *
956      *
957      */

958     public void save() {
959         if (!isValid()) {
960             return;
961         }
962         saveImpl(region);
963     }
964
965     /**
966      * Implements the stuff mentioned in save().
967      * This method does not throws any exceptions, cause all exceptions should be logged instead.
968      * @see CacheAccessImpl2#save()
969      * @todo Implement me.
970      * @param region the region to save.
971      */

972     private void saveImpl(CacheRegion region) {
973     }
974
975     /**
976      * See {@link #save()}. If the name refers to a specific object and that
977      * object does not implement the {@link java.io.Serializable}interface, a
978      * {@link CacheException}will be logged. If the name referenced a group or
979      * a region, all objects not implementing {@link java.io.Serializable}is
980      * ignored.
981      *
982      * @param name the name of the object to save.
983      *
984      */

985     public void save(Object JavaDoc name) {
986         if (!isValid()) {
987             return;
988         }
989         saveImpl(CacheImpl.getCache().getRegion(name));
990     }
991
992     /**
993      * May be used to wait for replies returned from invalidates or updates when
994      * a reply is requested. This method will block the calling thread until all
995      * the responses associated with the CacheAccess object have been retrieved
996      * or the time indicated in the timeout variable has expired. If this method
997      * times out and the caller does not intend to call waitForResponse again on
998      * this object, cancelResponse should be called. If the object is local or a
999      * reply has not been requested, this call return immediately.
1000     *
1001     * @param timeout the maximum number of milliseconds to wait for remote
1002     * caches to reply.
1003     *
1004     */

1005    public void waitForResponse(int timeout) {
1006        if (!isValid()) {
1007            return;
1008        }
1009    }
1010
1011    /**
1012     * Gets the region this access applies to.
1013     *
1014     * @return the region this access applies to.
1015     */

1016    public CacheRegion getRegion() {
1017        return region;
1018    }
1019
1020    private String JavaDoc getRegionName() {
1021        return region.getName() == null ? null : region.getName().toString();
1022    }
1023}
Popular Tags