FileDocCategorySizeDatePackage
InheritancePolicy.javaAPI DocGlassfish v2 API68271Tue Jul 10 11:11:20 BST 2007oracle.toplink.essentials.descriptors

InheritancePolicy

public class InheritancePolicy extends Object implements Serializable, Cloneable

Purpose: Allows customization of an object's inheritance. The primary supported inheritance model uses a class type indicator column in the table that stores the object's class type. The class-to-type mapping is specified on this policy. The full class name can also be used for the indicator instead of the mapping.

Each subclass can either share their parents table, or in addition add their own table(s).

For legacy models a customized inheritance class-extractor can be provided. This allows Java code to be used to compute the class type to use for a row. When this customized inheritance model is used an only-instances and with-all-subclasses filter expression may be required for concrete and branch querying.

Fields Summary
protected Class
parentClass
protected String
parentClassName
protected ClassDescriptor
parentDescriptor
protected Vector
childDescriptors
protected transient DatabaseField
classIndicatorField
protected transient Map
classIndicatorMapping
protected transient Map
classNameIndicatorMapping
protected transient boolean
shouldUseClassNameAsIndicator
protected transient Boolean
shouldReadSubclasses
protected transient DatabaseTable
readAllSubclassesView
protected transient Vector
allChildClassIndicators
protected transient Expression
onlyInstancesExpression
protected transient Expression
withAllSubclassesExpression
protected transient Vector
allTables
protected transient List
childrenTables
protected transient Map
childrenTablesJoinExpressions
protected transient Expression
childrenJoinExpression
protected transient ClassExtractor
classExtractor
Allow for class extraction method to be specified.
protected ClassDescriptor
descriptor
protected boolean
shouldAlwaysUseOuterJoin
protected boolean
useDescriptorsToValidateInheritedObjects
protected boolean
isJoinedStrategy
Constructors Summary
public InheritancePolicy()
INTERNAL: Create a new policy. Only descriptors involved in inheritence should have a policy.

         this.classIndicatorMapping = new HashMap(10);
         this.classNameIndicatorMapping = new HashMap(10);
        this.shouldUseClassNameAsIndicator = false;
         this.allChildClassIndicators = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
         this.childDescriptors = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(5);
        this.setJoinedStrategy();
    
public InheritancePolicy(ClassDescriptor descriptor)
INTERNAL: Create a new policy. Only descriptors involved in inheritence should have a policy.

        this();
        this.descriptor = descriptor;
    
Methods Summary
public voidaddChildDescriptor(oracle.toplink.essentials.descriptors.ClassDescriptor childDescriptor)
INTERNAL: Add child descriptor to the parent descriptor.

        getChildDescriptors().addElement(childDescriptor);
    
protected voidaddChildTableJoinExpression(oracle.toplink.essentials.internal.helper.DatabaseTable table, oracle.toplink.essentials.expressions.Expression expression)
INTERNAL: childrenTablesJoinExpressions, childrenTables, allTables and childrenJoinExpression are created simultaneously and kept in sync.

        if(childrenTablesJoinExpressions == null) {
           childrenTablesJoinExpressions = new HashMap();
           // childrenTables should've been null, too
           childrenTables = new ArrayList();
           // allTables should've been null, too
           allTables = new Vector(getDescriptor().getTables());
        }
        childrenTables.add(table);
        allTables.add(table);
        childrenTablesJoinExpressions.put(table, expression);
        childrenJoinExpression = expression.and(childrenJoinExpression);
    
public voidaddChildTableJoinExpressionToAllParents(oracle.toplink.essentials.internal.helper.DatabaseTable table, oracle.toplink.essentials.expressions.Expression expression)
INTERNAL: call addChildTableJoinExpression on all parents

        ClassDescriptor parentDescriptor = getParentDescriptor();
        while(parentDescriptor != null) {
            InheritancePolicy parentPolicy = parentDescriptor.getInheritancePolicy();
            parentPolicy.addChildTableJoinExpression(table, expression);
            parentDescriptor = parentPolicy.getParentDescriptor();
        }
    
public voidaddClassIndicator(java.lang.Class childClass, java.lang.Object typeValue)
PUBLIC: Add a class indicator for the root classes subclass. The indicator is used to determine the class to use for a row read from the database, and to query only instances of a class from the database. Every concrete persistent subclass must have a single unique indicator defined for it. If the root class is concrete then it must also define an indicator. Only the root class's descriptor of the entire inheritance hierarchy can define the class indicator mapping.

        // Note we should think about supporting null values.
        // Store as key and value for bi-diractional lookup.
        getClassIndicatorMapping().put(typeValue, childClass);
        getClassIndicatorMapping().put(childClass, typeValue);
    
public voidaddClassIndicatorFieldToInsertRow(oracle.toplink.essentials.internal.sessions.AbstractRecord databaseRow)
INTERNAL: Add abstract class indicator information to the database row. This is required when building a row for an insert or an update of a concrete child descriptor. This is only used to build a template row.

        if (hasClassExtractor()) {
            return;
        }

        DatabaseField field = getClassIndicatorField();
        databaseRow.put(field, null);
    
public voidaddClassIndicatorFieldToRow(oracle.toplink.essentials.internal.sessions.AbstractRecord databaseRow)
INTERNAL: Add abstract class indicator information to the database row. This is required when building a row for an insert or an update of a concrete child descriptor.

        if (hasClassExtractor()) {
            return;
        }

        DatabaseField field = getClassIndicatorField();
        Object value = getClassIndicatorValue();

        databaseRow.put(field, value);
    
protected voidaddClassIndicatorTypeToParent(java.lang.Object indicator)
INTERNAL: Post initialize the child descriptors

        ClassDescriptor parentDescriptor = getDescriptor().getInheritancePolicy().getParentDescriptor();

        if (parentDescriptor.getInheritancePolicy().isChildDescriptor()) {
            if (parentDescriptor.getInheritancePolicy().shouldReadSubclasses()) {
                parentDescriptor.getInheritancePolicy().getAllChildClassIndicators().addElement(indicator);
            }
            parentDescriptor.getInheritancePolicy().addClassIndicatorTypeToParent(indicator);
        }
    
public voidaddClassNameIndicator(java.lang.String childClassName, java.lang.Object typeValue)
INTERNAL: Add the class name reference by class name, used by the MW.

        getClassNameIndicatorMapping().put(childClassName, typeValue);
    
protected voidaddFieldsToParent(java.util.Vector fields)
INTERNAL: Recursively adds fields to all the parents

        if (isChildDescriptor()) {
            if (getParentDescriptor().isInvalid()) {
                return;
            }
            ClassDescriptor parentDescriptor = getParentDescriptor();
            if (parentDescriptor.getInheritancePolicy().shouldReadSubclasses()) {
                Helper.addAllUniqueToVector(parentDescriptor.getAllFields(), fields);
            }
            parentDescriptor.getInheritancePolicy().addFieldsToParent(fields);
        }
    
