head	1.22;
access;
symbols
	TIGRIS_0_9_2_4:1.16
	TIGRIS_0_9_2_3:1.16
	HELM_PEER_PORT_BRANCH:1.21.0.2
	TURBINE_PEER:1.21
	TIGRIS_0_9_2_1:1.21
	TIGRIS_0_9_2:1.16.0.2
	TIGRIS_0_9_0:1.8.0.2
	TIGRIS_0_8_4:1.1.1.1.0.2
	NEWHELM:1.1.1.1
	TIGRIS_NOV_12_2000:1.1.1;
locks; strict;
comment	@# @;


1.22
date	2001.02.21.03.23.56;	author edk;	state dead;
branches;
next	1.21;

1.21
date	2001.01.26.18.29.02;	author edk;	state Exp;
branches
	1.21.2.1;
next	1.20;

1.20
date	2001.01.26.05.24.05;	author edk;	state dead;
branches;
next	1.19;

1.19
date	2001.01.25.02.53.17;	author leonardr;	state Exp;
branches;
next	1.18;

1.18
date	2001.01.24.22.52.46;	author leonardr;	state Exp;
branches;
next	1.17;

1.17
date	2001.01.24.20.42.48;	author dlr;	state Exp;
branches;
next	1.16;

1.16
date	2000.12.29.02.35.58;	author dlr;	state Exp;
branches;
next	1.15;

1.15
date	2000.12.26.19.59.07;	author dlr;	state Exp;
branches;
next	1.14;

1.14
date	2000.12.23.00.33.20;	author dlr;	state Exp;
branches;
next	1.13;

1.13
date	2000.12.23.00.07.12;	author dlr;	state Exp;
branches;
next	1.12;

1.12
date	2000.12.23.00.01.42;	author dlr;	state Exp;
branches;
next	1.11;

1.11
date	2000.12.22.04.05.51;	author dlr;	state Exp;
branches;
next	1.10;

1.10
date	2000.12.22.03.02.59;	author dlr;	state Exp;
branches;
next	1.9;

1.9
date	2000.12.22.02.48.51;	author dlr;	state Exp;
branches;
next	1.8;

1.8
date	2000.12.13.22.31.05;	author dlr;	state Exp;
branches;
next	1.7;

1.7
date	2000.12.13.02.01.05;	author leonardr;	state Exp;
branches;
next	1.6;

1.6
date	2000.12.06.22.55.33;	author dlr;	state Exp;
branches;
next	1.5;

1.5
date	2000.12.06.22.55.05;	author dlr;	state Exp;
branches;
next	1.4;

1.4
date	2000.12.05.23.53.30;	author leonardr;	state Exp;
branches;
next	1.3;

1.3
date	2000.12.05.23.45.31;	author dlr;	state Exp;
branches;
next	1.2;

1.2
date	2000.12.05.23.28.58;	author leonardr;	state Exp;
branches;
next	1.1;

1.1
date	2000.11.12.21.15.17;	author dlr;	state Exp;
branches
	1.1.1.1;
next	;

1.1.1.1
date	2000.11.12.21.15.17;	author dlr;	state Exp;
branches;
next	;

1.21.2.1
date	2001.01.28.01.02.17;	author dlr;	state dead;
branches;
next	;


desc
@@


1.22
log
@delete stuff from the head which is obsolete in the branch (more changes
are still needed for a clean compile)
@
text
@/* ================================================================
 * Copyright (c) 2000 CollabNet.  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 acknowlegement: "This product includes
 * software developed by CollabNet (http://www.CollabNet/)."
 * Alternately, this acknowlegement may appear in the software itself, if
 * and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The hosted project names must not be used to endorse or promote
 * products derived from this software without prior written
 * permission. For written permission, please contact info@@collab.net.
 * 
 * 5. Products derived from this software may not use the "Tigris" name
 * nor may "Tigris" appear in their names without prior written
 * permission of CollabNet.
 * 
 * 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 COLLAB.NET 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 CollabNet.
 */


package org.tigris.helm.domain;

import java.sql.Connection;
import java.util.Dictionary;
import java.util.Hashtable;

import com.workingdogs.village.Record;
import com.workingdogs.village.DataSetException;

import org.joist.util.EscapedString;
import org.joist.util.QuotedString;
import org.joist.database.DataManager;

import org.tigris.helm.DoesNotExist;
import org.tigris.helm.tool.BufferCache;

/**
 * Interface to be implemented by all Tigris business objects.
 *
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@version $Id: BusinessObject.java,v 1.21 2001/01/26 18:29:02 edk Exp $
 */
