/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is Protege-2000.
 *
 * The Initial Developer of the Original Code is Stanford University. Portions
 * created by Stanford University are Copyright (C) 2007.  All Rights Reserved.
 *
 * Protege was developed by Stanford Medical Informatics
 * (http://www.smi.stanford.edu) at the Stanford University School of Medicine
 * with support from the National Library of Medicine, the National Science
 * Foundation, and the Defense Advanced Research Projects Agency.  Current
 * information about Protege can be obtained at http://protege.stanford.edu.
 *
 */

package edu.stanford.smi.protege.util.transaction.cache.impl;

import java.util.HashMap;
import java.util.Map;

import edu.stanford.smi.protege.util.transaction.cache.Cache;
import edu.stanford.smi.protege.util.transaction.cache.CacheResult;

/**
 * This is a basic cache that 
 *  - ignores the impact of transactions on the cache.  
 *  - ignores deletion functionality
 *  - ignore the cache completion mechanism (at least this one is correct...) 
 *  
 * It will only return 
 * valid results in the case that the transaction isolation level is NONE or where
 * the caller covers the in transaction case.
 * 
 * @author tredmond
 *
 */
public class BasicCache<S, V, R> implements Cache<S, V, R> {
    private Map<V, R> cache = new HashMap<V, R>();
    private Map<S, Integer> transactionNestingMap = new HashMap<S, Integer>();
    
    
    public CacheResult<R> readCache(S session, V var) {
        return new CacheResult<R>(cache.get(var), cache.containsKey(var));
    }

    public void updateCache(S session, V var) {
        ;
    }

    public void updateCache(S session, V var, R value) {
        cache.put(var, value);
    }

    public void modifyCache(S session, V var) {
        cache.remove(var);
    }

    public void modifyCache(S session, V var, R value) {
        cache.put(var, value);
    }
    
    public void delete(S session) {
        
    }
    
    public boolean isDeleted() {
        return false;
    }

    public void startCompleteCache() {
        ;
    }

    public void finishCompleteCache() {
        
    }
    
    public void abortCompleteCache() {
        ;
    }
    
    public boolean isCacheComplete() {
        return false;
    }

    public void beginTransaction(S session) {
        Integer nesting = transactionNestingMap.get(session);
        if (nesting == null) {
            transactionNestingMap.put(session, 1);
            return;
        }
        transactionNestingMap.put(session, nesting + 1);
    }

    public void commitTransaction(S session) {
        decrementTransaction(session);
    }
    
    public void rollbackTransaction(S session) {
        decrementTransaction(session);
    }
    
    private void decrementTransaction(S session) {
        Integer nesting = transactionNestingMap.get(session);
        if (nesting == null)  {
            ;
        }
        else if (nesting == 1) {
            transactionNestingMap.remove(session);
        }
        else {
            transactionNestingMap.put(session, nesting - 1);
        }
    }
    
    public int getTransactionNesting(S session) {
        Integer nesting = transactionNestingMap.get(session);
        if (nesting == null) {
            return 0;
        }
        return nesting;
    }

    public void flush() {
        transactionNestingMap.clear();
        cache.clear();
    }


}
