Package org.apache.isis.core.runtime.system

Source Code of org.apache.isis.core.runtime.system.IsisSystemFixturesHookAbstract

/*
*  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.core.runtime.system;

import java.io.File;
import java.util.Collection;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.isis.applib.fixtures.LogonFixture;
import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.commons.debug.DebugBuilder;
import org.apache.isis.core.commons.debug.DebuggableWithTitle;
import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
import org.apache.isis.core.metamodel.specloader.ServiceInitializer;
import org.apache.isis.core.runtime.about.AboutIsis;
import org.apache.isis.core.runtime.authentication.AuthenticationManager;
import org.apache.isis.core.runtime.authentication.exploration.ExplorationSession;
import org.apache.isis.core.runtime.authorization.AuthorizationManager;
import org.apache.isis.core.runtime.installerregistry.InstallerLookup;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.internal.InitialisationSession;
import org.apache.isis.core.runtime.system.internal.IsisLocaleInitializer;
import org.apache.isis.core.runtime.system.internal.IsisTimeZoneInitializer;
import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
import org.apache.isis.core.runtime.system.session.IsisSession;
import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
import org.apache.isis.core.runtime.system.transaction.IsisTransactionManagerException;

/**
* An implementation of {@link IsisSystem} that has a hook for installing
* fixtures but does not install them itself.
*/
public abstract class IsisSystemFixturesHookAbstract implements IsisSystem {

    public static final Logger LOG = LoggerFactory.getLogger(IsisSystemFixturesHookAbstract.class);

    private final IsisLocaleInitializer localeInitializer;
    private final IsisTimeZoneInitializer timeZoneInitializer;
    private final DeploymentType deploymentType;

    private boolean initialized = false;

    private IsisSessionFactory sessionFactory;

    private ServiceInitializer serviceInitializer;

    // ///////////////////////////////////////////
    // Constructors
    // ///////////////////////////////////////////

    public IsisSystemFixturesHookAbstract(final DeploymentType deploymentType) {
        this(deploymentType, new IsisLocaleInitializer(), new IsisTimeZoneInitializer());
    }

    public IsisSystemFixturesHookAbstract(final DeploymentType deploymentType, final IsisLocaleInitializer localeInitializer, final IsisTimeZoneInitializer timeZoneInitializer) {
        this.deploymentType = deploymentType;
        this.localeInitializer = localeInitializer;
        this.timeZoneInitializer = timeZoneInitializer;
    }

    // ///////////////////////////////////////////
    // DeploymentType
    // ///////////////////////////////////////////

    @Override
    public DeploymentType getDeploymentType() {
        return deploymentType;
    }

    // ///////////////////////////////////////////
    // init, shutdown
    // ///////////////////////////////////////////

    @Override
    public void init() {

        if (initialized) {
            throw new IllegalStateException("Already initialized");
        } else {
            initialized = true;
        }

        LOG.info("initialising Isis System");
        LOG.info("working directory: " + new File(".").getAbsolutePath());
        LOG.info("resource stream source: " + getConfiguration().getResourceStreamSource());

        localeInitializer.initLocale(getConfiguration());
        timeZoneInitializer.initTimeZone(getConfiguration());

        try {
            sessionFactory = doCreateSessionFactory(deploymentType);

            // temporarily make a configuration available
            // REVIEW: would rather inject this, or perhaps even the
            // ConfigurationBuilder
            IsisContext.setConfiguration(getConfiguration());

            initContext(sessionFactory);
            sessionFactory.init();

            serviceInitializer = initializeServices();

            installFixturesIfRequired();

        } catch (final IsisSystemException ex) {
            LOG.error("failed to initialise", ex);
            throw new RuntimeException(ex);
        }
    }

    private void initContext(final IsisSessionFactory sessionFactory) {
        getDeploymentType().initContext(sessionFactory);
    }

