FileDocCategorySizeDatePackage
ObjectExpression.javaAPI DocGlassfish v2 API15477Tue May 22 16:54:32 BST 2007oracle.toplink.essentials.internal.expressions

ObjectExpression

public abstract class ObjectExpression extends DataExpression
Superclass for any object type expressions.

Fields Summary
public transient ClassDescriptor
descriptor
public Vector
derivedExpressions
protected boolean
shouldUseOuterJoinForMultitableInheritance
indicates whether subclasses should be joined
protected boolean
shouldUseOuterJoin
Is this query key to be resolved using an outer join or not. Does not apply to attributes.
Constructors Summary
public ObjectExpression()

        this.shouldUseOuterJoin = false;
    
Methods Summary
public voidaddDerivedExpression(oracle.toplink.essentials.expressions.Expression addThis)

        if (derivedExpressions == null) {
            derivedExpressions = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
        }
        derivedExpressions.addElement(addThis);
    
public oracle.toplink.essentials.expressions.ExpressionadditionalExpressionCriteria()
INTERNAL: Return the expression to join the main table of this node to any auxiliary tables.

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

        Expression criteria = getDescriptor().getQueryManager().getAdditionalJoinExpression();
        if(getSession().getPlatform().shouldPrintOuterJoinInWhereClause()) {
            if(isUsingOuterJoinForMultitableInheritance()) {
                Expression childrenCriteria = getDescriptor().getInheritancePolicy().getChildrenJoinExpression();
                childrenCriteria = getBaseExpression().twist(childrenCriteria, this);
                childrenCriteria.convertToUseOuterJoin();
                if(criteria == null) {
                    criteria = childrenCriteria;
                } else {
                    criteria = criteria.and(childrenCriteria);
                }
            }
        }

        return criteria;
    
public java.util.MapadditionalExpressionCriteriaMap()
INTERNAL: Used in case outer joins should be printed in FROM clause. Each of the additional tables mapped to expressions that joins it.

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

        HashMap tablesJoinExpressions = null;
        if(isUsingOuterJoinForMultitableInheritance()) {
            Vector tables = getDescriptor().getTables();
            tablesJoinExpressions = new HashMap();
            List childrenTables = getDescriptor().getInheritancePolicy().getChildrenTables();
            for( int i=0; i < childrenTables.size(); i++) {
                DatabaseTable table = (DatabaseTable)childrenTables.get(i);
                Expression joinExpression = (Expression)getDescriptor().getInheritancePolicy().getChildrenTablesJoinExpressions().get(table);
                if (getBaseExpression() != null){
                    joinExpression = getBaseExpression().twist(joinExpression, this);
                } else {
                    joinExpression = twist(joinExpression, this);
                }
                tablesJoinExpressions.put(table, joinExpression);
            }
        }
        
        return tablesJoinExpressions;
    
public oracle.toplink.essentials.expressions.ExpressionanyOf(java.lang.String attributeName)
PUBLIC: Return an expression representing traversal of a 1:many or many:many relationship. This allows you to query whether any of the "many" side of the relationship satisfies the remaining criteria.

Example:

TopLink: employee.anyOf("managedEmployees").get("firstName").equal("Bob") Java: no direct equivalent SQL: SELECT DISTINCT ... WHERE (t2.MGR_ID = t1.ID) AND (t2.F_NAME = 'Bob')

        QueryKeyExpression queryKey = (QueryKeyExpression)newDerivedExpressionNamed(attributeName);

        queryKey.doQueryToManyRelationship();
        return queryKey;

    
public oracle.toplink.essentials.internal.expressions.QueryKeyExpressionderivedExpressionNamed(java.lang.String attributeName)

        QueryKeyExpression existing = existingDerivedExpressionNamed(attributeName);
        if (existing != null) {
            return existing;
        }
        return newDerivedExpressionNamed(attributeName);

    
public oracle.toplink.essentials.expressions.ExpressionderivedManualExpressionNamed(java.lang.String attributeName, oracle.toplink.essentials.descriptors.ClassDescriptor aDescriptor)

        Expression existing = existingDerivedExpressionNamed(attributeName);
        if (existing != null) {
            return existing;
        }
        return newManualDerivedExpressionNamed(attributeName, aDescriptor);

    
