/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2005 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.webapp.jonasadmin.xml.xs.hardcoded;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.ow2.jonas.webapp.jonasadmin.xml.xs.ElementRestrictions;
import org.ow2.jonas.webapp.jonasadmin.xml.xs.SchemaRestrictions;


/**
 * An implementation of SchemaRestrictions where the restrictions are not
 * retrieved from the schema but hard coded inside the class.
 *
 * @author Gregory Lapouchnian
 * @author Patrick Smith
 */
public class HCSchemaRestrictions implements SchemaRestrictions {

    /** The elements of this schema restriction. */
    private HashMap elements;

    /**
     * Create a new hard coded schema restriction.
     * @param documentType the document type.
     */
    public HCSchemaRestrictions(int documentType) {
        elements = new HashMap();

        if (documentType == RAR_TYPE) {
            populateJonasConnectorXSD();
            populateConnectorXSD();
        }
    }

    /**
     * Populate the connector XSD restrictions.
     */
    protected void populateConnectorXSD() {
        populateConfigProperty();
        populateResourceAdapter();
        populateConnector();
        populateOutboundResourceAdapter();
        populateInboundResourceAdapter();
        populateLicense();
        populateConnectionDefinition();
        populateAuthenticationMechanism();
        populateMessageAdapter();
        populateMessageListener();
        populateActivationSpec();
        populateRequiredConfigProperty();
    }

    /**
     * populate the jonas connector xsd restrictions.
     */
    protected void populateJonasConnectorXSD() {
        populateJonasConnector();
        populatePoolParams();
        populateJdbcConnParams();
        populateTmParams();
        populateTmConfigProperty();
        populateJonasConfigProperty();
        populateJonasConnectionDefinition();
        populateJonasActivationSpec();
        populateJonasAdminObject();
        populateJonasSecurityMapping();
        populateSecurityEntry();
    }

    /**
     * Populate the jonas connector restrictions
     *
     */
    protected void populateJonasConnector() {
        List children = new ArrayList();
        children.add("jndi-name");
        children.add("rarlink");
        children.add("native-lib");
        children.add("log-enabled");
        children.add("log-topic");
        children.add("pool-params");
        children.add("jdbc-conn-params");
        children.add("tm-params");
        children.add("jonas-config-property");
        children.add("jonas-connection-definition");
        children.add("jonas-activationspec");
        children.add("jonas-adminobject");
        children.add("jonas-security-mapping");
        ElementRestrictions el = new HCElementRestrictions("jonas-connector",
                true, children, null);
        el.setSequence(true);
        elements.put("jonas-connector", el);
    }

    /**
     * Populate the poolparams restrictions
     *
     */
    protected void populatePoolParams() {
        List children = new ArrayList();
        children.add("pool-init");
        children.add("pool-min");
        children.add("pool-max");
        children.add("pool-max-age");
        children.add("pool-max-age-minutes");
        children.add("pstmt-max");
        children.add("pool-max-opentime");
        children.add("pool-max-waiters");
        children.add("pool-max-waittime");
        children.add("pool-sampling-period");
        ElementRestrictions el = new HCElementRestrictions("pool-params", true,
                children, null);
        el.setSequence(true);
        elements.put("pool-params", el);
    }

    /**
     * Populate the jdbc-conn-params restrictions
     *
     */
    protected void populateJdbcConnParams() {
        List children = new ArrayList();
        children.add("jdbc-check-level");
        children.add("jdbc-test-statement");
        ElementRestrictions el = new HCElementRestrictions("jdbc-conn-params",
                true, children, null);
        el.setSequence(true);
        elements.put("jdbc-conn-params", el);
    }

    /**
     * Populate the tm-params restrictions
     *
     */
    protected void populateTmParams() {
        List children = new ArrayList();
        children.add("tm-config-property");
        ElementRestrictions el = new HCElementRestrictions("tm-params", true,
                children, null);
        el.setSequence(true);
        elements.put("tm-params", el);
    }

    /**
     * Populate the tm-config-property restrictions
     *
     */
    protected void populateTmConfigProperty() {
        List children = new ArrayList();
        children.add("tm-config-property-name");
        children.add("tm-config-property-value");
        ElementRestrictions el = new HCElementRestrictions(
                "tm-config-property", true, children, null);
        el.setSequence(true);
        elements.put("tm-config-property", el);
    }

    /**
     * Populate the jonas-config-property restrictions
     *
     */
    protected void populateJonasConfigProperty() {
        List children = new ArrayList();
        children.add("jonas-config-property-name");
        children.add("jonas-config-property-value");
        ElementRestrictions el = new HCElementRestrictions(
                "jonas-config-property", true, children, null);
        el.setSequence(true);
        elements.put("jonas-config-property", el);
    }