public abstract class BusinessObject
{
    /**
     * Table of instance caches for derived classes.
     */
    private static Hashtable instanceCaches = new Hashtable();

    /**
     * The JDBC database connection to use.
     */
    protected Connection conn;

    /**
     * The data layer manager.
     */
    protected DataManager dMgr;

    /**
     * The database row backing this instance.
     */
    protected Record rec;

    /**
     * Constructor for a business object which already exists--accessed by
     * <code>Record</code>.
     *
     * @@param conn The JDBC database connection.
     * @@param dMgr The associated data layer manager.
     * @@param rec  The data backing this business object.
     */
    protected BusinessObject (Connection conn, DataManager dMgr, Record rec)
        throws DoesNotExist, DataSetException
    {
        this(conn, dMgr);
        setRecord(rec);
    }

    /**
     * Initializes the data layer interface.  Note that this does <i>not</i>
     * setup the <code>Record</code> object which backs each instance with
     * data.
     *
     * @@param conn The JDBC database connection.
     * @@param dMgr The associated data layer manager.
     */
    protected BusinessObject (Connection conn, DataManager dMgr)
    {
        this.conn = conn;
        this.dMgr = dMgr;
        createManagers();
    }

    /**
     * Creates and caches all necessary database managers.
     */
    protected abstract void createManagers ();

    /**
     * Returns the cache of business object instances for the specified class.
     * This in memory cache should be used in factory methods of all derived 
     * classes that take a database key argument (i.e. <code>public static
     * BusinesObject getInstance(Connection conn, DataManager dMgr,
     * String id)</code>), before hitting the database.  Such a factory method
     * will typically wrap a <code>private</code> constructor of the same
     * signature.  Constructors which create a new database record should also
     * add their newly created instance to this cache.
     *
     * @@param key       The class whose cache to get.
     * @@param tableName The name of the table that the cache is for.
     * @@return          The cache.
     */
    protected static Dictionary getCache (Class key)
    {
        Dictionary cache = getCacheNonSync(key);
        if (cache == null)
        {
            // Class instance cache initialization (occurs only once).
            synchronized (instanceCaches)
            {
                cache = getCacheNonSync(key);
                if (cache == null)
                {
                    cache = new BufferCache();
                    instanceCaches.put(key, cache);
                }
            }
        }
        return cache;
    }

    /**
     * Macro for retrieving a specific cache without extraneous
     * synchronization.
     */
    private static final Dictionary getCacheNonSync (Class key)
    {
        return (Dictionary)instanceCaches.get(key);
    }

    /**
     * Some sort of unique identifier for this object.     
     */
    public abstract String getID () throws DataSetException;

    /**
     * Wrapper for <code>getCache(Class)</code>.
     */
    protected final Dictionary getCache ()
    {
        return getCache(getClass());
    }

    /**
     * The database table, if any, from which this is supposed to be a record.
     */
    protected abstract String getTableName ();

    /**
     * Helper method for getting a record's field as a string.
     *
     * @@param name The database field to use.
     */
    protected String getField (String name)
        throws DataSetException
    {
        return rec.getValue(name).asString();
    }

    /**
     * Sets the database row which holds this instance's data.
     *
     * @@param rec The database row to use.
     */
    protected void setRecord (Record rec)
        throws DoesNotExist, DataSetException
    {
        if (rec != null)
        {
            if (getTableName() != null)
            {
                String recTableName = rec.schema().getTableName();
                if (!getTableName().equals(recTableName))
                {
                    StringBuffer error = new StringBuffer();
                    error.append("Database record is from table ")
                        .append(recTableName).append(" (should be ")
                        .append(getTableName()).append(").");
                    throw new DataSetException(error.toString());
                }
            }
            this.rec = rec;
        }
        else
        {
            throw new DoesNotExist("Corresponding database record");
        }
    }

    /**
     * Escapes and quotes <code>String</code> inputs used in SQL queries.  
     * This method should be run on all Strings used in <code>where</code> 
     * clauses which contain non-numeric values.
     *
     * @@param s The text to sanitize.
     * @@return  The sanitized text.
     */
    protected static final String escapeAndQuoteSQL (String s)
    {
        return (s == null ? "null" : QuotedString.from(EscapedString.from(s)));
    }
}
@


1.21
log
@readding all the files as part of the process of returning to the way
things were as of tuesday
@
text
@d68 1
a68 1
 * @@version $Id: BusinessObject.java,v 1.16 2000/12/29 02:35:58 dlr Exp $
@


