package org.apache.turbine.services.intake.model;

/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache Turbine" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache Turbine", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.commons.pool.BaseKeyedPoolableObjectFactory;

import org.apache.turbine.om.Retrievable;
import org.apache.turbine.services.intake.IntakeException;
import org.apache.turbine.services.intake.TurbineIntake;
import org.apache.turbine.services.intake.xmlmodel.AppData;
import org.apache.turbine.services.intake.xmlmodel.XmlField;
import org.apache.turbine.services.intake.xmlmodel.XmlGroup;
import org.apache.turbine.util.TurbineException;
import org.apache.turbine.util.parser.ValueParser;

/**
 * Holds a group of Fields
 *
 * @deprecated Use the Fulcrum Intake component instead.
 * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
 * @version $Id$
 */
public class Group
{
    public static final String EMPTY = "";

    /*
     * An id representing a new object.
     */
    public static final String NEW = "_0";

    private static final Log log;
    private static final boolean isDebugEnabled;

    static
    {
        log = LogFactory.getLog(Group.class);
        isDebugEnabled = log.isDebugEnabled();
    }

    /**
     * The key used to represent this group in a parameter.
     * This key is usually a prefix as part of a field key.
     */
    protected final String gid;

    /**
     * The name used in templates and java code to refer to this group.
     */
    protected final String name;

    /**
     * The number of Groups with the same name that will be pooled.
     */
    private final int poolCapacity;

    /**
     * A map of the fields in this group mapped by field name.
     */
    protected Map fields;

    /**
     * Map of the fields by mapToObject
     */
    protected Map mapToObjectFields;

    /**
     * An array of fields in this group.
     */
    protected Field[] fieldsArray;

    /**
     * The object id used to associate this group to a bean
     * for one request cycle
     */
    protected String oid;

    /**
     * The object containing the request data
     */
    protected ValueParser pp;

    /**
     * A flag to help prevent duplicate hidden fields declaring this group.
     */
    protected boolean isDeclared;

    /**
     * Constructs a new Group based on the xml specification.  Groups are
     * instantiated and pooled by the IntakeService and should not
     * be instantiated otherwise.
     *
     * @param group a <code>XmlGroup</code> value
     * @exception IntakeException if an error occurs in other classes
     */
    public Group(XmlGroup group) throws IntakeException
    {
        gid = group.getKey();
        name = group.getName();
        poolCapacity = Integer.parseInt(group.getPoolCapacity());

        List inputFields = group.getFields();
        int size = inputFields.size();
        fields = new HashMap((int) (1.25 * size + 1));
        mapToObjectFields = new HashMap((int) (1.25 * size + 1));
        fieldsArray = new Field[size];
        for (int i = size - 1; i >= 0; i--)
        {
            XmlField f = (XmlField) inputFields.get(i);
            Field field = FieldFactory.getInstance(f, this);
            fieldsArray[i] = field;
            fields.put(f.getName(), field);

            // map fields by their mapToObject
            List tmpFields = (List) mapToObjectFields.get(f.getMapToObject());
            if (tmpFields == null)
            {
                tmpFields = new ArrayList(size);
                mapToObjectFields.put(f.getMapToObject(), tmpFields);
            }
            tmpFields.add(field);
        }

        // Change the mapToObjectFields values to Field[]
        for (Iterator keys = mapToObjectFields.keySet().iterator(); keys.hasNext();)
        {
            Object key = keys.next();
            List tmpFields = (List) mapToObjectFields.get(key);
            mapToObjectFields.put(key,
                    tmpFields.toArray(new Field[tmpFields.size()]));
        }
    }

    /**
     * Initializes the default Group using parameters.
     *
     * @param pp a <code>ValueParser</code> value
     * @return this Group
     */
    public Group init(ValueParser pp) throws TurbineException
    {
        return init(NEW, pp);
    }

    /**
     * Initializes the Group with parameters from RunData
     * corresponding to key.
     *
     * @param pp a <code>ValueParser</code> value
     * @return this Group
     */
    public Group init(String key, ValueParser pp) throws IntakeException
    {
        this.oid = key;
        this.pp = pp;
        for (int i = fieldsArray.length - 1; i >= 0; i--)
        {
            fieldsArray[i].init(pp);
        }
        return this;
    }