    /**
     * Populate the jonas-connection-definition restrictions
     *
     */
    protected void populateJonasConnectionDefinition() {
        List children = new ArrayList();
        children.addAll(populateConfigurationGroup());
        children.add("log-enabled");
        children.add("log-topic");
        children.add("pool-params");
        children.add("jdbc-conn-params");
        ElementRestrictions el = new HCElementRestrictions(
                "jonas-connection-definition", true, children, null);
        el.setSequence(true);
        elements.put("jonas-connection-definition", el);
    }

    /**
     * Populate the jonas-activationspec restrictions
     *
     */
    protected void populateJonasActivationSpec() {
        List children = new ArrayList();
        children.addAll(populateIdGroup());
        children.add("defaultAS");
        ElementRestrictions el = new HCElementRestrictions(
                "jonas-activationspec", true, children, null);
        el.setSequence(true);
        elements.put("jonas-activationspec", el);
    }

    /**
     * Populate the configurationgroup restrictions
     * @return the configuration group list
     */
    protected List populateConfigurationGroup() {
        List children = new ArrayList();
        children.addAll(populateIdGroup());
        children.add("jonas-config-property");
        return children;
    }

    /**
     * Populate the idgroup restrictions
     * @return the idgroup list
     */
    protected List populateIdGroup() {
        List children = new ArrayList();
        children.add("id");
        children.add("description");
        children.add("jndi-name");
        return children;
    }

    /**
     * Populate the jonas-adminobject restrictions
     *
     */
    protected void populateJonasAdminObject() {
        List children = new ArrayList();
        children.addAll(populateConfigurationGroup());
        ElementRestrictions el = new HCElementRestrictions("jonas-adminobject",
                true, children, null);
        elements.put("jonas-adminobject", el);
    }

    /**
     * Populate the jonas-security-mapping restrictions
     *
     */
    protected void populateJonasSecurityMapping() {
        List children = new ArrayList();
        children.add("security-entry");
        ElementRestrictions el = new HCElementRestrictions(
                "jonas-security-mapping", true, children, null);
        el.setSequence(true);
        elements.put("jonas-security-mapping", el);
    }

    /**
     * Populate the security-entry restrictions
     *
     */
    protected void populateSecurityEntry() {
        List children = new ArrayList();
        children.add("principalName");
        children.add("user");
        children.add("password");
        children.add("encrypted");
        ElementRestrictions el = new HCElementRestrictions("security-entry",
                true, children, null);
        el.setSequence(true);
        elements.put("security-entry", el);
    }

    /**
     * Populate the config-property restrictions
     *
     */
    protected void populateConfigProperty() {
        List configPropertyChildren = new ArrayList();

        // restrictions for the <config-property> element
        configPropertyChildren.add("description");
        configPropertyChildren.add("config-property-name");
        configPropertyChildren.add("config-property-type");
        configPropertyChildren.add("config-property-value");
        ElementRestrictions el = new HCElementRestrictions("config-property", true, configPropertyChildren, null);
        el.setSequence(true);
        elements.put("config-property", el);
    }

    /**
     * Populate the resource-adapter restrictions
     *
     */
    protected void populateResourceAdapter() {
        // restrictions for the <resourceadapter> element
        List resourceadapterChildren = new ArrayList();
        resourceadapterChildren.add("resourceadapter-class");
        resourceadapterChildren.add("config-property");
        resourceadapterChildren.add("outbound-resourceadapter");
        resourceadapterChildren.add("inbound-resourceadapter");
        ElementRestrictions el = new HCElementRestrictions("resourceadapter",
                true, resourceadapterChildren, null);
        el.setSequence(true);
        elements.put("resourceadapter", el);
    }

    /**
     * Populate the connector restrictions
     *
     */
    protected void populateConnector() {
        List connectorChildren = new ArrayList();

        // restrictions for the <connector> element.
        connectorChildren.addAll(populateDescriptionGroup());
        connectorChildren.add("vendor-name");
        connectorChildren.add("eis-type");
        connectorChildren.add("resourceadapter-version");
        connectorChildren.add("license");
        connectorChildren.add("version");
        ElementRestrictions conEl = new HCElementRestrictions("connector",
                true, connectorChildren, null);
        conEl.setSequence(true);
        elements.put("connector", conEl);
    }
    
    /**
     * Populate the descriptionGroup restrictions
     * @return the descriptionGroup list
     */
    protected List populateDescriptionGroup() {
        List children = new ArrayList();
        children.add("description");
        children.add("display-name");
        children.add("icon");
        return children;
    }    

