Package org.jpox.store.mapped.expression

Source Code of org.jpox.store.mapped.expression.ArrayExpression

/**********************************************************************
Copyright (c) 2006 Erik Bengtson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Contributors:
    ...
**********************************************************************/
package org.jpox.store.mapped.expression;

import org.jpox.ClassLoaderResolver;
import org.jpox.exceptions.JPOXUserException;
import org.jpox.store.mapped.DatastoreIdentifier;
import org.jpox.store.mapped.IdentifierFactory;
import org.jpox.store.mapped.mapping.JavaTypeMapping;
import org.jpox.store.mapped.scostore.ArrayStoreQueryable;
import org.jpox.store.scostore.ArrayStore;

/**
* Representation of array expression. Either backed
* by ScalarExpressions, or by an array field
* @version $Revision: 1.6 $
*/
public class ArrayExpression extends ScalarExpression
{
    /** Either <code>exprs</code> or
     *         <code>arrayStore</code> and <code>fieldName</code>
     *  are initialized
     */

    /** ScalarExpression elements of the array **/
    ScalarExpression[] exprs;

    /** The array Store **/
    private ArrayStore arrayStore;

    /** The field name **/
    private String fieldName;
   
    /**
     * Constructor
     * @param qs The query statement
     */
    protected ArrayExpression(QueryExpression qs)
    {
        super(qs);
    }

    /**
     * Constructor
     * @param qs The query statement
     * @param expr the array of expressions
     */
    public ArrayExpression(QueryExpression qs, ScalarExpression[] expr)
    {
        super(qs);
        this.exprs = expr;
    }
   
    /**
     * Constructor.
     * @param qs The Query Statement
     * @param ownerMapping The mapping to the owner of this collection
     * @param te The Table Expression
     * @param arrayStore the backing store.
     * @param fieldName Name of the field for the collection.
     **/
    public ArrayExpression(QueryExpression qs,
                                JavaTypeMapping ownerMapping,
                                LogicSetExpression te,
                                ArrayStore arrayStore,
                                String fieldName)
    {
        super(qs);
        this.mapping = ownerMapping;
        this.arrayStore = arrayStore;
        this.fieldName = fieldName;
        this.te = te;
    }   
   
    /**
     * Executed when the size() method is found in a query filter.
     * @return The NumericExpression resulting from the size() method.
     */
    public NumericExpression sizeMethod()
    {
        if (arrayStore != null)
        {
            IdentifierFactory idFactory = qs.getStoreManager().getIdentifierFactory();
            String ctIdentifier = idFactory.newIdentifier(te.getAlias(), fieldName).getIdentifier();
            DatastoreIdentifier ctRangeVar = idFactory.newIdentifier(IdentifierFactory.TABLE, ctIdentifier);

            return new ContainerSizeExpression(qs, getBackingStoreQueryable().getSizeSubquery(qs, mapping, te, ctRangeVar));
        }
        else
        {
            JavaTypeMapping mapping = qs.getStoreManager().getDatastoreAdapter().getMapping(Integer.class, qs.getStoreManager(), qs.getClassLoaderResolver());
            return new IntegerLiteral(qs,mapping,new Integer(exprs.length));
        }
    }   

    /**
     * Executed when the length() method is found in a query filter.
     * @return The NumericExpression resulting from the size() method.
     */
    public NumericExpression lengthMethod()
    {
        return sizeMethod();
    }
   
    /**
     * Access a field in an array
     * @param subfieldName the field to be accessed in this object
     * @param innerJoin whether to inner join
     * @return The field expression representing the required field of this object
     */
    public ScalarExpression accessField(String subfieldName, boolean innerJoin)
    {
        if( !subfieldName.endsWith("length") )
        {
            throw new JPOXUserException("The field "+subfieldName+" is not accessible in an array");
        }
        return sizeMethod();
    }
   