protected voiddoNotUseOuterJoin()

        shouldUseOuterJoin = false;
    
protected voiddoUseOuterJoin()

        shouldUseOuterJoin = true;
    
public oracle.toplink.essentials.internal.expressions.QueryKeyExpressionexistingDerivedExpressionNamed(java.lang.String attributeName)

        if (derivedExpressions == null) {
            return null;
        }
        for (Enumeration e = derivedExpressions.elements(); e.hasMoreElements();) {
            QueryKeyExpression exp = (QueryKeyExpression)e.nextElement();
            if (exp.getName().equals(attributeName)) {
                return exp;
            }
        }
        return null;

    
public oracle.toplink.essentials.expressions.Expressionget(java.lang.String attributeName, java.util.Vector arguments)

        Expression operatorExpression = super.get(attributeName, arguments);
        if (operatorExpression != null) {
            return operatorExpression;
        }

        QueryKeyExpression result = derivedExpressionNamed(attributeName);
        result.doNotUseOuterJoin();
        return result;

    
public oracle.toplink.essentials.expressions.ExpressiongetAllowingNull(java.lang.String attributeName, java.util.Vector arguments)

        ObjectExpression exp = (ObjectExpression)existingDerivedExpressionNamed(attributeName);

        // The same (aliased) table cannot participate in a normal join and an outer join.
        // To help enforce this, if the node already exists 
        if (exp != null) {
            return exp;
        }
        exp = (ObjectExpression)derivedExpressionNamed(attributeName);
        exp.doUseOuterJoin();
        return exp;

    
public oracle.toplink.essentials.descriptors.ClassDescriptorgetDescriptor()

        if (isAttribute()) {
            return null;
        }
        if (descriptor == null) {
            // Look first for query keys, then mappings. Ultimately we should have query keys
            // for everything and can dispense with the mapping part.
            ForeignReferenceQueryKey queryKey = (ForeignReferenceQueryKey)getQueryKeyOrNull();
            if (queryKey != null) {
                descriptor = getSession().getDescriptor(queryKey.getReferenceClass());
                return descriptor;
            }
            if (getMapping() == null) {
                throw QueryException.invalidQueryKeyInExpression(this);
            }

            // We assume this is either a foreign reference or an aggregate mapping
            descriptor = getMapping().getReferenceDescriptor();
            if (getMapping().isVariableOneToOneMapping()) {
                throw QueryException.cannotQueryAcrossAVariableOneToOneMapping(getMapping(), descriptor);
            }
        }
        return descriptor;

    
public java.util.VectorgetFields()
INTERNAL: Not to be confused with the public getField(String) This returns a collection of all fields associated with this object. Really only applies to query keys representing an object or to expression builders.

        if (getDescriptor() == null) {
            return new Vector(1);
        }
        if ((descriptor.hasInheritance() && ! descriptor.getInheritancePolicy().hasMultipleTableChild()) || (shouldUseOuterJoinForMultitableInheritance())){
            // return all fields because we can.
            return descriptor.getAllFields();
        }else{
            return descriptor.getFields();
        }
    
protected java.util.VectorgetForUpdateOfFields()
INTERNAL: Returns the first field from each of the owned tables, used for fine-grained pessimistic locking.

        Vector allFields = getFields();
        int expected = getTableAliases().size();
        Vector firstFields = new Vector(expected);
        DatabaseTable lastTable = null;
        DatabaseField field = null;
        int i = 0;

        // The following loop takes O(n*m) time.  n=# of fields. m=#tables.
        // However, in the m=1 case this will take one pass only.
        // Also assuming that fields are generally sorted by table, this will
        // take O(n) time.
        // An even faster way may be to go getDescriptor().getAdditionalPrimaryKeyFields.
        while ((i < allFields.size()) && (firstFields.size() < expected)) {
            field = (DatabaseField)allFields.elementAt(i++);
            if ((lastTable == null) || !field.getTable().equals(lastTable)) {
                lastTable = field.getTable();
                int j = 0;
                while (j < firstFields.size()) {
                    if (lastTable.equals(((DatabaseField)firstFields.elementAt(j)).getTable())) {
                        break;
                    }
                    j++;
                }
                if (j == firstFields.size()) {
                    firstFields.addElement(field);
                }
            }
        }
        return firstFields;
    
