Package org.jpox.store.mapped.expression

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

/**********************************************************************
Copyright (c) 2004 Andy Jefferson 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 java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jpox.store.mapped.DatastoreAdapter;
import org.jpox.store.mapped.mapping.JavaTypeMapping;

/**
* An SQL expression that will test if a column of a table falls within the
* given Map's keys.  This is used for Querys where a transient Map is passed
* in as a parameter.
*
* @version $Revision: 1.12 $
*/
public class MapKeyLiteral extends ScalarExpression
{
    private final boolean isEmpty;
    private final boolean containsNull;
    private final DatastoreAdapter dba;
    private final Map map;
    /** ScalarExpressions for all elements in the Map **/
    private List scalarExpressions;
   
    /**
     * Constructor.
     * @param qs  The QueryStatement the MapKeyLiteral will be used in.
     * @param mapping The mapping for the Map
     * @param map The transient Map that is the value.
     */
    public MapKeyLiteral(QueryExpression qs, JavaTypeMapping mapping, Map map)
    {
        super(qs);
        this.mapping = mapping;
        containsNull = (map != null) && map.containsValue(null);
        dba = qs.getStoreManager().getDatastoreAdapter();
        this.map = map;

        // We'll consider the Map to be empty if it is null, is really
        // empty, or only contains null.
        // If it contains null we need a special case when creating the SQL.
        isEmpty =
            (map == null) ||
            (map.isEmpty()) ||
            (map.size() == 1 && containsNull);

        // If the Map is empty, don't build the list of SQLExpressions.
        if (!isEmpty)
        {
            st.append("(");
            scalarExpressions = new ArrayList();

            boolean hadPrev = false;

            Set keys=map.keySet();
            for (Iterator it=keys.iterator(); it.hasNext();)
            {
                Object current = it.next();
                if (null != current)
                {
                    JavaTypeMapping m = dba.getMapping(current.getClass(), qs.getStoreManager(), qs.getClassLoaderResolver());
                    ScalarExpression expr = m.newLiteral(qs, current);

                    // Append the SQLExpression (should be a literal) for the
                    // current element.
                    st.append(hadPrev ? "," : "");
                    st.append(expr);
                    scalarExpressions.add(expr);

                    hadPrev = true;
                }
            }

            st.append(")");
        }
    }

    /**
     * Method to check the containing of a key in the Map.
     * Return the BooleanExpression that results from
     * MapKeyLiteral.contains(SQLExpression).
     * @param expr The SQLExpression that is checked for membership in the Map.
     * @return The BooleanExpression that results from
     *         MapKeyLiteral.contains(SQLExpression).
     */
    public BooleanExpression containsMethod(ScalarExpression expr)
    {
        if( isEmpty )
        {
            return new BooleanLiteral(qs, mapping, false);
        }
        BooleanExpression bExpr = null;
        for( int i=0; i<scalarExpressions.size(); i++)
        {
            if( bExpr == null )
            {
                bExpr = ((ScalarExpression)scalarExpressions.get(i)).eq(expr);
            }
            else
            {
                bExpr = bExpr.ior(((ScalarExpression)scalarExpressions.get(i)).eq(expr));
            }
        }
        bExpr.encloseWithInParentheses();
        return bExpr;
    }

    /**
     * Method to get a value from the Map for a key
     * @param expr The key argument expression
     * @return The statement
     **/
    public ScalarExpression getMethod(ScalarExpression expr)
    {
        if( map == null )
        {
            return new NullLiteral(qs);
        }
        if( expr instanceof Literal )
        {
            Object value = map.get(((Literal)expr).getValue());
            if( value == null )
            {
                return new NullLiteral(qs);
            }
            JavaTypeMapping m = dba.getMapping(value.getClass(), qs.getStoreManager(), qs.getClassLoaderResolver());
            return new ObjectLiteral(qs,m,value);
        }
        //impossible to invoke Map.get with an expression, only with literals
        //using CASE WHEN booleanexpression THEN expression does not work, since expression can only be
        //one single field (column), however, one could have two CASE expressions
        throw new IllegalOperationException(this, "getMethod", expr);
    }
   
    /**
     * Method to check for emptiness of the collection.
     * @return The BooleanExpression.
     **/
    public BooleanExpression isEmptyMethod()
    {
        return new BooleanLiteral(qs, mapping, isEmpty);
    }
}
TOP

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

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.