    /**
     * Populate the outbound-resourceadapter restrictions
     *
     */
    protected void populateOutboundResourceAdapter() {
        // restrictions for <outbound-resourceadapter> element.
        List outboundChildren = new ArrayList();
        outboundChildren.add("connection-definition");
        outboundChildren.add("transaction-support");
        outboundChildren.add("authentication-mechanism");
        outboundChildren.add("reauthentication-support");
        ElementRestrictions outEl = new HCElementRestrictions(
                "outbound-resourceadapter", true, outboundChildren, null);
        outEl.setSequence(true);
        elements.put("outbound-resourceadapter", outEl);
    }
    /**
     * Populate the inbound-resourceadapter restrictions
     *
     */
    protected void populateInboundResourceAdapter() {
        // restrictions for <inbound-resourceadapter> element.
        List inboundChildren = new ArrayList();
        inboundChildren.add("messageadapter");
        ElementRestrictions inEl = new HCElementRestrictions(
                "inbound-resourceadapter", true, inboundChildren, null);
        inEl.setSequence(true);
        elements.put("inbound-resourceadapter", inEl);
    }

    /**
     * Populate the license restrictions
     *
     */
    protected void populateLicense() {
        // restrictions for <inbound-resourceadapter> element.
        List licenseChildren = new ArrayList();
        licenseChildren.add("description");
        licenseChildren.add("license-required");
        ElementRestrictions licenseEl = new HCElementRestrictions("license",
                true, licenseChildren, null);
        licenseEl.setSequence(true);
        elements.put("license", licenseEl);
    }

    /**
     * Populate the connection-definition restrictions
     *
     */
    protected void populateConnectionDefinition() {

        List children = new ArrayList();
        children.add("managedconnectionfactory-class");
        children.add("config-property");
        children.add("connectionfactory-interface");
        children.add("connectionfactory-impl-class");
        children.add("connection-interface");
        children.add("connection-impl-class");
        ElementRestrictions el = new HCElementRestrictions(
                "connection-definition", true, children, null);
        el.setSequence(true);
        elements.put("connection-definition", el);
    }

    /**
     * Populate the authentication-mechanism restrictions
     *
     */
    protected void populateAuthenticationMechanism() {

        List children = new ArrayList();
        children.add("description");
        children.add("authentication-mechanism-type");
        children.add("credential-interface");
        ElementRestrictions el = new HCElementRestrictions(
                "authentication-mechanism", true, children, null);
        el.setSequence(true);
        elements.put("authentication-mechanism", el);
    }

    /**
     * Populate the message-adapter restrictions
     *
     */
    protected void populateMessageAdapter() {
        List children = new ArrayList();
        children.add("messagelistener");
        ElementRestrictions el = new HCElementRestrictions("messageadapter",
                true, children, null);
        el.setSequence(true);
        elements.put("messageadapter", el);
    }

    /**
     * Populate the message-listener restrictions
     *
     */
    protected void populateMessageListener() {
        List children = new ArrayList();
        children.add("messagelistener-type");
        children.add("activationspec");
        ElementRestrictions el = new HCElementRestrictions("messagelistener",
                true, children, null);
        el.setSequence(true);
        elements.put("messagelistener", el);
    }

    /**
     * Populate the activationspec restrictions
     *
     */
    protected void populateActivationSpec() {
        List children = new ArrayList();
        children.add("activationspec-class");
        children.add("required-config-property");
        ElementRestrictions el = new HCElementRestrictions("activationspec",
                true, children, null);
        el.setSequence(true);
        elements.put("activationspec", el);
    }

    /**
     * Populate the required-config-property restrictions
     *
     */
    protected void populateRequiredConfigProperty() {
        List children = new ArrayList();
        children.add("description");
        children.add("config-property-name");
        ElementRestrictions el = new HCElementRestrictions(
                "required-config-property", true, children, null);
        el.setSequence(true);
        elements.put("required-config-property", el);
    }

    /**
     * Returns if there is an element restriction for the given name.
     * @param name the name of the element to check
     * @return true if name has a restriction.
     */
    public boolean hasElementRestrictions(String name) {
        return elements.containsKey(name);
    }

    /**
     * Returns the element restrictions for the given element name.
     * @param name the name of the element to return the restrictions
     * @return the element restrictions for the element.
     */
    public ElementRestrictions getElementRestrictions(String name) {
        return (ElementRestrictions) elements.get(name);
    }

    /**
     * Returns a set of all complex elements for this schema.
     * @return a set of all complex elements for this schema.
     */
    public Set getComplexElements() {
        return elements.keySet();
    }
}
