All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.cq.searchcollections.qom.OperandEvaluator Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2012 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.adobe.cq.searchcollections.qom;

import static java.util.Locale.ENGLISH;
import static javax.jcr.PropertyType.NAME;

import java.util.Map;

import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.query.Row;
import javax.jcr.query.qom.BindVariableValue;
import javax.jcr.query.qom.FullTextSearchScore;
import javax.jcr.query.qom.Length;
import javax.jcr.query.qom.Literal;
import javax.jcr.query.qom.LowerCase;
import javax.jcr.query.qom.NodeLocalName;
import javax.jcr.query.qom.NodeName;
import javax.jcr.query.qom.Operand;
import javax.jcr.query.qom.PropertyValue;
import javax.jcr.query.qom.StaticOperand;
import javax.jcr.query.qom.UpperCase;

/**
 * Evaluator of QOM {@link Operand operands}. This class evaluates operands
 * in the context of a {@link ValueFactory value factory}, a set of bind
 * variables and possibly a query result row.
 * 
 * @deprecated
 */
public class OperandEvaluator {

    /** Value factory */
    private final ValueFactory factory;

    /** Bind variables */
    private final Map variables;

    /**
     * Creates an operand evaluator for the given value factory and set of
     * bind variables.
     *
     * @param factory value factory
     * @param variables bind variables
     */
    public OperandEvaluator(
            ValueFactory factory, Map variables) {
        this.factory = factory;
        this.variables = variables;
    }

    public Value getValue(StaticOperand operand, int type) throws RepositoryException {
        Value value = getValue(operand);
        if (type == PropertyType.UNDEFINED || type == value.getType()) {
            return value;
        } if (type == PropertyType.LONG) {
            return factory.createValue(value.getLong());
        } if (type == PropertyType.DOUBLE) {
            return factory.createValue(value.getDouble());
        } if (type == PropertyType.DATE) {
            return factory.createValue(value.getDate());
        } else {
            return factory.createValue(value.getString(), type);
        }
    }

    /**
     * Returns the value of the given static operand
     * ({@link Literal literal} or {@link BindVariableValue bind variable}).
     *
     * @param operand static operand to be evaluated
     * @return evaluated value
     * @throws RepositoryException if a named bind variable is not found,
     *                             or if the operand type is unknown
     */
    public Value getValue(StaticOperand operand) throws RepositoryException {
        if (operand instanceof Literal) {
            Literal literal = (Literal) operand;
            return literal.getLiteralValue();
        } else if (operand instanceof BindVariableValue) {
            BindVariableValue bvv = (BindVariableValue) operand;
            Value value = variables.get(bvv.getBindVariableName());
            if (value != null) {
                return value;
            } else {
                throw new RepositoryException(
                        "Unknown bind variable: " + bvv.getBindVariableName());
            }
        } else {
            throw new UnsupportedRepositoryOperationException(
                    "Unknown static operand type: " + operand);
        }
    }

