/*
 * 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.formbuilder.installer;

import com.arsdigita.formbuilder.BebopObjectType;
import com.arsdigita.formbuilder.MetaObject;

import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.TransactionContext;
import com.arsdigita.initializer.Configuration;
import com.arsdigita.initializer.InitializationException;
import com.arsdigita.formbuilder.PersistentProcessListener;
import com.arsdigita.kernel.BaseInitializer;
import java.util.Iterator;
import java.util.List;

import com.arsdigita.formbuilder.PersistentDataQuery;
import com.arsdigita.formbuilder.PersistentComponent;

/**
 * Initializer
 *
 * @author <a href="mailto:berrange@redhat.com">Daniel Berrange</a>
 * @version $Revision: #9 $ $Date: 2004/04/07 $
 */

public class Initializer extends BaseInitializer {
    public static String WIDGET_TYPES = "widgetTypes";
    public static String PROCESS_LISTENER_TYPES = "processListenerTypes";
    public static String DATA_QUERIES = "dataQueries";

    private Configuration m_conf = new Configuration();

    public Initializer() throws InitializationException {
        m_conf.initParameter
            (WIDGET_TYPES,
             "The persistent widget types",
             List.class);
        m_conf.initParameter
            (PROCESS_LISTENER_TYPES,
             "The persistent process listener types",
             List.class);
        m_conf.initParameter
            (DATA_QUERIES,
             "The queries for the data driven select box",
             List.class);
    }

    /**
     * Returns the configuration object used by this initializer.
     **/

    public Configuration getConfiguration() {
        return m_conf;
    }


    /**
     * Called on startup. Note. As you can not find a call
     * to this method in enterprise.ini, this method
     * may appear to execute mysteriously.
     * However, the process that runs through enterprise.ini
     * automitically calls the startup() method of any
     * class that implements com.arsdigita.util.initializer.Initializer
     * present in enterprise.ini
     *
     **/


    protected void doStartup() {

        TransactionContext txn = SessionManager.getSession()
            .getTransactionContext();
        txn.beginTxn();

        List widgets = (List)m_conf.getParameter(WIDGET_TYPES);
        if (widgets != null)
            loadMetaObjects(widgets, PersistentComponent.class);

        List listeners = (List)m_conf.getParameter(PROCESS_LISTENER_TYPES);
        if (listeners != null)
            loadMetaObjects(listeners, PersistentProcessListener.class);

        List queries = (List)m_conf.getParameter(DATA_QUERIES);
        if (queries != null)
            loadDataQueries(queries);

        txn.commitTxn();
    }


    /**
     * Called on shutdown. It's probably not a good idea to depend on this
     * being called.
     **/

    protected void doShutdown() {
    }

    public BebopObjectType getObjectType(String name,
                                         Class type) {
        BebopObjectType objectType = null;
        try {
            objectType = BebopObjectType.findByClass(name,
                                                     type);
        } catch (DataObjectNotFoundException ex) {
            objectType = BebopObjectType.create(name,
                                                type);
            objectType.save();
        }
        return objectType;
    }

    protected void loadMetaObjects(List objects,
                                   Class type)
        throws InitializationException {

        // XXX we don't yet delete types which are no longer in the list
        Iterator objects_i = objects.iterator();
        while (objects_i.hasNext()) {
            List object = (List)objects_i.next();

            String appName = (String)object.get(0);
            String prettyName = (String)object.get(1);
            String prettyPlural = (String)object.get(2);
            String className = (String)object.get(3);
            String propertiesForm = (String)object.get(4);

            try {
                Class.forName(className);
            } catch (ClassNotFoundException ex) {
                throw new InitializationException("cannot find class " + className);
            }
            try {
                Class.forName(propertiesForm);
            } catch (ClassNotFoundException ex) {
                throw new InitializationException("cannot find class " + propertiesForm);
            }

            try {
                MetaObject mo = MetaObject.findByClassName(getObjectType(appName,
                                                                         type),
                                                           className);

                mo.setPrettyName(prettyName);
                mo.setPrettyPlural(prettyPlural);
                mo.setWidgetClassName(className);
                mo.setPropertiesFormName(propertiesForm);

                mo.save();
            } catch (DataObjectNotFoundException ex) {
                MetaObject mo = MetaObject.create(getObjectType(appName,
                                                                type),
                                                  prettyName,
                                                  prettyPlural,
                                                  className,
                                                  propertiesForm);
                mo.save();
            }
        }
    }
    protected void loadDataQueries(List objects)
        throws InitializationException {

        // XXX we don't yet delete types which are no longer in the list
        Iterator objects_i = objects.iterator();
        while (objects_i.hasNext()) {
            List object = (List)objects_i.next();

            String appName = (String)object.get(0);
            String name = (String)object.get(1);
            String description = (String)object.get(2);

            try {
                PersistentDataQuery q = PersistentDataQuery.findByName(getObjectType(appName,
                                                                                     PersistentDataQuery.class),
                                                                       name);

                q.setName(name);
                q.setDescription(description);

                q.save();
            } catch (DataObjectNotFoundException ex) {
                PersistentDataQuery q = PersistentDataQuery.create(getObjectType(appName,
                                                                                 PersistentDataQuery.class),
                                                                   description, name);
                q.save();
            }
        }
    }

}
