You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by th...@apache.org on 2002/11/30 18:34:29 UTC

cvs commit: jakarta-ojb/src/java/org/apache/ojb/broker/metadata ClassDescriptor.java

thma        2002/11/30 09:34:29

  Modified:    src/java/org/apache/ojb/broker/metadata ClassDescriptor.java
  Log:
  add accept locks attribute to class-descriptor
  
  Revision  Changes    Path
  1.42      +1731 -1702jakarta-ojb/src/java/org/apache/ojb/broker/metadata/ClassDescriptor.java
  
  Index: ClassDescriptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ojb/src/java/org/apache/ojb/broker/metadata/ClassDescriptor.java,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- ClassDescriptor.java	21 Nov 2002 22:56:11 -0000	1.41
  +++ ClassDescriptor.java	30 Nov 2002 17:34:28 -0000	1.42
  @@ -1,1702 +1,1731 @@
  -package org.apache.ojb.broker.metadata;
  -
  -/* ====================================================================
  - * The Apache Software License, Version 1.1
  - *
  - * Copyright (c) 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 ObjectRelationalBridge" 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 ObjectRelationalBridge", 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 org.apache.ojb.broker.OJBRuntimeException;
  -import org.apache.ojb.broker.PersistenceBroker;
  -import org.apache.ojb.broker.PersistenceBrokerException;
  -import org.apache.ojb.broker.PersistenceBrokerFactory;
  -import org.apache.ojb.broker.accesslayer.RowReader;
  -import org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl;
  -import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
  -import org.apache.ojb.broker.util.logging.LoggerFactory;
  -
  -import java.io.Serializable;
  -import java.lang.reflect.Constructor;
  -import java.lang.reflect.Modifier;
  -import java.sql.Timestamp;
  -import java.util.ArrayList;
  -import java.util.Arrays;
  -import java.util.Collections;
  -import java.util.Date;
  -import java.util.HashMap;
  -import java.util.Iterator;
  -import java.util.Map;
  -import java.util.Vector;
  -
  -//#ifdef JDK13
  -import java.lang.reflect.Proxy;
  -//#else
  -/*
  -import com.develop.java.lang.reflect.Proxy;
  -*/
  -//#endif
  -
  -/**
  - * A ClassDescriptor contains all information for mapping objects of a
  - * given class to database tables.
  - *
  - * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
  - * @version $Id$
  - */
  -public class ClassDescriptor extends DescriptorBase implements Serializable, XmlCapable, IsolationLevels
  -{
  -
  -    public static final String OJB_CONCRETE_CLASS = "ojbConcreteClass";
  -
  -    private transient DescriptorRepository m_repository;
  -
  -    /**
  -     * transaction isolation level specified for this class, used in the ODMG server
  -     */
  -    private int m_IsolationLevel = IsolationLevels.IL_READ_UNCOMMITTED;
  -
  -    /**
  -     * the SQL SCHEMA of the underlying table of this class
  -     */
  -    private String schema = null;
  -
  -    /**
  -     * the described class
  -     */
  -    private Class m_Class = null;
  -
  -    /**
  -     * the name of the described class
  -     */
  -    private String classname = null;
  -
  -
  -    /**
  -     * the table name used to store the scalar attributes of this class
  -     */
  -    private String m_TableName = null;
  -
  -    /**
  -     * the FieldDescriptors for the primitive attributes
  -     */
  -    private FieldDescriptor[] m_FieldDescriptions = null;
  -
  -    /**
  -     * the descriptors for collection attributes
  -     */
  -    private Vector m_CollectionDescriptors = new Vector();
  -
  -    /**
  -     * the descriptor for 1-1 reference attributes
  -     */
  -    private Vector m_ObjectReferenceDescriptors = new Vector();
  -
  -    /**
  -     * the vector of indices used in DDL generation.
  -     */
  -    private Vector indexes = new Vector();
  -
  -    /**
  -     * the JDBCConnectionDescriptor describing the RDBMS connection to be used for this class
  -     */
  -    private JdbcConnectionDescriptor m_ConnDescription = null;
  -
  -    /**
  -     * the non-primary key FieldDescriptors
  -     */
  -    private FieldDescriptor[] nonPrimaryKeyFieldDescriptors = null;
  -
  -    /**
  -     * the primary key FieldDescriptors
  -     */
  -    private FieldDescriptor[] primaryKeyFieldDescriptors = null;
  -
  -    /**
  -     * the optimistic lockingFieldDescriptors BRJ
  -     */
  -    private FieldDescriptor[] lockingFieldDescriptors = null;
  -
  -    /**
  -     * the RowReader for this class
  -     */
  -    private RowReader rowReader = null;
  -
  -    /**
  -     * the RowReader class name for this class
  -     */
  -    private String rowReaderClassName = null;
  -
  -    /**
  -     * tells whether we tried to lookup multiargs Constructor already
  -     */
  -    private boolean alreadyLookedup = false;
  -
  -    /**
  -     * the types of the arguments for the attributes in m_FieldDescriptions
  -     */
  -    private Class[] argsForConstructor = null;
  -
  -    /**
  -     * the list of classes in the extent of this class. can be empty
  -     */
  -    private Vector extentClasses = new Vector();
  -
  -    /**
  -     * the list of class names in the extent of this class. can be empty
  -     */
  -    private Vector extentClassNames = new Vector();
  -
  -    /**
  -     * the class that this class extends
  -     */
  -    private String superClass;
  -    /**
  -     * reference column for the superclass
  -     */
  -    private int superClassFieldRef;
  -
  -    /**
  -     * does the described class represent an interface?
  -     */
  -    private boolean isInterface = false;
  -
  -    /**
  -     * the constructor defined by m_Class to initialze all scalar attributes described in m_FieldDescriptions
  -     */
  -    private Constructor multiArgumentConstructor = null;
  -
  -    /**
  -     * the proxy class for the described class, may be null
  -     */
  -    private Class proxyClass = null;
  -
  -    /**
  -     * the proxy class name for the described class, may be null
  -     */
  -    private String proxyClassName = null;
  -
  -    private FieldDescriptor m_autoIncrementField = null;
  -
  -    private Map m_fieldDescriptorNameMap = new HashMap();
  -    private Map m_collectionDescriptorNameMap = new HashMap();
  -    private Map m_objectReferenceDescriptorsNameMap = new HashMap();
  -
  -
  -    /**
  -     * Constructor declaration
  -     */
  -    public ClassDescriptor(DescriptorRepository pRepository)
  -    {
  -        this.m_repository = pRepository;
  -    }
  -
  -    public ClassDescriptor()
  -    {
  -        this(DescriptorRepository.getDefaultInstance());
  -    }
  -
  -
  -    /**
  -     * sets the row reader class for thie class descriptor
  -     */
  -    public void setRowReader(RowReader newReader)
  -    {
  -        this.rowReader = newReader;
  -        setRowReaderClassName(newReader.getClass().getName());
  -    }
  -
  -    /**
  -     * sets the row reader class name for thie class descriptor
  -     */
  -    public void setRowReaderClassName(String newReaderClassName)
  -    {
  -        this.rowReaderClassName = newReaderClassName;
  -    }
  -
  -    public String getRowReaderClassName()
  -    {
  -        return this.rowReaderClassName;
  -    }
  -
  -
  -    public synchronized RowReader getRowReader()
  -    {
  -        if (rowReader == null)
  -        {
  -            // if no RowReader has been declared, use the default reader
  -            if (rowReaderClassName == null)
  -            {
  -                rowReader = new RowReaderDefaultImpl();
  -            }
  -            else
  -            {
  -                try
  -                {
  -                    Class rowReaderClass = Class.forName(rowReaderClassName, true,
  -                            Thread.currentThread().getContextClassLoader());
  -                    rowReader = (RowReader) rowReaderClass.newInstance();
  -                }
  -                catch (Exception e)
  -                {
  -                    throw new MetadataException(e);
  -                }
  -            }
  -        }
  -        return this.rowReader;
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @return
  -     */
  -    private String getTableName()
  -    {
  -        return m_TableName;
  -    }
  -
  -    /**
  -     * Answer Table name including schema	BRJ
  -     */
  -    public String getFullTableName()
  -    {
  -        if (getSchema() != null)
  -            return getSchema() + "." + getTableName();
  -        else
  -            return getTableName();
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @param str
  -     */
  -    public void setTableName(String str)
  -    {
  -        m_TableName = str;
  -    }
  -
  -    /**
  -     * returns the name of the described class
  -     * @return String name of the described class
  -     */
  -    public String getClassNameOfObject()
  -    {
  -        return this.classname;
  -    }
  -
  -
  -    /**
  -     * returns the class object of the described class
  -     * @return Class the described class
  -     */
  -    public Class getClassOfObject()
  -    {
  -        if (m_Class != null)
  -        {
  -            return m_Class;
  -        }
  -        else if (classname != null)
  -        {
  -            try
  -            {
  -                m_Class = Class.forName(classname, true, Thread.currentThread().getContextClassLoader());
  -                return m_Class;
  -            }
  -            catch (ClassNotFoundException e)
  -            {
  -                throw new PersistenceBrokerException(e);
  -            }
  -        }
  -        else
  -        {
  -            return null;
  -        }
  -    }
  -
  -    /**
  -     * sets the class object described by this descriptor.
  -     * @param c the class to describe
  -     */
  -    public void setClassOfObject(Class c)
  -    {
  -        m_Class = c;
  -        this.classname = c.getName();
  -    }
  -
  -    /**
  -     * sets the name of the class described by this descriptor.
  -     * @param classname the class to describe
  -     */
  -    public void setClassNameOfObject(String classname)
  -    {
  -        this.classname = classname;
  -        // Shouldn't the HashMap in DescriptorRepository be updated as well?
  -    }
  -
  -
  -    /**
  -     * adds a FIELDDESCRIPTOR to this ClassDescriptor.
  -     * @param fld
  -     */
  -    public void addFieldDescriptor(FieldDescriptor fld)
  -    {
  -        fld.setClassDescriptor(this); // BRJ
  -        if (m_FieldDescriptions == null)
  -        {
  -            m_FieldDescriptions = new FieldDescriptor[1];
  -            m_FieldDescriptions[0] = fld;
  -            m_fieldDescriptorNameMap = new HashMap();
  -        }
  -        else
  -        {
  -            int size = m_FieldDescriptions.length;
  -            FieldDescriptor[] tmpArray = new FieldDescriptor[size + 1];
  -            System.arraycopy(m_FieldDescriptions, 0, tmpArray, 0, size);
  -            tmpArray[size] = fld;
  -            m_FieldDescriptions = tmpArray;
  -            // 2. Sort fields according to their getOrder() Property
  -            Arrays.sort(m_FieldDescriptions, FieldDescriptor.getComparator());
  -        }
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @return
  -     */
  -    public Vector getCollectionDescriptors()
  -    {
  -        return m_CollectionDescriptors;
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @param cod
  -     */
  -    public void addCollectionDescriptor(CollectionDescriptor cod)
  -    {
  -        cod.setClassDescriptor(this); // BRJ
  -        m_CollectionDescriptors.add(cod);
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @return
  -     */
  -    public Vector getObjectReferenceDescriptors()
  -    {
  -        return m_ObjectReferenceDescriptors;
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @param ord
  -     */
  -    public void addObjectReferenceDescriptor(ObjectReferenceDescriptor ord)
  -    {
  -        ord.setClassDescriptor(this); // BRJ
  -        m_ObjectReferenceDescriptors.add(ord);
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @return
  -     */
  -    public JdbcConnectionDescriptor getConnectionDescriptor()
  -    {
  -        if (m_ConnDescription == null)
  -        {
  -            // if class has no special JDBC Connection use the DefaultConnection
  -            m_ConnDescription = this.getRepository().getDefaultJdbcConnection();
  -        }
  -        return m_ConnDescription;
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @param jcd
  -     */
  -    public void setConnectionDescriptor(JdbcConnectionDescriptor jcd)
  -    {
  -        m_ConnDescription = jcd;
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @param index
  -     * @return
  -     */
  -    public FieldDescriptor getFieldDescriptorByIndex(int index)
  -    {
  -        return m_FieldDescriptions[index - 1];
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @return
  -     */
  -    public String toString()
  -    {
  -        return "table:      \t"
  -                + m_TableName
  -                + "\n"
  -                + "FieldDescriptions:\t"
  -                + (m_FieldDescriptions == null ? "" : m_FieldDescriptions.toString());
  -
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @param name
  -     * @return
  -     */
  -    public FieldDescriptor getFieldDescriptorByName(String name)
  -    {
  -        if (name == null)
  -            return null;
  -        if (m_FieldDescriptions == null)
  -            return null;
  -        FieldDescriptor retval = (FieldDescriptor) m_fieldDescriptorNameMap.get(name);
  -        if (retval == null)
  -        {
  -            int size = m_FieldDescriptions.length;
  -            FieldDescriptor temp = null;
  -            for (int i = 0; ((i < size) && (retval == null)); i++)
  -            {
  -                temp = m_FieldDescriptions[i];
  -                if (name.equals(temp.getPersistentField().getName()))
  -                {
  -                    retval = temp;
  -                    m_fieldDescriptorNameMap.put(name, retval);
  -                    break;
  -                }
  -            }
  -        }
  -        return retval;
  -    }
  -
  -    /**
  -     * Get an ObjectReferenceDescriptor by name	BRJ
  -     * @param name
  -     * @return ObjectReferenceDescriptor or null
  -     */
  -    public ObjectReferenceDescriptor getObjectReferenceDescriptorByName(String name)
  -    {
  -        if (name == null)
  -            return null;
  -        ObjectReferenceDescriptor retval = (ObjectReferenceDescriptor) this.m_objectReferenceDescriptorsNameMap.get(name);
  -        if (retval == null)
  -        {
  -            Vector descr = getObjectReferenceDescriptors();
  -            int size = descr.size();
  -            for (int i = 0; i < size; i++)
  -            {
  -                ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) descr.elementAt(i);
  -                if (ord.getPersistentField().getName().equals(name))
  -                {
  -                    retval = ord;
  -                    m_objectReferenceDescriptorsNameMap.put(name, retval);
  -                    break;
  -                }
  -            }
  -        }
  -        return retval;
  -    }
  -
  -    /**
  -     * Get an CollectionDescriptor by name	BRJ
  -     * @param name
  -     * @return CollectionDescriptor or null
  -     */
  -    public CollectionDescriptor getCollectionDescriptorByName(String name)
  -    {
  -        if (name == null)
  -            return null;
  -        CollectionDescriptor retval = (CollectionDescriptor) this.m_collectionDescriptorNameMap.get(name);
  -        if (retval == null)
  -        {
  -            Vector descr = getCollectionDescriptors();
  -            int size = descr.size();
  -            for (int i = 0; i < size; i++)
  -            {
  -                CollectionDescriptor ord = (CollectionDescriptor) descr.elementAt(i);
  -                if (ord.getPersistentField().getName().equals(name))
  -                {
  -                    retval = ord;
  -                    m_collectionDescriptorNameMap.put(name, retval);
  -                    break;
  -                }
  -            }
  -        }
  -        return retval;
  -    }
  -
  -    /**
  -     * returns the transaction isolation level to be used for this class. Used only in the ODMG server
  -     */
  -    public int getIsolationLevel()
  -    {
  -        return m_IsolationLevel;
  -    }
  -
  -    /**
  -     * Method declaration
  -     * @param isoLevel
  -     */
  -    public void setIsolationLevel(int isoLevel)
  -    {
  -        m_IsolationLevel = isoLevel;
  -    }
  -
  -
  -    /**
  -     * add an Extent class to the current descriptor
  -     * @param newExtendClass
  -     */
  -    public void addExtentClass(Class newExtendClass)
  -    {
  -        extentClasses.add(newExtendClass);
  -        this.addExtentClassName(newExtendClass.getName());
  -    }
  -
  -    /**
  -     * add an Extent class to the current descriptor
  -     * @param newExtendClassName name of the class to add
  -     */
  -    public void addExtentClassName(String newExtendClassName)
  -    {
  -        extentClassNames.add(newExtendClassName);
  -        m_repository.addExtent(newExtendClassName, this);
  -    }
  -
  -    public void setSuperClass(String classname)
  -    {
  -        this.superClass = classname;
  -
  -
  -    }
  -
  -    public void setSuperClassFieldRef(int fieldId)
  -    {
  -        this.superClassFieldRef = fieldId;
  -    }
  -
  -    public int getSuperClassFieldRef()
  -    {
  -        return superClassFieldRef;
  -    }
  -
  -    public String getSuperClass()
  -    {
  -        return superClass;
  -    }
  -
  -    /**
  -     * returns a Constructor that takes all persistent attributes
  -     * of the class as arguments.
  -     * Returns null, if such a constructor does not exist.
  -     * PersistenceBroker clients are not urged to implement such constructors
  -     * for persistence capable classes. But it's strongly recommended as
  -     * it minimizes the overhead for reflective operations.
  -     */
  -    public Constructor getConstructor()
  -    {
  -        if (multiArgumentConstructor == null && !alreadyLookedup)
  -        {
  -            if (argsForConstructor == null)
  -            {
  -                argsForConstructor = new Class[getFieldDescriptions().length];
  -                for (int i = 0; i < getFieldDescriptions().length; i++)
  -                {
  -                    argsForConstructor[i] = getFieldDescriptions()[i].getPersistentField().getType();
  -                }
  -            }
  -            try
  -            {
  -                multiArgumentConstructor = getClassOfObject().getConstructor(argsForConstructor);
  -            }
  -            catch (Exception ignored)
  -            {
  -                // this exception is thrown, if no suitable Constructor was
  -                // found. In this case we tell the user that it is better to have
  -                // a multiargs constructor defined
  -                String args = "";
  -                for (int i = 0; i < argsForConstructor.length; i++)
  -                {
  -                    args += ((args.length() == 0) ? "(" : ", ");
  -                    args += argsForConstructor[i].getName();
  -                }
  -                args += ")";
  -                LoggerFactory.getDefaultLogger().warn(
  -                        "Please define a public constructor for "
  -                        + this.getClassOfObject()
  -                        + "\nwith the following signature: "
  -                        + args
  -                        + ".\nIt must initialize the classes persistent attributes. This is recommended to increase performance but it's not mandatory!");
  -            }
  -            alreadyLookedup = true;
  -        }
  -        return multiArgumentConstructor;
  -    }
  -
  -    /**
  -     * return all classes in this extent.
  -     * Creation date: (02.02.2001 17:49:11)
  -     * @return java.util.Vector
  -     */
  -    public synchronized Vector getExtentClasses()
  -    {
  -        if (extentClassNames.size() > extentClasses.size())
  -        {
  -            extentClasses.clear();
  -            for (Iterator iter = extentClassNames.iterator(); iter.hasNext();)
  -            {
  -                String classname = (String) iter.next();
  -                Class extentClass;
  -                try
  -                {
  -                    extentClass = Class.forName(classname, true,
  -                            Thread.currentThread().getContextClassLoader());
  -                }
  -                catch (ClassNotFoundException e)
  -                {
  -                    throw new MetadataException("Unable to load class [" + classname + "]. Make sure it is available on the classpath.", e);
  -                }
  -                extentClasses.add(extentClass);
  -            }
  -        }
  -        return extentClasses;
  -    }
  -
  -    /**
  -     * Return the names of all classes in this extent
  -     * @return java.util.Vector a Vector containing the fully qualified names
  -     * of all classes in this extent
  -     */
  -    public synchronized Vector getExtentClassNames()
  -    {
  -        return this.extentClassNames;
  -    }
  -
  -    /**
  -     * Insert the method's description here.
  -     * Creation date: (26.01.2001 09:20:09)
  -     * @return java.lang.Class
  -     */
  -    public synchronized java.lang.Class getProxyClass()
  -    {
  -
  -        if ((proxyClass == null) && (proxyClassName != null))
  -        {
  -            String dynamic = "dynamic";
  -            if (dynamic.equalsIgnoreCase(proxyClassName))
  -            {
  -                proxyClass = getDynamicProxyClass();
  -            }
  -            else
  -            {
  -                try
  -                {
  -                    proxyClass = Class.forName(proxyClassName, true,
  -                            Thread.currentThread().getContextClassLoader());
  -                }
  -                catch (ClassNotFoundException e)
  -                {
  -                    throw new MetadataException(e);
  -                }
  -            }
  -        }
  -        return proxyClass;
  -    }
  -
  -    /**
  -     * Insert the method's description here.
  -     * Creation date: (02.02.2001 17:49:11)
  -     * @return boolean
  -     */
  -    public boolean isExtent()
  -    {
  -        return (getExtentClassNames().size() > 0);
  -    }
  -
  -    /**
  -     * Insert the method's description here.
  -     * Creation date: (02.02.2001 17:49:11)
  -     * @return boolean
  -     */
  -    public boolean isInterface()
  -    {
  -        return isInterface;
  -    }
  -
  -    /**
  -     * Insert the method's description here.
  -     * Creation date: (02.02.2001 17:49:11)
  -     * @param newIsInterface boolean
  -     */
  -    public void setIsInterface(boolean newIsInterface)
  -    {
  -        isInterface = newIsInterface;
  -    }
  -
  -    /**
  -     * @return boolean true if the mapped class is abstract
  -     */
  -    public boolean isAbstract()
  -    {
  -        return Modifier.isAbstract(getClassOfObject().getModifiers());
  -    }
  -
  -    /**
  -     * Sets the proxy class to be used.
  -     * @param newProxyClass java.lang.Class
  -     */
  -    public void setProxyClass(java.lang.Class newProxyClass)
  -    {
  -        proxyClass = newProxyClass;
  -        if (proxyClass == null)
  -            setProxyClassName(null);
  -        else
  -            proxyClassName = proxyClass.getName();
  -    }
  -
  -    /**
  -     * Sets the name of the proxy class to be used.
  -     * using "dynamic" instead of a real classname
  -     * will result in usage of dynamic proxies.
  -     * @param newProxyClassName the classname or "dynamic"
  -     */
  -    public void setProxyClassName(String newProxyClassName)
  -    {
  -        proxyClassName = newProxyClassName;
  -    }
  -
  -    /**
  -     * Get the name of the proxy class. This method doesn't try to access
  -     * the real class, so it can be called even if the class doesn't exist.
  -     */
  -    public String getProxyClassName()
  -    {
  -        return proxyClassName;
  -    }
  -
  -    /**
  -     * returns a vector containing values for all the Objects attribute
  -     * @throws MetadataException if tehre is an erros accessing obj field values
  -     */
  -    public Object[] getAllValues(Object obj) throws PersistenceBrokerException
  -    {
  -        FieldDescriptor[] allFields = getFieldDescriptions();
  -        Object[] result = new Object[allFields.length];
  -
  -        for (int i = 0; i < allFields.length; i++)
  -        {
  -            FieldDescriptor fmd = allFields[i];
  -            PersistentField f = fmd.getPersistentField();
  -            Object cv = f.get(obj);
  -
  -            // handle autoincrement attributes if not filled
  -            if (fmd.isAutoIncrement())
  -            {
  -                cv = getAutoIncrementValue(fmd, obj, cv);
  -            }
  -
  -            // apply type and value mapping
  -            cv = fmd.getFieldConversion().javaToSql(cv);
  -            result[i] = cv;
  -        }
  -        return result;
  -    }
  -
  -    /**
  -     * returns array of all FieldDescriptors.
  -     * @return FIELDDESCRIPTOR[]
  -     */
  -    public FieldDescriptor[] getFieldDescriptions()
  -    {
  -        return m_FieldDescriptions;
  -    }
  -
  -    /**
  -     * returns an Array with an Objects PK VALUES, with any java-to-sql
  -     * FieldConversion applied
  -     * @throws MetadataException if there is an erros accessing o field values
  -     */
  -    public Object[] getKeyValues(Object o) throws PersistenceBrokerException
  -    {
  -        return getKeyValues(o, true);
  -    }
  -
  -    /**
  -     * returns an Array with an Objects PK VALUES
  -     * if convertToSql is true, any associated java-to-sql conversions are applied
  -     * @throws MetadataException if there is an erros accessing o field values
  -     */
  -    public Object[] getKeyValues(Object o, boolean convertToSql) throws PersistenceBrokerException
  -    {
  -        FieldDescriptor[] pkFields = getPkFields();
  -        Object[] result = new Object[pkFields.length];
  -
  -        for (int i = 0; i < result.length; i++)
  -        {
  -            FieldDescriptor fmd = pkFields[i];
  -            PersistentField f = fmd.getPersistentField();
  -            Object cv = f.get(o);
  -
  -            // handle autoincrement attributes if not filled
  -            if (fmd.isAutoIncrement())
  -            {
  -                cv = getAutoIncrementValue(fmd, o, cv);
  -            }
  -
  -            if (convertToSql)
  -            {
  -                // BRJ : apply type and value mapping
  -                cv = fmd.getFieldConversion().javaToSql(cv);
  -            }
  -            result[i] = cv;
  -        }
  -        return result;
  -    }
  -
  -    /**
  -     * returns an Array with an Objects CURRENT locking VALUES , BRJ
  -     * @throws MetadataException if there is an erros accessing o field values
  -     */
  -    public Object[] getCurrentLockingValues(Object o) throws PersistenceBrokerException
  -    {
  -        FieldDescriptor[] fields = getLockingFields();
  -        Object[] result = new Object[fields.length];
  -        for (int i = 0; i < result.length; i++)
  -        {
  -            FieldDescriptor fmd = fields[i];
  -            PersistentField f = fmd.getPersistentField();
  -            Object cv = null;
  -            cv = f.get(o); // retrieve the Objects value for the specified field
  -            result[i] = cv;
  -        }
  -        return result;
  -    }
  -
  -    /**
  -     * updates the values for locking fields , BRJ
  -     * handles int, long, Timestamp
  -     * @throws MetadataException if there is an erros accessing obj field values
  -     */
  -    public void updateLockingValues(Object obj) throws PersistenceBrokerException
  -    {
  -        FieldDescriptor[] fields = getLockingFields();
  -        for (int i = 0; i < fields.length; i++)
  -        {
  -            FieldDescriptor fmd = fields[i];
  -            PersistentField f = fmd.getPersistentField();
  -            Object cv = null;
  -            cv = f.get(obj);
  -
  -            // int
  -            if ((f.getType() == int.class) || (f.getType() == Integer.class))
  -
  -            {
  -                int newCv = 0;
  -                if (cv != null)
  -                {
  -                    newCv = ((Number) cv).intValue();
  -                }
  -                newCv++;
  -                f.set(obj, new Integer(newCv));
  -            }
  -            // long
  -            else if ((f.getType() == long.class) || (f.getType() == Long.class))
  -
  -            {
  -                long newCv = 0;
  -                if (cv != null)
  -                {
  -                    newCv = ((Number) cv).longValue();
  -                }
  -                newCv++;
  -                f.set(obj, new Long(newCv));
  -            }
  -            // Timestamp
  -            else if (f.getType() == Timestamp.class)
  -
  -            {
  -                long newCv = (new Date()).getTime();
  -                f.set(obj, new Timestamp(newCv));
  -            }
  -        }
  -    }
  -
  -    /**
  -     * @throws MetadataException if there is an erros accessing obj field values
  -     */
  -    private Object getAutoIncrementValue(FieldDescriptor fmd, Object obj, Object cv)
  -    {
  -        if ((cv == null) || ((cv instanceof Number) && (((Number) cv).intValue() == 0)))
  -        {
  -            PersistentField f = fmd.getPersistentField();
  -            Object result = cv;
  -            PersistenceBroker broker = null;
  -            try
  -            {
  -                if (m_repository != null)
  -                {
  -                    // arminw
  -                    // use the PBKey of the associated descriptor repository
  -                    // to match the 'correct' repository
  -                    /* @todo maybe this could be critical in some
  -                     * situations, e.g. if the associated PBKey was always the
  -                     * default PBKey. Check this out.
  -                     */
  -                    broker = PersistenceBrokerFactory.createPersistenceBroker(m_repository.getPBkey());
  -                }
  -                else
  -                {
  -                    // no repository, we use the default PB
  -                    broker = PersistenceBrokerFactory.defaultPersistenceBroker();
  -                }
  -                // int
  -                if ((f.getType() == int.class) || (f.getType() == Integer.class))
  -                {
  -                    if ((f.get(obj) == null) || (((Number) f.get(obj)).intValue() == 0))
  -                    {
  -                        /*
  -                        arminw
  -                        old version
  -                        Class extent = broker.getExtentClass(this.getClassOfObject());
  -                        result = new Integer(broker.getUniqueId(extent, f.getName()));
  -
  -                        we should not give the top-level extent to sequence manager,
  -                        sequence manager itself should take care of uniqueness over the extents
  -                        */
  -                        result = new Integer(broker.getUniqueId(fmd));
  -                        // reflect autoincrement value back into object
  -                        f.set(obj, result);
  -                    }
  -                }
  -                // long
  -                else if ((f.getType() == long.class) || (f.getType() == Long.class))
  -                {
  -                    if ((f.get(obj) == null) || (((Number) f.get(obj)).longValue() == 0))
  -                    {
  -                        /*
  -                        arminw
  -                        old version
  -                        Class extent = broker.getExtentClass(this.getClassOfObject());
  -                        result = new Long(broker.getUniqueLong(extent, f.getName()));
  -
  -                        we should not give the top-level extent to sequence manager,
  -                        sequence manager itself should take care of uniqueness over the extents
  -                        */
  -
  -                        result = new Long(broker.getUniqueLong(fmd));
  -                        // reflect autoincrement value back into object
  -                        f.set(obj, result);
  -                    }
  -                }
  -                // String
  -                else if (String.class.isAssignableFrom(f.getType()))
  -                {
  -                    if (f.get(obj) == null)
  -                    {
  -                        result = broker.getUniqueString(fmd);
  -                        // reflect autoincrement value back into object
  -                        f.set(obj, result);
  -                    }
  -                }
  -                // Object
  -                else if (!f.getType().isPrimitive())
  -                {
  -                    // only assign a value if attribute == null
  -                    if (f.get(obj) == null)
  -                    {
  -                        result = broker.getUniqueObject(fmd);
  -                        if (result != null)
  -                        {
  -                            // reflect autoincrement value back into object
  -                            f.set(obj, result);
  -                        }
  -                        else
  -                        {
  -                            throw new OJBRuntimeException(
  -                                    "OJB ERROR: Dont know how to autoincrement field " +
  -                                    f.getDeclaringClass() + "#" + f.getName());
  -                        }
  -                    }
  -                }
  -                else
  -                {
  -                    throw new OJBRuntimeException(
  -                            "OJB ERROR: Dont know how to autoincrement field " +
  -                            f.getDeclaringClass() + "#" + f.getName());
  -                }
  -                return result;
  -            }
  -            catch (MetadataException e)
  -            {
  -                throw new OJBRuntimeException(
  -                        "Error while trying to autoincrement field " +
  -                        f.getDeclaringClass() + "#" + f.getName(), e);
  -            }
  -            finally
  -            {
  -                if (broker != null)
  -                {
  -                    broker.close();
  -                }
  -            }
  -        }
  -        else
  -        {
  -            return cv;
  -        }
  -
  -    }
  -
  -    /**
  -     * returns an Array with an Objects NON-PK VALUES
  -     * @throws MetadataException if there is an erros accessing o field values
  -     */
  -    public Object[] getNonKeyValues(Object o) throws PersistenceBrokerException
  -    {
  -        FieldDescriptor[] nonPkFields = getNonPkFields();
  -        Object[] result = new Object[nonPkFields.length];
  -
  -        for (int i = 0; i < result.length; i++)
  -        {
  -            FieldDescriptor fmd = nonPkFields[i];
  -            PersistentField f = fmd.getPersistentField();
  -            Object cv = f.get(o);
  -
  -            // handle autoincrement attributes if not filled
  -            if (fmd.isAutoIncrement())
  -            {
  -                cv = getAutoIncrementValue(fmd, o, cv);
  -            }
  -
  -            // apply type and value conversion
  -            cv = fmd.getFieldConversion().javaToSql(cv);
  -            result[i] = cv;
  -        }
  -        return result;
  -    }
  -
  -    /**
  -     * return an array of PK FieldDescription sorted ascending
  -     * according to the field-descriptions getOrder() property
  -     */
  -    public FieldDescriptor[] getNonPkFields()
  -    {
  -        if (nonPrimaryKeyFieldDescriptors == null)
  -        {
  -            // 1. collect all Primary Key fields from Field list
  -            Vector vec = new Vector();
  -            for (int i = 0; i < m_FieldDescriptions.length; i++)
  -            {
  -                FieldDescriptor fmd = m_FieldDescriptions[i];
  -                if (!fmd.isPrimaryKey())
  -                {
  -                    vec.add(fmd);
  -                }
  -            }
  -            // 2. Sort fields according to their getOrder() Property
  -            Collections.sort(vec, FieldDescriptor.getComparator());
  -            nonPrimaryKeyFieldDescriptors = (FieldDescriptor[]) vec.toArray(new FieldDescriptor[vec.size()]);
  -        }
  -        return nonPrimaryKeyFieldDescriptors;
  -    }
  -
  -    /**
  -     * return an array of PK FieldDescription sorted ascending
  -     * according to the field-descriptions getOrder() property
  -     */
  -    public FieldDescriptor[] getPkFields()
  -    {
  -        if (primaryKeyFieldDescriptors == null)
  -        {
  -            // 1. collect all Primary Key fields from Field list
  -            Vector vec = new Vector();
  -            FieldDescriptor[] fields = null;
  -            // 1.a if descriptor describes an interface: take PK fields from an implementors ClassDescriptor
  -            if (isInterface)
  -            {
  -                if (getExtentClasses().size() == 0)
  -                {
  -                    throw new PersistenceBrokerException(
  -                            "No Implementors declared for interface " + this.getClassOfObject().getName());
  -                }
  -                Class implementor = (Class) getExtentClasses().get(0);
  -                ClassDescriptor implCld = this.getRepository().getDescriptorFor(implementor);
  -                primaryKeyFieldDescriptors = implCld.getPkFields();
  -                return primaryKeyFieldDescriptors;
  -            }
  -            // 1.b if not an interface The classdescriptor must have FieldDescriptors
  -            else
  -            {
  -                fields = this.getFieldDescriptions();
  -            }
  -
  -            // now collect all PK fields
  -            for (int i = 0; i < fields.length; i++)
  -            {
  -                FieldDescriptor fmd = fields[i];
  -                if (fmd.isPrimaryKey())
  -                {
  -                    vec.add(fmd);
  -                }
  -            }
  -            // 2. Sort fields according to their getOrder() Property
  -            Collections.sort(vec, FieldDescriptor.getComparator());
  -            primaryKeyFieldDescriptors = (FieldDescriptor[]) vec.toArray(new FieldDescriptor[vec.size()]);
  -        }
  -        return primaryKeyFieldDescriptors;
  -    }
  -
  -    /**
  -     * return an array of FieldDescription for optimistic locking sorted ascending
  -     * according to the field-descriptions getOrder() property
  -     */
  -    public FieldDescriptor[] getLockingFields()
  -    {
  -        if (lockingFieldDescriptors == null)
  -        {
  -            // 1. collect all Primary Key fields from Field list
  -            Vector vec = new Vector();
  -            for (int i = 0; i < m_FieldDescriptions.length; i++)
  -            {
  -                FieldDescriptor fmd = m_FieldDescriptions[i];
  -                if (fmd.isLocking())
  -                {
  -                    vec.add(fmd);
  -                }
  -            }
  -            // 2. Sort fields according to their getOrder() Property
  -            Collections.sort(vec, FieldDescriptor.getComparator());
  -            lockingFieldDescriptors = (FieldDescriptor[]) vec.toArray(new FieldDescriptor[vec.size()]);
  -        }
  -        return lockingFieldDescriptors;
  -    }
  -
  -    /**
  -     * returns a dynamic Proxy that implements all interfaces of the
  -     * class described by this ClassDescriptor.
  -     *
  -     * @return Class the dynamically created proxy class
  -     */
  -    public Class getDynamicProxyClass()
  -    {
  -        Class clazz = getClassOfObject();
  -        Class superClass = clazz;
  -        Class[] interfaces = clazz.getInterfaces();
  -
  -        // clazz can be an interface itself and when getInterfaces()
  -        // is called on an interface it returns only the extending
  -        // interfaces, not the interface itself.
  -        if (clazz.isInterface())
  -        {
  -            Class[] tempInterfaces = new Class[interfaces.length + 1];
  -            tempInterfaces[0] = clazz;
  -
  -            System.arraycopy(interfaces, 0, tempInterfaces, 1, interfaces.length);
  -            interfaces = tempInterfaces;
  -        }
  -
  -        // add all interfaces implemented by superclasses to the interfaces array
  -        while ((superClass = superClass.getSuperclass()) != null)
  -        {
  -            Class[] superInterfaces = superClass.getInterfaces();
  -            Class[] combInterfaces = new Class[interfaces.length + superInterfaces.length];
  -            System.arraycopy(interfaces, 0, combInterfaces, 0, interfaces.length);
  -            System.arraycopy(superInterfaces, 0, combInterfaces, interfaces.length, superInterfaces.length);
  -            interfaces = combInterfaces;
  -        }
  -
  -        /**
  -         * Must remove duplicate interfaces before calling Proxy.getProxyClass().
  -         * Duplicates can occur if a subclass re-declares that it implements
  -         * the same interface as one of its ancestor classes.
  -         **/
  -        HashMap unique = new HashMap();
  -        for (int i = 0; i < interfaces.length; i++)
  -        {
  -            unique.put(interfaces[i].getName(), interfaces[i]);
  -        }
  -        interfaces = (Class[]) unique.values().toArray(new Class[unique.size()]);
  -        // return dynymic Proxy Class implementing all interfaces
  -        Class proxyClass = Proxy.getProxyClass(clazz.getClassLoader(), interfaces);
  -
  -        return proxyClass;
  -    }
  -
  -    /**
  -     * return true if optimistic locking is used
  -     */
  -    public boolean isLocking()
  -    {
  -        return getLockingFields().length > 0;
  -    }
  -
  -    /**
  -     * Gets the repository.
  -     * @return Returns a DescriptorRepository
  -     */
  -    public DescriptorRepository getRepository()
  -    {
  -        return m_repository;
  -    }
  -
  -    /**
  -     * Sets the repository.
  -     * @param repository The repository to set
  -     */
  -    public void setRepository(DescriptorRepository repository)
  -    {
  -        m_repository = repository;
  -    }
  -
  -    /**
  -     * Gets the schema.
  -     * @return Returns a String
  -     */
  -    public String getSchema()
  -    {
  -        return schema;
  -    }
  -
  -    /**
  -     * Sets the schema.
  -     * @param schema The schema to set
  -     */
  -    public void setSchema(String schema)
  -    {
  -        this.schema = schema;
  -    }
  -
  -    /**
  -     * Gets the IndexDescriptors used for DDL generation.
  -     */
  -    public Vector getIndexes()
  -    {
  -        return indexes;
  -    }
  -
  -    /**
  -     * Sets the IndexDescriptors used for DDL generation.
  -     */
  -    public void setIndexes(Vector indexes)
  -    {
  -        this.indexes = indexes;
  -    }
  -
  -    /**
  -     * return the FieldDescriptor for the Attribute referenced in the path<br>
  -     * the path may contain simple attribut names, functions and path expressions
  -     * using relationships <br>
  -     * ie: name, avg(price), adress.street
  -     * @param aPath the path to the attribute
  -     * @return the FieldDescriptor or null (ie: for m:n queries)
  -     */
  -    public FieldDescriptor getFieldDescriptorForPath(String aPath)
  -    {
  -        ArrayList desc = getAttributeDescriptorsForPath(aPath);
  -        FieldDescriptor fld = null;
  -        Object temp;
  -
  -        if (!desc.isEmpty())
  -        {
  -            temp = desc.get(desc.size() - 1);
  -            if (temp instanceof FieldDescriptor)
  -            {
  -                fld = (FieldDescriptor) temp;
  -            }
  -        }
  -        return fld;
  -    }
  -
  -
  -    /**
  -     * return all AttributeDescriptors for the path<br>
  -     * ie: partner.addresses.street returns a Collection of 3 AttributeDescriptors
  -     * (ObjectReferenceDescriptor, CollectionDescriptor, FieldDescriptor)<br>
  -     * ie: partner.addresses returns a Collection of 2 AttributeDescriptors
  -     * (ObjectReferenceDescriptor, CollectionDescriptor)
  -     * @param aPath the cleaned path to the attribute
  -     * @return ArrayList of AttributeDescriptors
  -     */
  -    public ArrayList getAttributeDescriptorsForPath(String aPath)
  -    {
  -        return getAttributeDescriptorsForCleanPath(cleanPath(aPath));
  -    }
  -
  -    /**
  -     * return all AttributeDescriptors for the path<br>
  -     * ie: partner.addresses.street returns a Collection of 3 AttributeDescriptors
  -     * (ObjectReferenceDescriptor, CollectionDescriptor, FieldDescriptor)<br>
  -     * ie: partner.addresses returns a Collection of 2 AttributeDescriptors
  -     * (ObjectReferenceDescriptor, CollectionDescriptor)
  -     * @param aPath the cleaned path to the attribute
  -     * @return ArrayList of AttributeDescriptors
  -     */
  -    private ArrayList getAttributeDescriptorsForCleanPath(String aPath)
  -    {
  -        ArrayList result = new ArrayList();
  -        ClassDescriptor cld = this;
  -        ObjectReferenceDescriptor ord = null;
  -        FieldDescriptor fld = null;
  -        String currPath = aPath;
  -        String segment;
  -        int sepPos;
  -
  -        while (currPath.length() > 0)
  -        {
  -            sepPos = currPath.indexOf(".");
  -            if (sepPos >= 0)
  -            {
  -                segment = currPath.substring(0, sepPos);
  -                currPath = currPath.substring(sepPos + 1);
  -            }
  -            else
  -            {
  -                segment = currPath;
  -                currPath = "";
  -            }
  -
  -            // look for 1:1 or n:1 Relationship
  -            ord = cld.getObjectReferenceDescriptorByName(segment);
  -            if (ord == null)
  -            {
  -                // look for 1:n or m:n Relationship
  -                ord = cld.getCollectionDescriptorByName(segment);
  -            }
  -
  -            if (ord != null)
  -            {
  -                cld = cld.getRepository().getDescriptorFor(ord.getItemClass());
  -                result.add(ord);
  -            }
  -            else
  -            {
  -                // look for Field
  -                fld = cld.getFieldDescriptorByName(segment);
  -                if (fld != null)
  -                {
  -                    result.add(fld);
  -                }
  -            }
  -        }
  -
  -        return result;
  -    }
  -
  -    /**
  -     * remove functions and () from path
  -     * ie: avg(amount) -> amount <br>
  -     * ie: sum(accounts.amount) -> accounts.amount
  -     * @param aPath the path to the attribute
  -     */
  -    public static String cleanPath(String aPath)
  -    {
  -        int braceBegin;
  -        int braceEnd;
  -
  -        if (aPath == null)
  -        {
  -            return aPath;
  -        }
  -
  -        braceBegin = aPath.indexOf("(");
  -        braceEnd = aPath.lastIndexOf(")");
  -        if (braceBegin >= 0 && braceEnd >= 0)
  -        {
  -            return aPath.substring(braceBegin + 1, braceEnd).trim();
  -        }
  -        else
  -        {
  -            return aPath;
  -        }
  -
  -    }
  -
  -
  -    /*
  -     * @see XmlCapable#toXML()
  -     */
  -    public String toXML()
  -    {
  -        RepositoryTags tags = RepositoryTags.getInstance();
  -        String eol = System.getProperty("line.separator");
  -
  -        // comment on class
  -        String result = eol + "  <!-- Mapping for Class " + this.getClassNameOfObject() + " -->" + eol;
  -
  -        // opening tag and attributes
  -        result += "  " + tags.getOpeningTagNonClosingById(CLASS_DESCRIPTOR) + eol;
  -
  -        // class
  -        result += "    " + tags.getAttribute(CLASS_NAME, this.getClassNameOfObject()) + eol;
  -
  -        // isolation level is optional
  -        if (getIsolationLevel() != this.getRepository().getDefaultIsolationLevel())
  -        {
  -            result += "    " + tags.getAttribute(ISOLATION_LEVEL, this.isolationLevelXml()) + eol;
  -        }
  -
  -
  -        Class theProxyClass = null;
  -        try
  -        {
  -            theProxyClass = this.getProxyClass();
  -        }
  -        catch (Throwable t)
  -        {
  -            // Ignore this exception, just try to get the Class object of the
  -            // proxy class in order to be able to decide, whether the class
  -            // is a dynamic proxy or not.
  -        }
  -
  -        // proxy is optional
  -        if (theProxyClass != null && Proxy.isProxyClass(theProxyClass))
  -        {
  -            result += "    " + tags.getAttribute(CLASS_PROXY, "dynamic") + eol;
  -        }
  -        else
  -        {
  -            result += "    " + tags.getAttribute(CLASS_PROXY, this.getProxyClassName()) + eol;
  -        }
  -
  -        // schema is optional
  -        if (this.getSchema() != null)
  -        {
  -            result += "    " + tags.getAttribute(SCHEMA_NAME, this.getSchema()) + eol;
  -        }
  -
  -        // table name
  -        if (this.getTableName() != null)
  -        {
  -            result += "    " + tags.getAttribute(TABLE_NAME, this.getTableName()) + eol;
  -        }
  -
  -        // rowreader is optional
  -        if (this.getRowReaderClassName() != null)
  -        {
  -            result += "    " + tags.getAttribute(ROW_READER, this.getRowReaderClassName()) + eol;
  -        }
  -
  -        // sequence manager attribute not yet implemented
  -
  -        result += "  >" + eol;
  -
  -        // end of attributes
  -
  -        // begin of elements
  -        if (isInterface())
  -        {
  -            // extent-class
  -            for (int i = 0; i < getExtentClassNames().size(); i++)
  -            {
  -                result += "      " + tags.getOpeningTagNonClosingById(CLASS_EXTENT) + " ";
  -                result += tags.getAttribute(CLASS_REF, getExtentClassNames().get(i).toString());
  -                result += " />" + eol;
  -            }
  -        }
  -        else
  -        {
  -            // class extent is optional
  -            if (isExtent())
  -            {
  -                for (int i = 0; i < getExtentClassNames().size(); i++)
  -                {
  -                    result += "      " + tags.getOpeningTagNonClosingById(CLASS_EXTENT) + " ";
  -                    result += tags.getAttribute(CLASS_REF, getExtentClassNames().get(i).toString());
  -                    result += " />" + eol;
  -                }
  -            }
  -
  -            // write all FieldDescriptors
  -            FieldDescriptor[] fields = getFieldDescriptions();
  -            for (int i = 0; i < fields.length; i++)
  -            {
  -                result += fields[i].toXML();
  -            }
  -
  -            // write optional ReferenceDescriptors
  -            Vector refs = getObjectReferenceDescriptors();
  -            for (int i = 0; i < refs.size(); i++)
  -            {
  -                result += ((ObjectReferenceDescriptor) refs.get(i)).toXML();
  -            }
  -
  -            // write optional CollectionDescriptors
  -            Vector cols = getCollectionDescriptors();
  -            for (int i = 0; i < cols.size(); i++)
  -            {
  -                result += ((CollectionDescriptor) cols.get(i)).toXML();
  -            }
  -
  -        }
  -
  -        result += "  " + tags.getClosingTagById(CLASS_DESCRIPTOR);
  -        return result;
  -    }
  -
  -    private String isolationLevelXml()
  -    {
  -        switch (this.getIsolationLevel())
  -        {
  -            case (IL_OPTIMISTIC):
  -                {
  -                    return LITERAL_IL_OPTIMISTIC;
  -                }
  -            case (IL_READ_COMMITTED):
  -                {
  -                    return LITERAL_IL_READ_COMMITTED;
  -                }
  -            case (IL_READ_UNCOMMITTED):
  -                {
  -                    return LITERAL_IL_READ_UNCOMMITTED;
  -                }
  -            case (IL_REPEATABLE_READ):
  -                {
  -                    return LITERAL_IL_REPEATABLE_READ;
  -                }
  -            case (IL_SERIALIZABLE):
  -                {
  -                    return LITERAL_IL_SERIALIZABLE;
  -                }
  -            default :
  -                {
  -                    return LITERAL_IL_READ_UNCOMMITTED;
  -                }
  -
  -        }
  -
  -    }
  -
  -    /**
  -     * Returns the first found autoincrement field
  -     * defined in this class descriptor. Use carefully
  -     * when multiple autoincrement field were defined.
  -     */
  -    public FieldDescriptor getAutoIncrementField()
  -    {
  -        if (m_autoIncrementField == null)
  -        {
  -            FieldDescriptor[] fds = getPkFields();
  -
  -            for (int i = 0; i < fds.length; i++)
  -            {
  -                FieldDescriptor fd = fds[i];
  -                if (fd.isAutoIncrement())
  -                {
  -                    m_autoIncrementField = fd;
  -                    break;
  -                }
  -            }
  -        }
  -        if(m_autoIncrementField == null)
  -        {
  -            LoggerFactory.getDefaultLogger().warn(
  -                    "Could not found autoincrement attribute for class: " + this.getClassNameOfObject());
  -        }
  -        return m_autoIncrementField;
  -    }
  -
  -    /**
  -     *
  -     * @return this classes FieldDescriptor's as well as it's parents and so on and so on
  -     */
  -    public FieldDescriptor[] getFieldDescriptorsInHeirarchy()
  -    {
  -        if (superClass == null)
  -        {
  -            return getFieldDescriptions();
  -        }
  -        ClassDescriptor cldSuper = getRepository().getDescriptorFor(superClass);
  -        return appendFieldDescriptorArrays(getFieldDescriptions(), cldSuper.getFieldDescriptorsInHeirarchy());
  -    }
  -
  -    private FieldDescriptor[] appendFieldDescriptorArrays(FieldDescriptor[] fieldDescriptions, FieldDescriptor[] fieldDescriptorsInHeirarchy)
  -    {
  -        // take the 2 arrays and add them into one
  -        int size = fieldDescriptions.length + fieldDescriptorsInHeirarchy.length;
  -        FieldDescriptor[] newArray = new FieldDescriptor[size];
  -        int i;
  -        int j = 0;
  -        for (i = 0; i < fieldDescriptions.length; i++, j++)
  -        {
  -            FieldDescriptor fieldDescription = fieldDescriptions[i];
  -            newArray[j] = fieldDescription;
  -        }
  -        for (i = 0; i < fieldDescriptorsInHeirarchy.length; i++, j++)
  -        {
  -            FieldDescriptor fieldDescription = fieldDescriptorsInHeirarchy[i];
  -            newArray[j] = fieldDescription;
  -        }
  -
  -        return newArray;
  -    }
  -
  -    /**
  -     * convenience function to get the first primary key
  -     * <p>
  -     * useful when there is only one
  -     * @return
  -     */
  -    public FieldDescriptor getPrimaryKey()
  -    {
  -        FieldDescriptor[] fds = getPkFields();
  -        if (fds != null && fds.length > 0)
  -        {
  -            return fds[0];
  -        }
  -        return null;
  -    }
  -
  -
  -}
  +package org.apache.ojb.broker.metadata;
  +
  +/* ====================================================================
  + * The Apache Software License, Version 1.1
  + *
  + * Copyright (c) 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 ObjectRelationalBridge" 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 ObjectRelationalBridge", 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 org.apache.ojb.broker.OJBRuntimeException;
  +import org.apache.ojb.broker.PersistenceBroker;
  +import org.apache.ojb.broker.PersistenceBrokerException;
  +import org.apache.ojb.broker.PersistenceBrokerFactory;
  +import org.apache.ojb.broker.accesslayer.RowReader;
  +import org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl;
  +import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
  +import org.apache.ojb.broker.util.logging.LoggerFactory;
  +
  +import java.io.Serializable;
  +import java.lang.reflect.Constructor;
  +import java.lang.reflect.Modifier;
  +import java.sql.Timestamp;
  +import java.util.ArrayList;
  +import java.util.Arrays;
  +import java.util.Collections;
  +import java.util.Date;
  +import java.util.HashMap;
  +import java.util.Iterator;
  +import java.util.Map;
  +import java.util.Vector;
  +
  +//#ifdef JDK13
  +import java.lang.reflect.Proxy;
  +//#else
  +/*
  +import com.develop.java.lang.reflect.Proxy;
  +*/
  +//#endif
  +
  +/**
  + * A ClassDescriptor contains all information for mapping objects of a
  + * given class to database tables.
  + *
  + * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
  + * @version $Id$
  + */
  +public class ClassDescriptor extends DescriptorBase implements Serializable, XmlCapable, IsolationLevels
  +{
  +
  +    public static final String OJB_CONCRETE_CLASS = "ojbConcreteClass";
  +
  +    private transient DescriptorRepository m_repository;
  +
  +    /**
  +     * transaction isolation level specified for this class, used in the ODMG server
  +     */
  +    private int m_IsolationLevel = IsolationLevels.IL_READ_UNCOMMITTED;
  +
  +    /**
  +     * the SQL SCHEMA of the underlying table of this class
  +     */
  +    private String schema = null;
  +
  +    /**
  +     * the described class
  +     */
  +    private Class m_Class = null;
  +
  +    /**
  +     * the name of the described class
  +     */
  +    private String classname = null;
  +
  +
  +    /**
  +     * the table name used to store the scalar attributes of this class
  +     */
  +    private String m_TableName = null;
  +
  +    /**
  +     * the FieldDescriptors for the primitive attributes
  +     */
  +    private FieldDescriptor[] m_FieldDescriptions = null;
  +
  +    /**
  +     * the descriptors for collection attributes
  +     */
  +    private Vector m_CollectionDescriptors = new Vector();
  +
  +    /**
  +     * the descriptor for 1-1 reference attributes
  +     */
  +    private Vector m_ObjectReferenceDescriptors = new Vector();
  +
  +    /**
  +     * the vector of indices used in DDL generation.
  +     */
  +    private Vector indexes = new Vector();
  +
  +    /**
  +     * the JDBCConnectionDescriptor describing the RDBMS connection to be used for this class
  +     */
  +    private JdbcConnectionDescriptor m_ConnDescription = null;
  +
  +    /**
  +     * the non-primary key FieldDescriptors
  +     */
  +    private FieldDescriptor[] nonPrimaryKeyFieldDescriptors = null;
  +
  +    /**
  +     * the primary key FieldDescriptors
  +     */
  +    private FieldDescriptor[] primaryKeyFieldDescriptors = null;
  +
  +    /**
  +     * the optimistic lockingFieldDescriptors BRJ
  +     */
  +    private FieldDescriptor[] lockingFieldDescriptors = null;
  +
  +    /**
  +     * the RowReader for this class
  +     */
  +    private RowReader rowReader = null;
  +
  +    /**
  +     * the RowReader class name for this class
  +     */
  +    private String rowReaderClassName = null;
  +
  +    /**
  +     * tells whether we tried to lookup multiargs Constructor already
  +     */
  +    private boolean alreadyLookedup = false;
  +
  +    /**
  +     * the types of the arguments for the attributes in m_FieldDescriptions
  +     */
  +    private Class[] argsForConstructor = null;
  +
  +    /**
  +     * the list of classes in the extent of this class. can be empty
  +     */
  +    private Vector extentClasses = new Vector();
  +
  +    /**
  +     * the list of class names in the extent of this class. can be empty
  +     */
  +    private Vector extentClassNames = new Vector();
  +
  +    /**
  +     * the class that this class extends
  +     */
  +    private String superClass;
  +    /**
  +     * reference column for the superclass
  +     */
  +    private int superClassFieldRef;
  +
  +    /**
  +     * does the described class represent an interface?
  +     */
  +    private boolean isInterface = false;
  +
  +    /**
  +     * the constructor defined by m_Class to initialze all scalar attributes described in m_FieldDescriptions
  +     */
  +    private Constructor multiArgumentConstructor = null;
  +
  +    /**
  +     * the proxy class for the described class, may be null
  +     */
  +    private Class proxyClass = null;
  +
  +    /**
  +     * the proxy class name for the described class, may be null
  +     */
  +    private String proxyClassName = null;
  +
  +    private FieldDescriptor m_autoIncrementField = null;
  +
  +    private Map m_fieldDescriptorNameMap = new HashMap();
  +    private Map m_collectionDescriptorNameMap = new HashMap();
  +    private Map m_objectReferenceDescriptorsNameMap = new HashMap();
  +
  +    /**
  +     * if false do not accept implicit locks on this class
  +     */
  +    private boolean acceptLocks = true;
  +
  +    /**
  +     * Constructor declaration
  +     */
  +    public ClassDescriptor(DescriptorRepository pRepository)
  +    {
  +        this.m_repository = pRepository;
  +    }
  +
  +    public ClassDescriptor()
  +    {
  +        this(DescriptorRepository.getDefaultInstance());
  +    }
  +
  +
  +    /**
  +     * sets the row reader class for thie class descriptor
  +     */
  +    public void setRowReader(RowReader newReader)
  +    {
  +        this.rowReader = newReader;
  +        setRowReaderClassName(newReader.getClass().getName());
  +    }
  +
  +    /**
  +     * sets the row reader class name for thie class descriptor
  +     */
  +    public void setRowReaderClassName(String newReaderClassName)
  +    {
  +        this.rowReaderClassName = newReaderClassName;
  +    }
  +
  +    public String getRowReaderClassName()
  +    {
  +        return this.rowReaderClassName;
  +    }
  +
  +
  +    public synchronized RowReader getRowReader()
  +    {
  +        if (rowReader == null)
  +        {
  +            // if no RowReader has been declared, use the default reader
  +            if (rowReaderClassName == null)
  +            {
  +                rowReader = new RowReaderDefaultImpl();
  +            }
  +            else
  +            {
  +                try
  +                {
  +                    Class rowReaderClass = Class.forName(rowReaderClassName, true,
  +                            Thread.currentThread().getContextClassLoader());
  +                    rowReader = (RowReader) rowReaderClass.newInstance();
  +                }
  +                catch (Exception e)
  +                {
  +                    throw new MetadataException(e);
  +                }
  +            }
  +        }
  +        return this.rowReader;
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @return
  +     */
  +    private String getTableName()
  +    {
  +        return m_TableName;
  +    }
  +
  +    /**
  +     * Answer Table name including schema	BRJ
  +     */
  +    public String getFullTableName()
  +    {
  +        if (getSchema() != null)
  +            return getSchema() + "." + getTableName();
  +        else
  +            return getTableName();
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @param str
  +     */
  +    public void setTableName(String str)
  +    {
  +        m_TableName = str;
  +    }
  +
  +    /**
  +     * returns the name of the described class
  +     * @return String name of the described class
  +     */
  +    public String getClassNameOfObject()
  +    {
  +        return this.classname;
  +    }
  +
  +
  +    /**
  +     * returns the class object of the described class
  +     * @return Class the described class
  +     */
  +    public Class getClassOfObject()
  +    {
  +        if (m_Class != null)
  +        {
  +            return m_Class;
  +        }
  +        else if (classname != null)
  +        {
  +            try
  +            {
  +                m_Class = Class.forName(classname, true, Thread.currentThread().getContextClassLoader());
  +                return m_Class;
  +            }
  +            catch (ClassNotFoundException e)
  +            {
  +                throw new PersistenceBrokerException(e);
  +            }
  +        }
  +        else
  +        {
  +            return null;
  +        }
  +    }
  +
  +    /**
  +     * sets the class object described by this descriptor.
  +     * @param c the class to describe
  +     */
  +    public void setClassOfObject(Class c)
  +    {
  +        m_Class = c;
  +        this.classname = c.getName();
  +    }
  +
  +    /**
  +     * sets the name of the class described by this descriptor.
  +     * @param classname the class to describe
  +     */
  +    public void setClassNameOfObject(String classname)
  +    {
  +        this.classname = classname;
  +        // Shouldn't the HashMap in DescriptorRepository be updated as well?
  +    }
  +
  +
  +    /**
  +     * adds a FIELDDESCRIPTOR to this ClassDescriptor.
  +     * @param fld
  +     */
  +    public void addFieldDescriptor(FieldDescriptor fld)
  +    {
  +        fld.setClassDescriptor(this); // BRJ
  +        if (m_FieldDescriptions == null)
  +        {
  +            m_FieldDescriptions = new FieldDescriptor[1];
  +            m_FieldDescriptions[0] = fld;
  +            m_fieldDescriptorNameMap = new HashMap();
  +        }
  +        else
  +        {
  +            int size = m_FieldDescriptions.length;
  +            FieldDescriptor[] tmpArray = new FieldDescriptor[size + 1];
  +            System.arraycopy(m_FieldDescriptions, 0, tmpArray, 0, size);
  +            tmpArray[size] = fld;
  +            m_FieldDescriptions = tmpArray;
  +            // 2. Sort fields according to their getOrder() Property
  +            Arrays.sort(m_FieldDescriptions, FieldDescriptor.getComparator());
  +        }
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @return
  +     */
  +    public Vector getCollectionDescriptors()
  +    {
  +        return m_CollectionDescriptors;
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @param cod
  +     */
  +    public void addCollectionDescriptor(CollectionDescriptor cod)
  +    {
  +        cod.setClassDescriptor(this); // BRJ
  +        m_CollectionDescriptors.add(cod);
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @return
  +     */
  +    public Vector getObjectReferenceDescriptors()
  +    {
  +        return m_ObjectReferenceDescriptors;
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @param ord
  +     */
  +    public void addObjectReferenceDescriptor(ObjectReferenceDescriptor ord)
  +    {
  +        ord.setClassDescriptor(this); // BRJ
  +        m_ObjectReferenceDescriptors.add(ord);
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @return
  +     */
  +    public JdbcConnectionDescriptor getConnectionDescriptor()
  +    {
  +        if (m_ConnDescription == null)
  +        {
  +            // if class has no special JDBC Connection use the DefaultConnection
  +            m_ConnDescription = this.getRepository().getDefaultJdbcConnection();
  +        }
  +        return m_ConnDescription;
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @param jcd
  +     */
  +    public void setConnectionDescriptor(JdbcConnectionDescriptor jcd)
  +    {
  +        m_ConnDescription = jcd;
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @param index
  +     * @return
  +     */
  +    public FieldDescriptor getFieldDescriptorByIndex(int index)
  +    {
  +        return m_FieldDescriptions[index - 1];
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @return
  +     */
  +    public String toString()
  +    {
  +        return "table:      \t"
  +                + m_TableName
  +                + "\n"
  +                + "FieldDescriptions:\t"
  +                + (m_FieldDescriptions == null ? "" : m_FieldDescriptions.toString());
  +
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @param name
  +     * @return
  +     */
  +    public FieldDescriptor getFieldDescriptorByName(String name)
  +    {
  +        if (name == null)
  +            return null;
  +        if (m_FieldDescriptions == null)
  +            return null;
  +        FieldDescriptor retval = (FieldDescriptor) m_fieldDescriptorNameMap.get(name);
  +        if (retval == null)
  +        {
  +            int size = m_FieldDescriptions.length;
  +            FieldDescriptor temp = null;
  +            for (int i = 0; ((i < size) && (retval == null)); i++)
  +            {
  +                temp = m_FieldDescriptions[i];
  +                if (name.equals(temp.getPersistentField().getName()))
  +                {
  +                    retval = temp;
  +                    m_fieldDescriptorNameMap.put(name, retval);
  +                    break;
  +                }
  +            }
  +        }
  +        return retval;
  +    }
  +
  +    /**
  +     * Get an ObjectReferenceDescriptor by name	BRJ
  +     * @param name
  +     * @return ObjectReferenceDescriptor or null
  +     */
  +    public ObjectReferenceDescriptor getObjectReferenceDescriptorByName(String name)
  +    {
  +        if (name == null)
  +            return null;
  +        ObjectReferenceDescriptor retval = (ObjectReferenceDescriptor) this.m_objectReferenceDescriptorsNameMap.get(name);
  +        if (retval == null)
  +        {
  +            Vector descr = getObjectReferenceDescriptors();
  +            int size = descr.size();
  +            for (int i = 0; i < size; i++)
  +            {
  +                ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) descr.elementAt(i);
  +                if (ord.getPersistentField().getName().equals(name))
  +                {
  +                    retval = ord;
  +                    m_objectReferenceDescriptorsNameMap.put(name, retval);
  +                    break;
  +                }
  +            }
  +        }
  +        return retval;
  +    }
  +
  +    /**
  +     * Get an CollectionDescriptor by name	BRJ
  +     * @param name
  +     * @return CollectionDescriptor or null
  +     */
  +    public CollectionDescriptor getCollectionDescriptorByName(String name)
  +    {
  +        if (name == null)
  +            return null;
  +        CollectionDescriptor retval = (CollectionDescriptor) this.m_collectionDescriptorNameMap.get(name);
  +        if (retval == null)
  +        {
  +            Vector descr = getCollectionDescriptors();
  +            int size = descr.size();
  +            for (int i = 0; i < size; i++)
  +            {
  +                CollectionDescriptor ord = (CollectionDescriptor) descr.elementAt(i);
  +                if (ord.getPersistentField().getName().equals(name))
  +                {
  +                    retval = ord;
  +                    m_collectionDescriptorNameMap.put(name, retval);
  +                    break;
  +                }
  +            }
  +        }
  +        return retval;
  +    }
  +
  +    /**
  +     * returns the transaction isolation level to be used for this class. Used only in the ODMG server
  +     */
  +    public int getIsolationLevel()
  +    {
  +        return m_IsolationLevel;
  +    }
  +
  +    /**
  +     * Method declaration
  +     * @param isoLevel
  +     */
  +    public void setIsolationLevel(int isoLevel)
  +    {
  +        m_IsolationLevel = isoLevel;
  +    }
  +
  +
  +    /**
  +     * add an Extent class to the current descriptor
  +     * @param newExtendClass
  +     */
  +    public void addExtentClass(Class newExtendClass)
  +    {
  +        extentClasses.add(newExtendClass);
  +        this.addExtentClassName(newExtendClass.getName());
  +    }
  +
  +    /**
  +     * add an Extent class to the current descriptor
  +     * @param newExtendClassName name of the class to add
  +     */
  +    public void addExtentClassName(String newExtendClassName)
  +    {
  +        extentClassNames.add(newExtendClassName);
  +        m_repository.addExtent(newExtendClassName, this);
  +    }
  +
  +    public void setSuperClass(String classname)
  +    {
  +        this.superClass = classname;
  +
  +
  +    }
  +
  +    public void setSuperClassFieldRef(int fieldId)
  +    {
  +        this.superClassFieldRef = fieldId;
  +    }
  +
  +    public int getSuperClassFieldRef()
  +    {
  +        return superClassFieldRef;
  +    }
  +
  +    public String getSuperClass()
  +    {
  +        return superClass;
  +    }
  +
  +    /**
  +     * returns a Constructor that takes all persistent attributes
  +     * of the class as arguments.
  +     * Returns null, if such a constructor does not exist.
  +     * PersistenceBroker clients are not urged to implement such constructors
  +     * for persistence capable classes. But it's strongly recommended as
  +     * it minimizes the overhead for reflective operations.
  +     */
  +    public Constructor getConstructor()
  +    {
  +        if (multiArgumentConstructor == null && !alreadyLookedup)
  +        {
  +            if (argsForConstructor == null)
  +            {
  +                argsForConstructor = new Class[getFieldDescriptions().length];
  +                for (int i = 0; i < getFieldDescriptions().length; i++)
  +                {
  +                    argsForConstructor[i] = getFieldDescriptions()[i].getPersistentField().getType();
  +                }
  +            }
  +            try
  +            {
  +                multiArgumentConstructor = getClassOfObject().getConstructor(argsForConstructor);
  +            }
  +            catch (Exception ignored)
  +            {
  +                // this exception is thrown, if no suitable Constructor was
  +                // found. In this case we tell the user that it is better to have
  +                // a multiargs constructor defined
  +                String args = "";
  +                for (int i = 0; i < argsForConstructor.length; i++)
  +                {
  +                    args += ((args.length() == 0) ? "(" : ", ");
  +                    args += argsForConstructor[i].getName();
  +                }
  +                args += ")";
  +                LoggerFactory.getDefaultLogger().warn(
  +                        "Please define a public constructor for "
  +                        + this.getClassOfObject()
  +                        + "\nwith the following signature: "
  +                        + args
  +                        + ".\nIt must initialize the classes persistent attributes. This is recommended to increase performance but it's not mandatory!");
  +            }
  +            alreadyLookedup = true;
  +        }
  +        return multiArgumentConstructor;
  +    }
  +
  +    /**
  +     * return all classes in this extent.
  +     * Creation date: (02.02.2001 17:49:11)
  +     * @return java.util.Vector
  +     */
  +    public synchronized Vector getExtentClasses()
  +    {
  +        if (extentClassNames.size() > extentClasses.size())
  +        {
  +            extentClasses.clear();
  +            for (Iterator iter = extentClassNames.iterator(); iter.hasNext();)
  +            {
  +                String classname = (String) iter.next();
  +                Class extentClass;
  +                try
  +                {
  +                    extentClass = Class.forName(classname, true,
  +                            Thread.currentThread().getContextClassLoader());
  +                }
  +                catch (ClassNotFoundException e)
  +                {
  +                    throw new MetadataException("Unable to load class [" + classname + "]. Make sure it is available on the classpath.", e);
  +                }
  +                extentClasses.add(extentClass);
  +            }
  +        }
  +        return extentClasses;
  +    }
  +
  +    /**
  +     * Return the names of all classes in this extent
  +     * @return java.util.Vector a Vector containing the fully qualified names
  +     * of all classes in this extent
  +     */
  +    public synchronized Vector getExtentClassNames()
  +    {
  +        return this.extentClassNames;
  +    }
  +
  +    /**
  +     * Insert the method's description here.
  +     * Creation date: (26.01.2001 09:20:09)
  +     * @return java.lang.Class
  +     */
  +    public synchronized java.lang.Class getProxyClass()
  +    {
  +
  +        if ((proxyClass == null) && (proxyClassName != null))
  +        {
  +            String dynamic = "dynamic";
  +            if (dynamic.equalsIgnoreCase(proxyClassName))
  +            {
  +                proxyClass = getDynamicProxyClass();
  +            }
  +            else
  +            {
  +                try
  +                {
  +                    proxyClass = Class.forName(proxyClassName, true,
  +                            Thread.currentThread().getContextClassLoader());
  +                }
  +                catch (ClassNotFoundException e)
  +                {
  +                    throw new MetadataException(e);
  +                }
  +            }
  +        }
  +        return proxyClass;
  +    }
  +
  +    /**
  +     * Insert the method's description here.
  +     * Creation date: (02.02.2001 17:49:11)
  +     * @return boolean
  +     */
  +    public boolean isExtent()
  +    {
  +        return (getExtentClassNames().size() > 0);
  +    }
  +
  +    /**
  +     * Insert the method's description here.
  +     * Creation date: (02.02.2001 17:49:11)
  +     * @return boolean
  +     */
  +    public boolean isInterface()
  +    {
  +        return isInterface;
  +    }
  +
  +    /**
  +     * Insert the method's description here.
  +     * Creation date: (02.02.2001 17:49:11)
  +     * @param newIsInterface boolean
  +     */
  +    public void setIsInterface(boolean newIsInterface)
  +    {
  +        isInterface = newIsInterface;
  +    }
  +
  +    /**
  +     * @return boolean true if the mapped class is abstract
  +     */
  +    public boolean isAbstract()
  +    {
  +        return Modifier.isAbstract(getClassOfObject().getModifiers());
  +    }
  +
  +    /**
  +     * Sets the proxy class to be used.
  +     * @param newProxyClass java.lang.Class
  +     */
  +    public void setProxyClass(java.lang.Class newProxyClass)
  +    {
  +        proxyClass = newProxyClass;
  +        if (proxyClass == null)
  +            setProxyClassName(null);
  +        else
  +            proxyClassName = proxyClass.getName();
  +    }
  +
  +    /**
  +     * Sets the name of the proxy class to be used.
  +     * using "dynamic" instead of a real classname
  +     * will result in usage of dynamic proxies.
  +     * @param newProxyClassName the classname or "dynamic"
  +     */
  +    public void setProxyClassName(String newProxyClassName)
  +    {
  +        proxyClassName = newProxyClassName;
  +    }
  +
  +    /**
  +     * Get the name of the proxy class. This method doesn't try to access
  +     * the real class, so it can be called even if the class doesn't exist.
  +     */
  +    public String getProxyClassName()
  +    {
  +        return proxyClassName;
  +    }
  +
  +    /**
  +     * returns a vector containing values for all the Objects attribute
  +     * @throws MetadataException if tehre is an erros accessing obj field values
  +     */
  +    public Object[] getAllValues(Object obj) throws PersistenceBrokerException
  +    {
  +        FieldDescriptor[] allFields = getFieldDescriptions();
  +        Object[] result = new Object[allFields.length];
  +
  +        for (int i = 0; i < allFields.length; i++)
  +        {
  +            FieldDescriptor fmd = allFields[i];
  +            PersistentField f = fmd.getPersistentField();
  +            Object cv = f.get(obj);
  +
  +            // handle autoincrement attributes if not filled
  +            if (fmd.isAutoIncrement())
  +            {
  +                cv = getAutoIncrementValue(fmd, obj, cv);
  +            }
  +
  +            // apply type and value mapping
  +            cv = fmd.getFieldConversion().javaToSql(cv);
  +            result[i] = cv;
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * returns array of all FieldDescriptors.
  +     * @return FIELDDESCRIPTOR[]
  +     */
  +    public FieldDescriptor[] getFieldDescriptions()
  +    {
  +        return m_FieldDescriptions;
  +    }
  +
  +    /**
  +     * returns an Array with an Objects PK VALUES, with any java-to-sql
  +     * FieldConversion applied
  +     * @throws MetadataException if there is an erros accessing o field values
  +     */
  +    public Object[] getKeyValues(Object o) throws PersistenceBrokerException
  +    {
  +        return getKeyValues(o, true);
  +    }
  +
  +    /**
  +     * returns an Array with an Objects PK VALUES
  +     * if convertToSql is true, any associated java-to-sql conversions are applied
  +     * @throws MetadataException if there is an erros accessing o field values
  +     */
  +    public Object[] getKeyValues(Object o, boolean convertToSql) throws PersistenceBrokerException
  +    {
  +        FieldDescriptor[] pkFields = getPkFields();
  +        Object[] result = new Object[pkFields.length];
  +
  +        for (int i = 0; i < result.length; i++)
  +        {
  +            FieldDescriptor fmd = pkFields[i];
  +            PersistentField f = fmd.getPersistentField();
  +            Object cv = f.get(o);
  +
  +            // handle autoincrement attributes if not filled
  +            if (fmd.isAutoIncrement())
  +            {
  +                cv = getAutoIncrementValue(fmd, o, cv);
  +            }
  +
  +            if (convertToSql)
  +            {
  +                // BRJ : apply type and value mapping
  +                cv = fmd.getFieldConversion().javaToSql(cv);
  +            }
  +            result[i] = cv;
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * returns an Array with an Objects CURRENT locking VALUES , BRJ
  +     * @throws MetadataException if there is an erros accessing o field values
  +     */
  +    public Object[] getCurrentLockingValues(Object o) throws PersistenceBrokerException
  +    {
  +        FieldDescriptor[] fields = getLockingFields();
  +        Object[] result = new Object[fields.length];
  +        for (int i = 0; i < result.length; i++)
  +        {
  +            FieldDescriptor fmd = fields[i];
  +            PersistentField f = fmd.getPersistentField();
  +            Object cv = null;
  +            cv = f.get(o); // retrieve the Objects value for the specified field
  +            result[i] = cv;
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * updates the values for locking fields , BRJ
  +     * handles int, long, Timestamp
  +     * @throws MetadataException if there is an erros accessing obj field values
  +     */
  +    public void updateLockingValues(Object obj) throws PersistenceBrokerException
  +    {
  +        FieldDescriptor[] fields = getLockingFields();
  +        for (int i = 0; i < fields.length; i++)
  +        {
  +            FieldDescriptor fmd = fields[i];
  +            PersistentField f = fmd.getPersistentField();
  +            Object cv = null;
  +            cv = f.get(obj);
  +
  +            // int
  +            if ((f.getType() == int.class) || (f.getType() == Integer.class))
  +
  +            {
  +                int newCv = 0;
  +                if (cv != null)
  +                {
  +                    newCv = ((Number) cv).intValue();
  +                }
  +                newCv++;
  +                f.set(obj, new Integer(newCv));
  +            }
  +            // long
  +            else if ((f.getType() == long.class) || (f.getType() == Long.class))
  +
  +            {
  +                long newCv = 0;
  +                if (cv != null)
  +                {
  +                    newCv = ((Number) cv).longValue();
  +                }
  +                newCv++;
  +                f.set(obj, new Long(newCv));
  +            }
  +            // Timestamp
  +            else if (f.getType() == Timestamp.class)
  +
  +            {
  +                long newCv = (new Date()).getTime();
  +                f.set(obj, new Timestamp(newCv));
  +            }
  +        }
  +    }
  +
  +    /**
  +     * @throws MetadataException if there is an erros accessing obj field values
  +     */
  +    private Object getAutoIncrementValue(FieldDescriptor fmd, Object obj, Object cv)
  +    {
  +        if ((cv == null) || ((cv instanceof Number) && (((Number) cv).intValue() == 0)))
  +        {
  +            PersistentField f = fmd.getPersistentField();
  +            Object result = cv;
  +            PersistenceBroker broker = null;
  +            try
  +            {
  +                if (m_repository != null)
  +                {
  +                    // arminw
  +                    // use the PBKey of the associated descriptor repository
  +                    // to match the 'correct' repository
  +                    /* @todo maybe this could be critical in some
  +                     * situations, e.g. if the associated PBKey was always the
  +                     * default PBKey. Check this out.
  +                     */
  +                    broker = PersistenceBrokerFactory.createPersistenceBroker(m_repository.getPBkey());
  +                }
  +                else
  +                {
  +                    // no repository, we use the default PB
  +                    broker = PersistenceBrokerFactory.defaultPersistenceBroker();
  +                }
  +                // int
  +                if ((f.getType() == int.class) || (f.getType() == Integer.class))
  +                {
  +                    if ((f.get(obj) == null) || (((Number) f.get(obj)).intValue() == 0))
  +                    {
  +                        /*
  +                        arminw
  +                        old version
  +                        Class extent = broker.getExtentClass(this.getClassOfObject());
  +                        result = new Integer(broker.getUniqueId(extent, f.getName()));
  +
  +                        we should not give the top-level extent to sequence manager,
  +                        sequence manager itself should take care of uniqueness over the extents
  +                        */
  +                        result = new Integer(broker.getUniqueId(fmd));
  +                        // reflect autoincrement value back into object
  +                        f.set(obj, result);
  +                    }
  +                }
  +                // long
  +                else if ((f.getType() == long.class) || (f.getType() == Long.class))
  +                {
  +                    if ((f.get(obj) == null) || (((Number) f.get(obj)).longValue() == 0))
  +                    {
  +                        /*
  +                        arminw
  +                        old version
  +                        Class extent = broker.getExtentClass(this.getClassOfObject());
  +                        result = new Long(broker.getUniqueLong(extent, f.getName()));
  +
  +                        we should not give the top-level extent to sequence manager,
  +                        sequence manager itself should take care of uniqueness over the extents
  +                        */
  +
  +                        result = new Long(broker.getUniqueLong(fmd));
  +                        // reflect autoincrement value back into object
  +                        f.set(obj, result);
  +                    }
  +                }
  +                // String
  +                else if (String.class.isAssignableFrom(f.getType()))
  +                {
  +                    if (f.get(obj) == null)
  +                    {
  +                        result = broker.getUniqueString(fmd);
  +                        // reflect autoincrement value back into object
  +                        f.set(obj, result);
  +                    }
  +                }
  +                // Object
  +                else if (!f.getType().isPrimitive())
  +                {
  +                    // only assign a value if attribute == null
  +                    if (f.get(obj) == null)
  +                    {
  +                        result = broker.getUniqueObject(fmd);
  +                        if (result != null)
  +                        {
  +                            // reflect autoincrement value back into object
  +                            f.set(obj, result);
  +                        }
  +                        else
  +                        {
  +                            throw new OJBRuntimeException(
  +                                    "OJB ERROR: Dont know how to autoincrement field " +
  +                                    f.getDeclaringClass() + "#" + f.getName());
  +                        }
  +                    }
  +                }
  +                else
  +                {
  +                    throw new OJBRuntimeException(
  +                            "OJB ERROR: Dont know how to autoincrement field " +
  +                            f.getDeclaringClass() + "#" + f.getName());
  +                }
  +                return result;
  +            }
  +            catch (MetadataException e)
  +            {
  +                throw new OJBRuntimeException(
  +                        "Error while trying to autoincrement field " +
  +                        f.getDeclaringClass() + "#" + f.getName(), e);
  +            }
  +            finally
  +            {
  +                if (broker != null)
  +                {
  +                    broker.close();
  +                }
  +            }
  +        }
  +        else
  +        {
  +            return cv;
  +        }
  +
  +    }
  +
  +    /**
  +     * returns an Array with an Objects NON-PK VALUES
  +     * @throws MetadataException if there is an erros accessing o field values
  +     */
  +    public Object[] getNonKeyValues(Object o) throws PersistenceBrokerException
  +    {
  +        FieldDescriptor[] nonPkFields = getNonPkFields();
  +        Object[] result = new Object[nonPkFields.length];
  +
  +        for (int i = 0; i < result.length; i++)
  +        {
  +            FieldDescriptor fmd = nonPkFields[i];
  +            PersistentField f = fmd.getPersistentField();
  +            Object cv = f.get(o);
  +
  +            // handle autoincrement attributes if not filled
  +            if (fmd.isAutoIncrement())
  +            {
  +                cv = getAutoIncrementValue(fmd, o, cv);
  +            }
  +
  +            // apply type and value conversion
  +            cv = fmd.getFieldConversion().javaToSql(cv);
  +            result[i] = cv;
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * return an array of PK FieldDescription sorted ascending
  +     * according to the field-descriptions getOrder() property
  +     */
  +    public FieldDescriptor[] getNonPkFields()
  +    {
  +        if (nonPrimaryKeyFieldDescriptors == null)
  +        {
  +            // 1. collect all Primary Key fields from Field list
  +            Vector vec = new Vector();
  +            for (int i = 0; i < m_FieldDescriptions.length; i++)
  +            {
  +                FieldDescriptor fmd = m_FieldDescriptions[i];
  +                if (!fmd.isPrimaryKey())
  +                {
  +                    vec.add(fmd);
  +                }
  +            }
  +            // 2. Sort fields according to their getOrder() Property
  +            Collections.sort(vec, FieldDescriptor.getComparator());
  +            nonPrimaryKeyFieldDescriptors = (FieldDescriptor[]) vec.toArray(new FieldDescriptor[vec.size()]);
  +        }
  +        return nonPrimaryKeyFieldDescriptors;
  +    }
  +
  +    /**
  +     * return an array of PK FieldDescription sorted ascending
  +     * according to the field-descriptions getOrder() property
  +     */
  +    public FieldDescriptor[] getPkFields()
  +    {
  +        if (primaryKeyFieldDescriptors == null)
  +        {
  +            // 1. collect all Primary Key fields from Field list
  +            Vector vec = new Vector();
  +            FieldDescriptor[] fields = null;
  +            // 1.a if descriptor describes an interface: take PK fields from an implementors ClassDescriptor
  +            if (isInterface)
  +            {
  +                if (getExtentClasses().size() == 0)
  +                {
  +                    throw new PersistenceBrokerException(
  +                            "No Implementors declared for interface " + this.getClassOfObject().getName());
  +                }
  +                Class implementor = (Class) getExtentClasses().get(0);
  +                ClassDescriptor implCld = this.getRepository().getDescriptorFor(implementor);
  +                primaryKeyFieldDescriptors = implCld.getPkFields();
  +                return primaryKeyFieldDescriptors;
  +            }
  +            // 1.b if not an interface The classdescriptor must have FieldDescriptors
  +            else
  +            {
  +                fields = this.getFieldDescriptions();
  +            }
  +
  +            // now collect all PK fields
  +            for (int i = 0; i < fields.length; i++)
  +            {
  +                FieldDescriptor fmd = fields[i];
  +                if (fmd.isPrimaryKey())
  +                {
  +                    vec.add(fmd);
  +                }
  +            }
  +            // 2. Sort fields according to their getOrder() Property
  +            Collections.sort(vec, FieldDescriptor.getComparator());
  +            primaryKeyFieldDescriptors = (FieldDescriptor[]) vec.toArray(new FieldDescriptor[vec.size()]);
  +        }
  +        return primaryKeyFieldDescriptors;
  +    }
  +
  +    /**
  +     * return an array of FieldDescription for optimistic locking sorted ascending
  +     * according to the field-descriptions getOrder() property
  +     */
  +    public FieldDescriptor[] getLockingFields()
  +    {
  +        if (lockingFieldDescriptors == null)
  +        {
  +            // 1. collect all Primary Key fields from Field list
  +            Vector vec = new Vector();
  +            for (int i = 0; i < m_FieldDescriptions.length; i++)
  +            {
  +                FieldDescriptor fmd = m_FieldDescriptions[i];
  +                if (fmd.isLocking())
  +                {
  +                    vec.add(fmd);
  +                }
  +            }
  +            // 2. Sort fields according to their getOrder() Property
  +            Collections.sort(vec, FieldDescriptor.getComparator());
  +            lockingFieldDescriptors = (FieldDescriptor[]) vec.toArray(new FieldDescriptor[vec.size()]);
  +        }
  +        return lockingFieldDescriptors;
  +    }
  +
  +    /**
  +     * returns a dynamic Proxy that implements all interfaces of the
  +     * class described by this ClassDescriptor.
  +     *
  +     * @return Class the dynamically created proxy class
  +     */
  +    public Class getDynamicProxyClass()
  +    {
  +        Class clazz = getClassOfObject();
  +        Class superClass = clazz;
  +        Class[] interfaces = clazz.getInterfaces();
  +
  +        // clazz can be an interface itself and when getInterfaces()
  +        // is called on an interface it returns only the extending
  +        // interfaces, not the interface itself.
  +        if (clazz.isInterface())
  +        {
  +            Class[] tempInterfaces = new Class[interfaces.length + 1];
  +            tempInterfaces[0] = clazz;
  +
  +            System.arraycopy(interfaces, 0, tempInterfaces, 1, interfaces.length);
  +            interfaces = tempInterfaces;
  +        }
  +
  +        // add all interfaces implemented by superclasses to the interfaces array
  +        while ((superClass = superClass.getSuperclass()) != null)
  +        {
  +            Class[] superInterfaces = superClass.getInterfaces();
  +            Class[] combInterfaces = new Class[interfaces.length + superInterfaces.length];
  +            System.arraycopy(interfaces, 0, combInterfaces, 0, interfaces.length);
  +            System.arraycopy(superInterfaces, 0, combInterfaces, interfaces.length, superInterfaces.length);
  +            interfaces = combInterfaces;
  +        }
  +
  +        /**
  +         * Must remove duplicate interfaces before calling Proxy.getProxyClass().
  +         * Duplicates can occur if a subclass re-declares that it implements
  +         * the same interface as one of its ancestor classes.
  +         **/
  +        HashMap unique = new HashMap();
  +        for (int i = 0; i < interfaces.length; i++)
  +        {
  +            unique.put(interfaces[i].getName(), interfaces[i]);
  +        }
  +        interfaces = (Class[]) unique.values().toArray(new Class[unique.size()]);
  +        // return dynymic Proxy Class implementing all interfaces
  +        Class proxyClass = Proxy.getProxyClass(clazz.getClassLoader(), interfaces);
  +
  +        return proxyClass;
  +    }
  +
  +    /**
  +     * return true if optimistic locking is used
  +     */
  +    public boolean isLocking()
  +    {
  +        return getLockingFields().length > 0;
  +    }
  +
  +    /**
  +     * Gets the repository.
  +     * @return Returns a DescriptorRepository
  +     */
  +    public DescriptorRepository getRepository()
  +    {
  +        return m_repository;
  +    }
  +
  +    /**
  +     * Sets the repository.
  +     * @param repository The repository to set
  +     */
  +    public void setRepository(DescriptorRepository repository)
  +    {
  +        m_repository = repository;
  +    }
  +
  +    /**
  +     * Gets the schema.
  +     * @return Returns a String
  +     */
  +    public String getSchema()
  +    {
  +        return schema;
  +    }
  +
  +    /**
  +     * Sets the schema.
  +     * @param schema The schema to set
  +     */
  +    public void setSchema(String schema)
  +    {
  +        this.schema = schema;
  +    }
  +
  +    /**
  +     * Gets the IndexDescriptors used for DDL generation.
  +     */
  +    public Vector getIndexes()
  +    {
  +        return indexes;
  +    }
  +
  +    /**
  +     * Sets the IndexDescriptors used for DDL generation.
  +     */
  +    public void setIndexes(Vector indexes)
  +    {
  +        this.indexes = indexes;
  +    }
  +
  +    /**
  +     * return the FieldDescriptor for the Attribute referenced in the path<br>
  +     * the path may contain simple attribut names, functions and path expressions
  +     * using relationships <br>
  +     * ie: name, avg(price), adress.street
  +     * @param aPath the path to the attribute
  +     * @return the FieldDescriptor or null (ie: for m:n queries)
  +     */
  +    public FieldDescriptor getFieldDescriptorForPath(String aPath)
  +    {
  +        ArrayList desc = getAttributeDescriptorsForPath(aPath);
  +        FieldDescriptor fld = null;
  +        Object temp;
  +
  +        if (!desc.isEmpty())
  +        {
  +            temp = desc.get(desc.size() - 1);
  +            if (temp instanceof FieldDescriptor)
  +            {
  +                fld = (FieldDescriptor) temp;
  +            }
  +        }
  +        return fld;
  +    }
  +
  +
  +    /**
  +     * return all AttributeDescriptors for the path<br>
  +     * ie: partner.addresses.street returns a Collection of 3 AttributeDescriptors
  +     * (ObjectReferenceDescriptor, CollectionDescriptor, FieldDescriptor)<br>
  +     * ie: partner.addresses returns a Collection of 2 AttributeDescriptors
  +     * (ObjectReferenceDescriptor, CollectionDescriptor)
  +     * @param aPath the cleaned path to the attribute
  +     * @return ArrayList of AttributeDescriptors
  +     */
  +    public ArrayList getAttributeDescriptorsForPath(String aPath)
  +    {
  +        return getAttributeDescriptorsForCleanPath(cleanPath(aPath));
  +    }
  +
  +    /**
  +     * return all AttributeDescriptors for the path<br>
  +     * ie: partner.addresses.street returns a Collection of 3 AttributeDescriptors
  +     * (ObjectReferenceDescriptor, CollectionDescriptor, FieldDescriptor)<br>
  +     * ie: partner.addresses returns a Collection of 2 AttributeDescriptors
  +     * (ObjectReferenceDescriptor, CollectionDescriptor)
  +     * @param aPath the cleaned path to the attribute
  +     * @return ArrayList of AttributeDescriptors
  +     */
  +    private ArrayList getAttributeDescriptorsForCleanPath(String aPath)
  +    {
  +        ArrayList result = new ArrayList();
  +        ClassDescriptor cld = this;
  +        ObjectReferenceDescriptor ord = null;
  +        FieldDescriptor fld = null;
  +        String currPath = aPath;
  +        String segment;
  +        int sepPos;
  +
  +        while (currPath.length() > 0)
  +        {
  +            sepPos = currPath.indexOf(".");
  +            if (sepPos >= 0)
  +            {
  +                segment = currPath.substring(0, sepPos);
  +                currPath = currPath.substring(sepPos + 1);
  +            }
  +            else
  +            {
  +                segment = currPath;
  +                currPath = "";
  +            }
  +
  +            // look for 1:1 or n:1 Relationship
  +            ord = cld.getObjectReferenceDescriptorByName(segment);
  +            if (ord == null)
  +            {
  +                // look for 1:n or m:n Relationship
  +                ord = cld.getCollectionDescriptorByName(segment);
  +            }
  +
  +            if (ord != null)
  +            {
  +                cld = cld.getRepository().getDescriptorFor(ord.getItemClass());
  +                result.add(ord);
  +            }
  +            else
  +            {
  +                // look for Field
  +                fld = cld.getFieldDescriptorByName(segment);
  +                if (fld != null)
  +                {
  +                    result.add(fld);
  +                }
  +            }
  +        }
  +
  +        return result;
  +    }
  +
  +    /**
  +     * remove functions and () from path
  +     * ie: avg(amount) -> amount <br>
  +     * ie: sum(accounts.amount) -> accounts.amount
  +     * @param aPath the path to the attribute
  +     */
  +    public static String cleanPath(String aPath)
  +    {
  +        int braceBegin;
  +        int braceEnd;
  +
  +        if (aPath == null)
  +        {
  +            return aPath;
  +        }
  +
  +        braceBegin = aPath.indexOf("(");
  +        braceEnd = aPath.lastIndexOf(")");
  +        if (braceBegin >= 0 && braceEnd >= 0)
  +        {
  +            return aPath.substring(braceBegin + 1, braceEnd).trim();
  +        }
  +        else
  +        {
  +            return aPath;
  +        }
  +
  +    }
  +
  +
  +    /*
  +     * @see XmlCapable#toXML()
  +     */
  +    public String toXML()
  +    {
  +        RepositoryTags tags = RepositoryTags.getInstance();
  +        String eol = System.getProperty("line.separator");
  +
  +        // comment on class
  +        String result = eol + "  <!-- Mapping for Class " + this.getClassNameOfObject() + " -->" + eol;
  +
  +        // opening tag and attributes
  +        result += "  " + tags.getOpeningTagNonClosingById(CLASS_DESCRIPTOR) + eol;
  +
  +        // class
  +        result += "    " + tags.getAttribute(CLASS_NAME, this.getClassNameOfObject()) + eol;
  +
  +        // isolation level is optional
  +        if (getIsolationLevel() != this.getRepository().getDefaultIsolationLevel())
  +        {
  +            result += "    " + tags.getAttribute(ISOLATION_LEVEL, this.isolationLevelXml()) + eol;
  +        }
  +
  +
  +        Class theProxyClass = null;
  +        try
  +        {
  +            theProxyClass = this.getProxyClass();
  +        }
  +        catch (Throwable t)
  +        {
  +            // Ignore this exception, just try to get the Class object of the
  +            // proxy class in order to be able to decide, whether the class
  +            // is a dynamic proxy or not.
  +        }
  +
  +        // proxy is optional
  +        if (theProxyClass != null && Proxy.isProxyClass(theProxyClass))
  +        {
  +            result += "    " + tags.getAttribute(CLASS_PROXY, "dynamic") + eol;
  +        }
  +        else
  +        {
  +            result += "    " + tags.getAttribute(CLASS_PROXY, this.getProxyClassName()) + eol;
  +        }
  +
  +        // schema is optional
  +        if (this.getSchema() != null)
  +        {
  +            result += "    " + tags.getAttribute(SCHEMA_NAME, this.getSchema()) + eol;
  +        }
  +
  +        // table name
  +        if (this.getTableName() != null)
  +        {
  +            result += "    " + tags.getAttribute(TABLE_NAME, this.getTableName()) + eol;
  +        }
  +
  +        // rowreader is optional
  +        if (this.getRowReaderClassName() != null)
  +        {
  +            result += "    " + tags.getAttribute(ROW_READER, this.getRowReaderClassName()) + eol;
  +        }
  +
  +        //accept-locks is optional, enabled by default
  +        if (!this.acceptLocks)
  +        {
  +            result += "        " + tags.getAttribute(ACCEPT_LOCKS,"false") + eol;
  +        }
  +        // sequence manager attribute not yet implemented
  +
  +        result += "  >" + eol;
  +
  +        // end of attributes
  +
  +        // begin of elements
  +        if (isInterface())
  +        {
  +            // extent-class
  +            for (int i = 0; i < getExtentClassNames().size(); i++)
  +            {
  +                result += "      " + tags.getOpeningTagNonClosingById(CLASS_EXTENT) + " ";
  +                result += tags.getAttribute(CLASS_REF, getExtentClassNames().get(i).toString());
  +                result += " />" + eol;
  +            }
  +        }
  +        else
  +        {
  +            // class extent is optional
  +            if (isExtent())
  +            {
  +                for (int i = 0; i < getExtentClassNames().size(); i++)
  +                {
  +                    result += "      " + tags.getOpeningTagNonClosingById(CLASS_EXTENT) + " ";
  +                    result += tags.getAttribute(CLASS_REF, getExtentClassNames().get(i).toString());
  +                    result += " />" + eol;
  +                }
  +            }
  +
  +            // write all FieldDescriptors
  +            FieldDescriptor[] fields = getFieldDescriptions();
  +            for (int i = 0; i < fields.length; i++)
  +            {
  +                result += fields[i].toXML();
  +            }
  +
  +            // write optional ReferenceDescriptors
  +            Vector refs = getObjectReferenceDescriptors();
  +            for (int i = 0; i < refs.size(); i++)
  +            {
  +                result += ((ObjectReferenceDescriptor) refs.get(i)).toXML();
  +            }
  +
  +            // write optional CollectionDescriptors
  +            Vector cols = getCollectionDescriptors();
  +            for (int i = 0; i < cols.size(); i++)
  +            {
  +                result += ((CollectionDescriptor) cols.get(i)).toXML();
  +            }
  +
  +        }
  +
  +        result += "  " + tags.getClosingTagById(CLASS_DESCRIPTOR);
  +        return result;
  +    }
  +
  +    private String isolationLevelXml()
  +    {
  +        switch (this.getIsolationLevel())
  +        {
  +            case (IL_OPTIMISTIC):
  +                {
  +                    return LITERAL_IL_OPTIMISTIC;
  +                }
  +            case (IL_READ_COMMITTED):
  +                {
  +                    return LITERAL_IL_READ_COMMITTED;
  +                }
  +            case (IL_READ_UNCOMMITTED):
  +                {
  +                    return LITERAL_IL_READ_UNCOMMITTED;
  +                }
  +            case (IL_REPEATABLE_READ):
  +                {
  +                    return LITERAL_IL_REPEATABLE_READ;
  +                }
  +            case (IL_SERIALIZABLE):
  +                {
  +                    return LITERAL_IL_SERIALIZABLE;
  +                }
  +            default :
  +                {
  +                    return LITERAL_IL_READ_UNCOMMITTED;
  +                }
  +
  +        }
  +
  +    }
  +
  +    /**
  +     * Returns the first found autoincrement field
  +     * defined in this class descriptor. Use carefully
  +     * when multiple autoincrement field were defined.
  +     */
  +    public FieldDescriptor getAutoIncrementField()
  +    {
  +        if (m_autoIncrementField == null)
  +        {
  +            FieldDescriptor[] fds = getPkFields();
  +
  +            for (int i = 0; i < fds.length; i++)
  +            {
  +                FieldDescriptor fd = fds[i];
  +                if (fd.isAutoIncrement())
  +                {
  +                    m_autoIncrementField = fd;
  +                    break;
  +                }
  +            }
  +        }
  +        if(m_autoIncrementField == null)
  +        {
  +            LoggerFactory.getDefaultLogger().warn(
  +                    "Could not found autoincrement attribute for class: " + this.getClassNameOfObject());
  +        }
  +        return m_autoIncrementField;
  +    }
  +
  +    /**
  +     *
  +     * @return this classes FieldDescriptor's as well as it's parents and so on and so on
  +     */
  +    public FieldDescriptor[] getFieldDescriptorsInHeirarchy()
  +    {
  +        if (superClass == null)
  +        {
  +            return getFieldDescriptions();
  +        }
  +        ClassDescriptor cldSuper = getRepository().getDescriptorFor(superClass);
  +        return appendFieldDescriptorArrays(getFieldDescriptions(), cldSuper.getFieldDescriptorsInHeirarchy());
  +    }
  +
  +    private FieldDescriptor[] appendFieldDescriptorArrays(FieldDescriptor[] fieldDescriptions, FieldDescriptor[] fieldDescriptorsInHeirarchy)
  +    {
  +        // take the 2 arrays and add them into one
  +        int size = fieldDescriptions.length + fieldDescriptorsInHeirarchy.length;
  +        FieldDescriptor[] newArray = new FieldDescriptor[size];
  +        int i;
  +        int j = 0;
  +        for (i = 0; i < fieldDescriptions.length; i++, j++)
  +        {
  +            FieldDescriptor fieldDescription = fieldDescriptions[i];
  +            newArray[j] = fieldDescription;
  +        }
  +        for (i = 0; i < fieldDescriptorsInHeirarchy.length; i++, j++)
  +        {
  +            FieldDescriptor fieldDescription = fieldDescriptorsInHeirarchy[i];
  +            newArray[j] = fieldDescription;
  +        }
  +
  +        return newArray;
  +    }
  +
  +    /**
  +     * convenience function to get the first primary key
  +     * <p>
  +     * useful when there is only one
  +     * @return
  +     */
  +    public FieldDescriptor getPrimaryKey()
  +    {
  +        FieldDescriptor[] fds = getPkFields();
  +        if (fds != null && fds.length > 0)
  +        {
  +            return fds[0];
  +        }
  +        return null;
  +    }
  +
  +    /**
  +     * Returns acceptLocks.
  +     * @return boolean
  +     */
  +    public boolean isAcceptLocks() 
  +    {
  +        return acceptLocks;
  +    }
  +
  +    /**
  +     * Sets acceptLocks.
  +     * @param m_acceptLocks The m_acceptLocks to set
  +     */
  +    public void setAcceptLocks(boolean acceptLocks) 
  +    {
  +        this.acceptLocks = acceptLocks;
  +    }
  +
  +    
  +
  +
  +}