1.21.2.1
log
@Porting to the Turbine Peer system.  -dlr and leonardr
@
text
@d68 1
a68 1
 * @@version $Id: BusinessObject.java,v 1.21 2001/01/26 18:29:02 edk Exp $
@


1.20
log
@revert this stuff to its state as of 2001/01/24 12:42:00 GMT -- with
the following exceptions, which have some different modifications so
they'll work with changes which have happened in joist:

ProjectNewsEdit.java
SkinManager.java
SkinStyleElementValueManager.java
StyleElementManager.java
StyleManager.java

it compiles.  i dunno if it works, though.
@
text
@d50 1
a61 2
import org.tigris.helm.database.DBException;
import org.tigris.helm.database.DBTool;
d68 1
a68 1
 * @@version $Id: BusinessObject.java,v 1.19 2001/01/25 02:53:17 leonardr Exp $
d78 5
d96 1
d100 2
a101 2
    protected BusinessObject (DataManager dMgr, Record rec)
        throws DoesNotExist, DBException
d103 1
a103 1
        this(dMgr);
d112 1
d115 1
a115 1
    protected BusinessObject (DataManager dMgr)
d117 1
d131 5
a135 5
     * BusinesObject getInstance(DataManager dMgr, String id)</code>), before
     * hitting the database.  Such a factory method will typically wrap a
     * <code>private</code> constructor of the same signature.  Constructors
     * which create a new database record should also add their newly created
     * instance to this cache.
d172 1
a172 2
    public abstract String getID ()
        throws DBException;
d193 1
a193 1
        throws DBException
d195 1
a195 1
        return DBTool.getField(rec, name);
d204 1
a204 1
        throws DoesNotExist, DBException
d208 1
a208 1
            try
d210 2
a211 1
                if (getTableName() != null)
d213 5
a217 9
                    String recTableName = rec.schema().getTableName();
                    if (!getTableName().equals(recTableName))
                    {
                        StringBuffer error = new StringBuffer();
                        error.append("Database record is from table ")
                            .append(recTableName).append(" (should be ")
                            .append(getTableName()).append(").");
                        throw new DBException(error.toString());
                    }
