1 16 17 package org.apache.jetspeed.cache.disk; 18 19 import org.apache.jetspeed.util.URIEncoder; 21 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; 22 import org.apache.jetspeed.services.logging.JetspeedLogger; 23 import org.apache.jetspeed.services.threadpool.ThreadPool; 24 import org.apache.jetspeed.services.urlmanager.URLManager; 25 import org.apache.jetspeed.services.urlmanager.URLFetcher; 26 import org.apache.jetspeed.services.urlmanager.URLFetcherDownloader; 27 import org.apache.jetspeed.services.resources.JetspeedResources; 28 29 import java.io.File ; 31 import java.io.FileOutputStream ; 32 import java.io.IOException ; 33 import java.io.Reader ; 34 import java.io.OutputStreamWriter ; 35 import java.net.MalformedURLException ; 36 import java.util.Enumeration ; 37 import java.util.Hashtable ; 38 import java.util.Vector ; 39 import javax.servlet.ServletContext ; 40 41 import org.apache.turbine.services.servlet.TurbineServlet; 43 44 45 55 public class JetspeedDiskCache implements DiskCache { 56 57 58 61 public static String DEFAULT_CACHE_DIRECTORY = 62 JetspeedResources.getString( JetspeedResources.CACHE_DIRECTORY_KEY, "WEB-INF/cache" ); 63 64 67 private static Hashtable instances = new Hashtable (); 68 69 72 private String directory; 73 74 77 private Hashtable entries = new Hashtable (); 78 79 82 private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(JetspeedDiskCache.class.getName()); 83 84 87 private JetspeedDiskCache(String directory) { 88 this.directory = directory; 89 90 if ( DEFAULT_CACHE_DIRECTORY.equals("use-servlet-temp") ) { 91 String tempdir = new String ("WEB-INF/cache"); 92 try { 93 ServletContext sc = TurbineServlet.getServletContext(); 94 tempdir = sc.getAttribute("javax.servlet.context.tempdir").toString() + "/jetspeed/cache"; 95 if ( logger.isDebugEnabled() ) 96 { 97 logger.debug("DISK CACHE: will create cache in servlet temp directory " + tempdir); 98 } 99 } catch (Exception e) { 100 logger.error("DISK CACHE: problems creating cache in servlet temp directory " 101 + " falling back to WEB-INF/cache : " + e); 102 } 103 this.directory = tempdir; 104 } else { 105 if ( logger.isDebugEnabled() ) 106 { 107 logger.debug("DISK CACHE: will use cache in user configured directory " + directory); 108 } 109 } 110 } 111 112 113 119 private void initEntries() { 120 121 logger.info("Disk Cache init Entries..."); 122 try { 130 org.apache.turbine.services.TurbineServices 131 .getInstance() 132 .getService( org.apache.jetspeed.services.urlmanager.URLManagerService.SERVICE_NAME ).init(); 133 } 134 catch (Throwable t) 135 { 136 logger.error( "initEntries: Unable to start URLManagerService", t ); 137 } 138 139 File temp = new File ( directory ); 140 141 String files[] = temp.list(); 142 143 144 if (files == null) 145 { 146 logger.error("DiskCache.initEntries: Error!!! - The cache directory cannot be found: " + directory); 147 } 148 149 for ( int i = 0; i < files.length; ++i ) { 150 151 if ( files[i].indexOf("http_") == 0 ) { 152 logger.info("Initializing cache entry: " + files[i]); 153 JetspeedDiskCacheEntry ent = new JetspeedDiskCacheEntry( new File ( getRoot(), files[i] ) ); 154 logger.info("Adding cache entry for " + ent.getSourceURL()); 155 156 String interned = ent.getSourceURL().intern(); 157 entries.put( interned, ent); 158 URLManager.register( interned, 159 URLManager.STATUS_OK, 160 "Recovered from cache" ); 161 } 162 163 } 164 logger.info("Disk Cache init Entries DONE."); 165 166 } 167 168 175 public DiskCacheEntry[] getEntries() { 176 177 Vector diskEntries = new Vector (); 178 179 Enumeration cacheEntries = entries.elements(); 180 logger.info("Calling JetspeedDiskCache getEntries"); 181 while(cacheEntries.hasMoreElements()) 182 { 183 diskEntries.addElement(cacheEntries.nextElement()); 184 } 185 DiskCacheEntry[] found = new DiskCacheEntry[diskEntries.size()]; 186 diskEntries.copyInto(found); 187 return found; 188 189 } 190 191 196 public String getRoot() { 197 new File ( this.directory ).mkdirs(); 198 return this.directory; 199 } 200 201 204 public DiskCacheEntry getEntry( String url ) throws IOException { 205 return getEntry( url, false ); 206 } 207 208 211 public DiskCacheEntry getEntry( String url, 212 boolean force ) throws IOException 213 { 214 215 if ( url == null ) { 216 throw new IllegalArgumentException ("You must specify a URL to obtain an entry from the cache"); 217 } 218 219 String interned = url.intern(); 221 JetspeedDiskCacheEntry entry = (JetspeedDiskCacheEntry)entries.get(interned); 222 if( entry != null) 223 { 224 225 if(force) 227 { 228 logger.info("Refreshing local URL!!!" + interned); 229 230 URLFetcher.refresh(interned); 231 } 232 return entry; 233 } 234 235 236 logger.warn( "Cache getEntry Called with " + url ); 239 if ( DiskCacheUtils.isLocal( url ) ) { 240 241 String local = DiskCacheUtils.getLocalURL( url ).intern(); 242 JetspeedDiskCacheEntry dce = (JetspeedDiskCacheEntry)entries.get( local ); 243 if(dce == null ) 244 { 245 246 logger.info("Adding Local to cache list: " + local); 247 dce = new JetspeedDiskCacheEntry( local ); 248 entries.put(local, dce); 249 URLManager.register( local, 250 URLManager.STATUS_OK, 251 "Local added" ); 252 } 253 logger.info("Returning local cached URL"); 254 255 return dce; 256 } 257 258 259 if ( DiskCacheUtils.isCacheable( url ) ) { 262 263 if ( ( DiskCacheUtils.isCached( this, url ) == false ) || force ) { 264 265 267 this.add( url, true ); 272 273 } 274 return this.getEntry(url, force); 275 277 } else { 278 279 logger.info( "DiskCache: this URL can't be stored in cache... providing it directly." + url ); 281 return new JetspeedDiskCacheEntry( url ); 282 283 } 284 285 } 286 287 291 public DiskCacheEntry getEntry( String url, 292 Reader is ) throws IOException { 293 294 String uri = URIEncoder.encode( url ); 295 String oldfilename = this.getRoot() + "/old." + uri; 296 String filename = DiskCacheUtils.getFile( this, url ).getAbsolutePath(); 297 String newfilename = this.getRoot() + "/new." + uri; 298 File file = new File ( DiskCacheUtils.getFile( this, url ).getAbsolutePath() ); 299 File newfile = new File ( newfilename); 300 301 OutputStreamWriter os = new OutputStreamWriter (new FileOutputStream ( newfile ), "utf-8" ); 302 303 char chars[] = new char[200]; 305 306 int readCount = 0; 307 while( ( readCount = is.read( chars )) > 0 ) { 308 os.write(chars, 0, readCount); 309 } 310 311 is.close(); 312 os.close(); 313 314 File oldfile = new File ( oldfilename); 315 if(oldfile.exists()) 316 oldfile.delete(); 317 if(newfile.exists() && newfile.length() > 0) { 318 file = new File ( filename ); 319 file.renameTo(oldfile); 320 newfile.renameTo(file); 321 } 322 try { 323 if( oldfile.exists() ) 324 oldfile.delete(); 325 } catch (Exception e) { 326 logger.info("Exception " + 327 e.getMessage() + 328 " while deleting " + oldfilename, e); 329 } 330 JetspeedDiskCacheEntry dce = (JetspeedDiskCacheEntry) entries.get(url.intern()); 331 if (dce != null ) 332 { 333 dce.setFile( file ); 334 return dce; 335 } else { 336 return this.getEntry(url, false); 337 } 338 339 } 340 341 342 345 public void remove( String url ) throws IOException { 346 String uri = URIEncoder.encode( url ); 347 if( DiskCacheUtils.isCached( this, url ) ) { 348 entries.remove(url.intern()); 349 URLManager.unregister( url.intern() ); 350 File file = DiskCacheUtils.getFile( this, url ); 351 if(file.exists()) { 352 file.delete(); 353 } 354 } 355 String oldfilename = this.getRoot() + "/old." + uri; 356 File file = new File (oldfilename); 357 if(file.exists()) { 358 file.delete(); 359 } 360 String newfilename = this.getRoot() + "/new." + uri; 361 file = new File (newfilename); 362 if(file.exists()) { 363 file.delete(); 364 } 365 366 } 367 368 371 public void add( String url ) throws IOException { 372 add( url, false ); 373 } 374 375 378 public void add( String url, boolean force ) throws IOException { 379 String interned = url.intern(); 380 this.fetch( url, 381 DiskCacheUtils.getFile( this, url ).getAbsolutePath(), 382 force ); 383 if(entries.get(interned) != null ) return; 384 entries.put(interned, new JetspeedDiskCacheEntry(interned)); 385 URLManager.register( interned, 386 URLManager.STATUS_OK, 387 "Added by Program" ); 388 389 } 390 391 397 public String fetch( String url, 398 String cache ) throws IOException { 399 return fetch( url, cache, false ); 400 } 401 402 409 public String fetch( String url, 410 String cache, 411 boolean force ) throws IOException { 412 413 if (url == null) { 414 throw new IllegalArgumentException ("url cannot be null"); 415 } 416 417 if (cache == null) { 418 throw new IllegalArgumentException ("cache cannot be null"); 419 } 420 421 try { 422 423 Reader is = URLFetcher.fetch( url, force ); 426 427 OutputStreamWriter os = new OutputStreamWriter ( new FileOutputStream ( cache ), 428 "utf-8" ); 429 430 char chars[] = new char[200]; 432 433 int readCount = 0; 434 while( ( readCount = is.read( chars )) > 0 ) { 435 os.write(chars, 0, readCount); 436 } 437 438 is.close(); 439 os.close(); 440 441 } catch (MalformedURLException e) { 442 logger.error("Error in URL", e ); 443 } 444 445 return cache; 446 447 } 448 449 452 public void refresh( String url ) { 453 ThreadPool.process( new URLFetcherDownloader( url ) ); 454 } 455 456 459 public static JetspeedDiskCache getInstance() { 460 461 return JetspeedDiskCache.getInstance( DEFAULT_CACHE_DIRECTORY ); 462 } 463 464 469 public static JetspeedDiskCache getInstance( String directory ) { 470 471 synchronized(JetspeedDiskCache.instances) { 472 473 JetspeedDiskCache cache = (JetspeedDiskCache)JetspeedDiskCache.instances.get(directory); 474 475 if (cache == null) { 476 cache = new JetspeedDiskCache(directory); 477 JetspeedDiskCache.instances.put( directory, cache ); 478 logger.info("DISK CACHE: Initing cache for " + directory); 479 cache.initEntries(); 480 logger.info("DISK CACHE: Inited cache:" + directory); 481 } 482 return cache; 483 } 484 } 485 486 488 public boolean isCached(String url) 489 { 490 return entries.containsKey(url.intern()); 491 } 492 493 } 494 495 496 | Popular Tags |