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 }