/*
 * Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * 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.
 *
 */
package com.arsdigita.kernel;

import com.arsdigita.util.Assert;

import org.apache.log4j.Logger;

import java.math.BigDecimal;
import javax.servlet.ServletRequest;

/**
 * A centralized cache for {@link ACSObject ACSObjects}. At present, it
 * only supports caching of objects in the request. Evenutally, it should
 * support caching objects as request, session and request attributes.
 *
 * <p> For request-scope caching, objects are stored as attributes of the
 * {@link ServletRequest}. The name of the attribute only depends on the
 * object's ID, so that only one copy of each object is stored.
 *
 * @author David Lutterkort
 * @version $Id: //core-platform/dev/src/com/arsdigita/kernel/ACSObjectCache.java#9 $
 */
public class ACSObjectCache {

    private static final Logger s_log =
        Logger.getLogger(ACSObjectCache.class.getName());

    private ACSObjectCache() {
        // nothing, constructor only here to keep people from instantiating
        // this object.
    }

    //
    // Caching of ACSObject in the request attribute
    //
    // FIXME: This should probably go into a separate class

    /**
     * Return the name of the request attribute used to cache the
     * <code>ACSObject</code> with id <code>key</code>. If this is called
     * with two different objects <code>k1</code> and <code>k2</code>, the
     * returned strings will be identical whenever
     * <code>k1.toString().equals(k2.toString())</code>.
     */
    private static String attributeName(Object key) {
        return ACSObject.BASE_DATA_OBJECT_TYPE + ":" + key.toString();
    }

    /**
     * Store <code>obj</code> as a request attribute.
     *
     * @param req the request, in which the object is to be cached.
     * @param obj the object to cache.
     * @pre req != null
     * @pre obj != null &&& obj.getID() != null
     * @post obj.equals(getRequestCache(req, obj.getID()))
     */
    public static void set(ServletRequest req, ACSObject obj) {
        Assert.assertNotNull(req);
        Assert.assertNotNull(obj);
        Assert.assertNotNull(obj.getID());
        req.setAttribute(attributeName(obj.getID()), obj);
    }

    /**
     * Get the <code>ACSObject</code> with ID <code>id</code> from the
     * request <code>req</code>. Return <code>null</code> if the object has
     * not been put into the cache.  If the ID is null then this will
     * return null.
     *
     * @param req the request, in which the object is to be cached.
     * @param id an <code>Object</code> value
     * @return an <code>ACSObject</code> value or null if the id is null
     */
    public static ACSObject get(ServletRequest req, BigDecimal id) {
        if (id == null) {
            return null;
        }
        ACSObject result =  (ACSObject) req.getAttribute(attributeName(id));
        return result;
    }

}