    /**
     * Initializes the group with properties from an object.
     *
     * @param obj a <code>Persistent</code> value
     * @return a <code>Group</code> value
     */
    public Group init(Retrievable obj)
    {
        this.oid = obj.getQueryKey();

        Class cls = obj.getClass();
        while (cls != null)
        {
            Field[] flds = (Field[]) mapToObjectFields.get(cls.getName());
            if (flds != null)
            {
                for (int i = flds.length - 1; i >= 0; i--)
                {
                    flds[i].init(obj);
                }
            }

            cls = cls.getSuperclass();
        }

        return this;
    }

    /**
     * Gets a list of the names of the fields stored in this object.
     *
     * @return A String array containing the list of names.
     */
    public String[] getFieldNames()
    {
        String nameList[] = new String[fieldsArray.length];
        for (int i = 0; i < nameList.length; i++)
        {
            nameList[i] = fieldsArray[i].name;
        }
        return nameList;
    }

    /**
     * Return the name given to this group.  The long name is to
     * avoid conflicts with the get(String key) method.
     *
     * @return a <code>String</code> value
     */
    public String getIntakeGroupName()
    {
        return name;
    }

    /**
     * Get the number of Group objects that will be pooled.
     *
     * @return an <code>int</code> value
     */
    public int getPoolCapacity()
    {
        return poolCapacity;
    }

    /**
     * Get the part of the key used to specify the group.
     * This is specified in the key attribute in the xml file.
     *
     * @return a <code>String</code> value
     */
    public String getGID()
    {
        return gid;
    }

    /**
     * Get the part of the key that distinguishes a group
     * from others of the same name.
     *
     * @return a <code>String</code> value
     */
    public String getOID()
    {
        return oid;
    }

    /**
     * Concatenation of gid and oid.
     *
     * @return a <code>String</code> value
     */
    public String getObjectKey()
    {
        return gid + oid;
    }

    /**
     * Describe <code>getObjects</code> method here.
     *
     * @param pp a <code>ValueParser</code> value
     * @return an <code>ArrayList</code> value
     * @exception IntakeException if an error occurs
     */
    public ArrayList getObjects(ValueParser pp) throws IntakeException
    {
        ArrayList objs = null;
        String[] oids = pp.getStrings(gid);
        if (oids != null)
        {
            objs = new ArrayList(oids.length);
            for (int i = oids.length - 1; i >= 0; i--)
            {
                objs.add(TurbineIntake.getGroup(name).init(oids[i], pp));
            }
        }
        return objs;
    }

    /**
     * Get the Field .
     * @return Field.
     * @throws IntakeException indicates the field could not be found.
     */
    public Field get(String fieldName)
            throws IntakeException
    {
        if (fields.containsKey(fieldName))
        {
            return (Field) fields.get(fieldName);
        }
        else
        {
            throw new IntakeException("Intake Field name: " + fieldName +
                    " not found!");
        }
    }

    /**
     * Performs an AND between all the fields in this group.
     *
     * @return a <code>boolean</code> value
     */
    public boolean isAllValid()
    {
        boolean valid = true;
        for (int i = fieldsArray.length - 1; i >= 0; i--)
        {
            valid &= fieldsArray[i].isValid();
            if (isDebugEnabled && !fieldsArray[i].isValid())
            {
                log.debug("Group(" + oid + "): " + name + "; Field: "
                        + fieldsArray[i].name + "; value=" +
                        fieldsArray[i].getValue() + " is invalid!");
            }
        }
        return valid;
    }

    /**
     * Calls a setter methods on obj, for fields which have been set.
     *
     * @param obj Object to be set with the values from the group.
     * @throws IntakeException indicates that a failure occurred while
     * executing the setter methods of the mapped object.
     */
    public void setProperties(Object obj) throws IntakeException
    {
        Class cls = obj.getClass();

        while (cls != null)
        {
            if (isDebugEnabled)
            {
                log.debug("setProperties(" + cls.getName() + ")");
            }

            Field[] flds = (Field[]) mapToObjectFields.get(cls.getName());
            if (flds != null)
            {
                for (int i = flds.length - 1; i >= 0; i--)
                {
                    flds[i].setProperty(obj);
                }
            }

            cls = cls.getSuperclass();
        }
        log.debug("setProperties() finished");
    }

