/*
 * 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 java.util.Locale;

import org.apache.log4j.Logger;

/**
 *
 * <p>The entry point into all the global state that CCM code expects to
 * have available to it when running, e.g. the current user, the
 * current resource, etc.</p>
 *
 * <p>This is a session object that provides an environment in which
 * code can execute. The KernelContext contains all session-specific
 * variables.  One session object is maintained per thread.</p>
 *
 * <p>Accessors of this class may return null.  Developers should take
 * care to trap null return values in their code.</p>
 *
 * @author Rafael Schloming
 * @author Richard Li
 * @author Justin Ross
 * @see com.arsdigita.kernel.Kernel
 * @see com.arsdigita.kernel.KernelExcursion
 */
public final class KernelContext {
    public static final String versionId =
        "$Id: //core-platform/dev/src/com/arsdigita/kernel/KernelContext.java#22 $" +
        "$Author: dennis $" +
        "$DateTime: 2004/04/07 16:07:11 $";

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

    private Resource m_resource = null;
    private Party m_party = null;
    private Party m_effectiveParty = null;
    private Locale m_locale = null;
    private String m_sessionID = null;
    private DatabaseTransaction m_transaction = null;

    KernelContext() {
        // Empty.
    }

    public final String getDebugInfo() {
        String info = "Current state of " + this + ":\n" +
            "           getResource() -> " + getResource() + "\n" +
            "              getParty() -> " + getParty() + "\n" +
            "     getEffectiveParty() -> " + getEffectiveParty() + "\n" +
            "             getLocale() -> " + getLocale() + "\n" +
            "          getSessionID() -> " + getSessionID() + "\n" +
            "        getTransaction() -> " + getTransaction();

        return info;
    }

    final KernelContext copy() {
        KernelContext result = new KernelContext();

        result.m_resource = m_resource;
        result.m_party = m_party;
        result.m_effectiveParty = m_effectiveParty;
        result.m_locale = m_locale;
        result.m_sessionID = m_sessionID;
        result.m_transaction = m_transaction;

        return result;
    }

    /**
     * @return the currently selected resource.
     */
    public final Resource getResource() {
        return m_resource;
    }

    final void setResource(Resource resource) {
        m_resource = resource;

        if (s_log.isDebugEnabled()) {
            s_log.debug("Resource set to " + resource);
        }
    }

    /**
     * @return the party that is actually executing the session.
     */
    public final Party getParty() {
        return m_party;
    }

    final void setParty(Party party) {
        m_party = party;

        if (s_log.isDebugEnabled()) {
            s_log.debug("Party set to " + party);
        }
    }

    /**
     * The effective party is the party under which you want a
     * particular set of operations to take place. This is useful when
     * you are running code under a context but need part of that code
     * to run under the guise of a different user (for example,
     * PUBLIC, ADMIN).
     *
     * @return the party assuming the role of the current party.
     */
    public final Party getEffectiveParty() {
        if (m_effectiveParty == null) {
            return m_party;
        } else {
            return m_effectiveParty;
        }
    }

    final void setEffectiveParty(Party party) {
        m_effectiveParty = party;

        if (s_log.isDebugEnabled()) {
            s_log.debug("Effective party set to " + m_effectiveParty);
        }
    }

    /**
     * @return the locale for the current session
     */
    public final Locale getLocale() {
        return m_locale;
    }

    final void setLocale(Locale locale) {
        m_locale = locale;

        if (s_log.isDebugEnabled()) {
            s_log.debug("Locale set to " + m_locale);
        }
    }

    /**
     * @return the ID of the current session.
     */
    public final String getSessionID() {
        return m_sessionID;
    }

    final void setSessionID(String sessionID) {
        m_sessionID = sessionID;

        if (s_log.isDebugEnabled()) {
            s_log.debug("Session ID set to " + m_sessionID);
        }
    }

    /**
     * @return the current database transaction.
     */
    public final DatabaseTransaction getTransaction() {
        return m_transaction;
    }

    final void setTransaction(final DatabaseTransaction transaction) {
        m_transaction = transaction;

        if (s_log.isDebugEnabled()) {
            s_log.debug("Transaction set to " + m_transaction);
        }
    }
}