    /**
     * Returns the value of the given operand in the context of the given row.
     * This is a convenience method that uses a somewhat lossy best-effort
     * mapping to evaluate multi-valued operands to a single value. Use the
     * {@link #getValues(Operand, Row)} method for more accurate results.
     *
     * @param operand operand to be evaluated
     * @param row query result row
     * @return evaluated value
     * @throws RepositoryException
     */
    public Value getValue(Operand operand, Row row) throws RepositoryException {
        Value[] values = getValues(operand, row);
        if (values.length == 1) {
            return values[0];
        } else {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < values.length; i++) {
                if (i > 0) {
                    builder.append(' ');
                }
                builder.append(values[i].getString());
            }
            return factory.createValue(builder.toString());
        }
    }

    /**
     * Evaluates the given operand in the context of the given row.
     *
     * @param operand operand to be evaluated
     * @param row query result row
     * @return values of the operand at the given row
     * @throws RepositoryException if the operand can't be evaluated
     */
    public Value[] getValues(Operand operand, Row row)
            throws RepositoryException {
        if (operand instanceof StaticOperand) {
            StaticOperand so = (StaticOperand) operand;
            return new Value[] { getValue(so) };
        } else if (operand instanceof FullTextSearchScore) {
            FullTextSearchScore ftss = (FullTextSearchScore) operand;
            double score = row.getScore(ftss.getSelectorName());
            return new Value[] { factory.createValue(score) };
        } else if (operand instanceof NodeName) {
            NodeName nn = (NodeName) operand;
            Node node = row.getNode(nn.getSelectorName());
            return new Value[] { factory.createValue(node.getName(), NAME) };
        } else if (operand instanceof Length) {
            return getLengthValues((Length) operand, row);
        } else if (operand instanceof LowerCase) {
            return getLowerCaseValues((LowerCase) operand, row);
        } else if (operand instanceof UpperCase) {
            return getUpperCaseValues((UpperCase) operand, row);
        } else if (operand instanceof NodeLocalName) {
            return getNodeLocalNameValues((NodeLocalName) operand, row);
        } else if (operand instanceof PropertyValue) {
            return getPropertyValues((PropertyValue) operand, row);
        } else {
            throw new UnsupportedRepositoryOperationException(
                    "Unknown operand type: " + operand);
        }
    }

    /**
     * Returns the values of the given value length operand at the given row.
     *
     * @see #getProperty(PropertyValue, Row)
     * @param operand value length operand
     * @param row row
     * @return values of the operand at the given row
     * @throws RepositoryException if the operand can't be evaluated
     */
    private Value[] getLengthValues(Length operand, Row row)
            throws RepositoryException {
        Property property = getProperty(operand.getPropertyValue(), row);
        if (property == null) {
            return new Value[0];
        } else if (property.isMultiple()) {
            long[] lengths = property.getLengths();
            Value[] values = new Value[lengths.length];
            for (int i = 0; i < lengths.length; i++) {
                values[i] = factory.createValue(lengths[i]);
            }
            return values;
        } else {
            long length = property.getLength();
            return new Value[] { factory.createValue(length) };
        }
    }

    /**
     * Returns the values of the given lower case operand at the given row.
     *
     * @param operand lower case operand
     * @param row row
     * @return values of the operand at the given row
     * @throws RepositoryException if the operand can't be evaluated
     */
    private Value[] getLowerCaseValues(LowerCase operand, Row row)
            throws RepositoryException {
        Value[] values = getValues(operand.getOperand(), row);
        for (int i = 0; i < values.length; i++) {
            String value = values[i].getString();
            String lower = value.toLowerCase(ENGLISH);
            if (!value.equals(lower)) {
                values[i] = factory.createValue(lower);
            }
        }
        return values;
    }

    /**
     * Returns the values of the given upper case operand at the given row.
     *
     * @param operand upper case operand
     * @param row row
     * @return values of the operand at the given row
     * @throws RepositoryException if the operand can't be evaluated
     */
    private Value[] getUpperCaseValues(UpperCase operand, Row row)
            throws RepositoryException {
        Value[] values = getValues(operand.getOperand(), row);
        for (int i = 0; i < values.length; i++) {
            String value = values[i].getString();
            String upper = value.toUpperCase(ENGLISH);
            if (!value.equals(upper)) {
                values[i] = factory.createValue(upper);
            }
        }
        return values;
    }

    /**
     * Returns the value of the given local name operand at the given row.
     *
     * @param operand local name operand
     * @param row row
     * @return value of the operand at the given row
     * @throws RepositoryException if the operand can't be evaluated
     */
    private Value[] getNodeLocalNameValues(NodeLocalName operand, Row row)
            throws RepositoryException {
        String name = row.getNode(operand.getSelectorName()).getName();
        int colon = name.indexOf(':');
        if (colon != -1) {
            name = name.substring(colon + 1);
        }
        return new Value[] { factory.createValue(name, NAME) };
    }

    /**
     * Returns the values of the given property value operand at the given row.
     *
     * @see #getProperty(PropertyValue, Row)
     * @param operand property value operand
     * @param row row
     * @return values of the operand at the given row
     * @throws RepositoryException if the operand can't be evaluated
     */
    private Value[] getPropertyValues(PropertyValue operand, Row row)
            throws RepositoryException {
        Property property = getProperty(operand, row);
        if (property == null) {
            return new Value[0];
        } else if (property.isMultiple()) {
            return property.getValues();
        } else {
            return new Value[] { property.getValue() };
        }
    }

    /**
     * Returns the identified property from the given row. This method
     * is used by both the {@link #getValue(Length, Row)} and the
     * {@link #getValue(PropertyValue, Row)} methods to access properties.
     *
     * @param operand property value operand
     * @param row row
     * @return the identified property,
     *         or null if the property does not exist
     * @throws RepositoryException if the property can't be accessed
     */
    private Property getProperty(PropertyValue operand, Row row)
            throws RepositoryException {
        Node node = row.getNode(operand.getSelectorName());
        if (node != null) {
            try {
                return node.getProperty(operand.getPropertyName());
            } catch (PathNotFoundException e) {
                return null;
            }
        } else {
            return null;
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy