/*
 * 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.domain.DataObjectNotFoundException;
import com.arsdigita.initializer.Configuration;
import com.arsdigita.initializer.InitializationException;
import com.arsdigita.kernel.permissions.PermissionManager;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.TransactionContext;

import java.math.BigDecimal;

/**
 * Base initializer for all WAF applications. Extend this class to
 * implement your own initializer. Runs each initializer in a
 * KernelExcursion with system privileges.
 *
 * @author Richard Li
 */
public abstract class BaseInitializer
    implements com.arsdigita.initializer.Initializer {

    public void startup() throws InitializationException {
        if (Kernel.getSystemParty() == null) {
            final DatabaseTransaction transaction = new DatabaseTransaction();

            transaction.begin();

            setupSystemParty();

            transaction.end();
        }

        KernelExcursion rootExcursion = new KernelExcursion() {
                public void excurse() {
                    setTransaction(new DatabaseTransaction());
                    setEffectiveParty(Kernel.getSystemParty());
                    doStartup();
                }
            };
        rootExcursion.run();
    }

    public void shutdown() throws InitializationException {
        KernelExcursion rootExcursion = new KernelExcursion() {
                public void excurse() {
                    setEffectiveParty(Kernel.getSystemParty());
                    doShutdown();
                }
            };
        rootExcursion.run();
    }

    public abstract Configuration getConfiguration();

    /**
     * Code that should be executed at initializer startup should go
     * inside this method.
     */
    protected abstract void doStartup();

    /**
     * Code that should be executed at initializer shutdown should go
     * inside this method.
     */
    protected abstract void doShutdown();

    private void setupSystemParty() {
        Party party;

        party = new Party
                (new OID(Party.BASE_DATA_OBJECT_TYPE,
                        new BigDecimal(PermissionManager.SYSTEM_PARTY))) {
            public String getName() {
                return "ACS System Party";
            }
        };

        party.disconnect();

        Kernel.setSystemParty(party);
    }

}
