corefunction.java

来自「JXPath」· Java 代码 · 共 688 行 · 第 1/2 页

JAVA
688
字号
/*
 * Copyright 1999-2004 The Apache Software Foundation
 *
 * 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.
 */
package org.apache.commons.jxpath.ri.compiler;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.Locale;

import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathException;
import org.apache.commons.jxpath.ri.Compiler;
import org.apache.commons.jxpath.ri.EvalContext;
import org.apache.commons.jxpath.ri.InfoSetUtil;
import org.apache.commons.jxpath.ri.model.NodePointer;

/**
 * An element of the compile tree representing one of built-in functions
 * like "position()" or "number()".
 *
 * @author Dmitri Plotnikov
 * @version $Revision: 1.16 $ $Date: 2004/04/01 02:53:45 $
 */
public class CoreFunction extends Operation {

    private static final Double ZERO = new Double(0);
    private int functionCode;

    public CoreFunction(int functionCode, Expression args[]) {
        super(args);
        this.functionCode = functionCode;
    }

    public int getFunctionCode() {
        return functionCode;
    }
    
    protected String getFunctionName() {
        switch (functionCode) {
            case Compiler.FUNCTION_LAST :
                return "last";
            case Compiler.FUNCTION_POSITION :
                return "position";
            case Compiler.FUNCTION_COUNT :
                return "count";
            case Compiler.FUNCTION_ID :
                return "id";
            case Compiler.FUNCTION_LOCAL_NAME :
                return "local-name";
            case Compiler.FUNCTION_NAMESPACE_URI :
                return "namespace-uri";
            case Compiler.FUNCTION_NAME :
                return "name";
            case Compiler.FUNCTION_STRING :
                return "string";
            case Compiler.FUNCTION_CONCAT :
                return "concat";
            case Compiler.FUNCTION_STARTS_WITH :
                return "starts-with";
            case Compiler.FUNCTION_CONTAINS :
                return "contains";
            case Compiler.FUNCTION_SUBSTRING_BEFORE :
                return "substring-before";
            case Compiler.FUNCTION_SUBSTRING_AFTER :
                return "substring-after";
            case Compiler.FUNCTION_SUBSTRING :
                return "substring";
            case Compiler.FUNCTION_STRING_LENGTH :
                return "string-length";
            case Compiler.FUNCTION_NORMALIZE_SPACE :
                return "normalize-space";
            case Compiler.FUNCTION_TRANSLATE :
                return "translate";
            case Compiler.FUNCTION_BOOLEAN :
                return "boolean";
            case Compiler.FUNCTION_NOT :
                return "not";
            case Compiler.FUNCTION_TRUE :
                return "true";
            case Compiler.FUNCTION_FALSE :
                return "false";
            case Compiler.FUNCTION_LANG :
                return "lang";
            case Compiler.FUNCTION_NUMBER :
                return "number";
            case Compiler.FUNCTION_SUM :
                return "sum";
            case Compiler.FUNCTION_FLOOR :
                return "floor";
            case Compiler.FUNCTION_CEILING :
                return "ceiling";
            case Compiler.FUNCTION_ROUND :
                return "round";
            case Compiler.FUNCTION_KEY :
                return "key";
            case Compiler.FUNCTION_FORMAT_NUMBER:
                return "format-number";
        }
        return "unknownFunction" + functionCode + "()";
    }

    public Expression getArg1() {
        return args[0];
    }

    public Expression getArg2() {
        return args[1];
    }

    public Expression getArg3() {
        return args[2];
    }

    public int getArgumentCount() {
        if (args == null) {
            return 0;
        }
        return args.length;
    }