    /**
     * Executed when the contains() method is found in a query filter.
     * @param expr The ScalarExpression passed as a parameter to contains().
     * @return The BooleanExpression resulting from the contains() method.
     */
    public BooleanExpression containsMethod(ScalarExpression expr)
    {
        // ct... = "collection table"
        // et... = "element table"

        IdentifierFactory idFactory = qs.getStoreManager().getIdentifierFactory();
        if (expr instanceof NullLiteral)
        {
            // JPOX doesn't currently support storing nulls in Collections so just return "1 = 0"
            // TODO Add support for storing nulls in collections and querying for this situation
            return new BooleanLiteral(qs, mapping, false).eq(new BooleanLiteral(qs, mapping, true));
        }
        else if( exprs != null )
        {
            BooleanExpression bExpr = null;
            for( int i=0; i<exprs.length; i++)
            {
                if( bExpr == null )
                {
                    bExpr = exprs[i].eq(expr);
                }
                else
                {
                    bExpr = bExpr.ior(exprs[i].eq(expr));
                }
            }
            bExpr.encloseWithInParentheses();
            return bExpr;
        }
        else if (expr instanceof UnboundVariable)
        {
            UnboundVariable var = (UnboundVariable)expr;
            if (var.getVariableType() == null)
            {
                //Set the variable type to be the element type for this collection
                //implicit variable type. We now set the type to the collection type
                var.setVariableType(qs.getClassLoaderResolver().classForName(arrayStore.getElementType()));
            }
            //ctJavaName += + '.' + var.getVariableName();
            //String etJavaName = qs.getDefaultTableExpression().getRangeVariable().getJavaName() + '.' + var.getVariableName();

            String etIdentifier = "UNBOUND" + '.' + var.getVariableName();
            String ctIdentifier = idFactory.newIdentifier(idFactory.newIdentifier(te.getAlias(), fieldName), var.getVariableName()).getIdentifier();

            DatastoreIdentifier ctRangeVar = idFactory.newIdentifier(IdentifierFactory.TABLE, ctIdentifier);
            DatastoreIdentifier etRangeVar = idFactory.newIdentifier(IdentifierFactory.TABLE, etIdentifier);
            QueryExpression qexpr = getBackingStoreQueryable().getExistsSubquery(qs, mapping, te, ctRangeVar);
            var.bindTo(getBackingStoreQueryable().joinElementsTo(qexpr,
                qs,
                mapping,
                te,
                ctRangeVar,
                var.getVariableType(),
                expr,
                expr.te == null ? etRangeVar : expr.te.getAlias()));

            return new ExistsExpression(qs, qexpr, true);

        }
        else if (expr instanceof Literal)
        {
            String ctIdentifier = idFactory.newIdentifier(te.getAlias(), fieldName).getIdentifier();
            DatastoreIdentifier ctRangeVar = qs.getStoreManager().getIdentifierFactory().newIdentifier(IdentifierFactory.TABLE, ctIdentifier);
            DatastoreIdentifier etRangeVar;            
            if (expr.te == null) // literals
            {
                int n = 0;

                do
                {
                    String etIdentifier = ctIdentifier + '.' + (++n);
                    etRangeVar = qs.getStoreManager().getIdentifierFactory().newIdentifier(IdentifierFactory.TABLE, etIdentifier);
                } while (qs.getTableExpression(etRangeVar) != null);
            }
            else
            {
                etRangeVar = expr.te.getAlias();
            }

            ClassLoaderResolver clr=qs.getClassLoaderResolver();
            QueryExpression qexpr = getBackingStoreQueryable().getExistsSubquery(qs, mapping, te, ctRangeVar);
            ScalarExpression expr1 = getBackingStoreQueryable().joinElementsTo(qexpr,
                qs,
                   mapping,
                   te,
                ctRangeVar,
                clr.classForName(expr.getMapping().getType()),
                expr,
                expr.te == null ? etRangeVar : expr.te.getAlias());
            qexpr.andCondition(expr.eq(expr1));
            return new ExistsExpression(qs, qexpr, true);
        }       
        else
        {
            String ctIdentifier = idFactory.newIdentifier(te.getAlias(), fieldName).getIdentifier();
            DatastoreIdentifier ctRangeVar = qs.getStoreManager().getIdentifierFactory().newIdentifier(IdentifierFactory.TABLE, ctIdentifier);
            DatastoreIdentifier etRangeVar;            
            if (expr.te == null) // literals
            {
                int n = 0;

                do
                {
                    String etIdentifier = ctIdentifier + '.' + (++n);
                    etRangeVar = qs.getStoreManager().getIdentifierFactory().newIdentifier(IdentifierFactory.TABLE, etIdentifier);
                } while (qs.getTableExpression(etRangeVar) != null);
            }
            else
            {
                etRangeVar = expr.te.getAlias();
            }

            ClassLoaderResolver clr = qs.getClassLoaderResolver();
            ScalarExpression joinExpr =
               getBackingStoreQueryable().joinElementsTo(expr.getQueryExpression(),
                                        qs,
                                        mapping,
                                        te,
                                        ctRangeVar,
                                        clr.classForName(arrayStore.getElementType()),
                                        expr,
                                        etRangeVar);

            return joinExpr.eq(expr);
        }
    }

    private ArrayStoreQueryable getBackingStoreQueryable()
    {
        return (ArrayStoreQueryable)arrayStore;
    }
}
TOP

Related Classes of org.jpox.store.mapped.expression.ArrayExpression

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.