/*
 * Copyright (C) 2003-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.packaging;

import com.arsdigita.runtime.*;

/**
 * The Check class provides a developer callback for performing
 * validation checks during various points in the package loading and
 * server startup process. This functionality is accessed by creating
 * a <i>package-key</i>.checklist file in the src dir of the package
 * that wishes to add checks. This must be a valid xml file that
 * conforms to the following format:
 *
 * <blockquote><pre>
 * &lt;checklist&gt;
 *   &lt;checks type="schema"&gt;
 *     &lt;check class="com.example.Check1"/&gt;
 *     &lt;check class="com.example.Check2"/&gt;
 *     ...
 *   &lt;/checks&gt;
 *   &lt;checks type="data"&gt;
 *     ...
 *   &lt;/checks&gt;
 *   &lt;checks type="startup"&gt;
 *     ...
 *   &lt;/checks&gt;
 * &lt;/checklist&gt;
 * </pre></blockquote>
 *
 * Checks of type "schema" will be run before the schema for a package
 * is loaded. Checks of type "data" will be run before the data for a
 * package is loaded. Checks of type "startup" will be run before the
 * server is started. All these checks will be run by the "ccm status"
 * command.
 *
 * The classes referred to from the checklist file must be concrete
 * subclasses of the Check class. They must also provide a public
 * noargs constructor. A check is performed by first creating an
 * instance of the specified class using the public noargs constructor
 * and then invoking the {@link #run(ScriptContext)} method. The check
 * must report success or failure using the {@link #status(Status)}
 * method.
 *
 * Checks will be invoked in the order in which they appear inside the
 * <checks> tags. If any one of the checks fail, the remaining checks
 * that appear within the containing <checks> tags will not be
 * performed.
 *
 * @author Rafael H. Schloming &lt;rhs@mit.edu&gt;
 * @version $Revision: #4 $ $Date: 2004/04/07 $
 **/

public abstract class Check extends AbstractScript {

    public final static String versionId = "$Id: //core-platform/dev/src/com/arsdigita/packaging/Check.java#4 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";

    public static final class Status {

        private String m_name;

        private Status(String name) {
            m_name = name;
        }

        public String toString() {
            return m_name;
        }

    };

    public static final Status PASS = new Status("pass");
    public static final Status FAIL = new Status("fail");
    public static final Status WARN = new Status("warn");

    private Status m_status = null;

    /**
     * Used by subclasses to report the result of the Check. This
     * method can be called at most once by a particular instance of
     * the Check class.
     *
     * @param status The status, one of PASS, FAIL, or WARN.
     **/

    protected void status(Status status) {
        if (m_status == null) {
            m_status = status;
        } else {
            throw new IllegalStateException("status called twice");
        }
    }

    /**
     * Accesses the status of the previous invocation of the {@link
     * #run(ScriptContext)} method.
     *
     * @return The status, one of PASS, FAIL, or WARN.
     **/

    public Status getStatus() {
        return m_status;
    }

}