public voidappendWithAllSubclassesExpression(oracle.toplink.essentials.internal.expressions.SQLSelectStatement selectStatement)
INTERNAL: Append the branch with all subclasses expression to the statement.

        if (getWithAllSubclassesExpression() != null) {
            // For Flashback: Must always rebuild with simple expression on right.
            if (selectStatement.getWhereClause() == null) {
                selectStatement.setWhereClause((Expression)getWithAllSubclassesExpression().clone());
            } else {
                selectStatement.setWhereClause(selectStatement.getWhereClause().and(getWithAllSubclassesExpression()));
            }
        }
    
public oracle.toplink.essentials.internal.expressions.SQLSelectStatementbuildClassIndicatorSelectStatement(oracle.toplink.essentials.queryframework.ObjectLevelReadQuery query)
INTERNAL: Return a select statement that will be used to query the class indicators required to query. This is used in the abstract-multiple read.

        SQLSelectStatement selectStatement;
        selectStatement = new SQLSelectStatement();
        selectStatement.useDistinct();
        selectStatement.addTable(classIndicatorField.getTable());
        selectStatement.addField(getClassIndicatorField());
        // 2612538 - the default size of IdentityHashtable (32) is appropriate
        IdentityHashtable clonedExpressions = new IdentityHashtable();
        selectStatement.setWhereClause(((ExpressionQueryMechanism)query.getQueryMechanism()).buildBaseSelectionCriteria(false, clonedExpressions));
        appendWithAllSubclassesExpression(selectStatement);
        selectStatement.setTranslationRow(query.getTranslationRow());
        selectStatement.normalize(query.getSession(), getDescriptor(), clonedExpressions);
        ExpressionQueryMechanism m = (ExpressionQueryMechanism)query.getQueryMechanism();

        return selectStatement;
    
public oracle.toplink.essentials.internal.expressions.SQLSelectStatementbuildViewSelectStatement(oracle.toplink.essentials.queryframework.ObjectLevelReadQuery query)
INTERNAL: Build a select statement for all subclasses on the view using the same selection criteria as the query.

        // 2612538 - the default size of IdentityHashtable (32) is appropriate
        IdentityHashtable clonedExpressions = new IdentityHashtable();
        ExpressionQueryMechanism mechanism = (ExpressionQueryMechanism)query.getQueryMechanism();

        // CR#3166555 - Have the mechanism build the statement to avoid duplicating code and ensure that lock-mode, hints, hierarchical, etc. are set.
        SQLSelectStatement selectStatement = mechanism.buildBaseSelectStatement(false, clonedExpressions);
         selectStatement.setTables(oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(1));
        selectStatement.addTable(getReadAllSubclassesView());

        // Case, normal read for branch inheritence class that reads subclasses all in its own table(s).
        if (getWithAllSubclassesExpression() != null) {
            Expression branchIndicator = (Expression)getWithAllSubclassesExpression().clone();
            if (branchIndicator != null) {
                selectStatement.setWhereClause(branchIndicator.and(selectStatement.getWhereClause()));
            }
        }

        selectStatement.setFields(mechanism.getSelectionFields(selectStatement, true));
        selectStatement.normalizeForView(query.getSession(), getDescriptor(), clonedExpressions);
        // Allow for joining indexes to be computed to ensure distinct rows
        ((ObjectLevelReadQuery)query).getJoinedAttributeManager().computeJoiningMappingIndexes(false, query.getSession(), 0);

        return selectStatement;
    
public java.lang.ClassclassFromRow(oracle.toplink.essentials.internal.sessions.AbstractRecord rowFromDatabase, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: This method is invoked only for the abstract descriptors.

        if (hasClassExtractor()) {
            return getClassExtractor().extractClassFromRow(rowFromDatabase, session);
        }

        Object classFieldValue = session.getDatasourcePlatform().getConversionManager().convertObject(rowFromDatabase.get(getClassIndicatorField()), getClassIndicatorField().getType());

        if (classFieldValue == null) {
            throw DescriptorException.missingClassIndicatorField(rowFromDatabase, getDescriptor());
        }

        Class concreteClass;
        if (!shouldUseClassNameAsIndicator()) {
            concreteClass = (Class)getClassIndicatorMapping().get(classFieldValue);
            if (concreteClass == null) {
                throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor());
            }
        } else {
            try {
                String className = (String)classFieldValue;
                //PWK 2.5.1.7 can not use class for name, must go through conversion manager.
                //Should use the root Descriptor's classloader to avoid loading from a loader other
                //than the one that loaded the project
                concreteClass = getDescriptor().getJavaClass().getClassLoader().loadClass(className);
                if (concreteClass == null) {
                    throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor());
                }
            } catch (ClassNotFoundException e) {
                throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor());
            } catch (ClassCastException e) {
                throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor());
            }
        }

        return concreteClass;
    
public java.lang.Objectclone()
INTERNAL: Clone the policy

        InheritancePolicy clone = null;

        try {
            clone = (InheritancePolicy)super.clone();
            if (hasClassIndicator()) {
                clone.setClassIndicatorField((DatabaseField)clone.getClassIndicatorField().clone());
            }
        } catch (Exception exception) {
            throw new InternalError("clone failed");
        }

        return clone;
    
public voidconvertClassNamesToClasses(java.lang.ClassLoader classLoader)
INTERNAL: Convert all the class-name-based settings in this InheritancePolicy to actual class-based settings. This method is used when converting a project that has been built with class names to a project with classes.

param
classLoader

        if (parentClassName == null){
            return;
        }
        Class parentClass = null;
        try{
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    parentClass = (Class)AccessController.doPrivileged(new PrivilegedClassForName(parentClassName, true, classLoader));
                } catch (PrivilegedActionException exception) {
                    throw ValidationException.classNotFoundWhileConvertingClassNames(parentClassName, exception.getException());
                }
            } else {
                parentClass = oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(parentClassName, true, classLoader);
            }
        } catch (ClassNotFoundException exc){
            throw ValidationException.classNotFoundWhileConvertingClassNames(parentClassName, exc);
        }
        setParentClass(parentClass);
    
public voiddontReadSubclassesOnQueries()
PUBLIC: Set the descriptor to only read instance of itself when queried. This is used with inheritance to configure the result of queries. By default this is true for root inheritance descriptors, and false for all others.

        setShouldReadSubclasses(false);
    
public voiddontUseClassNameAsIndicator()
PUBLIC: Set the descriptor not to use the class' full name as the indicator. The class indicator is used with inheritance to determine the class from a row. By default a class indicator mapping is required, this can be set to true if usage of the class name is desired. The field must be of a large enough size to store the fully qualified class name.

        setShouldUseClassNameAsIndicator(false);
    
