Coverage report

  %line %branch
org.apache.jetspeed.page.impl.DatabasePageManagerCache$Entry
0% 
0% 

 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  * 
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  * 
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.jetspeed.page.impl;
 18  
 
 19  
 import java.util.HashMap;
 20  
 import java.util.Iterator;
 21  
 import java.util.LinkedList;
 22  
 import java.util.List;
 23  
 import java.util.Properties;
 24  
 
 25  
 import org.apache.jetspeed.om.folder.impl.FolderImpl;
 26  
 import org.apache.jetspeed.page.PageManager;
 27  
 import org.apache.jetspeed.page.document.impl.NodeImpl;
 28  
 import org.apache.ojb.broker.Identity;
 29  
 import org.apache.ojb.broker.PersistenceBroker;
 30  
 import org.apache.ojb.broker.cache.ObjectCache;
 31  
 
 32  
 /**
 33  
  * DatabasePageManagerCache
 34  
  * 
 35  
  * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
 36  
  * @version $Id: $
 37  
  */
 38  
 public class DatabasePageManagerCache implements ObjectCache
 39  
 {
 40  
     private static HashMap cacheByOID;
 41  
     private static LinkedList cacheLRUList;
 42  
     private static HashMap cacheByPath;
 43  
     private static int cacheSize;
 44  
     private static int cacheExpiresSeconds;
 45  
     private static boolean constraintsEnabled;
 46  
     private static boolean permissionsEnabled;
 47  
     private static PageManager pageManager;
 48  
 
 49  
     /**
 50  
      * cacheInit
 51  
      *
 52  
      * Initialize cache using page manager configuration.
 53  
      *
 54  
      * @param pageManager configured page manager
 55  
      */
 56  
     public synchronized static void cacheInit(DatabasePageManager dbPageManager)
 57  
     {
 58  
         if (pageManager == null)
 59  
         {
 60  
             cacheByOID = new HashMap();
 61  
             cacheLRUList = new LinkedList();
 62  
             cacheByPath = new HashMap();
 63  
             cacheSize = dbPageManager.getCacheSize();
 64  
             cacheExpiresSeconds = dbPageManager.getCacheExpiresSeconds();
 65  
             constraintsEnabled = dbPageManager.getConstraintsEnabled();
 66  
             permissionsEnabled = dbPageManager.getPermissionsEnabled();
 67  
             pageManager = dbPageManager;
 68  
         }
 69  
     }
 70  
 
 71  
     /**
 72  
      * setPageManagerProxy
 73  
      *
 74  
      * @param proxy proxied page manager interface used to
 75  
      *              inject into Folder instances to provide
 76  
      *              transaction/interception
 77  
      */
 78  
     public synchronized static void setPageManagerProxy(PageManager proxy)
 79  
     {
 80  
         // set/reset page manager proxy and clear cache to
 81  
         // flush any objects referencing replaced page manager
 82  
         if (pageManager != proxy)
 83  
         {
 84  
             pageManager = proxy;
 85  
             cacheClear();
 86  
         }
 87  
     }
 88  
 
 89  
     /**
 90  
      * cacheLookup
 91  
      *
 92  
      * Lookup node instances by unique path.
 93  
      *
 94  
      * @param path node unique path
 95  
      * @return cached node
 96  
      */
 97  
     public synchronized static NodeImpl cacheLookup(String path)
 98  
     {
 99  
         if (path != null)
 100  
         {
 101  
             // return valid object cached by path
 102  
             return (NodeImpl)cacheValidateEntry((Entry)cacheByPath.get(path));
 103  
         }
 104  
         return null;
 105  
     }
 106  
 
 107  
     /**
 108  
      * cacheAdd
 109  
      *
 110  
      * Add object to cache and cache node instances by unique path;
 111  
      * infuse nodes loaded by OJB with page manager configuration.
 112  
      *
 113  
      * @param oid object/node indentity
 114  
      * @param obj object/node to cache
 115  
      */
 116  
     public synchronized static void cacheAdd(Identity oid, Object obj)
 117  
     {
 118  
         Entry entry = (Entry)cacheByOID.get(oid);
 119  
         if (entry != null)
 120  
         {
 121  
             // update cache LRU order
 122  
             cacheLRUList.remove(entry);
 123  
             cacheLRUList.addFirst(entry);
 124  
             // refresh cache entry
 125  
             entry.touch();
 126  
         }
 127  
         else
 128  
         {
 129  
             // create new cache entry and map
 130  
             entry = new Entry(obj, oid);
 131  
             cacheByOID.put(oid, entry);
 132  
             cacheLRUList.addFirst(entry);
 133  
             // infuse node with page manager configuration
 134  
             // or the page manager itself and add to the
 135  
             // paths cache 
 136  
             if (obj instanceof NodeImpl)
 137  
             {
 138  
                 NodeImpl node = (NodeImpl)obj;
 139  
                 node.setConstraintsEnabled(constraintsEnabled);
 140  
                 node.setPermissionsEnabled(permissionsEnabled);
 141  
                 cacheByPath.put(node.getPath(), entry);
 142  
                 if (obj instanceof FolderImpl)
 143  
                 {
 144  
                     ((FolderImpl)obj).setPageManager(pageManager);
 145  
                 }
 146  
             }
 147  
             // trim cache as required to maintain cache size
 148  
             while (cacheLRUList.size() > cacheSize)
 149  
             {
 150  
                 cacheRemoveEntry((Entry)cacheLRUList.getLast(), true);
 151  
             }
 152  
         }
 153  
     }
 154  
 
 155  
     /**
 156  
      * cacheClear
 157  
      *
 158  
      * Clear object and node caches.
 159  
      */
 160  
     public synchronized static void cacheClear()
 161  
     {
 162  
         // remove all cache entries
 163  
         Iterator removeIter = cacheLRUList.iterator();
 164  
         while (removeIter.hasNext())
 165  
         {
 166  
             cacheRemoveEntry((Entry)removeIter.next(), false);
 167  
         }
 168  
         // clear cache
 169  
         cacheByOID.clear();
 170  
         cacheLRUList.clear();
 171  
         cacheByPath.clear();
 172  
     }
 173  
 
 174  
     /**
 175  
      * cacheLookup
 176  
      *
 177  
      * Lookup objects by identity.
 178  
      *
 179  
      * @param oid object identity
 180  
      * @return cached object
 181  
      */
 182  
     public synchronized static Object cacheLookup(Identity oid)
 183  
     {
 184  
         if (oid != null)
 185  
         {
 186  
             // return valid object cached by oid
 187  
             return cacheValidateEntry((Entry)cacheByOID.get(oid));
 188  
         }
 189  
         return null;
 190  
     }
 191  
 
 192  
     /**
 193  
      * cacheRemove
 194  
      *
 195  
      * Remove identified object from object and node caches.
 196  
      *
 197  
      * @param oid object identity
 198  
      */
 199  
     public synchronized static void cacheRemove(Identity oid)
 200  
     {
 201  
         // remove from cache by oid
 202  
         cacheRemoveEntry((Entry)cacheByOID.get(oid), true);
 203  
     }
 204  
 
 205  
     /**
 206  
      * cacheRemove
 207  
      *
 208  
      * Remove identified object from object and node caches.
 209  
      *
 210  
      * @param path object path
 211  
      */
 212  
     public synchronized static void cacheRemove(String path)
 213  
     {
 214  
         // remove from cache by path
 215  
         cacheRemoveEntry((Entry)cacheByPath.get(path), true);
 216  
     }
 217  
     
 218  
     /**
 219  
      * cacheValidateEntry
 220  
      *
 221  
      * Validate specified entry from cache, returning cached
 222  
      * object if valid.
 223  
      *
 224  
      * @param entry cache entry to validate
 225  
      * @return validated object from cache
 226  
      */
 227  
     private synchronized static Object cacheValidateEntry(Entry entry)
 228  
     {
 229  
         if (entry != null)
 230  
         {
 231  
             if (!entry.isExpired())
 232  
             {
 233  
                 // update cache LRU order
 234  
                 cacheLRUList.remove(entry);
 235  
                 cacheLRUList.addFirst(entry);
 236  
                 // refresh cache entry and return object
 237  
                 entry.touch();
 238  
                 return entry.getObject();
 239  
             }
 240  
             else
 241  
             {
 242  
                 // remove expired entry
 243  
                 cacheRemoveEntry(entry, true);
 244  
             }
 245  
         }
 246  
         return null;
 247  
     }
 248  
     
 249  
     /**
 250  
      * cacheRemoveEntry
 251  
      *
 252  
      * Remove specified entry from cache.
 253  
      *
 254  
      * @param entry cache entry to remove
 255  
      * @param remove enable removal from cache
 256  
      */
 257  
     private synchronized static void cacheRemoveEntry(Entry entry, boolean remove)
 258  
     {
 259  
         if (entry != null)
 260  
         {
 261  
             Object removeObj = entry.getObject();
 262  
             if (remove)
 263  
             {
 264  
                 // remove entry, optimize for removal from end
 265  
                 // of list as cache size is met or entries expire
 266  
                 if (cacheLRUList.getLast() == entry)
 267  
                 {
 268  
                     cacheLRUList.removeLast();
 269  
                 }
 270  
                 else
 271  
                 {
 272  
                     int removeIndex = cacheLRUList.lastIndexOf(entry);
 273  
                     if (removeIndex > 0)
 274  
                     {
 275  
                         cacheLRUList.remove(removeIndex);
 276  
                     }
 277  
                 }
 278  
                 // unmap entry
 279  
                 cacheByOID.remove(entry.getOID());
 280  
                 if (removeObj instanceof NodeImpl)
 281  
                 {
 282  
                     cacheByPath.remove(((NodeImpl)removeObj).getPath());
 283  
                 }
 284  
             }
 285  
             // reset internal FolderImpl caches
 286  
             if (removeObj instanceof FolderImpl)
 287  
             {
 288  
                 ((FolderImpl)removeObj).resetAll(false);
 289  
             }
 290  
         }
 291  
     }
 292  
 
 293  
     /**
 294  
      * resetCachedSecurityConstraints
 295  
      *
 296  
      * Reset cached security constraints in all cached node objects.
 297  
      */
 298  
     public synchronized static void resetCachedSecurityConstraints()
 299  
     {
 300  
         // reset cached objects
 301  
         Iterator resetIter = cacheLRUList.iterator();
 302  
         while (resetIter.hasNext())
 303  
         {
 304  
             Object obj = ((Entry)resetIter.next()).getObject();
 305  
             if (obj instanceof NodeImpl)
 306  
             {
 307  
                 ((NodeImpl)obj).resetCachedSecurityConstraints();
 308  
             }
 309  
         }
 310  
     }
 311  
 
 312  
     /**
 313  
      * Entry
 314  
      *
 315  
      * Cache entry class adding entry timestamp to track expiration
 316  
      */
 317  
     private static class Entry
 318  
     {
 319  
         public long timestamp;
 320  
         public Object object;
 321  
         public Identity oid;
 322  
 
 323  
         public Entry(Object object, Identity oid)
 324  0
         {
 325  0
             touch();
 326  0
             this.object = object;
 327  0
             this.oid = oid;
 328  0
         }
 329  
 
 330  
         public boolean isExpired()
 331  
         {
 332  0
             if (DatabasePageManagerCache.cacheExpiresSeconds > 0)
 333  
             {
 334  0
                 long now = System.currentTimeMillis();
 335  0
                 if (((now - timestamp) / 1000) < DatabasePageManagerCache.cacheExpiresSeconds)
 336  
                 {
 337  0
                     timestamp = now;
 338  0
                     return false;
 339  
                 }
 340  0
                 return true;
 341  
             }
 342  0
             return false;
 343  
         }
 344  
         
 345  
         public void touch()
 346  
         {
 347  0
             if (DatabasePageManagerCache.cacheExpiresSeconds > 0)
 348  
             {
 349  0
                 timestamp = System.currentTimeMillis();
 350  
             }
 351  0
         }
 352  
 
 353  
         public Object getObject()
 354  
         {
 355  0
             return object;
 356  
         }
 357  
 
 358  
         public Identity getOID()
 359  
         {
 360  0
             return oid;
 361  
         }
 362  
     }
 363  
 
 364  
     /**
 365  
      * DatabasePageManagerCache
 366  
      *
 367  
      * Construct a cache instance using OJB compliant signatures.
 368  
      *
 369  
      * @param broker broker that is to own cache
 370  
      * @param props attribute properties passed to cache
 371  
      */
 372  
     public DatabasePageManagerCache(PersistenceBroker broker, Properties props)
 373  
     {
 374  
     }
 375  
 
 376  
     /* (non-Javadoc)
 377  
      * @see org.apache.ojb.broker.cache.ObjectCache#cache(org.apache.ojb.broker.Identity, java.lang.Object)
 378  
      */
 379  
     public void cache(Identity oid, Object obj)
 380  
     {
 381  
         cacheAdd(oid, obj);
 382  
     }
 383  
 
 384  
     /* (non-Javadoc)
 385  
      * @see org.apache.ojb.broker.cache.ObjectCache#clear()
 386  
      */
 387  
     public void clear()
 388  
     {
 389  
         cacheClear();
 390  
     }
 391  
 
 392  
     /* (non-Javadoc)
 393  
      * @see org.apache.ojb.broker.cache.ObjectCache#lookup(org.apache.ojb.broker.Identity)
 394  
      */
 395  
     public Object lookup(Identity oid)
 396  
     {
 397  
         return cacheLookup(oid);
 398  
     }
 399  
 
 400  
     /* (non-Javadoc)
 401  
      * @see org.apache.ojb.broker.cache.ObjectCache#remove(org.apache.ojb.broker.Identity)
 402  
      */
 403  
     public void remove(Identity oid)
 404  
     {
 405  
         cacheRemove(oid);
 406  
     }
 407  
 
 408  
     public synchronized static void dump()
 409  
     {
 410  
         System.out.println("--------------------------1");        
 411  
         Iterator dumpIter = cacheLRUList.iterator();
 412  
         while (dumpIter.hasNext())
 413  
         {
 414  
             Entry entry = (Entry)dumpIter.next();
 415  
             Object entryObject = entry.getObject();
 416  
             if (entryObject instanceof NodeImpl)
 417  
             {
 418  
                 System.out.println("entry = " + ((NodeImpl)entryObject).getPath() + ", " + entry.getOID());
 419  
             }
 420  
             else
 421  
             {
 422  
                 System.out.println("entry = <none>, " + entry.getOID());
 423  
             }
 424  
         }
 425  
         System.out.println("--------------------------2");
 426  
     }
 427  
     
 428  
     protected static ThreadLocal transactionedOperations = new ThreadLocal();
 429  
     
 430  
     public static List getTransactions()
 431  
     {
 432  
         List operations = (List)transactionedOperations.get();
 433  
         if (operations == null)
 434  
         {
 435  
             operations = new LinkedList();
 436  
             transactionedOperations.set(operations);
 437  
         }
 438  
         
 439  
         return operations;
 440  
     }
 441  
 
 442  
     /**
 443  
      * @param principal
 444  
      *            The principal to set.
 445  
      */
 446  
     public static void addTransaction(TransactionedOperation operation)
 447  
     {
 448  
         List transactions = getTransactions();        
 449  
         transactions.add(operation);
 450  
     }
 451  
     
 452  
     public static void rollbackTransactions()
 453  
     {
 454  
         Iterator transactions = getTransactions().iterator();
 455  
         while (transactions.hasNext())
 456  
         {
 457  
             TransactionedOperation operation = (TransactionedOperation)transactions.next();
 458  
             cacheRemove(operation.getPath());
 459  
         }
 460  
     }
 461  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.