David,

Here is the RowReader that I use for this.  It's an abstract class; a subclass
to handle a specific table would have code like this:

    protected String getDiscriminatorColumn() {
        return "KeyColumn";
    }

    protected Map getClassMappings() {
        if (sClassMap == null) {
            sClassMap = new HashMap();
            sClassMap.put("KeyValue1", Class1.class);
            sClassMap.put("KeyValue2", Class2.class);
        }
        return sClassMap;
    }


Here's the superclass:

package gov.doi.tat.ojb.readers;

import java.util.HashMap;
import java.util.Map;

import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.PersistenceBrokerException;
import org.apache.ojb.broker.PersistenceBrokerFactory;
import org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.FieldDescriptor;

/**
 * This class implements an OJB RowReader which can be used to read
 * objects from a table to which multiple classes have been mapped, with
 * String values in a designated column being used to indicate the
 * particular class to be instantiated.  The class is abstract; a subclass
 * must provide information about the mapping column and its values.
 *
 * @author <a href="mailto:[EMAIL PROTECTED]">Steve Clark</a>
 */
public abstract class KeyColumnClassMappingRowReader
    extends RowReaderDefaultImpl
{
    /** Column containing site type key */
    private String sKeyColumn = null;

    /** Mappings from sKeyColumn values to Classes */
    private static Map sClassMap = null;


    public KeyColumnClassMappingRowReader(ClassDescriptor cld) {
        super(cld);
        sKeyColumn = getDiscriminatorColumn();
        sClassMap = getClassMappings();
    }

    /**
     * Return the name of the column used to discriminate between
     * different classes.
     */
    protected abstract String getDiscriminatorColumn();

    /**
     * Return the mappings from values of the discriminator column
     * to classes to instantiate.
     */
    protected abstract Map getClassMappings();


    protected ClassDescriptor selectClassDescriptor(Map row)
        throws PersistenceBrokerException
    {
        String key = (String) row.get(sKeyColumn);
        Class clazz = null;

        if (key != null) {
            clazz = (Class) sClassMap.get(key);
        }
        if (clazz == null) {
            return getClassDescriptor();
        }

        PersistenceBroker broker = null;
        try {
            broker = PersistenceBrokerFactory.defaultPersistenceBroker();
            ClassDescriptor result = broker.getClassDescriptor(clazz);
            broker.close();
            if (result == null) {
                return getClassDescriptor();
            }
            else {
                return result;
            }
        }
        catch (PersistenceBrokerException e) {
            broker.close();
            throw e;
        }
    }
}

Hope this helps.

-steve

Steve Clark
Technology Applications Team
Natural Resources Research Center/USGS
[EMAIL PROTECTED]
(970)226-9291

>List-Id: "OJB Users List" <ojb-user.db.apache.org>
>Subject: RE: Getting the correct class instantiated
>To: "OJB Users List" <[EMAIL PROTECTED]>
>Cc: "'OJB Users List'" <[EMAIL PROTECTED]>
>From: [EMAIL PROTECTED]
>Date: Thu, 26 Jun 2003 08:51:30 -0400
>
>
>Well, not really.  Your code looks like it's examining the database to find
>the right ClassDescriptor, which I don't really need to do.  I'm looking
>for a way to override readObjectFromRow, so that I can simply return an
>object of the correct class.  All the different classes come from the same
>table, so I want to have only one class descriptor.
>
>David


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to