001    /*
002     * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org
003     * Copyright (C) 2011 NightLabs Consulting GmbH
004     *
005     * This program is free software: you can redistribute it and/or modify
006     * it under the terms of the GNU Affero General Public License as
007     * published by the Free Software Foundation, either version 3 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     * GNU Affero General Public License for more details.
014     *
015     * You should have received a copy of the GNU Affero General Public License
016     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017     */
018    package org.cumulus4j.store.query.method;
019    
020    import java.util.Set;
021    
022    import org.cumulus4j.store.model.FieldMetaRole;
023    import org.cumulus4j.store.query.QueryEvaluator;
024    import org.cumulus4j.store.query.eval.ExpressionHelper;
025    import org.cumulus4j.store.query.eval.InvokeExpressionEvaluator;
026    import org.cumulus4j.store.query.eval.ResultDescriptor;
027    import org.datanucleus.query.QueryUtils;
028    import org.datanucleus.query.expression.Expression;
029    import org.datanucleus.query.expression.Literal;
030    import org.datanucleus.query.expression.ParameterExpression;
031    import org.datanucleus.query.expression.PrimaryExpression;
032    import org.datanucleus.query.expression.VariableExpression;
033    
034    /**
035     * Evaluator for "Map.containsValue(val)".
036     */
037    public class MapContainsValueEvaluator extends AbstractMethodEvaluator
038    {
039            /* (non-Javadoc)
040             * @see org.cumulus4j.store.query.method.MethodEvaluator#evaluate(org.cumulus4j.store.query.QueryEvaluator, org.datanucleus.query.expression.InvokeExpression, org.datanucleus.query.expression.Expression, org.cumulus4j.store.query.eval.ResultDescriptor)
041             */
042            @Override
043            public Set<Long> evaluate(QueryEvaluator queryEval, InvokeExpressionEvaluator invokeExprEval, 
044                            Expression invokedExpr, ResultDescriptor resultDesc){
045                    if (invokeExprEval.getExpression().getArguments().size() != 1)
046                            throw new IllegalStateException("containsValue(...) expects exactly one argument, but there are " + 
047                                            invokeExprEval.getExpression().getArguments().size());
048    
049                    if (invokedExpr instanceof PrimaryExpression) {
050                            // Evaluate the invoke argument
051                            Expression invokeArgExpr = invokeExprEval.getExpression().getArguments().get(0);
052                            Object invokeArgument;
053                            if (invokeArgExpr instanceof Literal)
054                                    invokeArgument = ((Literal)invokeArgExpr).getLiteral();
055                            else if (invokeArgExpr instanceof ParameterExpression)
056                                    invokeArgument = QueryUtils.getValueForParameterExpression(queryEval.getParameterValues(), (ParameterExpression)invokeArgExpr);
057                            else if (invokeArgExpr instanceof VariableExpression)
058                                    return new ExpressionHelper.ContainsVariableResolver(
059                                                    queryEval, (PrimaryExpression) invokedExpr, FieldMetaRole.mapValue, (VariableExpression) invokeArgExpr,
060                                                    resultDesc.isNegated()
061                                    ).query();
062                            else
063                                    throw new UnsupportedOperationException("NYI");
064    
065                            return new ExpressionHelper.ContainsConstantResolver(
066                                            queryEval, (PrimaryExpression) invokedExpr, FieldMetaRole.mapValue, invokeArgument,
067                                            resultDesc.isNegated()
068                            ).query();
069                    }
070                    else {
071                            throw new UnsupportedOperationException("NYI invocation of Map.containsValue on a variable");
072                    }
073            }
074    }