protected java.util.VectorgetAllChildClassIndicators()
INTERNAL: Stores class indicators for all child and children's children. Used for queries on branch classes only.

        return allChildClassIndicators;
    
public java.util.VectorgetAllChildDescriptors()
INTERNAL: Returns all the child descriptors, even descriptors for subclasses of subclasses. Required for bug 3019934.

        // Guess the number of child descriptors...
        Vector allChildDescriptors = new Vector(this.getAllChildClassIndicators().size());
        return getAllChildDescriptors(allChildDescriptors);
    
protected java.util.VectorgetAllChildDescriptors(java.util.Vector allChildDescriptors)
INTERNAL: Recursive subroutine of getAllChildDescriptors.

        for (Enumeration enumtr = getChildDescriptors().elements(); enumtr.hasMoreElements();) {
            ClassDescriptor childDescriptor = (ClassDescriptor)enumtr.nextElement();
            allChildDescriptors.addElement(childDescriptor);
            childDescriptor.getInheritancePolicyOrNull().getAllChildDescriptors(allChildDescriptors);
        }
        return allChildDescriptors;
    
public java.util.VectorgetAllTables()
INTERNAL: all tables for reference class plus childrenTables

        if(allTables == null) {
            return this.getDescriptor().getTables();
        } else {
            return allTables;
        }
    
public java.util.VectorgetChildDescriptors()
INTERNAL: Return all the immediate child descriptors. Only descriptors from direct subclasses are returned.

        return childDescriptors;
    
public oracle.toplink.essentials.expressions.ExpressiongetChildrenJoinExpression()
INTERNAL: all expressions from childrenTablesJoinExpressions ANDed together

        return childrenJoinExpression;
    
public java.util.ListgetChildrenTables()
INTERNAL: if reads subclasses, all tables for all read subclasses (indirect included).

        return childrenTables;
    
public java.util.MapgetChildrenTablesJoinExpressions()
INTERNAL: join expression for each child table, keyed by the table

        return childrenTablesJoinExpressions;
    
protected java.lang.reflect.MethodgetClassExtractionMethod()
INTERNAL: Return all the classExtractionMethod

        if (classExtractor instanceof MethodClassExtractor) {
            return ((MethodClassExtractor)classExtractor).getClassExtractionMethod();
        } else {
            return null;
        }
    
public java.lang.StringgetClassExtractionMethodName()
ADVANCED: A class extraction method can be registered with the descriptor to override the default inheritance mechanism. This allows for the class indicator field to not be used, and a user defined one instead. The method registered must be a static method on the class that the descriptor is for, the method must take DatabaseRow as argument, and must return the class to use for that row. This method will be used to decide which class to instantiate when reading from the database. It is the application's responsiblity to populate any typing information in the database required to determine the class from the row. If this method is used then the class indicator field and mapping cannot be used, also the descriptor's withAllSubclasses and onlyInstances expressions must also be setup correctly.

see
#setWithAllSubclassesExpression(Expression)
see
#setOnlyInstancesExpression(Expression)

        if (classExtractor instanceof MethodClassExtractor) {
            return ((MethodClassExtractor)classExtractor).getClassExtractionMethodName();
        } else {
            return null;
        }
    
public oracle.toplink.essentials.descriptors.ClassExtractorgetClassExtractor()
ADVANCED: A class extractor can be registered with the descriptor to override the default inheritance mechanism. This allows for the class indicator field to not be used, and a user defined one instead. The instance registered must extend the ClassExtractor class and implement the extractClass(Map) method, the method must take database row (Map) as argument, and must return the class to use for that row. This method will be used to decide which class to instantiate when reading from the database. It is the application's responsiblity to populate any typing information in the database required to determine the class from the row, such as usage of a direct or transformation mapping for the type fields. If this method is used then the class indicator field and mapping cannot be used, also the descriptor's withAllSubclasses and onlyInstances expressions must also be setup correctly.

see
#setWithAllSubclassesExpression(Expression)
see
#setOnlyInstancesExpression(Expression)

        return classExtractor;
    
public java.util.VectorgetClassIndicatorAssociations()
INTERNAL: Return the class indicator associations for XML. List of class-name/value associations.

        Vector associations = new Vector(getClassNameIndicatorMapping().size() / 2);
         Iterator classesEnum = getClassNameIndicatorMapping().keySet().iterator();
         Iterator valuesEnum = getClassNameIndicatorMapping().values().iterator();
         while (classesEnum.hasNext()) {
             Object className = classesEnum.next();

            // If the project was built in runtime is a class, MW is a string.
            if (className instanceof Class) {
                className = ((Class)className).getName();
            }
             Object value = valuesEnum.next();
            associations.addElement(new TypedAssociation(className, value));
        }

        return associations;
    
public oracle.toplink.essentials.internal.helper.DatabaseFieldgetClassIndicatorField()
INTERNAL: Returns field that the class type indicator is store when using inheritence.

        return classIndicatorField;
    
public java.lang.StringgetClassIndicatorFieldName()
PUBLIC: Return the class indicator field name. This is the name of the field in the table that stores what type of object this is.

        if (getClassIndicatorField() == null) {
            return null;
        } else {
            return getClassIndicatorField().getQualifiedName();
        }
    
public java.util.MapgetClassIndicatorMapping()
INTERNAL: Return the association of indicators and classes

        return getClassIndicatorMapping(ConversionManager.getDefaultManager());
    
public java.util.MapgetClassIndicatorMapping(oracle.toplink.essentials.internal.helper.ConversionManager conversionManager)
INTERNAL: Return the association of indicators and classes using specified ConversionManager

        if (classIndicatorMapping.isEmpty() && !classNameIndicatorMapping.isEmpty()) {
             Iterator keysEnum = classNameIndicatorMapping.keySet().iterator();
             Iterator valuesEnum = classNameIndicatorMapping.values().iterator();
             while (keysEnum.hasNext()) {
                 Object key = keysEnum.next();
                 Object value = valuesEnum.next();
                Class theClass = (Class)conversionManager.convertObject((String)key, ClassConstants.CLASS);
                classIndicatorMapping.put(theClass, value);
                classIndicatorMapping.put(value, theClass);
            }
        }
        return classIndicatorMapping;
    
protected java.lang.ObjectgetClassIndicatorValue()
INTERNAL: Returns value of the abstract class indicator for the Java class.

        return getClassIndicatorValue(getDescriptor().getJavaClass());
    
protected java.lang.ObjectgetClassIndicatorValue(java.lang.Class javaClass)
INTERNAL: Returns the indicator field value for the given class If no abstract indicator mapping is specified, use the class name.

        if (shouldUseClassNameAsIndicator()) {
            return javaClass.getName();
        } else {
            return getClassIndicatorMapping().get(javaClass);
        }
    