    /**
     * @see #shutdownServices(ServiceInitializer)
     */
    private ServiceInitializer initializeServices() {

        final List<Object> services = sessionFactory.getServices();
       
//        // autowire
//        final ServicesInjectorDefault servicesInjector = new ServicesInjectorDefault();
//        servicesInjector.setSpecificationLookup(sessionFactory.getSpecificationLoader());
//        servicesInjector.setServices(services);
//        servicesInjector.init();

        // validate
        final ServiceInitializer serviceInitializer = new ServiceInitializer();
        serviceInitializer.validate(getConfiguration(), services);

        // call @PostConstruct (in a session)
        IsisContext.openSession(new InitialisationSession());
        try {
            getTransactionManager().startTransaction();
            try {
                serviceInitializer.postConstruct();
               
                return serviceInitializer;
            } catch(RuntimeException ex) {
                getTransactionManager().getTransaction().setAbortCause(new IsisTransactionManagerException(ex));
                return serviceInitializer;
            } finally {
                // will commit or abort
                getTransactionManager().endTransaction();
            }
        } finally {
            IsisContext.closeSession();
        }
    }


    @Override
    public void shutdown() {
        LOG.info("shutting down system");
       
        shutdownServices(this.serviceInitializer);
       
        IsisContext.closeAllSessions();
    }

    /**
     * @see #initializeServices()
     */
    private void shutdownServices(final ServiceInitializer serviceInitializer) {
       
        // call @PostDestroy (in a session)
        IsisContext.openSession(new InitialisationSession());
        try {
            getTransactionManager().startTransaction();
            try {
                serviceInitializer.preDestroy();
               
            } catch(RuntimeException ex) {
                getTransactionManager().getTransaction().setAbortCause(new IsisTransactionManagerException(ex));
            } finally {
                // will commit or abort
                getTransactionManager().endTransaction();
            }
        } finally {
            IsisContext.closeSession();
        }
    }
   
    // ///////////////////////////////////////////
    // Hook:
    // ///////////////////////////////////////////

    /**
     * Hook method; the returned implementation is expected to use the same
     * general approach as the subclass itself.
     *
     * <p>
     * So, for example, <tt>IsisSystemUsingInstallers</tt> uses the
     * {@link InstallerLookup} mechanism to find its components. The
     * corresponding <tt>ExecutionContextFactoryUsingInstallers</tt> object
     * returned by this method should use {@link InstallerLookup} likewise.
     */
    protected abstract IsisSessionFactory doCreateSessionFactory(final DeploymentType deploymentType) throws IsisSystemException;

    // ///////////////////////////////////////////
    // Configuration
    // ///////////////////////////////////////////

    /**
     * Populated after {@link #init()}.
     */
    @Override
    public IsisSessionFactory getSessionFactory() {
        return sessionFactory;
    }

    // ///////////////////////////////////////////
    // Configuration
    // ///////////////////////////////////////////

    @Override
    public abstract IsisConfiguration getConfiguration();


    // ///////////////////////////////////////////
    // OidMarshaller
    // ///////////////////////////////////////////

    /**
     * Just returns a {@link OidMarshaller}; subclasses may override if
     * required.
     */
    protected OidMarshaller obtainOidMarshaller() {
        return new OidMarshaller();
    }

    // ///////////////////////////////////////////
    // Reflector
    // ///////////////////////////////////////////

    protected abstract SpecificationLoaderSpi obtainSpecificationLoaderSpi(DeploymentType deploymentType, Collection<MetaModelRefiner> metaModelRefiners) throws IsisSystemException;

    // ///////////////////////////////////////////
    // PersistenceSessionFactory
    // ///////////////////////////////////////////

    protected abstract PersistenceSessionFactory obtainPersistenceSessionFactory(DeploymentType deploymentType) throws IsisSystemException;

    // ///////////////////////////////////////////
    // Fixtures (hooks)
    // ///////////////////////////////////////////

    /**
     * Optional hook for appending debug information pertaining to fixtures
     * installer if required.
     */
    protected void appendFixturesInstallerDebug(final DebugBuilder debug) {
    }

    /**
     * The {@link LogonFixture}, if any, obtained by running fixtures.
     *
     * <p>
     * Intended to be used when for {@link DeploymentType#SERVER_EXPLORATION
     * exploration} (instead of an {@link ExplorationSession}) or
     * {@link DeploymentType#SERVER_PROTOTYPE prototype} deployments (saves logging
     * in). Should be <i>ignored</i> in other {@link DeploymentType}s.
     *
     * <p>
     * This implementation always returns <tt>null</tt>.
     */
    @Override
    public LogonFixture getLogonFixture() {
        return null;
    }

    /**
     * Optional hook for installing fixtures.
     *
     * <p>
     * This implementation does nothing.
     */
    protected void installFixturesIfRequired() throws IsisSystemException {
    }

