alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Number.java)

This example Java source code file (Number.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

attributevaluetemplate, constantpoolgen, dom_intf_sig, getfield, instructionlist, invokevirtual, level_any, level_multiple, level_single, methodgenerator, node_counter_sig, push, string, string_sig, util

The Number.java Java example source code

/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Copyright 2001-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.
 */
/*
 * $Id: Number.java,v 1.2.4.1 2005/09/21 09:40:51 pvedula Exp $
 */

package com.sun.org.apache.xalan.internal.xsltc.compiler;

import java.util.ArrayList;

import com.sun.org.apache.bcel.internal.classfile.Field;
import com.sun.org.apache.bcel.internal.generic.ALOAD;
import com.sun.org.apache.bcel.internal.generic.ILOAD;
import com.sun.org.apache.bcel.internal.generic.ASTORE;
import com.sun.org.apache.bcel.internal.generic.BranchHandle;
import com.sun.org.apache.bcel.internal.generic.CHECKCAST;
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
import com.sun.org.apache.bcel.internal.generic.GETFIELD;
import com.sun.org.apache.bcel.internal.generic.GOTO;
import com.sun.org.apache.bcel.internal.generic.IFNONNULL;
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
import com.sun.org.apache.bcel.internal.generic.InstructionList;
import com.sun.org.apache.bcel.internal.generic.D2I;
import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
import com.sun.org.apache.bcel.internal.generic.NEW;
import com.sun.org.apache.bcel.internal.generic.PUSH;
import com.sun.org.apache.bcel.internal.generic.PUTFIELD;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MatchGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeCounterGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.RealType;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;

/**
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 */
final class Number extends Instruction implements Closure {
    private static final int LEVEL_SINGLE   = 0;
    private static final int LEVEL_MULTIPLE = 1;
    private static final int LEVEL_ANY      = 2;

    static final private String[] ClassNames = {
        "com.sun.org.apache.xalan.internal.xsltc.dom.SingleNodeCounter",          // LEVEL_SINGLE
        "com.sun.org.apache.xalan.internal.xsltc.dom.MultipleNodeCounter", // LEVEL_MULTIPLE
        "com.sun.org.apache.xalan.internal.xsltc.dom.AnyNodeCounter"      // LEVEL_ANY
    };

    static final private String[] FieldNames = {
        "___single_node_counter",                  // LEVEL_SINGLE
        "___multiple_node_counter",                // LEVEL_MULTIPLE
        "___any_node_counter"                      // LEVEL_ANY
    };

    private Pattern _from = null;
    private Pattern _count = null;
    private Expression _value = null;

    private AttributeValueTemplate _lang = null;
    private AttributeValueTemplate _format = null;
    private AttributeValueTemplate _letterValue = null;
    private AttributeValueTemplate _groupingSeparator = null;
    private AttributeValueTemplate _groupingSize = null;

    private int _level = LEVEL_SINGLE;
    private boolean _formatNeeded = false;

    private String _className = null;
    private ArrayList _closureVars = null;

     // -- Begin Closure interface --------------------

    /**
     * Returns true if this closure is compiled in an inner class (i.e.
     * if this is a real closure).
     */
    public boolean inInnerClass() {
        return (_className != null);
    }

    /**
     * Returns a reference to its parent closure or null if outermost.
     */
    public Closure getParentClosure() {
        return null;
    }

    /**
     * Returns the name of the auxiliary class or null if this predicate
     * is compiled inside the Translet.
     */
    public String getInnerClassName() {
        return _className;
    }

    /**
     * Add new variable to the closure.
     */
    public void addVariable(VariableRefBase variableRef) {
        if (_closureVars == null) {
            _closureVars = new ArrayList();
        }

        // Only one reference per variable
        if (!_closureVars.contains(variableRef)) {
            _closureVars.add(variableRef);
        }
    }

    // -- End Closure interface ----------------------

   public void parseContents(Parser parser) {
        final int count = _attributes.getLength();

        for (int i = 0; i < count; i++) {
            final String name = _attributes.getQName(i);
            final String value = _attributes.getValue(i);

            if (name.equals("value")) {
                _value = parser.parseExpression(this, name, null);
            }
            else if (name.equals("count")) {
                _count = parser.parsePattern(this, name, null);
            }
            else if (name.equals("from")) {
                _from = parser.parsePattern(this, name, null);
            }
            else if (name.equals("level")) {
                if (value.equals("single")) {
                    _level = LEVEL_SINGLE;
                }
                else if (value.equals("multiple")) {
                    _level = LEVEL_MULTIPLE;
                }
                else if (value.equals("any")) {
                    _level = LEVEL_ANY;
                }
            }
            else if (name.equals("format")) {
                _format = new AttributeValueTemplate(value, parser, this);
                _formatNeeded = true;
            }
            else if (name.equals("lang")) {
                _lang = new AttributeValueTemplate(value, parser, this);
                _formatNeeded = true;
            }
            else if (name.equals("letter-value")) {
                _letterValue = new AttributeValueTemplate(value, parser, this);
                _formatNeeded = true;
            }
            else if (name.equals("grouping-separator")) {
                _groupingSeparator = new AttributeValueTemplate(value, parser, this);
                _formatNeeded = true;
            }
            else if (name.equals("grouping-size")) {
                _groupingSize = new AttributeValueTemplate(value, parser, this);
                _formatNeeded = true;
            }
        }
    }

    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
        if (_value != null) {
            Type tvalue = _value.typeCheck(stable);
            if (tvalue instanceof RealType == false) {
                _value = new CastExpr(_value, Type.Real);
            }
        }
        if (_count != null) {
            _count.typeCheck(stable);
        }
        if (_from != null) {
            _from.typeCheck(stable);
        }
        if (_format != null) {
            _format.typeCheck(stable);
        }
        if (_lang != null) {
            _lang.typeCheck(stable);
        }
        if (_letterValue != null) {
            _letterValue.typeCheck(stable);
        }
        if (_groupingSeparator != null) {
            _groupingSeparator.typeCheck(stable);
        }
        if (_groupingSize != null) {
            _groupingSize.typeCheck(stable);
        }
        return Type.Void;
    }

    /**
     * True if the has specified a value for this instance of number.
     */
    public boolean hasValue() {
        return _value != null;
    }

    /**
     * Returns <tt>true if this instance of number has neither
     * a from nor a count pattern.
     */
    public boolean isDefault() {
        return _from == null && _count == null;
    }

    private void compileDefault(ClassGenerator classGen,
                                MethodGenerator methodGen) {
        int index;
        ConstantPoolGen cpg = classGen.getConstantPool();
        InstructionList il = methodGen.getInstructionList();

        int[] fieldIndexes = getXSLTC().getNumberFieldIndexes();

        if (fieldIndexes[_level] == -1) {
            Field defaultNode = new Field(ACC_PRIVATE,
                                          cpg.addUtf8(FieldNames[_level]),
                                          cpg.addUtf8(NODE_COUNTER_SIG),
                                          null,
                                          cpg.getConstantPool());

            // Add a new private field to this class
            classGen.addField(defaultNode);

            // Get a reference to the newly added field
            fieldIndexes[_level] = cpg.addFieldref(classGen.getClassName(),
                                                   FieldNames[_level],
                                                   NODE_COUNTER_SIG);
        }

        // Check if field is initialized (runtime)
        il.append(classGen.loadTranslet());
        il.append(new GETFIELD(fieldIndexes[_level]));
        final BranchHandle ifBlock1 = il.append(new IFNONNULL(null));

        // Create an instance of DefaultNodeCounter
        index = cpg.addMethodref(ClassNames[_level],
                                 "getDefaultNodeCounter",
                                 "(" + TRANSLET_INTF_SIG
                                 + DOM_INTF_SIG
                                 + NODE_ITERATOR_SIG
                                 + ")" + NODE_COUNTER_SIG);
        il.append(classGen.loadTranslet());
        il.append(methodGen.loadDOM());
        il.append(methodGen.loadIterator());
        il.append(new INVOKESTATIC(index));
        il.append(DUP);

        // Store the node counter in the field
        il.append(classGen.loadTranslet());
        il.append(SWAP);
        il.append(new PUTFIELD(fieldIndexes[_level]));
        final BranchHandle ifBlock2 = il.append(new GOTO(null));

        // Backpatch conditionals
        ifBlock1.setTarget(il.append(classGen.loadTranslet()));
        il.append(new GETFIELD(fieldIndexes[_level]));

        ifBlock2.setTarget(il.append(NOP));
    }

    /**
     * Compiles a constructor for the class <tt>_className that
     * inherits from {Any,Single,Multiple}NodeCounter. This constructor
     * simply calls the same constructor in the super class.
     */
    private void compileConstructor(ClassGenerator classGen) {
        MethodGenerator cons;
        final InstructionList il = new InstructionList();
        final ConstantPoolGen cpg = classGen.getConstantPool();

        cons = new MethodGenerator(ACC_PUBLIC,
                                   com.sun.org.apache.bcel.internal.generic.Type.VOID,
                                   new com.sun.org.apache.bcel.internal.generic.Type[] {
                                       Util.getJCRefType(TRANSLET_INTF_SIG),
                                       Util.getJCRefType(DOM_INTF_SIG),
                                       Util.getJCRefType(NODE_ITERATOR_SIG),
                                       com.sun.org.apache.bcel.internal.generic.Type.BOOLEAN
                                   },
                                   new String[] {
                                       "dom",
                                       "translet",
                                       "iterator",
                                       "hasFrom"
                                   },
                                   "<init>", _className, il, cpg);

        il.append(ALOAD_0);         // this
        il.append(ALOAD_1);         // translet
        il.append(ALOAD_2);         // DOM
        il.append(new ALOAD(3));    // iterator
        il.append(new ILOAD(4));    // hasFrom

        int index = cpg.addMethodref(ClassNames[_level],
                                     "<init>",
                                     "(" + TRANSLET_INTF_SIG
                                     + DOM_INTF_SIG
                                     + NODE_ITERATOR_SIG
                                     + "Z)V");
        il.append(new INVOKESPECIAL(index));
        il.append(RETURN);

        classGen.addMethod(cons);
    }

    /**
     * This method compiles code that is common to matchesFrom() and
     * matchesCount() in the auxillary class.
     */
    private void compileLocals(NodeCounterGenerator nodeCounterGen,
                               MatchGenerator matchGen,
                               InstructionList il)
    {
        int field;
        LocalVariableGen local;
        ConstantPoolGen cpg = nodeCounterGen.getConstantPool();

        // Get NodeCounter._iterator and store locally
        local = matchGen.addLocalVariable("iterator",
                                          Util.getJCRefType(NODE_ITERATOR_SIG),
                                          null, null);
        field = cpg.addFieldref(NODE_COUNTER, "_iterator",
                                ITERATOR_FIELD_SIG);
        il.append(ALOAD_0); // 'this' pointer on stack
        il.append(new GETFIELD(field));
        local.setStart(il.append(new ASTORE(local.getIndex())));
        matchGen.setIteratorIndex(local.getIndex());

        // Get NodeCounter._translet and store locally
        local = matchGen.addLocalVariable("translet",
                                  Util.getJCRefType(TRANSLET_SIG),
                                  null, null);
        field = cpg.addFieldref(NODE_COUNTER, "_translet",
                                "Lcom/sun/org/apache/xalan/internal/xsltc/Translet;");
        il.append(ALOAD_0); // 'this' pointer on stack
        il.append(new GETFIELD(field));
        il.append(new CHECKCAST(cpg.addClass(TRANSLET_CLASS)));
        local.setStart(il.append(new ASTORE(local.getIndex())));
        nodeCounterGen.setTransletIndex(local.getIndex());

        // Get NodeCounter._document and store locally
        local = matchGen.addLocalVariable("document",
                                          Util.getJCRefType(DOM_INTF_SIG),
                                          null, null);
        field = cpg.addFieldref(_className, "_document", DOM_INTF_SIG);
        il.append(ALOAD_0); // 'this' pointer on stack
        il.append(new GETFIELD(field));
        // Make sure we have the correct DOM type on the stack!!!
        local.setStart(il.append(new ASTORE(local.getIndex())));
        matchGen.setDomIndex(local.getIndex());
    }

    private void compilePatterns(ClassGenerator classGen,
                                 MethodGenerator methodGen)
    {
        int current;
        int field;
        LocalVariableGen local;
        MatchGenerator matchGen;
        NodeCounterGenerator nodeCounterGen;

        _className = getXSLTC().getHelperClassName();
        nodeCounterGen = new NodeCounterGenerator(_className,
                                                  ClassNames[_level],
                                                  toString(),
                                                  ACC_PUBLIC | ACC_SUPER,
                                                  null,
                                                  classGen.getStylesheet());
        InstructionList il = null;
        ConstantPoolGen cpg = nodeCounterGen.getConstantPool();

        // Add a new instance variable for each var in closure
        final int closureLen = (_closureVars == null) ? 0 :
            _closureVars.size();

        for (int i = 0; i < closureLen; i++) {
            VariableBase var =
                ((VariableRefBase) _closureVars.get(i)).getVariable();

            nodeCounterGen.addField(new Field(ACC_PUBLIC,
                                        cpg.addUtf8(var.getEscapedName()),
                                        cpg.addUtf8(var.getType().toSignature()),
                                        null, cpg.getConstantPool()));
        }

        // Add a single constructor to the class
        compileConstructor(nodeCounterGen);

        /*
         * Compile method matchesFrom()
         */
        if (_from != null) {
            il = new InstructionList();
            matchGen =
                new MatchGenerator(ACC_PUBLIC | ACC_FINAL,
                                   com.sun.org.apache.bcel.internal.generic.Type.BOOLEAN,
                                   new com.sun.org.apache.bcel.internal.generic.Type[] {
                                       com.sun.org.apache.bcel.internal.generic.Type.INT,
                                   },
                                   new String[] {
                                       "node",
                                   },
                                   "matchesFrom", _className, il, cpg);

            compileLocals(nodeCounterGen,matchGen,il);

            // Translate Pattern
            il.append(matchGen.loadContextNode());
            _from.translate(nodeCounterGen, matchGen);
            _from.synthesize(nodeCounterGen, matchGen);
            il.append(IRETURN);

            nodeCounterGen.addMethod(matchGen);
        }

        /*
         * Compile method matchesCount()
         */
        if (_count != null) {
            il = new InstructionList();
            matchGen = new MatchGenerator(ACC_PUBLIC | ACC_FINAL,
                                          com.sun.org.apache.bcel.internal.generic.Type.BOOLEAN,
                                          new com.sun.org.apache.bcel.internal.generic.Type[] {
                                              com.sun.org.apache.bcel.internal.generic.Type.INT,
                                          },
                                          new String[] {
                                              "node",
                                          },
                                          "matchesCount", _className, il, cpg);

            compileLocals(nodeCounterGen,matchGen,il);

            // Translate Pattern
            il.append(matchGen.loadContextNode());
            _count.translate(nodeCounterGen, matchGen);
            _count.synthesize(nodeCounterGen, matchGen);

            il.append(IRETURN);

            nodeCounterGen.addMethod(matchGen);
        }

        getXSLTC().dumpClass(nodeCounterGen.getJavaClass());

        // Push an instance of the newly created class
        cpg = classGen.getConstantPool();
        il = methodGen.getInstructionList();

        final int index = cpg.addMethodref(_className, "<init>",
                                           "(" + TRANSLET_INTF_SIG
                                           + DOM_INTF_SIG
                                           + NODE_ITERATOR_SIG
                                           + "Z)V");
        il.append(new NEW(cpg.addClass(_className)));
        il.append(DUP);
        il.append(classGen.loadTranslet());
        il.append(methodGen.loadDOM());
        il.append(methodGen.loadIterator());
        il.append(_from != null ? ICONST_1 : ICONST_0);
        il.append(new INVOKESPECIAL(index));

        // Initialize closure variables
        for (int i = 0; i < closureLen; i++) {
            final VariableRefBase varRef = (VariableRefBase) _closureVars.get(i);
            final VariableBase var = varRef.getVariable();
            final Type varType = var.getType();

            // Store variable in new closure
            il.append(DUP);
            il.append(var.loadInstruction());
            il.append(new PUTFIELD(
                    cpg.addFieldref(_className, var.getEscapedName(),
                        varType.toSignature())));
        }
    }

    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
        int index;
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();

        // Push "this" for the call to characters()
        il.append(classGen.loadTranslet());

        if (hasValue()) {
            compileDefault(classGen, methodGen);
            _value.translate(classGen, methodGen);

            // Using java.lang.Math.floor(number + 0.5) to return a double value
            il.append(new PUSH(cpg, 0.5));
            il.append(DADD);
            index = cpg.addMethodref(MATH_CLASS, "floor", "(D)D");
            il.append(new INVOKESTATIC(index));

            // Call setValue on the node counter
            index = cpg.addMethodref(NODE_COUNTER,
                                     "setValue",
                                     "(D)" + NODE_COUNTER_SIG);
            il.append(new INVOKEVIRTUAL(index));
        }
        else if (isDefault()) {
            compileDefault(classGen, methodGen);
        }
        else {
            compilePatterns(classGen, methodGen);
        }

        // Call setStartNode()
        if (!hasValue()) {
            il.append(methodGen.loadContextNode());
            index = cpg.addMethodref(NODE_COUNTER,
                                     SET_START_NODE,
                                     "(I)" + NODE_COUNTER_SIG);
            il.append(new INVOKEVIRTUAL(index));
        }

        // Call getCounter() with or without args
        if (_formatNeeded) {
            if (_format != null) {
                _format.translate(classGen, methodGen);
            }
            else {
                il.append(new PUSH(cpg, "1"));
            }

            if (_lang != null) {
                _lang.translate(classGen, methodGen);
            }
            else {
                il.append(new PUSH(cpg, "en"));         // TODO ??
            }

            if (_letterValue != null) {
                _letterValue.translate(classGen, methodGen);
            }
            else {
                il.append(new PUSH(cpg, Constants.EMPTYSTRING));
            }

            if (_groupingSeparator != null) {
                _groupingSeparator.translate(classGen, methodGen);
            }
            else {
                il.append(new PUSH(cpg, Constants.EMPTYSTRING));
            }

            if (_groupingSize != null) {
                _groupingSize.translate(classGen, methodGen);
            }
            else {
                il.append(new PUSH(cpg, "0"));
            }

            index = cpg.addMethodref(NODE_COUNTER, "getCounter",
                                     "(" + STRING_SIG + STRING_SIG
                                     + STRING_SIG + STRING_SIG
                                     + STRING_SIG + ")" + STRING_SIG);
            il.append(new INVOKEVIRTUAL(index));
        }
        else {
            index = cpg.addMethodref(NODE_COUNTER, "setDefaultFormatting",
                                     "()" + NODE_COUNTER_SIG);
            il.append(new INVOKEVIRTUAL(index));

            index = cpg.addMethodref(NODE_COUNTER, "getCounter",
                                     "()" + STRING_SIG);
            il.append(new INVOKEVIRTUAL(index));
        }

        // Output the resulting string to the handler
        il.append(methodGen.loadHandler());
        index = cpg.addMethodref(TRANSLET_CLASS,
                                 CHARACTERSW,
                                 CHARACTERSW_SIG);
        il.append(new INVOKEVIRTUAL(index));
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java Number.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.