public java.util.MapgetClassNameIndicatorMapping()
INTERNAL: Return the mapping from class name to indicator, used by MW.

        if (classNameIndicatorMapping.isEmpty() && !classIndicatorMapping.isEmpty()) {
             Iterator keysEnum = classIndicatorMapping.keySet().iterator();
             Iterator valuesEnum = classIndicatorMapping.values().iterator();
             while (keysEnum.hasNext()) {
                 Object key = keysEnum.next();
                 Object value = valuesEnum.next();
                if (key instanceof Class) {
                    String className = ((Class)key).getName();
                    classNameIndicatorMapping.put(className, value);
                }
            }
        }

        return classNameIndicatorMapping;
    
public oracle.toplink.essentials.descriptors.ClassDescriptorgetDescriptor()
INTERNAL: Returns the descriptor which the policy belongs to.

        return descriptor;
    
public oracle.toplink.essentials.expressions.ExpressiongetOnlyInstancesExpression()
ADVANCED: Return the 'only instances expression'.

        return onlyInstancesExpression;
    
public java.lang.ClassgetParentClass()
PUBLIC: Return the parent class.

        return parentClass;
    
public java.lang.StringgetParentClassName()
INTERNAL: Return the parent class name.

        if ((parentClassName == null) && (parentClass != null)) {
            parentClassName = parentClass.getName();
        }
        return parentClassName;
    
public oracle.toplink.essentials.descriptors.ClassDescriptorgetParentDescriptor()
INTERNAL: Return the parent descirptor

        return parentDescriptor;
    
public oracle.toplink.essentials.internal.helper.DatabaseTablegetReadAllSubclassesView()
INTERNAL: The view can be used to optimize/customize the query for all subclasses where they have multiple tables. This view can do the outer join, we require the view because we cannot generate dynmic platform independent SQL for outer joins (i.e. not possible to do so either).

        return readAllSubclassesView;
    
public java.lang.StringgetReadAllSubclassesViewName()
ADVANCED: The view can be used to optimize/customize the query for all subclasses where they have multiple tables. This view can use outer joins or unions to combine the results of selecting from all of the subclass tables. If a view is not given then TopLink must make an individual call for each subclass.

        if (getReadAllSubclassesView() == null) {
            return null;
        }
        return getReadAllSubclassesView().getName();
    
public oracle.toplink.essentials.descriptors.ClassDescriptorgetRootParentDescriptor()
INTERNAL: Return the root parent descriptor

        if (isRootParentDescriptor()) {
            return getDescriptor();
        } else {
            return getParentDescriptor().getInheritancePolicy().getRootParentDescriptor();
        }
    
public oracle.toplink.essentials.descriptors.ClassDescriptorgetSubclassDescriptor(java.lang.Class theClass)
INTERNAL: use aggregate in inheritance

        if (hasChildren()) {
            for (Iterator enumtr = getChildDescriptors().iterator(); enumtr.hasNext();) {
                ClassDescriptor childDescriptor = (ClassDescriptor)enumtr.next();
                if (childDescriptor.getJavaClass().equals(theClass)) {
                    return childDescriptor;
                } else {
                    ClassDescriptor descriptor = childDescriptor.getInheritancePolicy().getSubclassDescriptor(theClass);
                    if (descriptor != null) {
                        return descriptor;
                    }
                }
            }
        }
        return null;
    
public booleangetUseDescriptorsToValidateInheritedObjects()
INTERNAL: return if we should use the descriptor inheritance to determine if an object can be returned from the identity map or not.

        return useDescriptorsToValidateInheritedObjects;
    
public oracle.toplink.essentials.expressions.ExpressiongetWithAllSubclassesExpression()
ADVANCED: Return the Expression which gets all subclasses.

        return withAllSubclassesExpression;
    
public booleanhasChildren()
INTERNAL: Check if descriptor has children

        return !getChildDescriptors().isEmpty();
    
public booleanhasClassExtractor()
INTERNAL:

        return getClassExtractor() != null;
    
public booleanhasClassIndicator()
INTERNAL: Checks if the class is invloved in inheritence

        return getClassIndicatorField() != null;
    
public booleanhasMultipleTableChild()
INTERNAL: Return if any children of this descriptor require information from another table not specified at the parent level.

        return childrenTables != null;
    
public booleanhasView()
INTERNAL: Return if a view is used for inheritance reads.

        return getReadAllSubclassesView() != null;
    
public voidinitialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Initialized the inheritence properties of the descriptor once the mappings are initialized. This is done before formal postInitialize during the end of mapping initialize.

        // Must reset this in the case that a child thinks it wants to read its subclasses.
        if ((shouldReadSubclasses == null) || shouldReadSubclasses()) {
            setShouldReadSubclasses(!getChildDescriptors().isEmpty());
        }

        if (isChildDescriptor()) {
            getDescriptor().setMappings(Helper.concatenateVectors(getParentDescriptor().getMappings(), getDescriptor().getMappings()));
             getDescriptor().setQueryKeys(Helper.concatenateMaps(getParentDescriptor().getQueryKeys(), getDescriptor().getQueryKeys()));
            addFieldsToParent(getDescriptor().getFields());
            // Parents fields must be first for indexing to work.
            Vector parentsFields = (Vector)getParentDescriptor().getFields().clone();

            //bug fix on Oracle duplicate field SQL using "order by"
            Helper.addAllUniqueToVector(parentsFields, getDescriptor().getFields());
            getDescriptor().setFields(parentsFields);

            if (getClassIndicatorValue() != null) {
                if (shouldReadSubclasses()) {
                    getAllChildClassIndicators().addElement(getClassIndicatorValue());
                }
                addClassIndicatorTypeToParent(getClassIndicatorValue());
            }

            // CR#3214106, do not override if specified in subclass.
            if (!getDescriptor().usesOptimisticLocking() && getParentDescriptor().usesOptimisticLocking()) {
                getDescriptor().setOptimisticLockingPolicy((OptimisticLockingPolicy)getParentDescriptor().getOptimisticLockingPolicy().clone());
                getDescriptor().getOptimisticLockingPolicy().setDescriptor(getDescriptor());
            }

            // create CMPPolicy on child if parent has one and it does not.  Then copy individual fields
            CMPPolicy parentCMPPolicy = getDescriptor().getInheritancePolicy().getParentDescriptor().getCMPPolicy();
            if (parentCMPPolicy != null) {
                CMPPolicy cmpPolicy = getDescriptor().getCMPPolicy();
                if (cmpPolicy == null) {
                    cmpPolicy = new CMPPolicy();
                    getDescriptor().setCMPPolicy(cmpPolicy);
                }
            }
        }

        initializeOnlyInstancesExpression();
        initializeWithAllSubclassesExpression();
    