    // ///////////////////////////////////////////
    // Authentication & Authorization Manager
    // ///////////////////////////////////////////

    protected abstract AuthenticationManager obtainAuthenticationManager(DeploymentType deploymentType) throws IsisSystemException;

    protected abstract AuthorizationManager obtainAuthorizationManager(final DeploymentType deploymentType);

    // ///////////////////////////////////////////
    // Services
    // ///////////////////////////////////////////

    protected abstract List<Object> obtainServices();


    // ///////////////////////////////////////////
    // debugging
    // ///////////////////////////////////////////

    private void debug(final DebugBuilder debug, final Object object) {
        if (object instanceof DebuggableWithTitle) {
            final DebuggableWithTitle d = (DebuggableWithTitle) object;
            debug.appendTitle(d.debugTitle());
            d.debugData(debug);
        } else {
            debug.appendln(object.toString());
            debug.appendln("... no further debug information");
        }
    }

    @Override
    public DebuggableWithTitle debugSection(final String selectionName) {
        // DebugInfo deb;
        if (selectionName.equals("Configuration")) {
            return getConfiguration();
        } /*
           * else if (selectionName.equals("Overview")) { debugOverview(debug);
           * } else if (selectionName.equals("Authenticator")) { deb =
           * IsisContext.getAuthenticationManager(); } else if
           * (selectionName.equals("Reflector")) { deb =
           * IsisContext.getSpecificationLoader(); } else if
           * (selectionName.equals("Contexts")) { deb =
           * debugListContexts(debug); } else { deb =
           * debugDisplayContext(selectionName, debug); }
           */
        return null;
    }

    private void debugDisplayContext(final String selector, final DebugBuilder debug) {
        final IsisSession d = IsisContext.getSession(selector);
        if (d != null) {
            d.debugAll(debug);
        } else {
            debug.appendln("No context: " + selector);
        }
    }

    private void debugListContexts(final DebugBuilder debug) {
        final String[] contextIds = IsisContext.getInstance().allSessionIds();
        for (final String contextId : contextIds) {
            debug.appendln(contextId);
            debug.appendln("-----");
            final IsisSession d = IsisContext.getSession(contextId);
            d.debug(debug);
            debug.appendln();
        }
    }

    @Override
    public String[] debugSectionNames() {
        final String[] general = new String[] { "Overview", "Authenticator", "Configuration", "Reflector", "Requests", "Contexts" };
        final String[] contextIds = IsisContext.getInstance().allSessionIds();
        final String[] combined = new String[general.length + contextIds.length];
        System.arraycopy(general, 0, combined, 0, general.length);
        System.arraycopy(contextIds, 0, combined, general.length, contextIds.length);
        return combined;
    }

    private void debugOverview(final DebugBuilder debug) {
        try {
            debug.appendln(AboutIsis.getFrameworkName());
            debug.appendln(AboutIsis.getFrameworkVersion());
            if (AboutIsis.getApplicationName() != null) {
                debug.appendln("application: " + AboutIsis.getApplicationName());
            }
            if (AboutIsis.getApplicationVersion() != null) {
                debug.appendln("version" + AboutIsis.getApplicationVersion());
            }

            final String user = System.getProperty("user.name");
            final String system = System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ") " + System.getProperty("os.version");
            final String java = System.getProperty("java.vm.name") + " " + System.getProperty("java.vm.version");
            debug.appendln("user: " + user);
            debug.appendln("os: " + system);
            debug.appendln("java: " + java);
            debug.appendln("working directory: " + new File(".").getAbsolutePath());

            debug.appendTitle("System Installer");
            appendFixturesInstallerDebug(debug);

            debug.appendTitle("System Components");
            debug.appendln("Authentication manager", IsisContext.getAuthenticationManager().getClass().getName());
            debug.appendln("Configuration", getConfiguration().getClass().getName());

            final DebuggableWithTitle[] inf = IsisContext.debugSystem();
            for (final DebuggableWithTitle element : inf) {
                if (element != null) {
                    element.debugData(debug);
                }
            }
        } catch (final RuntimeException e) {
            debug.appendException(e);
        }
    }

    IsisTransactionManager getTransactionManager() {
        return IsisContext.getTransactionManager();
    }


}
TOP

Related Classes of org.apache.isis.core.runtime.system.IsisSystemFixturesHookAbstract

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.