    /**
     * Calls a setter methods on obj, for fields which pass validity tests.
     * In most cases one should call Intake.isAllValid() and then if that
     * test passes call setProperties.  Use this method when some data is
     * known to be invalid, but you still want to set the object properties
     * that are valid.
     */
    public void setValidProperties(Object obj)
    {
        Class cls = obj.getClass();
        while (cls != null)
        {
            Field[] flds = (Field[]) mapToObjectFields.get(cls.getName());
            if (flds != null)
            {
                for (int i = flds.length - 1; i >= 0; i--)
                {
                    try
                    {
                        flds[i].setProperty(obj);
                    }
                    catch (Exception e)
                    {
                        // just move on to next field
                    }
                }
            }

            cls = cls.getSuperclass();
        }
    }

    /**
     * Calls getter methods on objects that are known to Intake
     * so that field values in forms can be initialized from
     * the values contained in the intake tool.
     *
     * @param obj Object that will be used to as a source of data for
     * setting the values of the fields within the group.
     * @throws IntakeException indicates that a failure occurred while
     * executing the setter methods of the mapped object.
     */
    public void getProperties(Object obj) throws IntakeException
    {
        Class cls = obj.getClass();
        while (cls != null)
        {
            Field[] flds = (Field[]) mapToObjectFields.get(cls.getName());
            if (flds != null)
            {
                for (int i = flds.length - 1; i >= 0; i--)
                {
                    flds[i].getProperty(obj);
                }
            }

            cls = cls.getSuperclass();
        }
    }

    /**
     * Removes references to this group and its fields from the
     * query parameters
     */
    public void removeFromRequest()
    {
        if (pp != null)
        {
            String[] groups = pp.getStrings(gid);
            if (groups != null)
            {
                pp.remove(gid);
                for (int i = 0; i < groups.length; i++)
                {
                    if (groups[i] != null && !groups[i].equals(oid))
                    {
                        pp.add(gid, groups[i]);
                    }
                }
                for (int i = fieldsArray.length - 1; i >= 0; i--)
                {
                    fieldsArray[i].removeFromRequest();
                }
            }
        }
    }

    /**
     * To be used in the event this group is used within multiple
     * forms within the same template.
     */
    public void resetDeclared()
    {
        isDeclared = false;
    }

    /**
     * A xhtml valid hidden input field that notifies intake of the
     * group's presence.
     *
     * @return a <code>String</code> value
     */
    public String getHtmlFormInput()
    {
        StringBuffer sb = new StringBuffer(64);
        appendHtmlFormInput(sb);
        return sb.toString();
    }

    /**
     * A xhtml valid hidden input field that notifies intake of the
     * group's presence.
     */
    public void appendHtmlFormInput(StringBuffer sb)
    {
        if (!isDeclared)
        {
            isDeclared = true;
            sb.append("<input type=\"hidden\" name=\"")
                    .append(gid)
                    .append("\" value=\"")
                    .append(oid)
                    .append("\"/>\n");
        }
    }

    // ********** PoolableObjectFactory implementation ******************

    public static class GroupFactory
            extends BaseKeyedPoolableObjectFactory
    {
        private AppData appData;

        public GroupFactory(AppData appData)
        {
            this.appData = appData;
        }

        /**
         * Creates an instance that can be returned by the pool.
         * @return an instance that can be returned by the pool.
         * @throws IntakeException indicates that the group could not be retreived
         */
        public Object makeObject(Object key) throws IntakeException
        {
            return new Group(appData.getGroup((String) key));
        }

        /**
         * Uninitialize an instance to be returned to the pool.
         * @param obj the instance to be passivated
         */
        public void passivateObject(Object key, Object obj)
        {
            Group group = (Group) obj;
            group.oid = null;
            group.pp = null;
            for (int i = group.fieldsArray.length - 1; i >= 0; i--)
            {
                group.fieldsArray[i].dispose();
            }
            group.isDeclared = false;
        }
    }
}