public oracle.toplink.essentials.expressions.ExpressiongetManualQueryKey(java.lang.String attributeName, oracle.toplink.essentials.descriptors.ClassDescriptor aDescriptor)

        return derivedManualExpressionNamed(attributeName, aDescriptor);
    
public java.util.VectorgetOwnedTables()
INTERNAL:

        if(isUsingOuterJoinForMultitableInheritance()) {
            return getDescriptor().getInheritancePolicy().getAllTables();
        } else {
            return super.getOwnedTables();
        }
    
protected booleanhasDerivedExpressions()

        return derivedExpressions != null;
    
public booleanisObjectExpression()

        return true;
    
public booleanisUsingOuterJoinForMultitableInheritance()
INTERNAL: indicates whether additional expressions for multitable inheritance should be used and are available

        return shouldUseOuterJoinForMultitableInheritance() && 
                getDescriptor() != null && getDescriptor().hasInheritance() &&
                getDescriptor().getInheritancePolicy().hasMultipleTableChild() &&
                getDescriptor().getInheritancePolicy().shouldReadSubclasses();
    
public oracle.toplink.essentials.internal.expressions.QueryKeyExpressionnewDerivedExpressionNamed(java.lang.String attributeName)

        QueryKeyExpression result = new QueryKeyExpression(attributeName, this);
        addDerivedExpression(result);
        return result;

    
public oracle.toplink.essentials.expressions.ExpressionnewManualDerivedExpressionNamed(java.lang.String attributeName, oracle.toplink.essentials.descriptors.ClassDescriptor aDescriptor)

        QueryKeyExpression result = new ManualQueryKeyExpression(attributeName, this, aDescriptor);
        addDerivedExpression(result);
        return result;

    
protected voidpostCopyIn(java.util.Dictionary alreadyDone)
INTERNAL: Used for cloning.

        super.postCopyIn(alreadyDone);
        derivedExpressions = copyCollection(derivedExpressions, alreadyDone);
    
public voidpostCopyIn(java.util.Dictionary alreadyDone, java.util.Vector oldDerivedFields, java.util.Vector oldDerivedTables)
INTERNAL: The method was added to circumvent derivedFields and derivedTables being protected.

see
oracle.toplink.essentials.expressions.ExpressionBuilder#registerIn(Dictionary alreadyDone)
bug
2637484 INVALID QUERY KEY EXCEPTION THROWN USING BATCH READS AND PARALLEL EXPRESSIONS

        if (oldDerivedFields != null) {
            if (derivedFields == null) {
                derivedFields = copyCollection(oldDerivedFields, alreadyDone);
            } else {
                derivedFields.addAll(copyCollection(oldDerivedFields, alreadyDone));
            }
        }
        if (oldDerivedTables != null) {
            if (derivedTables == null) {
                derivedTables = copyCollection(oldDerivedTables, alreadyDone);
            } else {
                derivedTables.addAll(copyCollection(oldDerivedTables, alreadyDone));
            }
        }
    
public voidsetShouldUseOuterJoinForMultitableInheritance(boolean shouldUseOuterJoinForMultitableInheritance)
INTERNAL: set the flag indicating whether subclasses should be joined

        this.shouldUseOuterJoinForMultitableInheritance = shouldUseOuterJoinForMultitableInheritance;
    
public booleanshouldUseOuterJoin()

        return shouldUseOuterJoin;
    
public booleanshouldUseOuterJoinForMultitableInheritance()

        return shouldUseOuterJoinForMultitableInheritance;
    
protected voidwriteForUpdateOfFields(oracle.toplink.essentials.internal.expressions.ExpressionSQLPrinter printer, oracle.toplink.essentials.internal.expressions.SQLSelectStatement statement)
INTERNAL: writes the first field from each of the owned tables, used for fine-grained pessimistic locking.

        for (Enumeration fieldsEnum = getForUpdateOfFields().elements();
                 fieldsEnum.hasMoreElements();) {
            DatabaseField field = (DatabaseField)fieldsEnum.nextElement();
            writeField(printer, field, statement);
        }