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 }