//# 0 errors, 140 messages
//#
/*
    //#ExpiringLRUCacheImpl.java:1:1: class: org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  The ASF licenses this file to You
 * under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */

package org.apache.roller.weblogger.util.cache;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * An LRU cache where entries expire after a given timeout period.
 */
public class ExpiringLRUCacheImpl extends LRUCacheImpl {
    
    private static Log log = LogFactory.getLog(ExpiringLRUCacheImpl.class);
    //#ExpiringLRUCacheImpl.java:30: method: org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init
    //#ExpiringLRUCacheImpl.java:30: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl
    //#    method: org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Descendant_Table[org/apache/roller/weblogger/util/cache/ExpiringLRUCacheImpl]
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.clear()V
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.get(Ljava/lang/String;)Ljava/lang/Object;
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.getId()Ljava/lang/String;
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.getStats()Ljava/util/Map;
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.put(Ljava/lang/String;Ljava/lang/Object;)V
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.remove(Ljava/lang/String;)V
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): log
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): org/apache/roller/weblogger/util/cache/Cache.__Descendant_Table[org/apache/roller/weblogger/util/cache/ExpiringLRUCacheImpl]
    //#output(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): org/apache/roller/weblogger/util/cache/LRUCacheImpl.__Descendant_Table[org/apache/roller/weblogger/util/cache/ExpiringLRUCacheImpl]
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Descendant_Table[org/apache/roller/weblogger/util/cache/ExpiringLRUCacheImpl] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): org/apache/roller/weblogger/util/cache/Cache.__Descendant_Table[org/apache/roller/weblogger/util/cache/ExpiringLRUCacheImpl] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): org/apache/roller/weblogger/util/cache/LRUCacheImpl.__Descendant_Table[org/apache/roller/weblogger/util/cache/ExpiringLRUCacheImpl] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.clear()V == &org/apache/roller/weblogger/util/cache/LRUCacheImpl.clear
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.get(Ljava/lang/String;)Ljava/lang/Object; == &get
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.getId()Ljava/lang/String; == &org/apache/roller/weblogger/util/cache/LRUCacheImpl.getId
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.getStats()Ljava/util/Map; == &org/apache/roller/weblogger/util/cache/LRUCacheImpl.getStats
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.put(Ljava/lang/String;Ljava/lang/Object;)V == &put
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): __Dispatch_Table.remove(Ljava/lang/String;)V == &org/apache/roller/weblogger/util/cache/LRUCacheImpl.remove
    //#post(org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init): init'ed(log)
    //#ExpiringLRUCacheImpl.java:30: end of method: org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl__static_init
    
    private long timeout = 0;
    
    
    protected ExpiringLRUCacheImpl(String id) {
        
        super(id);
    //#ExpiringLRUCacheImpl.java:37: method: void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)
    //#input(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): id
    //#input(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): new Date(LRUCacheImpl#1) num objects
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.cache
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.hits
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.id
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.misses
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.puts
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.removes
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.startTime
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.timeout
    //#new obj(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): new Date(LRUCacheImpl#1)
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): init'ed(this.cache)
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.hits == +0
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.misses == +0
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.puts == +0
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.removes == +0
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.id == id
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): init'ed(this.id)
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.startTime == &new Date(LRUCacheImpl#1)
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): this.timeout == 3_600_000
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): new Date(LRUCacheImpl#1) num objects == 1
    //#unanalyzed(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): Effects-of-calling:java.util.Date
    //#unanalyzed(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): Effects-of-calling:java.util.LinkedHashMap
    //#unanalyzed(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)): Effects-of-calling:java.util.Collections:synchronizedMap
        this.timeout = 60 * 60 * 1000;
    }
    //#ExpiringLRUCacheImpl.java:39: end of method: void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String)
    
    
    protected ExpiringLRUCacheImpl(String id, int maxsize, long timeout) {
        
        super(id, maxsize);
    //#ExpiringLRUCacheImpl.java:44: method: void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)
    //#input(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): id
    //#input(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): maxsize
    //#input(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this
    //#input(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): timeout
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): new Date(LRUCacheImpl#1) num objects
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.cache
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.hits
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.id
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.misses
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.puts
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.removes
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.startTime
    //#output(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.timeout
    //#new obj(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): new Date(LRUCacheImpl#1)
    //#pre[2] (void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): maxsize in -1_610_612_737..3_221_225_471
    //#pre[4] (void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): timeout <= 18_446_744_073_709_551
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): init'ed(this.cache)
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.hits == +0
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.misses == +0
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.puts == +0
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.removes == +0
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.id == id
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): init'ed(this.id)
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.startTime == &new Date(LRUCacheImpl#1)
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.timeout == One-of{0, timeout*1_000}
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): this.timeout in {0, 1_000..18_446_744_073_709_551_000}
    //#post(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): new Date(LRUCacheImpl#1) num objects == 1
    //#unanalyzed(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): Effects-of-calling:java.util.Date
    //#unanalyzed(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): Effects-of-calling:java.util.LinkedHashMap
    //#unanalyzed(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): Effects-of-calling:java.util.Collections:synchronizedMap
    //#test_vector(void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)): timeout: {-9_223_372_036_854_775_808..0}, {1..18_446_744_073_709_551}
        
        // timeout is specified in seconds; only positive values allowed
        if(timeout > 0) {
            this.timeout = timeout * 1000;
        }
    }
    //#ExpiringLRUCacheImpl.java:50: end of method: void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl(String, int, long)
    
    
    /**
     * Store an entry in the cache.
     *
     * We wrap the cached object in our ExpiringCacheEntry object so that we
     * can track when the entry has expired.
     */
    public synchronized void put(String key, Object value) {
        
        ExpiringCacheEntry entry = new ExpiringCacheEntry(value, this.timeout);
    //#ExpiringLRUCacheImpl.java:61: method: void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.put(String, Object)
    //#input(void put(String, Object)): key
    //#input(void put(String, Object)): this
    //#input(void put(String, Object)): this.cache
    //#input(void put(String, Object)): this.puts
    //#input(void put(String, Object)): this.timeout
    //#input(void put(String, Object)): value
    //#output(void put(String, Object)): this.puts
    //#pre[2] (void put(String, Object)): init'ed(this.puts)
    //#pre[4] (void put(String, Object)): this.cache != null
    //#pre[5] (void put(String, Object)): init'ed(this.timeout)
    //#post(void put(String, Object)): this.puts == old this.puts + 1
    //#post(void put(String, Object)): init'ed(this.puts)
    //#unanalyzed(void put(String, Object)): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(void put(String, Object)): Effects-of-calling:java.util.Map:put
        super.put(key, entry);
    }
    //#ExpiringLRUCacheImpl.java:63: end of method: void org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.put(String, Object)
    
    
    /**
     * Retrieve an entry from the cache.
     *
     * This LRU cache supports timeouts, so if the cached object has expired
     * then we return null, just as if the entry wasn't found.
     */
    public Object get(String key) {
        
        Object value = null;
    //#ExpiringLRUCacheImpl.java:74: method: Object org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.get(String)
    //#input(Object get(String)): "EXPIRED ["._tainted
    //#input(Object get(String)): "]"._tainted
    //#input(Object get(String)): key
    //#input(Object get(String)): key._tainted
    //#input(Object get(String)): log
    //#input(Object get(String)): org/apache/roller/weblogger/util/cache/ExpiringCacheEntry.__Descendant_Table[org/apache/roller/weblogger/util/cache/ExpiringCacheEntry]
    //#input(Object get(String)): org/apache/roller/weblogger/util/cache/ExpiringCacheEntry.__Descendant_Table[others]
    //#input(Object get(String)): org/apache/roller/weblogger/util/cache/ExpiringCacheEntry.__Dispatch_Table.getValue()Ljava/lang/Object;
    //#input(Object get(String)): org/apache/roller/weblogger/util/cache/ExpiringCacheEntry.__Dispatch_Table.hasExpired()Z
    //#input(Object get(String)): this
    //#input(Object get(String)): this.cache
    //#input(Object get(String)): this.hits
    //#input(Object get(String)): this.misses
    //#input(Object get(String)): this.removes
    //#output(Object get(String)): return_value
    //#output(Object get(String)): this.hits
    //#output(Object get(String)): this.misses
    //#output(Object get(String)): this.removes
    //#pre[8] (Object get(String)): this.cache != null
    //#pre[3] (Object get(String)): (soft) log != null
    //#pre[4] (Object get(String)): (soft) init'ed(this.hits)
    //#pre[5] (Object get(String)): (soft) init'ed(this.misses)
    //#pre[6] (Object get(String)): (soft) init'ed(this.removes)
    //#presumption(Object get(String)): get(...).__Tag == org/apache/roller/weblogger/util/cache/ExpiringCacheEntry
    //#post(Object get(String)): init'ed(return_value)
    //#post(Object get(String)): this.hits == One-of{old this.hits, old this.hits + 1, One-of{old this.hits, old this.hits + 1} - 1}
    //#post(Object get(String)): (soft) init'ed(this.hits)
    //#post(Object get(String)): this.misses == One-of{old this.misses + 1, old this.misses}
    //#post(Object get(String)): init'ed(this.misses)
    //#post(Object get(String)): this.removes == One-of{old this.removes, old this.removes + 1}
    //#post(Object get(String)): (soft) init'ed(this.removes)
    //#unanalyzed(Object get(String)): Effects-of-calling:java.lang.System:currentTimeMillis
    //#unanalyzed(Object get(String)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(Object get(String)): Effects-of-calling:java.util.Map:remove
    //#test_vector(Object get(String)): java.util.Map:get(...)@82: Addr_Set{null}, Inverse{null}
        ExpiringCacheEntry entry = null;
    //#ExpiringLRUCacheImpl.java:75: Warning: unused assignment
    //#    unused assignment into entry
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl
    //#    method: Object get(String)
    //#    Attribs:  Uncertain
        
        synchronized(this) {
            entry = (ExpiringCacheEntry) super.get(key);
        }
        
        if (entry != null) {
            
            value = entry.getValue();
            
            // if the value is null then that means this entry expired
            if (value == null) {
                log.debug("EXPIRED ["+key+"]");
    //#ExpiringLRUCacheImpl.java:87: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl
    //#    method: Object get(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
                hits--;
                super.remove(key);
            }
        }
        
        return value;
    //#ExpiringLRUCacheImpl.java:93: end of method: Object org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl.get(String)
    }
    
}
    //#ExpiringLRUCacheImpl.java:: end of class: org.apache.roller.weblogger.util.cache.ExpiringLRUCacheImpl
