View Javadoc

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 javax.util.jcache;
20  
21  import java.io.File;
22  import java.io.OutputStream;
23  import java.io.Serializable;
24  import org.fjank.jcache.CacheImpl;
25  import org.fjank.jcache.CacheObject;
26  import org.fjank.jcache.CacheRegion;
27  import org.fjank.jcache.StreamCacheObject;
28  
29  
30  /**
31   * This class loads object into the cache with the aid of the abstract load
32   * method. Should be extended by the user to implement custom loaders, such as
33   * Database queries, Directory searches, File extraction, Net searches etc.
34   * @deprecated Will be removed and replaced with an interface.
35   * @author Frank Karlstrøm
36   */
37  public abstract class CacheLoader implements Serializable {
38      /**
39       * this method must be implemented by the user to load objects into the
40       * cache. This will typically be a database-call or directory call, or
41       * extracting information from a file. This method returns a reference to
42       * the newly loaded object. If the object being loaded is a StreamAccess
43       * object or a disk object, the OutputStream object created by the
44       * createStream method, or the File created by the createDiskObject method
45       * should be returned.
46       *
47       * @param handle is supplied by the cache and is used by the netSearch and
48       *        setAttributes methods to access information about the object
49       *        being searched for.
50       * @param arguments is the object pass to the cache in the get method.
51       *
52       * @return a reference to the newly created object.
53       */
54      public abstract Object load(final Object handle, final Object arguments)
55          throws CacheException;
56  
57      /**
58       * will cause the attributes associated with the object being loaded to be
59       * set to values provided in attributes. If the attributes is null,
60       * default attributes are assumed.
61       *
62       * @param handle handle is the object passed into the load method.
63       * @param attributes the attributes to set.
64       *
65       * @throws CacheException if an error occurs.
66       */
67      public final void setAttributes(final Object handle,
68          final Attributes attributes) throws CacheException {
69          CacheObject cacheObj = convertHandle(handle);
70          if (attributes == null) {
71              cacheObj.setAttributes(CacheAccessFactory.getInstance().getDefaultAttributes());
72          } else {
73              cacheObj.setAttributes(attributes);
74          }
75      }
76  
77      /**
78       * Will validate an handle and return the correct class for this Object.
79       *
80       * @param handle the handle to convert.
81       *
82       * @return the handle converted to a CacheObject
83       *
84       * @throws InvalidArgumentException of the handle is not an instance of a
85       *         CacheObject
86       */
87      private CacheObject convertHandle(final Object handle)
88          throws InvalidArgumentException {
89          if (handle == null) {
90              throw new InvalidArgumentException(
91                  "The handle passed in to this method was null.");
92          }
93          if (!(handle instanceof CacheObject)) {
94              throw new InvalidArgumentException(
95                  "The handle was not a valid CacheObject.");
96          }
97          CacheObject cacheObj = ((CacheObject) handle);
98          return cacheObj;
99      }
100 
101     /**
102      * returns the name associated with object being loaded. This method is
103      * only available to be called by application overrides of the load
104      * method.
105      *
106      * @param handle the handle to the object being loaded.
107      *
108      * @return the name associated with the object being loaded.
109      *
110      * @throws CacheException if some strange unexpected exception occur.
111      */
112     protected final Object getName(final Object handle)
113         throws CacheException {
114         return convertHandle(handle).getKey();
115     }
116 
117     /**
118      * return the name of the region for the object being loaded. This method
119      * is only available to be called from applications overriding the load
120      * method.
121      *
122      * @param handle the handle to the object being loaded.
123      *
124      * @return the region for the object being loaded.
125      *
126      * @throws CacheException if strange unexpected exceptions occur.
127      * @throws NullObjectException if an object is discovered with required
128      *         variables which is null.
129      */
130     protected final String getRegion(final Object handle)
131         throws CacheException {
132         final CacheObject cacheObj = convertHandle(handle);
133         final CacheRegion region = cacheObj.getRegion();
134         if (region == null) {
135             throw new NullObjectException("The object " + cacheObj
136                 + " is not attached to a region.");
137         }
138         final Object name = region.getName();
139         if (name != null) {
140             return name.toString();
141         } else {
142             return null;
143         }
144     }
145 
146     /**
147      * will search other caches for the object to be loaded. This method is
148      * only available to be called from applications overriding the load
149      * method. If the search is successfull, a reference to a local copy of
150      * the object is returned.
151      *
152      * @param handle the handle to the object being created.
153      * @param timeout the net search timeout.
154      *
155      * @return a reference to a local copy of the object.
156      *
157      * @throws CacheException if a timeout occurs, or the object is not found.
158      * @throws NotImplementedException will always be thrown
159      *
160      * @todo implement distribution.
161      */
162     protected final Object netSearch(final Object handle, final int timeout)
163         throws CacheException {
164         throw new NotImplementedException();
165     }
166 
167     /**
168      * should be called from the load method to create a StreamAccess object.
169      * The OutputStream returned is used to load the object into the cache.
170      * Default attributes are used. ObjectExistsExceptions occuring during
171      * this call can either be propagated to the caller , or null is returned.
172      * In both cases the cache will recognize that the object has been loaded
173      * by another cache, and return the object to the user.
174      *
175      * @param handle the object passed into the load method.
176      *
177      * @return an OutputStream to read the object into the cache.
178      *
179      * @throws ObjectExistsException if the object is declared as distributed,
180      *         and another cache is in the progress of loading.
181      * @throws InvalidArgumentException if some of the arguments are not valid
182      *         in this context
183      */
184     public final OutputStream createStream(final Object handle)
185         throws ObjectExistsException, InvalidArgumentException {
186         CacheObject co = convertHandle(handle);
187         try {
188             StreamCacheObject str =
189                 new StreamCacheObject(co.getKey(), null, co.getGroup(),
190                     co.getRegion(), CacheImpl.getCache(true).getReferenceQueue());
191             return str.getOutputStream();
192         } catch (CacheNotAvailableException e) {
193             throw new InvalidArgumentException("The cache is not available.");
194         } catch (CacheException e) {
195             throw new InvalidArgumentException(
196                 "The cache is not available, as an error occured."
197                 + e.getMessage());
198         }
199     }
200 
201     /**
202      * should be called from the load method to create a StreamAccess object.
203      * The OutputStream returned is used to load the object into the cache.
204      * Default attributes are used. ObjectExistsExceptions occuring during
205      * this call can either be propagated to the caller , or null is returned.
206      * In both cases the cache will recognize that the object has been loaded
207      * by another cache, and return the object to the user.
208      *
209      * @param handle the object passed into the load method.
210      * @param attributes the attributes will be set on the object by this
211      *        method. If null, default attributes are used.
212      *
213      * @return an OutputStream to read the object into the cache.
214      *
215      * @throws CacheException if the object is declared as distributed, and
216      *         another cache is in the progress of loading, or any other
217      *         strange exceptions occurs.
218      */
219     public final OutputStream createStream(final Object handle,
220         final Attributes attributes) throws CacheException {
221         setAttributes(handle, attributes);
222         return createStream(handle);
223     }
224 
225     /**
226      * is called from the load object to create a disk object. The File
227      * returned can then be used to load the object into the cache.
228      * ObjectExistsExceptions occuring during this call can either be
229      * propagated to the caller , or null is returned. In both cases the cache
230      * will recognize that the object has been loaded by another cache, and
231      * return the object to the user.
232      *
233      * @param handle the object passed into the load method.
234      * @param extension The extension parameter is used as the extension to the
235      *        file name (java, class, exe etc.) If null, no extension is
236      *        added.
237      *
238      * @return a File which represent the object being created.
239      *
240      * @throws CacheException if the object is declared as distributed, and
241      *         another cache is in the progress of loading, or any other
242      *         strange exceptions occurs.
243      */
244     public final File createDiskObject(final Object handle,
245         final String extension) throws CacheException {
246         CacheObject cacheObj = convertHandle(handle);
247         CacheAttributes att = getCacheAttributes();
248         String rootPath = att.getDiskPath();
249         String ext;
250         if (extension == null) {
251             ext = "";
252         } else {
253             ext = '.' + extension;
254         }
255         return new File(rootPath + File.separatorChar + cacheObj.getKey() + ext);
256     }
257 
258     /**
259      * DOCUMENT ME!
260      *
261      * @return DOCUMENT ME!
262      *
263      * @throws CacheNotAvailableException DOCUMENT ME!
264      * @throws CacheException DOCUMENT ME!
265      */
266     private CacheAttributes getCacheAttributes()
267         throws CacheNotAvailableException, CacheException {
268         CacheAccessFactory fact = CacheAccessFactory.getInstance();
269         Cache cache = fact.getCache();
270         return cache.getAttributes();
271     }
272 
273     /**
274      * is called from the load object to create a disk object. The File
275      * returned can then be used to load the object into the cache.
276      * ObjectExistsExceptions occuring during this call can either be
277      * propagated to the caller , or null is returned. In both cases the cache
278      * will recognize that the object has been loaded by another cache, and
279      * return the object to the user.
280      *
281      * @param handle the object passed into the load method.
282      * @param attributes the attributes will be set on the object by this
283      *        method. If null, default attributes are used.
284      * @param extension The extension parameter is used as the extension to the
285      *        file name (java, class, exe etc.) If null, no extension is
286      *        added.
287      *
288      * @return a File wich represent the object being created.
289      *
290      * @throws CacheException if the object is declared as distributed, and
291      *         another cache is in the progress of loading, or any other
292      *         strange exceptions occurs.
293      */
294     public final File createDiskObject(final Object handle,
295         final Attributes attributes, final String extension)
296         throws CacheException {
297         setAttributes(handle, attributes);
298         return createDiskObject(handle, extension);
299     }
300 
301     /**
302      * is called from the load method to record a message in the cache's log.
303      * How and where the logging occurs is dependent if the configuration of
304      * the logger in the cache.
305      *
306      * @param msg the message to log.
307      *
308      * @todo implement this method.
309      */
310     public final void log(final String msg) {
311         try {
312             CacheAttributes cacheAttributes = getCacheAttributes();
313             CacheLogger logger = cacheAttributes.getLogger();
314             logger.log(msg);
315         } catch (CacheNotAvailableException e) {
316             //doh, how did we get here then?
317         } catch (CacheException e) {
318             //doh, what now?
319         }
320     }
321 
322     /**
323      * this method is called from the load method to convert any non
324      * CacheExceptions into CacheExceptions, with the base exception set to
325      * the original exception. This allows the load method to only throw
326      * CacheExceptions without loosing important information. The exception
327      * will also be logged assuming the logging is configured and the logging
328      * severity is set sufficently high. For all CacheExceptions, if
329      * CacheException.printStackTrace() is called, and there is a base
330      * exception, the stack for the base will be printed.
331      *
332      * @param msg a message to provide to the CacheException.
333      * @param exception the Exception to be wrapped. If null, a default
334      *        CacheException is returned.
335      *
336      * @return a CacheException wrapping the exception.
337      */
338     public final CacheException exceptionHandler(final String msg,
339         final Exception exception) {
340         return new CacheException(msg, exception);
341     }
342 }