    /**
     * Returns true if any argument is context dependent or if
     * the function is last(), position(), boolean(), local-name(),
     * name(), string(), lang(), number().
     */
    public boolean computeContextDependent() {
        if (super.computeContextDependent()) {
            return true;
        }

        switch(functionCode) {
            case Compiler.FUNCTION_LAST:
            case Compiler.FUNCTION_POSITION:
                return true;

            case Compiler.FUNCTION_BOOLEAN:
            case Compiler.FUNCTION_LOCAL_NAME:
            case Compiler.FUNCTION_NAME:
            case Compiler.FUNCTION_NAMESPACE_URI:
            case Compiler.FUNCTION_STRING:
            case Compiler.FUNCTION_LANG:
            case Compiler.FUNCTION_NUMBER:
                return args == null || args.length == 0;

            case Compiler.FUNCTION_COUNT:
            case Compiler.FUNCTION_ID:
            case Compiler.FUNCTION_CONCAT:
            case Compiler.FUNCTION_STARTS_WITH:
            case Compiler.FUNCTION_CONTAINS:
            case Compiler.FUNCTION_SUBSTRING_BEFORE:
            case Compiler.FUNCTION_SUBSTRING_AFTER:
            case Compiler.FUNCTION_SUBSTRING:
            case Compiler.FUNCTION_STRING_LENGTH:
            case Compiler.FUNCTION_NORMALIZE_SPACE:
            case Compiler.FUNCTION_TRANSLATE:
            case Compiler.FUNCTION_NOT:
            case Compiler.FUNCTION_TRUE:
            case Compiler.FUNCTION_FALSE:
            case Compiler.FUNCTION_SUM:
            case Compiler.FUNCTION_FLOOR:
            case Compiler.FUNCTION_CEILING:
            case Compiler.FUNCTION_ROUND:
                return false;
                
            case Compiler.FUNCTION_FORMAT_NUMBER:
                return args != null && args.length == 2;                             
        }

        return false;
    }
    
    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append(getFunctionName());
        buffer.append('(');
        Expression args[] = getArguments();
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                if (i > 0) {
                    buffer.append(", ");
                }
                buffer.append(args[i]);
            }
        }
        buffer.append(')');
        return buffer.toString();
    }

    public Object compute(EvalContext context) {
        return computeValue(context);
    }

    /**
     * Computes a built-in function
     */
    public Object computeValue(EvalContext context) {
        switch (functionCode) {
            case Compiler.FUNCTION_LAST :
                return functionLast(context);
            case Compiler.FUNCTION_POSITION :
                return functionPosition(context);
            case Compiler.FUNCTION_COUNT :
                return functionCount(context);
            case Compiler.FUNCTION_LANG :
                return functionLang(context);
            case Compiler.FUNCTION_ID :
                return functionID(context);
            case Compiler.FUNCTION_LOCAL_NAME :
                return functionLocalName(context);
            case Compiler.FUNCTION_NAMESPACE_URI :
                return functionNamespaceURI(context);
            case Compiler.FUNCTION_NAME :
                return functionName(context);
            case Compiler.FUNCTION_STRING :
                return functionString(context);
            case Compiler.FUNCTION_CONCAT :
                return functionConcat(context);
            case Compiler.FUNCTION_STARTS_WITH :
                return functionStartsWith(context);
            case Compiler.FUNCTION_CONTAINS :
                return functionContains(context);
            case Compiler.FUNCTION_SUBSTRING_BEFORE :
                return functionSubstringBefore(context);
            case Compiler.FUNCTION_SUBSTRING_AFTER :
                return functionSubstringAfter(context);
            case Compiler.FUNCTION_SUBSTRING :
                return functionSubstring(context);
            case Compiler.FUNCTION_STRING_LENGTH :
                return functionStringLength(context);
            case Compiler.FUNCTION_NORMALIZE_SPACE :
                return functionNormalizeSpace(context);
            case Compiler.FUNCTION_TRANSLATE :
                return functionTranslate(context);
            case Compiler.FUNCTION_BOOLEAN :
                return functionBoolean(context);
            case Compiler.FUNCTION_NOT :
                return functionNot(context);
            case Compiler.FUNCTION_TRUE :
                return functionTrue(context);
            case Compiler.FUNCTION_FALSE :
                return functionFalse(context);
            case Compiler.FUNCTION_NULL :
                return functionNull(context);
            case Compiler.FUNCTION_NUMBER :
                return functionNumber(context);
            case Compiler.FUNCTION_SUM :
                return functionSum(context);
            case Compiler.FUNCTION_FLOOR :
                return functionFloor(context);
            case Compiler.FUNCTION_CEILING :
                return functionCeiling(context);
            case Compiler.FUNCTION_ROUND :
                return functionRound(context);
            case Compiler.FUNCTION_KEY :
                return functionKey(context);
            case Compiler.FUNCTION_FORMAT_NUMBER :
                return functionFormatNumber(context);
        }
        return null;
    }

    protected Object functionLast(EvalContext context) {
        assertArgCount(0);
        // Move the position to the beginning and iterate through
        // the context to count nodes.
        int old = context.getCurrentPosition();
        context.reset();
        int count = 0;
        while (context.nextNode()) {
            count++;
        }

        // Restore the current position.
        if (old != 0) {
            context.setPosition(old);
        }
        return new Double(count);
    }

    protected Object functionPosition(EvalContext context) {
        assertArgCount(0);
        return new Integer(context.getCurrentPosition());
    }

    protected Object functionCount(EvalContext context) {
        assertArgCount(1);
        Expression arg1 = getArg1();
        int count = 0;
        Object value = arg1.compute(context);
        if (value instanceof NodePointer) {
            value = ((NodePointer) value).getValue();
        }
        if (value instanceof EvalContext) {
            EvalContext ctx = (EvalContext) value;
            while (ctx.hasNext()) {
                ctx.next();
                count++;
            }
        }
        else if (value instanceof Collection) {
            count = ((Collection) value).size();
        }
        else if (value == null) {
            count = 0;
        }
        else {
            count = 1;
        }
        return new Double(count);
    }

    protected Object functionLang(EvalContext context) {
        assertArgCount(1);
        String lang = InfoSetUtil.stringValue(getArg1().computeValue(context));
        NodePointer pointer = (NodePointer) context.getSingleNodePointer();
        if (pointer == null) {
            return Boolean.FALSE;
        }
        return pointer.isLanguage(lang) ? Boolean.TRUE : Boolean.FALSE;
    }

    protected Object functionID(EvalContext context) {
        assertArgCount(1);
        String id = InfoSetUtil.stringValue(getArg1().computeValue(context));
        JXPathContext jxpathContext = context.getJXPathContext();
        NodePointer pointer = (NodePointer) jxpathContext.getContextPointer();
        return pointer.getPointerByID(jxpathContext, id);
    }

    protected Object functionKey(EvalContext context) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?