Package org.apache.isis.runtimes.dflt.runtime.system.context

Source Code of org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext

/*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  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.
*/

package org.apache.isis.runtimes.dflt.runtime.system.context;

import java.util.List;

import org.apache.log4j.Logger;

import org.apache.isis.applib.profiles.Localization;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.components.TransactionScopedComponent;
import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.commons.config.IsisConfigurationException;
import org.apache.isis.core.commons.debug.DebugBuilder;
import org.apache.isis.core.commons.debug.DebugList;
import org.apache.isis.core.commons.debug.DebuggableWithTitle;
import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.metamodel.spec.SpecificationLoader;
import org.apache.isis.core.runtime.authentication.AuthenticationManager;
import org.apache.isis.core.runtime.authorization.AuthorizationManager;
import org.apache.isis.core.runtime.imageloader.TemplateImageLoader;
import org.apache.isis.core.runtime.userprofile.UserProfile;
import org.apache.isis.core.runtime.userprofile.UserProfileLoader;
import org.apache.isis.runtimes.dflt.runtime.system.DeploymentType;
import org.apache.isis.runtimes.dflt.runtime.system.persistence.PersistenceSession;
import org.apache.isis.runtimes.dflt.runtime.system.session.IsisSession;
import org.apache.isis.runtimes.dflt.runtime.system.session.IsisSessionFactory;
import org.apache.isis.runtimes.dflt.runtime.system.transaction.IsisTransaction;
import org.apache.isis.runtimes.dflt.runtime.system.transaction.IsisTransactionManager;
import org.apache.isis.runtimes.dflt.runtime.system.transaction.MessageBroker;
import org.apache.isis.runtimes.dflt.runtime.system.transaction.UpdateNotifier;

/**
* Provides singleton <i>access to</i> the current (session scoped)
* {@link IsisSession}, along with convenience methods to obtain
* application-scoped components and also any transaction-scoped components
* {@link TransactionScopedComponent} s if a {@link IsisTransaction}
* {@link IsisSession#getCurrentTransaction() is in progress}.
*
* <p>
* Somewhat analogous to (the static methods in) <tt>HibernateUtil</tt>.
*/
public abstract class IsisContext implements DebuggableWithTitle {

    private static final Logger LOG = Logger.getLogger(IsisContext.class);

    private static IsisContext singleton;

    private final IsisSessionFactory sessionFactory;
    private final ContextReplacePolicy replacePolicy;
    private final SessionClosePolicy sessionClosePolicy;

    private static IsisConfiguration configuration;

    // ///////////////////////////////////////////////////////////
    // Singleton & Constructor
    // ///////////////////////////////////////////////////////////

    /**
     * Returns the singleton providing access to the set of execution contexts.
     */
    public static IsisContext getInstance() {
        return singleton;
    }

    /**
     * Whether a singleton has been created using {@link #getInstance()}.
     */
    public static boolean exists() {
        return singleton != null;
    }

    /**
     * Resets the singleton, so another can created.
     *
     * @see #Isis()
     */
    public static void testReset() {
        singleton = null;
    }

    protected static enum SessionClosePolicy {
        /**
         * Sessions must be explicitly closed.
         */
        EXPLICIT_CLOSE,
        /**
         * Sessions will be automatically closed.
         */
        AUTO_CLOSE;
    }

    /**
     * Whether the {@link IsisContext#getInstance() singleton} itself may be
     * replaced.
     */
    protected static enum ContextReplacePolicy {
        NOT_REPLACEABLE, REPLACEABLE
    }

    /**
     * Creates a new instance of the {@link IsisSession} holder.
     *
     * <p>
     * Will throw an exception if an instance has already been created and is
     * not {@link ContextReplacePolicy#REPLACEABLE}.
     */
    protected IsisContext(final ContextReplacePolicy replacePolicy, final SessionClosePolicy sessionClosePolicy, final IsisSessionFactory sessionFactory) {
        if (singleton != null && !singleton.isContextReplaceable()) {
            throw new IsisException("Isis Context already set up and cannot be replaced");
        }
        singleton = this;
        this.sessionFactory = sessionFactory;
        this.sessionClosePolicy = sessionClosePolicy;
        this.replacePolicy = replacePolicy;
    }

