/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 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 Jetspeed" 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" or
 *    "Apache Jetspeed", 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/>.
 */

package org.apache.jetspeed.om.security.turbine;

import java.util.List;
import java.util.Hashtable;
import java.util.ArrayList;
import com.workingdogs.village.*;

import org.apache.torque.util.Criteria;
import org.apache.torque.TorqueException;
import org.apache.torque.om.NumberKey;
import org.apache.turbine.util.ObjectUtils;

import org.apache.jetspeed.om.security.JetspeedUser;
import org.apache.jetspeed.om.security.JetspeedUserFactory;


// Local classes

/** 
 * The skeleton for this class was autogenerated by Torque on:
 *
 * [Wed May 29 23:45:25 PDT 2002]
 *
 *  You should add additional methods to this class to meet the
 *  application requirements.  This class will only be generated as
 *  long as it does not already exist in the output directory.
 */
public class TurbineUserPeer 
    extends org.apache.jetspeed.om.security.turbine.BaseTurbineUserPeer
{

    /** The schema. */
    private static Schema schema = initTableSchema(TABLE_NAME);

    /** The columns. */
    private static com.workingdogs.village.Column[] columns = 
        initTableColumns(schema);


    /** The names of the columns. */
    public static String[] columnNames = initColumnNames(columns);


    /** 
      * Selects Jetspeed Users or a derived class there of, creating the
      * JetspeedUsers,  and populating each user's hashtable of attributes
      * from the result set of the query
      *
      * @param criteria the query criteria.
      * @return a List of JetspeedUsers
      */
    public static List doSelectUsers( Criteria criteria ) throws TorqueException
    {
        return populateUserObjects( doSelectVillageRecords(criteria) );
    }


    /**
     * The returned list will contain objects of the default type or
     * objects that inherit from the default.
     */
    public static List populateUserObjects(List records)
        throws TorqueException
    {
        List results = new ArrayList(records.size());

        // populate the object(s)
        for ( int i=0; i<records.size(); i++ )
        {
            Record row = (Record)records.get(i);
            results.add(TurbineUserPeer.row2UserObject(row, 1, TurbineUserPeer.getOMClass()));
        }
        return results;
    }


    /**
     * Create a new object of type cls from a resultset row starting
     * from a specified offset.  This is done so that you can select
     * other rows than just those needed for this object.  You may
     * for example want to create two objects from the same row.
     */
    public static JetspeedUser row2UserObject (Record row,
                                              int offset,
                                              Class cls )
        throws TorqueException
    {
        try
        {
            //TurbineUser obj = (TurbineUser)cls.newInstance();
            //populateObject(row, offset, obj);
            //obj.setModified(false);
            //obj.setNew(false);
            JetspeedUser user = JetspeedUserFactory.getInstance(false);
            populateUserObject(row, offset, user);
            return user;
        }
        catch (Exception e)
        {
            throw new TorqueException(e);
        }
    }

    protected static final String TURBINE_OBJECTDATA = "OBJECTDATA";

    /*
     * Populates a JetspeedUser from a single row in the result set.
     * The hashtable of attributes for each user is populated with columns
     * from the result set. 
     *
     * @param row a row containing a single user's attributes.
     * @param user the JetspeedUser object to be populated.
     *
     */
    protected static void populateUserObject(Record row, int offset, JetspeedUser user)
        throws Exception
    {
        // Set values are where columns are expected.  They are not
        // required to be in these positions, as we set the positions
        // immediately following.
        int idPosition = 1;
        int objectDataPosition = columnNames.length;
        for( int i=0; i<columnNames.length; i++ )
        {
            if (columnNames[i].equals(USER_ID))
                idPosition = i+1;

            if (columnNames[i].equals(TURBINE_OBJECTDATA))
                objectDataPosition = i+1;
        }

        // Restore the Permanent Storage Hashtable.  First the
        // Hashtable is restored, then any explicit table columns
        // which should be included in the Hashtable are added.
        byte[] objectData = (byte[])row.getValue(objectDataPosition).asBytes();
        Hashtable tempHash = (Hashtable)ObjectUtils.deserialize(objectData);
        if (tempHash == null)
        {
            tempHash = new Hashtable(10);
        }

        for( int j=0; j<columnNames.length; j++ )
        {
            if (! columnNames[j].equalsIgnoreCase( TURBINE_OBJECTDATA ) )
            {
                Object obj2 = null;
                Value value = row.getValue(j+1);
                if (value.isString()) 
                    obj2 = value.asString();
                else if (value.isBigDecimal()) 
                    obj2 = value.asBigDecimal();
                else if (value.isBytes()) 
                    obj2 = value.asBytes();
                else if (value.isDate()) 
                    obj2 = value.asDate();
                else if (value.isShort()) 
                    obj2 = new Short(value.asShort());
                else if (value.isInt()) 
                    obj2 = new Integer(value.asInt());
                else if (value.isLong()) 
                    obj2 = new Long(value.asLong());
                else if (value.isDouble()) 
                    obj2 = new Double(value.asDouble());
                else if (value.isFloat()) 
                    obj2 = new Float(value.asFloat());
                else if (value.isBoolean()) 
                    obj2 = new Boolean(value.asBoolean());
                else if (value.isTime()) 
                    obj2 = value.asTime();
                else if (value.isTimestamp()) 
                    obj2 = value.asTimestamp();
                else if (value.isUtilDate()) 
                    obj2 = value.asUtilDate();
                else if (value.isByte()) 
                    obj2 = new Byte(value.asByte());

                if ( obj2 != null )
                {
                    if (columnNames[j].equalsIgnoreCase( JetspeedUser.USER_ID ))
                    {
                        obj2 = value.toString();
                    }

                    tempHash.put( columnNames[j], obj2 );
                }
            }
        }
        user.setPermStorage( tempHash );
    }


    /*
     * Populates a JetspeedUser from a single row in the result set.
     * The hashtable of attributes for each user is populated with columns
     * from the result set.
     *
     * @param row a row containing a single user's attributes.
     * @param user the JetspeedUser object to be populated.
     *
     */
    /*
    DST: COMMITTED 8/19 FROM AMIT AMTE - IT HAS SOME BUGS, GOING TO REMOVE UNTIL RESOLVED
    
    protected static void populateUserObject(Record row, int offset, JetspeedUser user)
        throws Exception
    {
        // Restore the Permanent Storage Hashtable.  First the
        // Hashtable is restored, then any explicit table columns
        // which should be included in the Hashtable are added.
        byte[] objectData = (byte[])row.getValue(OBJECTDATA).asBytes();
        Hashtable tempHash = (Hashtable)ObjectUtils.deserialize(objectData);
        if (tempHash == null)
        {
            tempHash = new Hashtable(10);
        }

        for( int j=0; j<columnNames.length; j++ )
        {
            if (! columnNames[j].equalsIgnoreCase( OBJECTDATA ) )
            {
                Object obj2 = null;
                Value value = null;
                try {
                    value = row.getValue(columnNames[j]);
                } catch (Exception ex) {
                    // Column missing from the torque record ..
                    // Probable/intentional mis-match between the
                    // torque schema and db table
                    continue;
                }

                if (value.isString())
                    obj2 = value.asString();
                else if (value.isBigDecimal())
                    obj2 = value.asBigDecimal();
                else if (value.isBytes())
                    obj2 = value.asBytes();
                else if (value.isDate())
                    obj2 = value.asDate();
                else if (value.isShort())
                    obj2 = new Short(value.asShort());
                else if (value.isInt())
                    obj2 = new Integer(value.asInt());
                else if (value.isLong())
                    obj2 = new Long(value.asLong());
                else if (value.isDouble())
                    obj2 = new Double(value.asDouble());
                else if (value.isFloat())
                    obj2 = new Float(value.asFloat());
                else if (value.isBoolean())
                    obj2 = new Boolean(value.asBoolean());
                else if (value.isTime())
                    obj2 = value.asTime();
                else if (value.isTimestamp())
                    obj2 = value.asTimestamp();
                else if (value.isUtilDate())
                    obj2 = value.asUtilDate();
                else if (value.isByte())
                    obj2 = new Byte(value.asByte());

                if ( obj2 != null )
                {
                    if (columnNames[j].equalsIgnoreCase( JetspeedUser.USER_ID ))
                    {
                        obj2 = value.toString();
                    }

                    System.out.println(columnNames[j] + ": " + obj2.toString());
                    tempHash.put( columnNames[j], obj2 );
                }
            }
        }
        user.setPermStorage( tempHash );
    }
    */

    /**
     * Builds a criteria object based upon an User object
     */
    public static Criteria buildCriteria(JetspeedUser user)
    {
        Hashtable permData = (Hashtable) user.getPermStorage().clone();
        Criteria criteria = new Criteria();
        if ( !user.isNew() )
        {
            criteria.add(USER_ID, new NumberKey(user.getUserId()));
        }

        for (int i=1; i < columnNames.length; i++ )
        {
            if ( permData.containsKey(columnNames[i]) )
            {
                String key = new StringBuffer(TABLE_NAME)
                    .append('.').append(columnNames[i]).toString();

                criteria.add( key,
                              permData.remove(TurbineUserPeer.columnNames[i]) );
            }
        }
        String dataKey = new StringBuffer(TABLE_NAME).append('.').append(TURBINE_OBJECTDATA).toString();
        criteria.add( dataKey, permData );
        return criteria;
    }

}
