    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *     http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.jxpath.ri.compiler;
    019
    020import org.apache.commons.jxpath.ri.Compiler;
    021import org.apache.commons.jxpath.ri.QName;
    022
    023/**
    024 * A tree {@link Compiler}.
    025 */
    026public class TreeCompiler implements Compiler {
    027
    028    private static final QName QNAME_NAME = new QName(null, "name");
    029
    030    /**
    031     * Constructs a new instance.
    032     */
    033    public TreeCompiler() {
    034        // empty
    035    }
    036
    037    @Override
    038    public Object and(final Object[] arguments) {
    039        return new CoreOperationAnd(toExpressionArray(arguments));
    040    }
    041
    042    @Override
    043    public Object divide(final Object left, final Object right) {
    044        return new CoreOperationDivide((Expression) left, (Expression) right);
    045    }
    046
    047    @Override
    048    public Object equal(final Object left, final Object right) {
    049        return isNameAttributeTest((Expression) left) ? new NameAttributeTest((Expression) left, (Expression) right)
    050                : new CoreOperationEqual((Expression) left, (Expression) right);
    051    }
    052
    053    @Override
    054    public Object expressionPath(final Object expression, final Object[] predicates, final Object[] steps) {
    055        return new ExpressionPath((Expression) expression, toExpressionArray(predicates), toStepArray(steps));
    056    }
    057
    058    @Override
    059    public Object function(final int code, final Object[] args) {
    060        return new CoreFunction(code, toExpressionArray(args));
    061    }
    062
    063    @Override
    064    public Object function(final Object name, final Object[] args) {
    065        return new ExtensionFunction((QName) name, toExpressionArray(args));
    066    }
    067
    068    @Override
    069    public Object greaterThan(final Object left, final Object right) {
    070        return new CoreOperationGreaterThan((Expression) left, (Expression) right);
    071    }
    072
    073    @Override
    074    public Object greaterThanOrEqual(final Object left, final Object right) {
    075        return new CoreOperationGreaterThanOrEqual((Expression) left, (Expression) right);
    076    }
    077
    078    /**
    079     * Tests whether arg is a name attribute test.
    080     *
    081     * @param arg Expression to test
    082     * @return boolean
    083     */
    084    private boolean isNameAttributeTest(final Expression arg) {
    085        if (!(arg instanceof LocationPath)) {
    086            return false;
    087        }
    088        final Step[] steps = ((LocationPath) arg).getSteps();
    089        if (steps.length != 1) {
    090            return false;
    091        }
    092        if (steps[0].getAxis() != AXIS_ATTRIBUTE) {
    093            return false;
    094        }
    095        final NodeTest test = steps[0].getNodeTest();
    096        if (!(test instanceof NodeNameTest)) {
    097            return false;
    098        }
    099        if (!((NodeNameTest) test).getNodeName().equals(QNAME_NAME)) {
    100            return false;
    101        }
    102        return true;
    103    }
    104
    105    @Override
    106    public Object lessThan(final Object left, final Object right) {
    107        return new CoreOperationLessThan((Expression) left, (Expression) right);
    108    }
    109
    110    @Override
    111    public Object lessThanOrEqual(final Object left, final Object right) {
    112        return new CoreOperationLessThanOrEqual((Expression) left, (Expression) right);
    113    }
    114
    115    @Override
    116    public Object literal(final String value) {
    117        return new Constant(value);
    118    }
    119
    120    @Override
    121    public Object locationPath(final boolean absolute, final Object[] steps) {
    122        return new LocationPath(absolute, toStepArray(steps));
    123    }
    124
    125    @Override
    126    public Object minus(final Object argument) {
    127        return new CoreOperationNegate((Expression) argument);
    128    }
    129
    130    @Override
    131    public Object minus(final Object left, final Object right) {
    132        return new CoreOperationSubtract((Expression) left, (Expression) right);
    133    }
    134
    135    @Override
    136    public Object mod(final Object left, final Object right) {
    137        return new CoreOperationMod((Expression) left, (Expression) right);
    138    }
    139
    140    @Override
    141    public Object multiply(final Object left, final Object right) {
    142        return new CoreOperationMultiply((Expression) left, (Expression) right);
    143    }
    144
    145    @Override
    146    public Object nodeNameTest(final Object qname) {
    147        return new NodeNameTest((QName) qname);
    148    }
    149
    150    @Override
    151    public Object nodeTypeTest(final int nodeType) {
    152        return new NodeTypeTest(nodeType);
    153    }
    154
    155    @Override
    156    public Object notEqual(final Object left, final Object right) {
    157        return new CoreOperationNotEqual((Expression) left, (Expression) right);
    158    }
    159
    160    @Override
    161    public Object number(final String value) {
    162        return new Constant(Double.valueOf(value));
    163    }
    164
    165    @Override
    166    public Object or(final Object[] arguments) {
    167        return new CoreOperationOr(toExpressionArray(arguments));
    168    }
    169
    170    @Override
    171    public Object processingInstructionTest(final String instruction) {
    172        return new ProcessingInstructionTest(instruction);
    173    }
    174
    175    @Override
    176    public Object qname(final String prefix, final String name) {
    177        return new QName(prefix, name);
    178    }
    179
    180    @Override
    181    public Object step(final int axis, final Object nodeTest, final Object[] predicates) {
    182        return new Step(axis, (NodeTest) nodeTest, toExpressionArray(predicates));
    183    }
    184
    185    @Override
    186    public Object sum(final Object[] arguments) {
    187        return new CoreOperationAdd(toExpressionArray(arguments));
    188    }
    189
    190    /**
    191     * Gets an Object[] as an Expression[].
    192     *
    193     * @param array Object[]
    194     * @return Expression[]
    195     */
    196    private Expression[] toExpressionArray(final Object[] array) {
    197        Expression[] expArray = null;
    198        if (array != null) {
    199            expArray = new Expression[array.length];
    200            for (int i = 0; i < expArray.length; i++) {
    201                expArray[i] = (Expression) array[i];
    202            }
    203        }
    204        return expArray;
    205    }
    206
    207    /**
    208     * Gets an Object[] as a Step[].
    209     *
    210     * @param array Object[]
    211     * @return Step[]
    212     */
    213    private Step[] toStepArray(final Object[] array) {
    214        Step[] stepArray = null;
    215        if (array != null) {
    216            stepArray = new Step[array.length];
    217            for (int i = 0; i < stepArray.length; i++) {
    218                stepArray[i] = (Step) array[i];
    219            }
    220        }
    221        return stepArray;
    222    }
    223
    224    @Override
    225    public Object union(final Object[] arguments) {
    226        return new CoreOperationUnion(toExpressionArray(arguments));
    227    }
    228
    229    @Override
    230    public Object variableReference(final Object qName) {
    231        return new VariableReference((QName) qName);
    232    }
    233}