Java tutorial
/** * Copyright 2012 NetDigital Sweden AB * * 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 com.nginious.http.xsp.expr; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; /** * A function which takes on value argument and returns the length of a string when evaluated. * Below is an example which evaluates to 4. * * <pre> * length('Test') * </pre> * * @author Bojan Pisler, NetDigital Sweden AB * */ public class LengthFunction extends Function { private Value value; /** * Constructs a new length function with the specified value as argument. * * @param value */ public LengthFunction(Value value) { super(); this.value = value; } /** * Returns the type of value returned by this function when evaluated, {@link Type#INT}. * * @return the type */ protected Type getType() { return Type.INT; } /** * Evaluates this function which returns the length of a string. * * @return the result of evaluating this function */ protected Value evaluate() { return new IntegerValue(getIntValue()); } /** * Evaluates this function and returns the length as an integer. * * @return the integer result of evaluating this function */ protected int getIntValue() { String expr = value.getStringValue(); if (expr == null) { return 0; } return expr.length(); } /** * Evaluates this function and returns the length converted to a double. * * @return the double result of evaluating this function */ protected double getDoubleValue() { return (double) getIntValue(); } /** * Evaluates this function and returns the length converted to a string. * * @return the string result of evaluating this function */ protected String getStringValue() { return Integer.toString(getIntValue()); } /** * Evaluates this function and returns the length converted to a boolean. * * @return the boolean result of evaluating this function */ protected boolean getBooleanValue() { return getIntValue() != 0; } /** * Creates bytecode for evaluating this function. The specified method * visitor is used to generate bytecode. The generated bytecode produces * a result of the specified type. * * @param visitor the method visitor * @param type the type */ void compile(MethodVisitor visitor, Type type) { value.compile(visitor, Type.STRING); visitor.visitVarInsn(Opcodes.ASTORE, 1); Label nullLabel = new Label(); Label notNullLabel = new Label(); visitor.visitVarInsn(Opcodes.ALOAD, 1); visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel); visitor.visitVarInsn(Opcodes.ALOAD, 1); visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "length", "()I"); visitor.visitJumpInsn(Opcodes.GOTO, notNullLabel); visitor.visitLabel(nullLabel); visitor.visitLdcInsn(0); visitor.visitLabel(notNullLabel); } }