    // ///////////////////////////////////////////////////////////
    // SessionFactory
    // ///////////////////////////////////////////////////////////

    /**
     * As injected in constructor.
     */
    public final IsisSessionFactory getSessionFactoryInstance() {
        return sessionFactory;
    }

    // ///////////////////////////////////////////////////////////
    // Policies
    // ///////////////////////////////////////////////////////////

    /**
     * Whether a context singleton can simply be replaced or not.
     */
    public final boolean isContextReplaceable() {
        return replacePolicy == ContextReplacePolicy.REPLACEABLE;
    }

    /**
     * Whether any open session can be automatically
     * {@link #closeSessionInstance() close}d on
     * {@link #openSessionInstance(AuthenticationSession) open}.
     */
    public final boolean isSessionAutocloseable() {
        return sessionClosePolicy == SessionClosePolicy.AUTO_CLOSE;
    }

    /**
     * Helper method for subclasses' implementation of
     * {@link #openSessionInstance(AuthenticationSession)}.
     */
    protected void applySessionClosePolicy() {
        if (getSessionInstance() == null) {
            return;
        }
        if (!isSessionAutocloseable()) {
            throw new IllegalStateException("Session already open and context not configured for autoclose");
        }
        closeSessionInstance();
    }

    // ///////////////////////////////////////////////////////////
    // open / close / shutdown
    // ///////////////////////////////////////////////////////////

    /**
     * Creates a new {@link IsisSession} and binds into the current context.
     *
     * @throws IllegalStateException
     *             if already opened.
     */
    public abstract IsisSession openSessionInstance(AuthenticationSession session);

    /**
     * Closes the {@link IsisSession} for the current context.
     *
     * <p>
     * Ignored if already closed.
     *
     * <p>
     * This method is <i>not</i> marked <tt>final</tt> so it can be overridden
     * if necessarily. Generally speaking this shouldn't be necessary; one case
     * where it might though is if an implementation has multiple concurrent
     * uses of a session, in which case "closing" the session really means just
     * deregistering the usage of it by a particular thread; only when all
     * threads have finished with a session can it really be closed.
     */
    public void closeSessionInstance() {
        if (getSessionInstance() != null) {
            getSessionInstance().close();
            doClose();
        }
    }

    /**
     * Overridable hook method called from {@link #closeSessionInstance()},
     * allowing subclasses to clean up (for example datastructures).
     *
     * <p>
     * The {@link #getSessionInstance() current} {@link IsisSession} will
     * already have been {@link IsisSession#close() closed}.
     */
    protected void doClose() {
    }

    /**
     * Shutdown the application.
     */
    protected abstract void closeAllSessionsInstance();

    // ///////////////////////////////////////////////////////////
    // getSession()
    // ///////////////////////////////////////////////////////////

    /**
     * Locates the current {@link IsisSession}.
     *
     * <p>
     * This might just be a singleton (eg {@link IsisContextStatic}), or could
     * be retrieved from the thread (eg {@link IsisContextThreadLocal}).
     */
    public abstract IsisSession getSessionInstance();

    /**
     * The {@link IsisSession} for specified {@link IsisSession#getId()}.
     */
    protected abstract IsisSession getSessionInstance(String sessionId);

    /**
     * All known session Ids.
     *
     * <p>
     * Provided primarily for debugging.
     */
    public abstract String[] allSessionIds();

    // ///////////////////////////////////////////////////////////
    // Static Convenience methods (session management)
    // ///////////////////////////////////////////////////////////

    /**
     * Convenience method to open a new {@link IsisSession}.
     *
     * @see #openSessionInstance(AuthenticationSession)
     */
    public static IsisSession openSession(final AuthenticationSession authenticationSession) {
        return getInstance().openSessionInstance(authenticationSession);
    }