a218 5
                this.rec = rec;
            }
            catch (DataSetException e)
            {
                throw new DBException(e);
d220 1
@


1.19
log
@Made use of DBTool.
-dlr
@
text
@d69 1
a69 1
 * @@version $Id: BusinessObject.java,v 1.18 2001/01/24 22:52:46 leonardr Exp $
@


1.18
log
@Removed JDBC connection retention.
@
text
@d62 1
d69 1
a69 1
 * @@version $Id: BusinessObject.java,v 1.17 2001/01/24 20:42:48 dlr Exp $
d189 1
a189 8
        try
        {
            return rec.getValue(name).asString();
        }
        catch (DataSetException e)
        {
            throw new DBException(e);
        }
@


1.17
log
@Making use of DBException.
@
text
@a49 1
import java.sql.Connection;
d68 1
a68 1
 * @@version $Id: BusinessObject.java,v 1.16 2000/12/29 02:35:58 dlr Exp $
a77 5
     * The JDBC database connection to use.
     */
    protected Connection conn;

    /**
a90 1
     * @@param conn The JDBC database connection.
d94 1
a94 1
    protected BusinessObject (Connection conn, DataManager dMgr, Record rec)
d97 1
a97 1
        this(conn, dMgr);
a105 1
     * @@param conn The JDBC database connection.
d108 1
a108 1
    protected BusinessObject (Connection conn, DataManager dMgr)
a109 1
        this.conn = conn;
d123 5
a127 5
     * BusinesObject getInstance(Connection conn, DataManager dMgr,
     * String id)</code>), before hitting the database.  Such a factory method
     * will typically wrap a <code>private</code> constructor of the same
     * signature.  Constructors which create a new database record should also
     * add their newly created instance to this cache.
@


1.16
log
@Moved booleanValueOf() method into tool.DBFlag class.
@
text
@d62 1
d69 1
a69 1
 * @@version $Id: BusinessObject.java,v 1.15 2000/12/26 19:59:07 dlr Exp $
d102 1
a102 1
        throws DoesNotExist, DataSetException
d173 2
a174 1
    public abstract String getID () throws DataSetException;
d195 1
a195 1
        throws DataSetException
d197 8
a204 1
        return rec.getValue(name).asString();
d213 1
a213 1
        throws DoesNotExist, DataSetException
d217 1
a217 1
            if (getTableName() != null)
d219 1
a219 2
                String recTableName = rec.schema().getTableName();
                if (!getTableName().equals(recTableName))
d221 9
a229 5
                    StringBuffer error = new StringBuffer();
                    error.append("Database record is from table ")
                        .append(recTableName).append(" (should be ")
                        .append(getTableName()).append(").");
                    throw new DataSetException(error.toString());
d231 5
a236 1
            this.rec = rec;
@


1.15
log
@Changed method name from getBooleanValue(String) to
booleanValueOf(String).
@
text
@d68 1
a68 1
 * @@version $Id: BusinessObject.java,v 1.14 2000/12/23 00:33:20 dlr Exp $
a238 16
    }

    /**
     * Returns a <code>Boolean</code> value from a 
     * <code>Y</code>/<code>N</code> or <code>1</code>/<code>0</code> flag.
     * Eases parsing of boolean values from two element database enumerations
     *
     * @@param flag The flag to decipher.
     * @@return     The <code>Boolean</code> equivalent of the flag.
     */
    protected static final Boolean booleanValueOf (String flag)
    {
        return (flag != null &&
                (flag.equalsIgnoreCase("Y") || flag.equals("1")) ? 
                Boolean.TRUE :
                Boolean.FALSE);
@


1.14
log
@- Removed cache mutator/accessor wrapper methods in light of their poor
  complexity reduction value vs. performance ratio.  Consolidated
  JavaDoc in getCache(Class key).
- Added getCache() instance wrapper.
@
text
@d68 1
a68 1
 * @@version $Id: BusinessObject.java,v 1.13 2000/12/23 00:07:12 dlr Exp $
d249 1
a249 1
    protected static final Boolean getBooleanValue (String flag)
@


1.13
log
@- Various cleanup.
- Changed getCache(Class) from private to protected so that derived
  classes can sync on their cache (when necessary).
@
text
@d68 1
a68 1
 * @@version $Id: BusinessObject.java,v 1.12 2000/12/23 00:01:42 dlr Exp $
a127 32
     * Attempts to retrieve a cached instance of the business object
     * corresponding to the provided database key.  This in memory cache 
     * should be used in all sub class factory methods that take a database 
     * key argument (i.e. <code>public static BusinesObject
     * getInstance(Connection conn, DataManager dMgr, String id)</code>),
     * before hitting the database.  Such a factory method will typically wrap
     * a <code>private</code> constructor of the same signature.
     *
     * @@param key The class whose cache to get an instance from.
     * @@param id  The database key of the desired instance, or
     *            <code>null</code> if a corresponding instance is not cached.
     * @@return    The cached instance of the business object.
     */
    protected static BusinessObject getCachedInstance (Class key, String id)
    {
        return (BusinessObject)getCache(key).get(id);
    }

    /**
     * Caches the provided instance using the specified key.  This method is
     * called in a subclass's factory method to cache freshly minted instances.
     *
     * @@param c  The class whose cache to add an instance to.
     * @@param id The database key of the object to cache.
     * @@param bo The business object to cache.
     */
    protected static void cacheInstance (String id, BusinessObject bo)
    {
        getCache(bo.getClass()).put(id, bo);
    }

    /**
d129 7
d173 8
@


1.12
log
@Modified caching interface to store all cache instances in class
member.  Cache retrieval interface now concrete.
@
text
@d68 1
a68 1
 * @@version $Id: BusinessObject.java,v 1.11 2000/12/22 04:05:51 dlr Exp $
d73 1
a73 1
     * Table of caches for derived classes.
d75 1
a75 1
    private static Hashtable tableCaches = new Hashtable();
d166 1
a166 1
    private static Dictionary getCache (Class key)
d171 2
a172 1
            synchronized (tableCaches)
d178 1
a178 1
                    tableCaches.put(key, cache);
d191 1
a191 1
        return (Dictionary)tableCaches.get(key);
@


1.11
log
@Added new factory interface as concretion--will soon make abstract and
implement in subclasses.
@
text
@d52 1
d62 1
d68 1
a68 1
 * @@version $Id: BusinessObject.java,v 1.10 2000/12/22 03:02:59 dlr Exp $
d73 5
d100 1
a100 1
    public BusinessObject (Connection conn, DataManager dMgr, Record rec)
d106 1
a106 1
    
d123 19
a141 8
     * Factory method for getting a handle to a business object by database
     * key.
     * <p>
     * TODO: Make <code>abstract</code> and implement in subclasses.
     */
    public BusinessObject getInstance (Connection conn, 
                                       DataManager dmgr,
                                       String id)
d143 1
a143 1
        return null;
d147 6
a152 1
     * Creates and caches all necessary database managers.
d154 4
a157 1
    protected abstract void createManagers ();
d160 1
a160 4
     * Attempts to retrieve a cached instance of the business object
     * corresponding to the provided database key.  This in memory cache 
     * should be used in all sub class constructors that take a database key 
     * argument before hitting the database.
d162 8
a169 9
     * @@param id The database key of the desired instance, or
     *           <code>null</code> if a corresponding instance is not cached.
     * @@return   The cached instance of the business object.
     */
    protected BusinessObject getCachedInstance (String id)
    {
        BusinessObject cached = null;
        Dictionary cache = getCache();
        if (cache != null)
d171 9
a179 1
            cached = (BusinessObject)cache.get(id);
d181 1
a181 1
        return cached;
d185 2
a186 5
     * Returns the cache of business object instances.  Implementation
     * of this method should involve returning a static class field,
     * and should be in the body of a <code>synchronized</code> block.
     *
     * @@return The cache.
d188 4
a191 1
    protected abstract Dictionary getCache ();
@


1.10
log
@Propogated object cache interface.
@
text
@d66 1
a66 1
 * @@version $Id: BusinessObject.java,v 1.9 2000/12/22 02:48:51 dlr Exp $
d87 5
a91 1
     * Record.
d116 13
d166 1
a166 1
    public abstract String getID() throws DataSetException;
d171 1
a171 1
    protected abstract String getTableName();
@


1.9
log
@Start of an object cache interface.
@
text
@d51 1
a51 1
import java.util.Map;
d66 1
a66 1
 * @@version $Id: BusinessObject.java,v 1.8 2000/12/13 22:31:05 dlr Exp $
d132 1
a132 1
            cached = cache.get(id);
@


1.8
log
@Added a getBooleanValue(String) method to make parsing of boolean
values from two element database enumerations easier.
@
text
@d51 1
d66 1
a66 1
 * @@version $Id: BusinessObject.java,v 1.7 2000/12/13 02:01:05 leonardr Exp $
a85 10
     * The database table, if any, from which this is supposed to be a record.
     */
    protected abstract String getTableName();

    /**
     * Some sort of unique identifier for this object.     
     */
    public abstract String getID() throws DataSetException;

    /**
d112 1
a112 1
     * Creates all the various database managers for this instance.
d115 40
@


1.7
log
@Added support for an audit log. Actually getting the log to contain things comes next.
@
text
@d65 1
a65 1
 * @@version $Id: BusinessObject.java,v 1.6 2000/12/06 22:55:33 dlr Exp $
d177 16
@


1.6
log
@Added necessary imports.
@
text
@d65 1
a65 1
 * @@version $Id: BusinessObject.java,v 1.5 2000/12/06 22:55:05 dlr Exp $
d88 5
@


1.5
log
@Moved in functionality from Domain--it is preferred that the
TableManagers be used, but there are rare cases where they cannot be.
@
text
@d55 2
d65 1
a65 1
 * @@version $Id: BusinessObject.java,v 1.4 2000/12/05 23:53:30 leonardr Exp $
@


1.4
log
@Enabled security check of records passed into business objects.
@
text
@d63 1
a63 1
 * @@version $Id: BusinessObject.java,v 1.3 2000/12/05 23:45:31 dlr Exp $
d157 13
@


1.3
log
@Corrected JavaDoc comment.
@
text
@d63 1
a63 1
 * @@version $Id: BusinessObject.java,v 1.2 2000/12/05 23:28:58 leonardr Exp $
d83 1
a83 1
     * The database table, if any, which this is supposed to be a record from.
d85 1
a85 1
    protected static String tableName;
d139 1
a139 1
            if (tableName != null)
d142 1
a142 1
                if (!tableName.equals(recTableName))
d147 1
a147 1
                        .append(tableName).append(").");
@


1.2
log
@Added a check so that business objects cannot be created with records from the wrong table. Also added some new business objects.
@
text
@d63 1
a63 1
 * @@version $Id: BusinessObject.java,v 1.1.1.1 2000/11/12 21:15:17 dlr Exp $
d121 1
a121 1
     * @@param rec The database row to use.
@


1.1
log
@Initial revision
@
text
@d53 1
d63 1
a63 1
 * @@version $Id: BusinessObject.java,v 1.2 2000/11/10 01:50:37 dlr Exp $
d83 5
d92 1
a92 1
        throws DoesNotExist
d97 1
a97 1

d119 11
d135 1
a135 1
        throws DoesNotExist
d139 12
@


1.1.1.1
log
@Merging newhelm tree into helm, as per IZ issue #557.  Previous major version of helm is tagged TIGRIS_NOV_11_2000.
@
text
@@