protected voidinitializeClassExtractor(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Setup the default classExtractionMethod, or if one was specified by the user make sure it is valid.

        if (getClassExtractor() == null) {
            if (isChildDescriptor()) {
                setClassExtractor(getParentDescriptor().getInheritancePolicy().getClassExtractor());
            }
        } else {
            getClassExtractor().initialize(getDescriptor(), session);
        }
    
protected voidinitializeOnlyInstancesExpression()
INTERNAL: Initialize the expression to use to check the specific type field.

        if (getOnlyInstancesExpression() == null) {
            if (hasClassExtractor()) {
                return;
            }
            Object typeValue = getClassIndicatorValue();
            if (typeValue == null) {
                if (shouldReadSubclasses()) {
                    return;// No indicator is allowed in this case.
                }

                throw DescriptorException.valueNotFoundInClassIndicatorMapping(getParentDescriptor(), getDescriptor());
            }

            DatabaseField typeField = getClassIndicatorField();
            if (typeField == null) {
                throw DescriptorException.classIndicatorFieldNotFound(getParentDescriptor(), getDescriptor());
            }

            // cr3546
            if (shouldAlwaysUseOuterJoin()) {
                setOnlyInstancesExpression(new ExpressionBuilder().getField(typeField).equalOuterJoin(typeValue));
            } else {
                setOnlyInstancesExpression(new ExpressionBuilder().getField(typeField).equal(typeValue));
            }
        }

        // If subclasses are read, this is anded dynamically.
        if (!shouldReadSubclasses()) {
            getDescriptor().getQueryManager().setAdditionalJoinExpression(getOnlyInstancesExpression().and(getDescriptor().getQueryManager().getAdditionalJoinExpression()));
        }
    
protected voidinitializeWithAllSubclassesExpression()
INTERNAL: Initialize the expression to use for queries to the class and its subclasses.

        if (getWithAllSubclassesExpression() == null) {
            if (hasClassExtractor()) {
                return;
            }
            if (isChildDescriptor() && shouldReadSubclasses()) {
                setWithAllSubclassesExpression(new ExpressionBuilder().getField(getClassIndicatorField()).in(getAllChildClassIndicators()));
            }
        }
    
public booleanisChildDescriptor()
INTERNAL: Check if it is a child descriptor.

        return getParentClassName() != null;
    
public booleanisJoinedStrategy()
INTERNAL: Indicate whether a single table or joined inheritance strategy is being used. Since we currently do not support TABLE_PER_CLASS, indicating either joined/not joined is sufficient.

return
isJoinedStrategy value

        return isJoinedStrategy;
    
public booleanisRootParentDescriptor()
INTERNAL: Return whether or not is root parent descriptor

        return getParentDescriptor() == null;
    
public voidpostInitialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Initialized the inheritence properties that cannot be initialized unitl after the mappings have been.

    
public voidpreInitialize(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Allow the inheritence properties of the descriptor to be initialized. The descriptor's parent must first be initialized.

        // Make sure that parent is already preinitialized.
        if (isChildDescriptor()) {
            // Unique is required because the builder can add the same table many times.
            Vector<DatabaseTable> childTables = getDescriptor().getTables();
            Vector<DatabaseTable> parentTables = getParentDescriptor().getTables();
            Vector<DatabaseTable> uniqueTables = Helper.concatenateUniqueVectors(parentTables, childTables);
            getDescriptor().setTables(uniqueTables);
            
            // After filtering out any duplicate tables, set the default table
            // if one is not already set. This must be done now before any other
            // initialization occurs. In a joined strategy case, the default 
            // table will be at an index greater than 0. Which is where
            // setDefaultTable() assumes it is. Therefore, we need to send the 
            // actual default table instead.
            if (childTables.isEmpty()) {
                getDescriptor().setInternalDefaultTable();
            } else {
                getDescriptor().setInternalDefaultTable(uniqueTables.get(uniqueTables.indexOf(childTables.get(0))));
            }

            setClassIndicatorMapping(getParentDescriptor().getInheritancePolicy().getClassIndicatorMapping(session.getDatasourcePlatform().getConversionManager()));
            setShouldUseClassNameAsIndicator(getParentDescriptor().getInheritancePolicy().shouldUseClassNameAsIndicator());

            // Initialize properties.
            getDescriptor().setPrimaryKeyFields(getParentDescriptor().getPrimaryKeyFields());
            getDescriptor().setAdditionalTablePrimaryKeyFields(Helper.concatenateMaps(getParentDescriptor().getAdditionalTablePrimaryKeyFields(), getDescriptor().getAdditionalTablePrimaryKeyFields()));

            Expression localExpression = getDescriptor().getQueryManager().getMultipleTableJoinExpression();
            Expression parentExpression = getParentDescriptor().getQueryManager().getMultipleTableJoinExpression();

            if (localExpression != null) {
                getDescriptor().getQueryManager().setInternalMultipleTableJoinExpression(localExpression.and(parentExpression));
            } else if (parentExpression != null) {
                getDescriptor().getQueryManager().setInternalMultipleTableJoinExpression(parentExpression);
            }

            Expression localAdditionalExpression = getDescriptor().getQueryManager().getAdditionalJoinExpression();
            Expression parentAdditionalExpression = getParentDescriptor().getQueryManager().getAdditionalJoinExpression();

            if (localAdditionalExpression != null) {
                getDescriptor().getQueryManager().setAdditionalJoinExpression(localAdditionalExpression.and(parentAdditionalExpression));
            } else if (parentAdditionalExpression != null) {
                getDescriptor().getQueryManager().setAdditionalJoinExpression(parentAdditionalExpression);
            }

            setClassIndicatorField(getParentDescriptor().getInheritancePolicy().getClassIndicatorField());

            //if child has sequencing setting, do not bother to call the parent
            if (!getDescriptor().usesSequenceNumbers()) {
                getDescriptor().setSequenceNumberField(getParentDescriptor().getSequenceNumberField());
                getDescriptor().setSequenceNumberName(getParentDescriptor().getSequenceNumberName());
            }
        } else {
            // This must be done now before any other initialization occurs. 
            getDescriptor().setInternalDefaultTable();
        }

        initializeClassExtractor(session);

        if (!isChildDescriptor()) {
            // build abstract class indicator field.
            if ((getClassIndicatorField() == null) && (!hasClassExtractor())) {
                session.getIntegrityChecker().handleError(DescriptorException.classIndicatorFieldNotFound(getDescriptor(), getDescriptor()));
            }
            if (getClassIndicatorField() != null) {
                getDescriptor().buildField(getClassIndicatorField());
                // Determine and set the class indicator classification.
                if (shouldUseClassNameAsIndicator()) {
                    getClassIndicatorField().setType(ClassConstants.STRING);
                } else if (!getClassIndicatorMapping(session.getDatasourcePlatform().getConversionManager()).isEmpty()) {
                    Class type = null;
                    Iterator fieldValuesEnum = getClassIndicatorMapping(session.getDatasourcePlatform().getConversionManager()).values().iterator();
                     while (fieldValuesEnum.hasNext() && (type == null)) {
                         Object value = fieldValuesEnum.next();
                        if (value.getClass() != getClass().getClass()) {
                            type = value.getClass();
                        }
                    }
                    getClassIndicatorField().setType(type);
                }
                getDescriptor().getFields().addElement(getClassIndicatorField());
            }
        }
    
public voidreadSubclassesOnQueries()
PUBLIC: Set the descriptor to read instance of itself and its subclasses when queried. This is used with inheritance to configure the result of queries. By default this is true for root inheritance descriptors, and false for all others.

        setShouldReadSubclasses(true);
    
public booleanrequiresMultipleTableSubclassRead()
INTERNAL: Return if this descriptor has children that define additional tables and needs to read them. This case requires a special read, because the query cannot be done through a single SQL call with normal joins.

        return hasMultipleTableChild() && shouldReadSubclasses();
    
protected java.util.VectorselectAllRowUsingCustomMultipleTableSubclassRead(oracle.toplink.essentials.queryframework.ReadAllQuery query)
INTERNAL: Select all rows from a abstract table descriptor. This is accomplished by selecting for all of the concrete classes and then merging the rows. This does not optimize using type select, as the type infomation is not known.

return
vector containing database rows.
exception
DatabaseException - an error has occurred on the database.

        Vector rows = new Vector();
        // CR#3701077, it must either have a filter only instances expression, or not have subclasses.
        // This method recurses, so even though this is only called when shouldReadSubclasses is true, it may be false for subclasses.
        if ((getOnlyInstancesExpression() != null)  || (! shouldReadSubclasses())) {
            ReadAllQuery concreteQuery = (ReadAllQuery)query.clone();
            concreteQuery.setReferenceClass(getDescriptor().getJavaClass());
            concreteQuery.setDescriptor(getDescriptor());

            Vector concreteRows = ((ExpressionQueryMechanism)concreteQuery.getQueryMechanism()).selectAllRowsFromConcreteTable();
            rows = Helper.concatenateVectors(rows, concreteRows);
        }

        // Recursively collect all rows from all concrete children and their children.
        for (Enumeration childrenEnum = getChildDescriptors().elements();
                 childrenEnum.hasMoreElements();) {
            ClassDescriptor concreteDescriptor = (ClassDescriptor)childrenEnum.nextElement();
            Vector concreteRows = concreteDescriptor.getInheritancePolicy().selectAllRowUsingCustomMultipleTableSubclassRead(query);
            rows = Helper.concatenateVectors(rows, concreteRows);
        }

        return rows;
    
protected java.util.VectorselectAllRowUsingDefaultMultipleTableSubclassRead(oracle.toplink.essentials.queryframework.ReadAllQuery query)
INTERNAL: Select all rows from a abstract table descriptor. This is accomplished by selecting for all of the concrete classes and then merging the rows.

return
vector containing database rows.
exception
DatabaseException - an error has occurred on the database.

        // Get all rows for the given class indicator field
        // The indicator select is prepared in the original query, so can just be executed.
        Vector classIndicators = ((ExpressionQueryMechanism)query.getQueryMechanism()).selectAllRowsFromTable();

        Vector classes = new Vector();
        for (Enumeration rowsEnum = classIndicators.elements(); rowsEnum.hasMoreElements();) {
            AbstractRecord row = (AbstractRecord)rowsEnum.nextElement();
            Class concreteClass = classFromRow(row, query.getSession());
            if (!classes.contains(concreteClass)) {//Ensure unique ** we should do a distinct.. we do
                classes.addElement(concreteClass);
            }
        }

        Vector rows = new Vector();
        // joinedMappingIndexes contains Integer indexes corrsponding to the number of fields
        // to which the query rference class is mapped, for instance:
        // referenceClass = SmallProject => joinedMappingIndexes(0) = 6;
        // referenceClass = LargeProject => joinedMappingIndexes(0) = 8;
        // This information should be preserved in the main query against the parent class,
        // therefore in this case joinedMappedIndexes contains a Map of classes to Integers:
        // referenceClass = Project => joinedMappingIndexes(0) = Map {SmallProject -> 6; LargeProject -> 8}.
        // These maps are populated in the loop below, and set into the main query joinedMappingIndexes.
        HashMap joinedMappingIndexes = null;
        if(query.getJoinedAttributeManager().hasJoinedAttributes()) {
            joinedMappingIndexes = new HashMap();
        }
        for (Enumeration classesEnum = classes.elements(); classesEnum.hasMoreElements();) {
            Class concreteClass = (Class)classesEnum.nextElement();
            ClassDescriptor concreteDescriptor = query.getSession().getDescriptor(concreteClass);
            if (concreteDescriptor == null) {
                throw QueryException.noDescriptorForClassFromInheritancePolicy(query, concreteClass);
            }
            ReadAllQuery concreteQuery = (ReadAllQuery)query.clone();
            concreteQuery.setReferenceClass(concreteClass);
            concreteQuery.setDescriptor(concreteDescriptor);

            Vector concreteRows = ((ExpressionQueryMechanism)concreteQuery.getQueryMechanism()).selectAllRowsFromConcreteTable();
            rows = Helper.concatenateVectors(rows, concreteRows);
            
            if(joinedMappingIndexes != null) {
                Iterator it = concreteQuery.getJoinedAttributeManager().getJoinedMappingIndexes_().entrySet().iterator();
                while(it.hasNext()) {
                    Map.Entry entry = (Map.Entry)it.next();
                    HashMap map = (HashMap)joinedMappingIndexes.get(entry.getKey());
                    if(map == null) {
                        map = new HashMap(classes.size());
                        joinedMappingIndexes.put(entry.getKey(), map);
                    }
                    map.put(concreteClass, entry.getValue());
                }
            }
        }
        if(joinedMappingIndexes != null) {
            query.getJoinedAttributeManager().setJoinedMappingIndexes_(joinedMappingIndexes);
        }

        return rows;
    
public java.util.VectorselectAllRowUsingMultipleTableSubclassRead(oracle.toplink.essentials.queryframework.ReadAllQuery query)
INTERNAL: Select all rows from a abstract table descriptor. This is accomplished by selecting for all of the concrete classes and then merging the rows.

return
vector containing database rows.
exception
DatabaseException - an error has occurred on the database.

        if (hasClassExtractor()) {
            return selectAllRowUsingCustomMultipleTableSubclassRead(query);
        } else {
            return selectAllRowUsingDefaultMultipleTableSubclassRead(query);
        }
    
protected oracle.toplink.essentials.internal.sessions.AbstractRecordselectOneRowUsingCustomMultipleTableSubclassRead(oracle.toplink.essentials.queryframework.ReadObjectQuery query)
INTERNAL: Select one rows from a abstract table descriptor. This is accomplished by selecting for all of the concrete classes until a row is found. This does not optimize using type select, as the type infomation is not known.

exception
DatabaseException - an error has occurred on the database.

        // CR#3701077, it must either have a filter only instances expression, or not have subclasses.
        // This method recurses, so even though this is only called when shouldReadSubclasses is true, it may be false for subclasses.
        if ((getOnlyInstancesExpression() != null)  || (! shouldReadSubclasses())) {
            ReadObjectQuery concreteQuery = (ReadObjectQuery)query.clone();
            concreteQuery.setReferenceClass(getDescriptor().getJavaClass());
            concreteQuery.setDescriptor(getDescriptor());

            AbstractRecord row = ((ExpressionQueryMechanism)concreteQuery.getQueryMechanism()).selectOneRowFromConcreteTable();

            if (row != null) {
                return row;
            }
        }

        // Recursively collect all rows from all concrete children and their children.
        for (Enumeration childrenEnum = getChildDescriptors().elements();
                 childrenEnum.hasMoreElements();) {
            ClassDescriptor concreteDescriptor = (ClassDescriptor)childrenEnum.nextElement();
            AbstractRecord row = concreteDescriptor.getInheritancePolicy().selectOneRowUsingCustomMultipleTableSubclassRead(query);

            if (row != null) {
                return row;
            }
        }

        return null;
    
protected oracle.toplink.essentials.internal.sessions.AbstractRecordselectOneRowUsingDefaultMultipleTableSubclassRead(oracle.toplink.essentials.queryframework.ReadObjectQuery query)
INTERNAL: Select one row of any concrete subclass, This must use two selects, the first retreives the type field only.

        // Get the row for the given class indicator field
        // The indicator select is prepared in the original query, so can just be executed.
        AbstractRecord typeRow = ((ExpressionQueryMechanism)query.getQueryMechanism()).selectOneRowFromTable();

        if (typeRow == null) {
            return null;
        }

        Class concreteClass = classFromRow(typeRow, query.getSession());
        ClassDescriptor concreteDescriptor = query.getSession().getDescriptor(concreteClass);
        if (concreteDescriptor == null) {
            throw QueryException.noDescriptorForClassFromInheritancePolicy(query, concreteClass);
        }

        ReadObjectQuery concreteQuery = (ReadObjectQuery)query.clone();
        concreteQuery.setReferenceClass(concreteClass);
        concreteQuery.setDescriptor(concreteDescriptor);

        AbstractRecord resultRow = ((ExpressionQueryMechanism)concreteQuery.getQueryMechanism()).selectOneRowFromConcreteTable();

        return resultRow;
    
public oracle.toplink.essentials.internal.sessions.AbstractRecordselectOneRowUsingMultipleTableSubclassRead(oracle.toplink.essentials.queryframework.ReadObjectQuery query)
INTERNAL: Select one row of any concrete subclass, This must use two selects, the first retreives the type field only.

        if (hasClassExtractor()) {
            return selectOneRowUsingCustomMultipleTableSubclassRead(query);
        } else {
            return selectOneRowUsingDefaultMultipleTableSubclassRead(query);
        }
    
protected voidsetAllChildClassIndicators(java.util.Vector allChildClassIndicators)
INTERNAL:

        this.allChildClassIndicators = allChildClassIndicators;
    
public voidsetAlwaysUseOuterJoinForClassType(boolean choice)
PUBLIC: Sets the inheritance policy to always use an outer join when quering across a relationship of class. used when using getAllowingNull(), or anyOfAllowingNone()

        this.shouldAlwaysUseOuterJoin = choice;
    
public voidsetChildDescriptors(java.util.Vector theChildDescriptors)
INTERNAL:

        childDescriptors = theChildDescriptors;
    
public voidsetClassExtractionMethodName(java.lang.String staticClassClassExtractionMethod)
ADVANCED: A class extraction method can be registered with the descriptor to override the default inheritance mechanism. This allows for the class indicator field to not be used, and a user defined one instead. The method registered must be a static method on the class that the descriptor is for, the method must take DatabaseRow as argument, and must return the class to use for that row. This method will be used to decide which class to instantiate when reading from the database. It is the application's responsiblity to populate any typing information in the database required to determine the class from the row. If this method is used then the class indicator field and mapping cannot be used, also the descriptor's withAllSubclasses and onlyInstances expressions must also be setup correctly.

see
#setWithAllSubclassesExpression(Expression)
see
#setOnlyInstancesExpression(Expression)

        if ((staticClassClassExtractionMethod == null) || (staticClassClassExtractionMethod.length() == 0)) {
            return;
        }
        if (!(getClassExtractor() instanceof MethodClassExtractor)) {
            setClassExtractor(new MethodClassExtractor());
        }
        ((MethodClassExtractor)getClassExtractor()).setClassExtractionMethodName(staticClassClassExtractionMethod);
    
public voidsetClassExtractor(oracle.toplink.essentials.descriptors.ClassExtractor classExtractor)
ADVANCED: A class extractor can be registered with the descriptor to override the default inheritance mechanism. This allows for the class indicator field to not be used, and a user defined one instead. The instance registered must extend the ClassExtractor class and implement the extractClass(Map) method, the method must take database row (Map) as argument, and must return the class to use for that row. This method will be used to decide which class to instantiate when reading from the database. It is the application's responsiblity to populate any typing information in the database required to determine the class from the row, such as usage of a direct or transformation mapping for the type fields. If this method is used then the class indicator field and mapping cannot be used, also the descriptor's withAllSubclasses and onlyInstances expressions must also be setup correctly.

see
#setWithAllSubclassesExpression(Expression)
see
#setOnlyInstancesExpression(Expression)

        this.classExtractor = classExtractor;
    
public voidsetClassIndicatorAssociations(java.util.Vector classIndicatorAssociations)
INTERNAL: Set the class indicator associations from reading the deployment XML.

         setClassNameIndicatorMapping(new HashMap(classIndicatorAssociations.size() + 1));
         setClassIndicatorMapping(new HashMap((classIndicatorAssociations.size() * 2) + 1));
        for (Enumeration associationsEnum = classIndicatorAssociations.elements();
                 associationsEnum.hasMoreElements();) {
            Association association = (Association)associationsEnum.nextElement();
            Object classValue = association.getKey();
            if (classValue instanceof Class) {
                // 904 projects will be a class type.
                addClassIndicator((Class)association.getKey(), association.getValue());
            } else {
                addClassNameIndicator((String)association.getKey(), association.getValue());
            }
        }
    
public voidsetClassIndicatorField(oracle.toplink.essentials.internal.helper.DatabaseField classIndicatorField)
ADVANCED: To set the class indicator field. This can be used for advanced field types, such as XML nodes, or to set the field type.

        this.classIndicatorField = classIndicatorField;
    
public voidsetClassIndicatorFieldName(java.lang.String fieldName)
PUBLIC: To set the class indicator field name. This is the name of the field in the table that stores what type of object this is.

        if (fieldName == null) {
            setClassIndicatorField(null);
        } else {
            setClassIndicatorField(new DatabaseField(fieldName));
        }
    
public voidsetClassIndicatorMapping(java.util.Map classIndicatorMapping)
PUBLIC: Set the association of indicators and classes. This may be desired to be used by clients in strange inheritence models.

        this.classIndicatorMapping = classIndicatorMapping;
    
public voidsetClassNameIndicatorMapping(java.util.Map classNameIndicatorMapping)
INTERNAL: Set the class name indicator mapping, used by the MW.

        this.classNameIndicatorMapping = classNameIndicatorMapping;
    
public voidsetDescriptor(oracle.toplink.essentials.descriptors.ClassDescriptor descriptor)
INTERNAL: Set the descriptor.

        this.descriptor = descriptor;
    
public voidsetJoinedStrategy()
INTERNAL: Used to indicate a JOINED inheritance strategy.

        isJoinedStrategy = true;
    
public voidsetOnlyInstancesExpression(oracle.toplink.essentials.expressions.Expression onlyInstancesExpression)
ADVANCED: Sets the expression used to select instance of the class only. Can be used to customize the inheritance class indicator expression.

        this.onlyInstancesExpression = onlyInstancesExpression;
    
public voidsetParentClass(java.lang.Class parentClass)
PUBLIC: Set the parent class. A descriptor can inherit from another descriptor through defining it as its parent. The root descriptor must define a class indicator field and mapping. All children must share the same table as their parent but can add additional tables. All children must share the root descriptor primary key.

        this.parentClass = parentClass;
        if (parentClass != null) {
            setParentClassName(parentClass.getName());
        }
    
public voidsetParentClassName(java.lang.String parentClassName)
INTERNAL: Set the parent class name, used by MW to avoid referencing the real class for deployment XML generation.

        this.parentClassName = parentClassName;
    
public voidsetParentDescriptor(oracle.toplink.essentials.descriptors.ClassDescriptor parentDescriptor)
INTERNAL:

        this.parentDescriptor = parentDescriptor;
    
protected voidsetReadAllSubclassesView(oracle.toplink.essentials.internal.helper.DatabaseTable readAllSubclassesView)
INTERNAL: The view can be used to optimize/customize the query for all subclasses where they have multiple tables. This view can do the outer join, we require the view because we cannot generate dynmic platform independent SQL for outer joins (i.e. not possible to do so either).

        this.readAllSubclassesView = readAllSubclassesView;
    
public voidsetReadAllSubclassesViewName(java.lang.String readAllSubclassesViewName)
ADVANCED: The view can be used to optimize/customize the query for all subclasses where they have multiple tables. This view can use outer joins or unions to combine the results of selecting from all of the subclass tables. If a view is not given then TopLink must make an individual call for each subclass.

        if (readAllSubclassesViewName == null) {
            setReadAllSubclassesView(null);
        } else {
            setReadAllSubclassesView(new DatabaseTable(readAllSubclassesViewName));
        }
    
public voidsetShouldReadSubclasses(java.lang.Boolean shouldReadSubclasses)
INTERNAL: Set the descriptor to read instance of itself and its subclasses when queried. This is used with inheritence to configure the result of queries. By default this is true for root inheritence descriptors, and false for all others.

        this.shouldReadSubclasses = shouldReadSubclasses;
    
public voidsetShouldReadSubclasses(boolean shouldReadSubclasses)
PUBLIC: Set the descriptor to read instance of itself and its subclasses when queried. This is used with inheritence to configure the result of queries. By default this is true for root inheritence descriptors, and false for all others.

        this.shouldReadSubclasses = Boolean.valueOf(shouldReadSubclasses);
    
public voidsetShouldUseClassNameAsIndicator(boolean shouldUseClassNameAsIndicator)
PUBLIC: Set if the descriptor uses the classes fully qualified name as the indicator. The class indicator is used with inheritence to determine the class from a row. By default a class indicator mapping is required, this can be set to true if usage of the class name is desired. The field must be of a large enough size to store the fully qualified class name.

        this.shouldUseClassNameAsIndicator = shouldUseClassNameAsIndicator;
    
public voidsetSingleTableStrategy()
INTERNAL: Used to indicate a SINGLE_TABLE inheritance strategy. Since only JOINED and SINGLE_TABLE strategies are supported at this time (no support for TABLE_PER_CLASS) using a !isJoinedStrategy an an indicator for SINGLE_TABLE is sufficient.

        isJoinedStrategy = false;
    
public voidsetUseDescriptorsToValidateInheritedObjects(boolean useDescriptorsToValidateInheritedObjects)
INTERNAL: Sets if we should use the descriptor inheritance to determine if an object can be returned from the identity map or not.

        //CR 4005
        this.useDescriptorsToValidateInheritedObjects = useDescriptorsToValidateInheritedObjects;
    
public voidsetWithAllSubclassesExpression(oracle.toplink.essentials.expressions.Expression withAllSubclassesExpression)
ADVANCED: Sets the expression to be used for querying for a class and all its subclasses. Can be used to customize the inheritence class indicator expression.

        this.withAllSubclassesExpression = withAllSubclassesExpression;
    
public booleanshouldAlwaysUseOuterJoin()
PUBLIC: returns if the inheritance policy will always use an outerjoin when selecting class type

        return this.shouldAlwaysUseOuterJoin;
    
public booleanshouldReadSubclasses()
PUBLIC: Return true if this descriptor should read instances of itself and subclasses on queries.

        if (shouldReadSubclasses == null) {
            return true;
        }
        return shouldReadSubclasses.booleanValue();
    
public java.lang.BooleanshouldReadSubclassesValue()
INTERNAL: Return true if this descriptor should read instances of itself and subclasses on queries.

        return shouldReadSubclasses;
    
public booleanshouldUseClassNameAsIndicator()
PUBLIC: Return true if the descriptor use the classes full name as the indicator. The class indicator is used with inheritance to determine the class from a row. By default a class indicator mapping is required, this can be set to true if usage of the class name is desired. The field must be of a large enough size to store the fully qualified class name.

        return shouldUseClassNameAsIndicator;
    
public java.lang.StringtoString()
INTERNAL:

        return Helper.getShortClassName(getClass()) + "(" + getDescriptor() + ")";
    
public voiduseClassNameAsIndicator()
PUBLIC: Set the descriptor to use the classes full name as the indicator. The class indicator is used with inheritance to determine the class from a row. By default a class indicator mapping is required, this can be set to true if usage of the class name is desired. The field must be of a large enough size to store the fully qualified class name.

        setShouldUseClassNameAsIndicator(true);