    /**
     * Convenience method to close the current {@link IsisSession}.
     *
     * @see #closeSessionInstance()
     */
    public static void closeSession() {
        getInstance().closeSessionInstance();
    }

    /**
     * Convenience method to return {@link IsisSession} for specified
     * {@link IsisSession#getId()}.
     *
     * <p>
     * Provided primarily for debugging.
     *
     * @see #getSessionInstance(String)
     */
    public static IsisSession getSession(final String sessionId) {
        return getInstance().getSessionInstance(sessionId);
    }

    /**
     * Convenience method to close all sessions.
     */
    public static void closeAllSessions() {
        LOG.info("closing all instances");
        final IsisContext instance = getInstance();
        if (instance != null) {
            instance.closeAllSessionsInstance();
        }
    }

    // ///////////////////////////////////////////////////////////
    // Static Convenience methods (application scoped)
    // ///////////////////////////////////////////////////////////

    /**
     * Convenience method returning the {@link IsisSessionFactory} of the
     * current {@link #getSession() session}.
     */
    public static IsisSessionFactory getSessionFactory() {
        return getInstance().getSessionFactoryInstance();
    }

    /**
     * Convenience method.
     *
     * @see IsisSessionFactory#getConfiguration()
     */
    public static IsisConfiguration getConfiguration() {
        if (configuration == null) {
            throw new IsisConfigurationException("No configuration available");
        }
        // REVIEW
        return configuration;
        // return getSessionFactory().getConfiguration();
    }

    public static void setConfiguration(final IsisConfiguration configuration) {
        IsisContext.configuration = configuration;
    }

    /**
     * Convenience method.
     *
     * @see IsisSessionFactory#getDeploymentType()
     */
    public static DeploymentType getDeploymentType() {
        return getSessionFactory().getDeploymentType();
    }

    /**
     * Convenience method.
     *
     * @see IsisSessionFactory#getSpecificationLoader()
     */
    public static SpecificationLoader getSpecificationLoader() {
        return getSessionFactory().getSpecificationLoader();
    }

    /**
     * Convenience method.
     *
     * @see IsisSessionFactory#getAuthenticationManager()
     */
    public static AuthenticationManager getAuthenticationManager() {
        return getSessionFactory().getAuthenticationManager();
    }

    /**
     * Convenience method.
     *
     * @see IsisSessionFactory#getAuthorizationManager()
     */
    public static AuthorizationManager getAuthorizationManager() {
        return getSessionFactory().getAuthorizationManager();
    }

    /**
     * Convenience method.
     *
     * @see IsisSessionFactory#getTemplateImageLoader()
     */
    public static TemplateImageLoader getTemplateImageLoader() {
        return getSessionFactory().getTemplateImageLoader();
    }

    public static UserProfileLoader getUserProfileLoader() {
        return getSessionFactory().getUserProfileLoader();
    }

    public static List<Object> getServices() {
        return getSessionFactory().getServices();
    }

    // ///////////////////////////////////////////////////////////
    // Static Convenience methods (session scoped)
    // ///////////////////////////////////////////////////////////

    public static boolean inSession() {
        final IsisSession session = getInstance().getSessionInstance();
        return session != null;
    }

    /**
     * Convenience method returning the current {@link IsisSession}.
     */
    public static IsisSession getSession() {
        final IsisSession session = getInstance().getSessionInstance();
        if (session == null) {
            throw new IllegalStateException("No Session opened for this thread");
        }
        return session;
    }

    /**
     * Convenience method to return the {@link #getSession() current}
     * {@link IsisSession}'s {@link IsisSession#getId() id}.
     *
     * @see IsisSession#getId()
     */
    public static String getSessionId() {
        return getSession().getId();
    }

    /**
     * @see IsisSession#getAuthenticationSession()
     */
    public static AuthenticationSession getAuthenticationSession() {
        return getSession().getAuthenticationSession();
    }

    /**
     * Convenience method.
     *
     * @see IsisSession#getPersistenceSession()
     */
    public static PersistenceSession getPersistenceSession() {
        return getSession().getPersistenceSession();
    }

    /**
     * Convenience method.
     *
     * @see IsisSession#getUserProfile()
     */
    public static UserProfile getUserProfile() {
        return getSession().getUserProfile();
    }

    /**
     * Convenience method.
     *
     * @see IsisSession#getUserProfile()
     * @see UserProfile#getLocalization()
     */
    public static Localization getLocalization() {
        return getUserProfile().getLocalization();
    }

    /**
     * Convenience methods
     *
     * @see IsisSession#getPersistenceSession()
     * @see PersistenceSession#getTransactionManager()
     */
    public static IsisTransactionManager getTransactionManager() {
        return getPersistenceSession().getTransactionManager();
    }

    // ///////////////////////////////////////////////////////////
    // Static Convenience methods (transaction scoped)
    // ///////////////////////////////////////////////////////////

    public static boolean inTransaction() {
        return inSession() && getCurrentTransaction() != null && !getCurrentTransaction().getState().isComplete();
    }

    /**
     * Convenience method, returning the current {@link IsisTransaction
     * transaction} (if any).
     *
     * <p>
     * Transactions are managed using the {@link IsisTransactionManager}
     * obtainable from the {@link IsisSession's} {@link PersistenceSession}.
     *
     * @see IsisSession#getCurrentTransaction()
     * @see PersistenceSession#getTransactionManager()
     */
    public static IsisTransaction getCurrentTransaction() {
        return getSession().getCurrentTransaction();
    }

    /**
     * Convenience method, returning the {@link MessageBroker} of the
     * {@link #getCurrentTransaction() current transaction}.
     */
    public static MessageBroker getMessageBroker() {
        return getCurrentTransaction().getMessageBroker();
    }

    /**
     * Convenience method, returning the {@link UpdateNotifier} of the
     * {@link #getCurrentTransaction() current transaction}.
     */
    public static UpdateNotifier getUpdateNotifier() {
        return getCurrentTransaction().getUpdateNotifier();
    }

    // ///////////////////////////////////////////////////////////
    // Debug
    // ///////////////////////////////////////////////////////////

    public static DebuggableWithTitle[] debugSystem() {
        final DebugList debugList = new DebugList("Apache Isis System");
        debugList.add("Context", getInstance());
        debugList.add("Apache Isis session factory", getSessionFactory());
        debugList.add("  Authentication manager", getSessionFactory().getAuthenticationManager());
        debugList.add("  Persistence session factory", getSessionFactory().getPersistenceSessionFactory());
        debugList.add("User profile loader", getUserProfileLoader());

        debugList.add("Reflector", getSpecificationLoader());
        debugList.add("Template image loader", getTemplateImageLoader());

        debugList.add("Deployment type", getDeploymentType().getDebug());
        debugList.add("Configuration", getConfiguration());

        debugList.add("Services", getServices());
        return debugList.debug();
    }

    public static DebuggableWithTitle[] debugSession() {
        final DebugList debugList = new DebugList("Apache Isis Session");
        debugList.add("Apache Isis session", getSession());
        debugList.add("Authentication session", getAuthenticationSession());
        debugList.add("User profile", getUserProfile());

        debugList.add("Persistence Session", getPersistenceSession());
        debugList.add("Transaction Manager", getTransactionManager());

        debugList.add("Service injector", getPersistenceSession().getServicesInjector());
        debugList.add("Adapter factory", getPersistenceSession().getAdapterFactory());
        debugList.add("Object factory", getPersistenceSession().getObjectFactory());
        debugList.add("OID generator", getPersistenceSession().getOidGenerator());
        debugList.add("Adapter manager", getPersistenceSession().getAdapterManager());
        debugList.add("Services", getPersistenceSession().getServices());
        return debugList.debug();
    }

    @Override
    public void debugData(final DebugBuilder debug) {
        debug.appendln("context ", this);
    }

}
TOP

Related Classes of org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.