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

Java example source code file (BasisLibrary.java)

This example Java source code file (BasisLibrary.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

boolean, decimalformat, dom, double, dtmaxisiterator, dtmnodeproxy, emptystring, integer, multidom, node, number, object, sax, string, stringbuilder, text, util

The BasisLibrary.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: BasisLibrary.java,v 1.6 2006/06/20 21:51:58 spericas Exp $
 */

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

import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.FieldPosition;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.xml.transform.dom.DOMSource;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.Translet;
import com.sun.org.apache.xalan.internal.xsltc.dom.AbsoluteIterator;
import com.sun.org.apache.xml.internal.dtm.Axis;
import com.sun.org.apache.xalan.internal.xsltc.dom.DOMAdapter;
import com.sun.org.apache.xalan.internal.xsltc.dom.MultiDOM;
import com.sun.org.apache.xalan.internal.xsltc.dom.SingletonIterator;
import com.sun.org.apache.xalan.internal.xsltc.dom.StepIterator;
import com.sun.org.apache.xalan.internal.xsltc.dom.ArrayNodeListIterator;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.dtm.DTMManager;
import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase;
import com.sun.org.apache.xml.internal.dtm.ref.DTMNodeProxy;

import org.w3c.dom.DOMException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import com.sun.org.apache.xml.internal.serializer.NamespaceMappings;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import com.sun.org.apache.xml.internal.utils.XML11Char;

/**
 * Standard XSLT functions. All standard functions expect the current node
 * and the DOM as their last two arguments.
 */
public final class BasisLibrary {

    private final static String EMPTYSTRING = "";

    /**
     * Re-use a single instance of StringBuffer (per thread) in the basis library.
     * StringBuilder is better, however, DecimalFormat only accept StringBuffer
     */
    private static final ThreadLocal<StringBuilder> threadLocalStringBuilder =
        new ThreadLocal<StringBuilder> () {
            @Override protected StringBuilder initialValue() {
                return new StringBuilder();
            }
    };

    /**
     * ThreadLocal for StringBuffer used
     */
    private static final ThreadLocal<StringBuffer> threadLocalStringBuffer =
        new ThreadLocal<StringBuffer> () {
            @Override protected StringBuffer initialValue() {
                return new StringBuffer();
            }
    };

    /**
     * Standard function count(node-set)
     */
    public static int countF(DTMAxisIterator iterator) {
        return(iterator.getLast());
    }

    /**
     * Standard function position()
     * @deprecated This method exists only for backwards compatibility with old
     *             translets.  New code should not reference it.
     */
    public static int positionF(DTMAxisIterator iterator) {
        return iterator.isReverse()
                     ? iterator.getLast() - iterator.getPosition() + 1
                     : iterator.getPosition();
    }

    /**
     * XSLT Standard function sum(node-set).
     * stringToDouble is inlined
     */
    public static double sumF(DTMAxisIterator iterator, DOM dom) {
        try {
            double result = 0.0;
            int node;
            while ((node = iterator.next()) != DTMAxisIterator.END) {
                result += Double.parseDouble(dom.getStringValueX(node));
            }
            return result;
        }
        catch (NumberFormatException e) {
            return Double.NaN;
        }
    }

    /**
     * XSLT Standard function string()
     */
    public static String stringF(int node, DOM dom) {
        return dom.getStringValueX(node);
    }

    /**
     * XSLT Standard function string(value)
     */
    public static String stringF(Object obj, DOM dom) {
        if (obj instanceof DTMAxisIterator) {
            return dom.getStringValueX(((DTMAxisIterator)obj).reset().next());
        }
        else if (obj instanceof Node) {
            return dom.getStringValueX(((Node)obj).node);
        }
        else if (obj instanceof DOM) {
            return ((DOM)obj).getStringValue();
        }
        else {
            return obj.toString();
        }
    }

    /**
     * XSLT Standard function string(value)
     */
    public static String stringF(Object obj, int node, DOM dom) {
        if (obj instanceof DTMAxisIterator) {
            return dom.getStringValueX(((DTMAxisIterator)obj).reset().next());
        }
        else if (obj instanceof Node) {
            return dom.getStringValueX(((Node)obj).node);
        }
        else if (obj instanceof DOM) {
            // When the first argument is a DOM we want the whole
            // DOM and not just a single node - that would not make sense.
            //return ((DOM)obj).getStringValueX(node);
            return ((DOM)obj).getStringValue();
        }
        else if (obj instanceof Double) {
            Double d = (Double)obj;
            final String result = d.toString();
            final int length = result.length();
            if ((result.charAt(length-2)=='.') &&
                (result.charAt(length-1) == '0'))
                return result.substring(0, length-2);
            else
                return result;
        }
        else {
            return obj != null ? obj.toString() : "";
        }
    }

    /**
     * XSLT Standard function number()
     */
    public static double numberF(int node, DOM dom) {
        return stringToReal(dom.getStringValueX(node));
    }

    /**
     * XSLT Standard function number(value)
     */
    public static double numberF(Object obj, DOM dom) {
        if (obj instanceof Double) {
            return ((Double) obj).doubleValue();
        }
        else if (obj instanceof Integer) {
            return ((Integer) obj).doubleValue();
        }
        else if (obj instanceof Boolean) {
            return  ((Boolean) obj).booleanValue() ? 1.0 : 0.0;
        }
        else if (obj instanceof String) {
            return stringToReal((String) obj);
        }
        else if (obj instanceof DTMAxisIterator) {
            DTMAxisIterator iter = (DTMAxisIterator) obj;
            return stringToReal(dom.getStringValueX(iter.reset().next()));
        }
        else if (obj instanceof Node) {
            return stringToReal(dom.getStringValueX(((Node) obj).node));
        }
        else if (obj instanceof DOM) {
            return stringToReal(((DOM) obj).getStringValue());
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(INVALID_ARGUMENT_ERR, className, "number()");
            return 0.0;
        }
    }

    /**
     * XSLT Standard function round()
     */
    public static double roundF(double d) {
            return (d<-0.5 || d>0.0)?Math.floor(d+0.5):((d==0.0)?
                        d:(Double.isNaN(d)?Double.NaN:-0.0));
    }

    /**
     * XSLT Standard function boolean()
     */
    public static boolean booleanF(Object obj) {
        if (obj instanceof Double) {
            final double temp = ((Double) obj).doubleValue();
            return temp != 0.0 && !Double.isNaN(temp);
        }
        else if (obj instanceof Integer) {
            return ((Integer) obj).doubleValue() != 0;
        }
        else if (obj instanceof Boolean) {
            return  ((Boolean) obj).booleanValue();
        }
        else if (obj instanceof String) {
            return !((String) obj).equals(EMPTYSTRING);
        }
        else if (obj instanceof DTMAxisIterator) {
            DTMAxisIterator iter = (DTMAxisIterator) obj;
            return iter.reset().next() != DTMAxisIterator.END;
        }
        else if (obj instanceof Node) {
            return true;
        }
        else if (obj instanceof DOM) {
            String temp = ((DOM) obj).getStringValue();
            return !temp.equals(EMPTYSTRING);
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(INVALID_ARGUMENT_ERR, className, "boolean()");
        }
        return false;
    }

    /**
     * XSLT Standard function substring(). Must take a double because of
     * conversions resulting into NaNs and rounding.
     */
    public static String substringF(String value, double start) {
        if (Double.isNaN(start))
            return(EMPTYSTRING);

            final int strlen = value.length();
            int istart = (int)Math.round(start) - 1;

        if (istart > strlen)
            return(EMPTYSTRING);
        if (istart < 1)
            istart = 0;
        try {
            return value.substring(istart);
        } catch (IndexOutOfBoundsException e) {
            runTimeError(RUN_TIME_INTERNAL_ERR, "substring()");
            return null;
        }
    }

    /**
     * XSLT Standard function substring(). Must take a double because of
     * conversions resulting into NaNs and rounding.
     */
    public static String substringF(String value, double start, double length) {
        if (Double.isInfinite(start) ||
            Double.isNaN(start) ||
            Double.isNaN(length))
            return(EMPTYSTRING);

            int istart = (int)Math.round(start) - 1;
        final int isum;
        if (Double.isInfinite(length))
            isum = Integer.MAX_VALUE;
        else
            isum = istart + (int)Math.round(length);

        final int strlen = value.length();
        if (isum < 0 || istart > strlen)
                return(EMPTYSTRING);

        if (istart < 0)
            istart = 0;

        try {
            if (isum > strlen)
                return value.substring(istart);
            else
                return value.substring(istart, isum);
        } catch (IndexOutOfBoundsException e) {
            runTimeError(RUN_TIME_INTERNAL_ERR, "substring()");
            return null;
        }
    }

    /**
     * XSLT Standard function substring-after().
     */
    public static String substring_afterF(String value, String substring) {
        final int index = value.indexOf(substring);
        if (index >= 0)
            return value.substring(index + substring.length());
        else
            return EMPTYSTRING;
    }

    /**
     * XSLT Standard function substring-before().
     */
    public static String substring_beforeF(String value, String substring) {
        final int index = value.indexOf(substring);
        if (index >= 0)
            return value.substring(0, index);
        else
            return EMPTYSTRING;
    }

    /**
     * XSLT Standard function translate().
     */
    public static String translateF(String value, String from, String to) {
        final int tol = to.length();
        final int froml = from.length();
        final int valuel = value.length();

        final StringBuilder result = threadLocalStringBuilder.get();
    result.setLength(0);
        for (int j, i = 0; i < valuel; i++) {
            final char ch = value.charAt(i);
            for (j = 0; j < froml; j++) {
                if (ch == from.charAt(j)) {
                    if (j < tol)
                        result.append(to.charAt(j));
                    break;
                }
            }
            if (j == froml)
                result.append(ch);
        }
        return result.toString();
    }

    /**
     * XSLT Standard function normalize-space().
     */
    public static String normalize_spaceF(int node, DOM dom) {
        return normalize_spaceF(dom.getStringValueX(node));
    }

    /**
     * XSLT Standard function normalize-space(string).
     */
    public static String normalize_spaceF(String value) {
        int i = 0, n = value.length();
        StringBuilder result = threadLocalStringBuilder.get();
    result.setLength(0);

        while (i < n && isWhiteSpace(value.charAt(i)))
            i++;

        while (true) {
            while (i < n && !isWhiteSpace(value.charAt(i))) {
                result.append(value.charAt(i++));
            }
            if (i == n)
                break;
            while (i < n && isWhiteSpace(value.charAt(i))) {
                i++;
            }
            if (i < n)
                result.append(' ');
        }
        return result.toString();
    }

    /**
     * XSLT Standard function generate-id().
     */
    public static String generate_idF(int node) {
        if (node > 0)
            // Only generate ID if node exists
            return "N" + node;
        else
            // Otherwise return an empty string
            return EMPTYSTRING;
    }

    /**
     * utility function for calls to local-name().
     */
    public static String getLocalName(String value) {
        int idx = value.lastIndexOf(':');
        if (idx >= 0) value = value.substring(idx + 1);
        idx = value.lastIndexOf('@');
        if (idx >= 0) value = value.substring(idx + 1);
        return(value);
    }

    /**
     * External functions that cannot be resolved are replaced with a call
     * to this method. This method will generate a runtime errors. A good
     * stylesheet checks whether the function exists using conditional
     * constructs, and never really tries to call it if it doesn't exist.
     * But simple stylesheets may result in a call to this method.
     * The compiler should generate a warning if it encounters a call to
     * an unresolved external function.
     */
    public static void unresolved_externalF(String name) {
        runTimeError(EXTERNAL_FUNC_ERR, name);
    }

    /**
     * Utility function to throw a runtime error on the use of an extension
     * function when the secure processing feature is set to true.
     */
    public static void unallowed_extension_functionF(String name) {
        runTimeError(UNALLOWED_EXTENSION_FUNCTION_ERR, name);
    }

    /**
     * Utility function to throw a runtime error on the use of an extension
     * element when the secure processing feature is set to true.
     */
    public static void unallowed_extension_elementF(String name) {
        runTimeError(UNALLOWED_EXTENSION_ELEMENT_ERR, name);
    }

    /**
     * Utility function to throw a runtime error for an unsupported element.
     *
     * This is only used in forward-compatibility mode, when the control flow
     * cannot be determined. In 1.0 mode, the error message is emitted at
     * compile time.
     */
    public static void unsupported_ElementF(String qname, boolean isExtension) {
        if (isExtension)
            runTimeError(UNSUPPORTED_EXT_ERR, qname);
        else
            runTimeError(UNSUPPORTED_XSL_ERR, qname);
    }

    /**
     * XSLT Standard function namespace-uri(node-set).
     */
    public static String namespace_uriF(DTMAxisIterator iter, DOM dom) {
        return namespace_uriF(iter.next(), dom);
    }

    /**
     * XSLT Standard function system-property(name)
     */
    public static String system_propertyF(String name) {
        if (name.equals("xsl:version"))
            return("1.0");
        if (name.equals("xsl:vendor"))
            return("Apache Software Foundation (Xalan XSLTC)");
        if (name.equals("xsl:vendor-url"))
            return("http://xml.apache.org/xalan-j");

        runTimeError(INVALID_ARGUMENT_ERR, name, "system-property()");
        return(EMPTYSTRING);
    }

    /**
     * XSLT Standard function namespace-uri().
     */
    public static String namespace_uriF(int node, DOM dom) {
        final String value = dom.getNodeName(node);
        final int colon = value.lastIndexOf(':');
        if (colon >= 0)
            return value.substring(0, colon);
        else
            return EMPTYSTRING;
    }

    /**
     * Implements the object-type() extension function.
     *
     * @see <a href="http://www.exslt.org/">EXSLT
     */
    public static String objectTypeF(Object obj)
    {
      if (obj instanceof String)
        return "string";
      else if (obj instanceof Boolean)
        return "boolean";
      else if (obj instanceof Number)
        return "number";
      else if (obj instanceof DOM)
        return "RTF";
      else if (obj instanceof DTMAxisIterator)
        return "node-set";
      else
        return "unknown";
    }

    /**
     * Implements the nodeset() extension function.
     */
    public static DTMAxisIterator nodesetF(Object obj) {
        if (obj instanceof DOM) {
           //final DOMAdapter adapter = (DOMAdapter) obj;
           final DOM dom = (DOM)obj;
           return new SingletonIterator(dom.getDocument(), true);
        }
        else if (obj instanceof DTMAxisIterator) {
           return (DTMAxisIterator) obj;
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(DATA_CONVERSION_ERR, "node-set", className);
            return null;
        }
    }

    //-- Begin utility functions

    private static boolean isWhiteSpace(char ch) {
        return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
    }

    private static boolean compareStrings(String lstring, String rstring,
                                          int op, DOM dom) {
        switch (op) {
    case Operators.EQ:
            return lstring.equals(rstring);

    case Operators.NE:
            return !lstring.equals(rstring);

    case Operators.GT:
            return numberF(lstring, dom) > numberF(rstring, dom);

    case Operators.LT:
            return numberF(lstring, dom) < numberF(rstring, dom);

    case Operators.GE:
            return numberF(lstring, dom) >= numberF(rstring, dom);

    case Operators.LE:
            return numberF(lstring, dom) <= numberF(rstring, dom);

        default:
            runTimeError(RUN_TIME_INTERNAL_ERR, "compare()");
            return false;
        }
    }

    /**
     * Utility function: node-set/node-set compare.
     */
    public static boolean compare(DTMAxisIterator left, DTMAxisIterator right,
                                  int op, DOM dom) {
        int lnode;
        left.reset();

        while ((lnode = left.next()) != DTMAxisIterator.END) {
            final String lvalue = dom.getStringValueX(lnode);

            int rnode;
            right.reset();
            while ((rnode = right.next()) != DTMAxisIterator.END) {
                // String value must be the same if both nodes are the same
                if (lnode == rnode) {
                    if (op == Operators.EQ) {
                        return true;
                    } else if (op == Operators.NE) {
                        continue;
                    }
                }
                if (compareStrings(lvalue, dom.getStringValueX(rnode), op,
                                   dom)) {
                    return true;
                }
            }
        }
        return false;
    }

    public static boolean compare(int node, DTMAxisIterator iterator,
                                  int op, DOM dom) {
        //iterator.reset();

        int rnode;
        String value;

        switch(op) {
    case Operators.EQ:
            rnode = iterator.next();
            if (rnode != DTMAxisIterator.END) {
                value = dom.getStringValueX(node);
                do {
                    if (node == rnode
                          || value.equals(dom.getStringValueX(rnode))) {
                       return true;
                    }
                } while ((rnode = iterator.next()) != DTMAxisIterator.END);
            }
            break;
    case Operators.NE:
            rnode = iterator.next();
            if (rnode != DTMAxisIterator.END) {
                value = dom.getStringValueX(node);
                do {
                    if (node != rnode
                          && !value.equals(dom.getStringValueX(rnode))) {
                        return true;
                    }
                } while ((rnode = iterator.next()) != DTMAxisIterator.END);
            }
            break;
    case Operators.LT:
            // Assume we're comparing document order here
            while ((rnode = iterator.next()) != DTMAxisIterator.END) {
                if (rnode > node) return true;
            }
            break;
    case Operators.GT:
            // Assume we're comparing document order here
            while ((rnode = iterator.next()) != DTMAxisIterator.END) {
                if (rnode < node) return true;
            }
            break;
        }
        return(false);
    }

    /**
     * Utility function: node-set/number compare.
     */
    public static boolean compare(DTMAxisIterator left, final double rnumber,
                                  final int op, DOM dom) {
        int node;
        //left.reset();

        switch (op) {
    case Operators.EQ:
            while ((node = left.next()) != DTMAxisIterator.END) {
                if (numberF(dom.getStringValueX(node), dom) == rnumber)
                    return true;
            }
            break;

    case Operators.NE:
            while ((node = left.next()) != DTMAxisIterator.END) {
                if (numberF(dom.getStringValueX(node), dom) != rnumber)
                    return true;
            }
            break;

    case Operators.GT:
            while ((node = left.next()) != DTMAxisIterator.END) {
                if (numberF(dom.getStringValueX(node), dom) > rnumber)
                    return true;
            }
            break;

    case Operators.LT:
            while ((node = left.next()) != DTMAxisIterator.END) {
                if (numberF(dom.getStringValueX(node), dom) < rnumber)
                    return true;
            }
            break;

    case Operators.GE:
            while ((node = left.next()) != DTMAxisIterator.END) {
                if (numberF(dom.getStringValueX(node), dom) >= rnumber)
                    return true;
            }
            break;

    case Operators.LE:
            while ((node = left.next()) != DTMAxisIterator.END) {
                if (numberF(dom.getStringValueX(node), dom) <= rnumber)
                    return true;
            }
            break;

        default:
            runTimeError(RUN_TIME_INTERNAL_ERR, "compare()");
        }

        return false;
    }

    /**
     * Utility function: node-set/string comparison.
     */
    public static boolean compare(DTMAxisIterator left, final String rstring,
                                  int op, DOM dom) {
        int node;
        //left.reset();
        while ((node = left.next()) != DTMAxisIterator.END) {
            if (compareStrings(dom.getStringValueX(node), rstring, op, dom)) {
                return true;
            }
        }
        return false;
    }


    public static boolean compare(Object left, Object right,
                                  int op, DOM dom)
    {
        boolean result = false;
        boolean hasSimpleArgs = hasSimpleType(left) && hasSimpleType(right);

    if (op != Operators.EQ && op != Operators.NE) {
            // If node-boolean comparison -> convert node to boolean
            if (left instanceof Node || right instanceof Node) {
                if (left instanceof Boolean) {
                    right = new Boolean(booleanF(right));
                    hasSimpleArgs = true;
                }
                if (right instanceof Boolean) {
                    left = new Boolean(booleanF(left));
                    hasSimpleArgs = true;
                }
            }

            if (hasSimpleArgs) {
                switch (op) {
        case Operators.GT:
                    return numberF(left, dom) > numberF(right, dom);

        case Operators.LT:
                    return numberF(left, dom) < numberF(right, dom);

        case Operators.GE:
                    return numberF(left, dom) >= numberF(right, dom);

        case Operators.LE:
                    return numberF(left, dom) <= numberF(right, dom);

        default:
                    runTimeError(RUN_TIME_INTERNAL_ERR, "compare()");
                }
            }
            // falls through
        }

        if (hasSimpleArgs) {
            if (left instanceof Boolean || right instanceof Boolean) {
                result = booleanF(left) == booleanF(right);
            }
            else if (left instanceof Double || right instanceof Double ||
                     left instanceof Integer || right instanceof Integer) {
                result = numberF(left, dom) == numberF(right, dom);
            }
            else { // compare them as strings
                result = stringF(left, dom).equals(stringF(right, dom));
            }

            if (op == Operators.NE) {
                result = !result;
            }
        }
        else {
            if (left instanceof Node) {
                left = new SingletonIterator(((Node)left).node);
            }
            if (right instanceof Node) {
                right = new SingletonIterator(((Node)right).node);
            }

            if (hasSimpleType(left) ||
                left instanceof DOM && right instanceof DTMAxisIterator) {
                // swap operands and operator
                final Object temp = right; right = left; left = temp;
                op = Operators.swapOp(op);
            }

            if (left instanceof DOM) {
                if (right instanceof Boolean) {
                    result = ((Boolean)right).booleanValue();
                    return result == (op == Operators.EQ);
                }

                final String sleft = ((DOM)left).getStringValue();

                if (right instanceof Number) {
                    result = ((Number)right).doubleValue() ==
                        stringToReal(sleft);
                }
                else if (right instanceof String) {
                    result = sleft.equals((String)right);
                }
                else if (right instanceof DOM) {
                    result = sleft.equals(((DOM)right).getStringValue());
                }

                if (op == Operators.NE) {
                    result = !result;
                }
                return result;
            }

            // Next, node-set/t for t in {real, string, node-set, result-tree}

            DTMAxisIterator iter = ((DTMAxisIterator)left).reset();

            if (right instanceof DTMAxisIterator) {
                result = compare(iter, (DTMAxisIterator)right, op, dom);
            }
            else if (right instanceof String) {
                result = compare(iter, (String)right, op, dom);
            }
            else if (right instanceof Number) {
                final double temp = ((Number)right).doubleValue();
                result = compare(iter, temp, op, dom);
            }
            else if (right instanceof Boolean) {
                boolean temp = ((Boolean)right).booleanValue();
                result = (iter.reset().next() != DTMAxisIterator.END) == temp;
            }
            else if (right instanceof DOM) {
                result = compare(iter, ((DOM)right).getStringValue(),
                                 op, dom);
            }
            else if (right == null) {
                return(false);
            }
            else {
                final String className = right.getClass().getName();
                runTimeError(INVALID_ARGUMENT_ERR, className, "compare()");
            }
        }
        return result;
    }

    /**
     * Utility function: used to test context node's language
     */
    public static boolean testLanguage(String testLang, DOM dom, int node) {
        // language for context node (if any)
        String nodeLang = dom.getLanguage(node);
        if (nodeLang == null)
            return(false);
        else
            nodeLang = nodeLang.toLowerCase();

        // compare context node's language agains test language
        testLang = testLang.toLowerCase();
        if (testLang.length() == 2) {
            return(nodeLang.startsWith(testLang));
        }
        else {
            return(nodeLang.equals(testLang));
        }
    }

    private static boolean hasSimpleType(Object obj) {
        return obj instanceof Boolean || obj instanceof Double ||
            obj instanceof Integer || obj instanceof String ||
            obj instanceof Node || obj instanceof DOM;
    }

    /**
     * Utility function: used in StringType to convert a string to a real.
     */
    public static double stringToReal(String s) {
        try {
            return Double.valueOf(s).doubleValue();
        }
        catch (NumberFormatException e) {
            return Double.NaN;
        }
    }

    /**
     * Utility function: used in StringType to convert a string to an int.
     */
    public static int stringToInt(String s) {
        try {
            return Integer.parseInt(s);
        }
        catch (NumberFormatException e) {
            return(-1); // ???
        }
    }

    private static final int DOUBLE_FRACTION_DIGITS = 340;
    private static final double lowerBounds = 0.001;
    private static final double upperBounds = 10000000;
    private static DecimalFormat defaultFormatter, xpathFormatter;
    private static String defaultPattern = "";

    static {
        NumberFormat f = NumberFormat.getInstance(Locale.getDefault());
        defaultFormatter = (f instanceof DecimalFormat) ?
            (DecimalFormat) f : new DecimalFormat();
        // Set max fraction digits so that truncation does not occur. Setting
        // the max to Integer.MAX_VALUE may cause problems with some JDK's.
        defaultFormatter.setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);
        defaultFormatter.setMinimumFractionDigits(0);
        defaultFormatter.setMinimumIntegerDigits(1);
        defaultFormatter.setGroupingUsed(false);

        // This formatter is used to convert numbers according to the XPath
        // 1.0 syntax which ignores locales (http://www.w3.org/TR/xpath#NT-Number)
        xpathFormatter = new DecimalFormat("",
            new DecimalFormatSymbols(Locale.US));
        xpathFormatter.setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);
        xpathFormatter.setMinimumFractionDigits(0);
        xpathFormatter.setMinimumIntegerDigits(1);
        xpathFormatter.setGroupingUsed(false);
    }

    /**
     * Utility function: used in RealType to convert a real to a string.
     * Removes the decimal if null. Uses a specialized formatter object
     * for very large and very small numbers that ignores locales, thus
     * using always using "." as a decimal separator.
     */
    public static String realToString(double d) {
        final double m = Math.abs(d);
        if ((m >= lowerBounds) && (m < upperBounds)) {
            final String result = Double.toString(d);
            final int length = result.length();
            // Remove leading zeros.
            if ((result.charAt(length-2) == '.') &&
                (result.charAt(length-1) == '0'))
                return result.substring(0, length-2);
            else
                return result;
        }
        else {
            if (Double.isNaN(d) || Double.isInfinite(d))
                return(Double.toString(d));

            //Convert -0.0 to +0.0 other values remains the same
            d = d + 0.0;

            // Use the XPath formatter to ignore locales
            StringBuffer result = threadLocalStringBuffer.get();
            result.setLength(0);
            xpathFormatter.format(d, result, _fieldPosition);
            return result.toString();
        }
    }

    /**
     * Utility function: used in RealType to convert a real to an integer
     */
    public static int realToInt(double d) {
        return (int)d;
    }

    /**
     * Utility function: used to format/adjust  a double to a string. The
     * DecimalFormat object comes from the 'formatSymbols' hashtable in
     * AbstractTranslet.
     */
    private static FieldPosition _fieldPosition = new FieldPosition(0);

    public static String formatNumber(double number, String pattern,
                                      DecimalFormat formatter) {
        // bugzilla fix 12813
        if (formatter == null) {
            formatter = defaultFormatter;
        }
        try {
            StringBuffer result = threadLocalStringBuffer.get();
        result.setLength(0);
            if (pattern != defaultPattern) {
                formatter.applyLocalizedPattern(pattern);
            }
        formatter.format(number, result, _fieldPosition);
            return result.toString();
        }
        catch (IllegalArgumentException e) {
            runTimeError(FORMAT_NUMBER_ERR, Double.toString(number), pattern);
            return(EMPTYSTRING);
        }
    }

    /**
     * Utility function: used to convert references to node-sets. If the
     * obj is an instanceof Node then create a singleton iterator.
     */
    public static DTMAxisIterator referenceToNodeSet(Object obj) {
        // Convert var/param -> node
        if (obj instanceof Node) {
            return(new SingletonIterator(((Node)obj).node));
        }
        // Convert var/param -> node-set
        else if (obj instanceof DTMAxisIterator) {
            return(((DTMAxisIterator)obj).cloneIterator().reset());
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(DATA_CONVERSION_ERR, className, "node-set");
            return null;
        }
    }

    /**
     * Utility function: used to convert reference to org.w3c.dom.NodeList.
     */
    public static NodeList referenceToNodeList(Object obj, DOM dom) {
        if (obj instanceof Node || obj instanceof DTMAxisIterator) {
            DTMAxisIterator iter = referenceToNodeSet(obj);
            return dom.makeNodeList(iter);
        }
        else if (obj instanceof DOM) {
          dom = (DOM)obj;
          return dom.makeNodeList(DTMDefaultBase.ROOTNODE);
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(DATA_CONVERSION_ERR, className,
                "org.w3c.dom.NodeList");
            return null;
        }
    }

    /**
     * Utility function: used to convert reference to org.w3c.dom.Node.
     */
    public static org.w3c.dom.Node referenceToNode(Object obj, DOM dom) {
        if (obj instanceof Node || obj instanceof DTMAxisIterator) {
            DTMAxisIterator iter = referenceToNodeSet(obj);
            return dom.makeNode(iter);
        }
        else if (obj instanceof DOM) {
          dom = (DOM)obj;
          DTMAxisIterator iter = dom.getChildren(DTMDefaultBase.ROOTNODE);
          return dom.makeNode(iter);
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(DATA_CONVERSION_ERR, className, "org.w3c.dom.Node");
            return null;
        }
    }

    /**
     * Utility function: used to convert reference to long.
     */
    public static long referenceToLong(Object obj) {
        if (obj instanceof Number) {
            return ((Number) obj).longValue();    // handles Integer and Double
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(DATA_CONVERSION_ERR, className, Long.TYPE);
            return 0;
        }
    }

    /**
     * Utility function: used to convert reference to double.
     */
    public static double referenceToDouble(Object obj) {
        if (obj instanceof Number) {
            return ((Number) obj).doubleValue();   // handles Integer and Double
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(DATA_CONVERSION_ERR, className, Double.TYPE);
            return 0;
        }
    }

    /**
     * Utility function: used to convert reference to boolean.
     */
    public static boolean referenceToBoolean(Object obj) {
        if (obj instanceof Boolean) {
            return ((Boolean) obj).booleanValue();
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(DATA_CONVERSION_ERR, className, Boolean.TYPE);
            return false;
        }
    }

    /**
     * Utility function: used to convert reference to String.
     */
    public static String referenceToString(Object obj, DOM dom) {
        if (obj instanceof String) {
            return (String) obj;
        }
        else if (obj instanceof DTMAxisIterator) {
            return dom.getStringValueX(((DTMAxisIterator)obj).reset().next());
        }
        else if (obj instanceof Node) {
            return dom.getStringValueX(((Node)obj).node);
        }
        else if (obj instanceof DOM) {
            return ((DOM) obj).getStringValue();
        }
        else {
            final String className = obj.getClass().getName();
            runTimeError(DATA_CONVERSION_ERR, className, String.class);
            return null;
        }
    }

    /**
     * Utility function used to convert a w3c Node into an internal DOM iterator.
     */
    public static DTMAxisIterator node2Iterator(org.w3c.dom.Node node,
        Translet translet, DOM dom)
    {
        final org.w3c.dom.Node inNode = node;
        // Create a dummy NodeList which only contains the given node to make
        // use of the nodeList2Iterator() interface.
        org.w3c.dom.NodeList nodelist = new org.w3c.dom.NodeList() {
            public int getLength() {
                return 1;
            }

            public org.w3c.dom.Node item(int index) {
                if (index == 0)
                    return inNode;
                else
                    return null;
            }
        };

        return nodeList2Iterator(nodelist, translet, dom);
    }

    /**
     * In a perfect world, this would be the implementation for
     * nodeList2Iterator. In reality, though, this causes a
     * ClassCastException in getDTMHandleFromNode because SAXImpl is
     * not an instance of DOM2DTM. So we use the more lengthy
     * implementation below until this issue has been addressed.
     *
     * @see org.apache.xml.dtm.ref.DTMManagerDefault#getDTMHandleFromNode
     */
    private static DTMAxisIterator nodeList2IteratorUsingHandleFromNode(
                                        org.w3c.dom.NodeList nodeList,
                                        Translet translet, DOM dom)
    {
        final int n = nodeList.getLength();
        final int[] dtmHandles = new int[n];
        DTMManager dtmManager = null;
        if (dom instanceof MultiDOM)
            dtmManager = ((MultiDOM) dom).getDTMManager();
        for (int i = 0; i < n; ++i) {
            org.w3c.dom.Node node = nodeList.item(i);
            int handle;
            if (dtmManager != null) {
                handle = dtmManager.getDTMHandleFromNode(node);
            }
            else if (node instanceof DTMNodeProxy
                     && ((DTMNodeProxy) node).getDTM() == dom) {
                handle = ((DTMNodeProxy) node).getDTMNodeNumber();
            }
            else {
                runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM");
                return null;
            }
            dtmHandles[i] = handle;
            System.out.println("Node " + i + " has handle 0x" +
                               Integer.toString(handle, 16));
        }
        return new ArrayNodeListIterator(dtmHandles);
    }

    /**
     * Utility function used to convert a w3c NodeList into a internal
     * DOM iterator.
     */
    public static DTMAxisIterator nodeList2Iterator(
                                        org.w3c.dom.NodeList nodeList,
                                        Translet translet, DOM dom)
    {
        // First pass: build w3c DOM for all nodes not proxied from our DOM.
        //
        // Notice: this looses some (esp. parent) context for these nodes,
        // so some way to wrap the original nodes inside a DTMAxisIterator
        // might be preferable in the long run.
        int n = 0; // allow for change in list length, just in case.
        Document doc = null;
        DTMManager dtmManager = null;
        int[] proxyNodes = new int[nodeList.getLength()];
        if (dom instanceof MultiDOM)
            dtmManager = ((MultiDOM) dom).getDTMManager();
        for (int i = 0; i < nodeList.getLength(); ++i) {
            org.w3c.dom.Node node = nodeList.item(i);
            if (node instanceof DTMNodeProxy) {
                DTMNodeProxy proxy = (DTMNodeProxy)node;
                DTM nodeDTM = proxy.getDTM();
                int handle = proxy.getDTMNodeNumber();
                boolean isOurDOM = (nodeDTM == dom);
                if (!isOurDOM && dtmManager != null) {
                    try {
                        isOurDOM = (nodeDTM == dtmManager.getDTM(handle));
                    }
                    catch (ArrayIndexOutOfBoundsException e) {
                        // invalid node handle, so definitely not our doc
                    }
                }
                if (isOurDOM) {
                    proxyNodes[i] = handle;
                    ++n;
                    continue;
                }
            }
            proxyNodes[i] = DTM.NULL;
            int nodeType = node.getNodeType();
            if (doc == null) {
                if (dom instanceof MultiDOM == false) {
                    runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM");
                    return null;
                }
                try {
                    AbstractTranslet at = (AbstractTranslet) translet;
                    doc = at.newDocument("", "__top__");
                }
                catch (javax.xml.parsers.ParserConfigurationException e) {
                    runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage());
                    return null;
                }
            }
            // Use one dummy element as container for each node of the
            // list. That way, it is easier to detect resp. avoid
            // funny things which change the number of nodes,
            // e.g. auto-concatenation of text nodes.
            Element mid;
            switch (nodeType) {
                case org.w3c.dom.Node.ELEMENT_NODE:
                case org.w3c.dom.Node.TEXT_NODE:
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                case org.w3c.dom.Node.COMMENT_NODE:
                case org.w3c.dom.Node.ENTITY_REFERENCE_NODE:
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    mid = doc.createElementNS(null, "__dummy__");
                    mid.appendChild(doc.importNode(node, true));
                    doc.getDocumentElement().appendChild(mid);
                    ++n;
                    break;
                case org.w3c.dom.Node.ATTRIBUTE_NODE:
                    // The mid element also serves as a container for
                    // attributes, avoiding problems with conflicting
                    // attributes or node order.
                    mid = doc.createElementNS(null, "__dummy__");
                    mid.setAttributeNodeNS((Attr)doc.importNode(node, true));
                    doc.getDocumentElement().appendChild(mid);
                    ++n;
                    break;
                default:
                    // Better play it safe for all types we aren't sure we know
                    // how to deal with.
                    runTimeError(RUN_TIME_INTERNAL_ERR,
                                 "Don't know how to convert node type "
                                 + nodeType);
            }
        }

        // w3cDOM -> DTM -> DOMImpl
        DTMAxisIterator iter = null, childIter = null, attrIter = null;
        if (doc != null) {
            final MultiDOM multiDOM = (MultiDOM) dom;
            DOM idom = (DOM)dtmManager.getDTM(new DOMSource(doc), false,
                                              null, true, false);
            // Create DOMAdapter and register with MultiDOM
            DOMAdapter domAdapter = new DOMAdapter(idom,
                translet.getNamesArray(),
                translet.getUrisArray(),
                translet.getTypesArray(),
                translet.getNamespaceArray());
            multiDOM.addDOMAdapter(domAdapter);

            DTMAxisIterator iter1 = idom.getAxisIterator(Axis.CHILD);
            DTMAxisIterator iter2 = idom.getAxisIterator(Axis.CHILD);
            iter = new AbsoluteIterator(
                new StepIterator(iter1, iter2));

            iter.setStartNode(DTMDefaultBase.ROOTNODE);

            childIter = idom.getAxisIterator(Axis.CHILD);
            attrIter = idom.getAxisIterator(Axis.ATTRIBUTE);
        }

        // Second pass: find DTM handles for every node in the list.
        int[] dtmHandles = new int[n];
        n = 0;
        for (int i = 0; i < nodeList.getLength(); ++i) {
            if (proxyNodes[i] != DTM.NULL) {
                dtmHandles[n++] = proxyNodes[i];
                continue;
            }
            org.w3c.dom.Node node = nodeList.item(i);
            DTMAxisIterator iter3 = null;
            int nodeType = node.getNodeType();
            switch (nodeType) {
                case org.w3c.dom.Node.ELEMENT_NODE:
                case org.w3c.dom.Node.TEXT_NODE:
                case org.w3c.dom.Node.CDATA_SECTION_NODE:
                case org.w3c.dom.Node.COMMENT_NODE:
                case org.w3c.dom.Node.ENTITY_REFERENCE_NODE:
                case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                    iter3 = childIter;
                    break;
                case org.w3c.dom.Node.ATTRIBUTE_NODE:
                    iter3 = attrIter;
                    break;
                default:
                    // Should not happen, as first run should have got all these
                    throw new InternalRuntimeError("Mismatched cases");
            }
            if (iter3 != null) {
                iter3.setStartNode(iter.next());
                dtmHandles[n] = iter3.next();
                // For now, play it self and perform extra checks:
                if (dtmHandles[n] == DTMAxisIterator.END)
                    throw new InternalRuntimeError("Expected element missing at " + i);
                if (iter3.next() != DTMAxisIterator.END)
                    throw new InternalRuntimeError("Too many elements at " + i);
                ++n;
            }
        }
        if (n != dtmHandles.length)
            throw new InternalRuntimeError("Nodes lost in second pass");

        return new ArrayNodeListIterator(dtmHandles);
    }

    /**
     * Utility function used to convert references to DOMs.
     */
    public static DOM referenceToResultTree(Object obj) {
        try {
            return ((DOM) obj);
        }
        catch (IllegalArgumentException e) {
            final String className = obj.getClass().getName();
            runTimeError(DATA_CONVERSION_ERR, "reference", className);
            return null;
        }
    }

    /**
     * Utility function: used with nth position filters to convert a sequence
     * of nodes to just one single node (the one at position n).
     */
    public static DTMAxisIterator getSingleNode(DTMAxisIterator iterator) {
        int node = iterator.next();
        return(new SingletonIterator(node));
    }

    /**
     * Utility function: used in xsl:copy.
     */
    private static char[] _characterArray = new char[32];

    public static void copy(Object obj,
                            SerializationHandler handler,
                            int node,
                            DOM dom) {
        try {
            if (obj instanceof DTMAxisIterator)
      {
                DTMAxisIterator iter = (DTMAxisIterator) obj;
                dom.copy(iter.reset(), handler);
            }
            else if (obj instanceof Node) {
                dom.copy(((Node) obj).node, handler);
            }
            else if (obj instanceof DOM) {
                //((DOM)obj).copy(((com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase)((DOMAdapter)obj).getDOMImpl()).getDocument(), handler);
                DOM newDom = (DOM)obj;
                newDom.copy(newDom.getDocument(), handler);
            }
            else {
                String string = obj.toString();         // or call stringF()
                final int length = string.length();
                if (length > _characterArray.length)
                    _characterArray = new char[length];
                string.getChars(0, length, _characterArray, 0);
                handler.characters(_characterArray, 0, length);
            }
        }
        catch (SAXException e) {
            runTimeError(RUN_TIME_COPY_ERR);
        }
    }

    /**
     * Utility function to check if xsl:attribute has a valid qname
     * This method should only be invoked if the name attribute is an AVT
     */
    public static void checkAttribQName(String name) {
        final int firstOccur = name.indexOf(":");
        final int lastOccur = name.lastIndexOf(":");
        final String localName = name.substring(lastOccur + 1);

        if (firstOccur > 0) {
            final String newPrefix = name.substring(0, firstOccur);

            if (firstOccur != lastOccur) {
               final String oriPrefix = name.substring(firstOccur+1, lastOccur);
                if (!XML11Char.isXML11ValidNCName(oriPrefix)) {
                    // even though the orignal prefix is ignored, it should still get checked for valid NCName
                    runTimeError(INVALID_QNAME_ERR,oriPrefix+":"+localName);
                }
            }

            // prefix must be a valid NCName
            if (!XML11Char.isXML11ValidNCName(newPrefix)) {
                runTimeError(INVALID_QNAME_ERR,newPrefix+":"+localName);
            }
        }

        // local name must be a valid NCName and must not be XMLNS
        if ((!XML11Char.isXML11ValidNCName(localName))||(localName.equals(Constants.XMLNS_PREFIX))) {
            runTimeError(INVALID_QNAME_ERR,localName);
        }
    }

    /**
     * Utility function to check if a name is a valid ncname
     * This method should only be invoked if the attribute value is an AVT
     */
    public static void checkNCName(String name) {
        if (!XML11Char.isXML11ValidNCName(name)) {
            runTimeError(INVALID_NCNAME_ERR,name);
        }
    }

    /**
     * Utility function to check if a name is a valid qname
     * This method should only be invoked if the attribute value is an AVT
     */
    public static void checkQName(String name) {
        if (!XML11Char.isXML11ValidQName(name)) {
            runTimeError(INVALID_QNAME_ERR,name);
        }
    }

    /**
     * Utility function for the implementation of xsl:element.
     */
    public static String startXslElement(String qname, String namespace,
        SerializationHandler handler, DOM dom, int node)
    {
        try {
            // Get prefix from qname
            String prefix;
            final int index = qname.indexOf(':');

            if (index > 0) {
                prefix = qname.substring(0, index);

                // Handle case when prefix is not known at compile time
                if (namespace == null || namespace.length() == 0) {
                    try {
                        // not sure if this line of code ever works
                        namespace = dom.lookupNamespace(node, prefix);
                    }
                    catch(RuntimeException e) {
                        handler.flushPending();  // need to flush or else can't get namespacemappings
                        NamespaceMappings nm = handler.getNamespaceMappings();
                        namespace = nm.lookupNamespace(prefix);
                        if (namespace == null) {
                            runTimeError(NAMESPACE_PREFIX_ERR,prefix);
                        }
                    }
                }

                handler.startElement(namespace, qname.substring(index+1),
                                         qname);
                handler.namespaceAfterStartElement(prefix, namespace);
            }
            else {
                // Need to generate a prefix?
                if (namespace != null && namespace.length() > 0) {
                    prefix = generatePrefix();
                    qname = prefix + ':' + qname;
                    handler.startElement(namespace, qname, qname);
                    handler.namespaceAfterStartElement(prefix, namespace);
                }
                else {
                    handler.startElement(null, null, qname);
                }
            }
        }
        catch (SAXException e) {
            throw new RuntimeException(e.getMessage());
        }

        return qname;
    }

    /**
     * This function is used in the execution of xsl:element
     */
    public static String getPrefix(String qname) {
        final int index = qname.indexOf(':');
        return (index > 0) ? qname.substring(0, index) : null;
    }

    /**
     * This function is used in the execution of xsl:element
     */
    private static int prefixIndex = 0;

    public static String generatePrefix() {
        synchronized (BasisLibrary.class) {
            return ("ns" + prefixIndex++);
        }
    }

    public static final String RUN_TIME_INTERNAL_ERR =
                                           "RUN_TIME_INTERNAL_ERR";
    public static final String RUN_TIME_COPY_ERR =
                                           "RUN_TIME_COPY_ERR";
    public static final String DATA_CONVERSION_ERR =
                                           "DATA_CONVERSION_ERR";
    public static final String EXTERNAL_FUNC_ERR =
                                           "EXTERNAL_FUNC_ERR";
    public static final String EQUALITY_EXPR_ERR =
                                           "EQUALITY_EXPR_ERR";
    public static final String INVALID_ARGUMENT_ERR =
                                           "INVALID_ARGUMENT_ERR";
    public static final String FORMAT_NUMBER_ERR =
                                           "FORMAT_NUMBER_ERR";
    public static final String ITERATOR_CLONE_ERR =
                                           "ITERATOR_CLONE_ERR";
    public static final String AXIS_SUPPORT_ERR =
                                           "AXIS_SUPPORT_ERR";
    public static final String TYPED_AXIS_SUPPORT_ERR =
                                           "TYPED_AXIS_SUPPORT_ERR";
    public static final String STRAY_ATTRIBUTE_ERR =
                                           "STRAY_ATTRIBUTE_ERR";
    public static final String STRAY_NAMESPACE_ERR =
                                           "STRAY_NAMESPACE_ERR";
    public static final String NAMESPACE_PREFIX_ERR =
                                           "NAMESPACE_PREFIX_ERR";
    public static final String DOM_ADAPTER_INIT_ERR =
                                           "DOM_ADAPTER_INIT_ERR";
    public static final String PARSER_DTD_SUPPORT_ERR =
                                           "PARSER_DTD_SUPPORT_ERR";
    public static final String NAMESPACES_SUPPORT_ERR =
                                           "NAMESPACES_SUPPORT_ERR";
    public static final String CANT_RESOLVE_RELATIVE_URI_ERR =
                                           "CANT_RESOLVE_RELATIVE_URI_ERR";
    public static final String UNSUPPORTED_XSL_ERR =
                                           "UNSUPPORTED_XSL_ERR";
    public static final String UNSUPPORTED_EXT_ERR =
                                           "UNSUPPORTED_EXT_ERR";
    public static final String UNKNOWN_TRANSLET_VERSION_ERR =
                                           "UNKNOWN_TRANSLET_VERSION_ERR";
    public static final String INVALID_QNAME_ERR = "INVALID_QNAME_ERR";
    public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR";
    public static final String UNALLOWED_EXTENSION_FUNCTION_ERR = "UNALLOWED_EXTENSION_FUNCTION_ERR";
    public static final String UNALLOWED_EXTENSION_ELEMENT_ERR = "UNALLOWED_EXTENSION_ELEMENT_ERR";

    // All error messages are localized and are stored in resource bundles.
    private static ResourceBundle m_bundle;

    public final static String ERROR_MESSAGES_KEY = "error-messages";

    static {
        String resource = "com.sun.org.apache.xalan.internal.xsltc.runtime.ErrorMessages";
        m_bundle = SecuritySupport.getResourceBundle(resource);
    }

    /**
     * Print a run-time error message.
     */
    public static void runTimeError(String code) {
        throw new RuntimeException(m_bundle.getString(code));
    }

    public static void runTimeError(String code, Object[] args) {
        final String message = MessageFormat.format(m_bundle.getString(code),
                                                    args);
        throw new RuntimeException(message);
    }

    public static void runTimeError(String code, Object arg0) {
        runTimeError(code, new Object[]{ arg0 } );
    }

    public static void runTimeError(String code, Object arg0, Object arg1) {
        runTimeError(code, new Object[]{ arg0, arg1 } );
    }

    public static void consoleOutput(String msg) {
        System.out.println(msg);
    }

    /**
     * Replace a certain character in a string with a new substring.
     */
    public static String replace(String base, char ch, String str) {
        return (base.indexOf(ch) < 0) ? base :
            replace(base, String.valueOf(ch), new String[] { str });
    }

    public static String replace(String base, String delim, String[] str) {
        final int len = base.length();
        final StringBuilder result = threadLocalStringBuilder.get();
        result.setLength(0);

        for (int i = 0; i < len; i++) {
            final char ch = base.charAt(i);
            final int k = delim.indexOf(ch);

            if (k >= 0) {
                result.append(str[k]);
            }
            else {
                result.append(ch);
            }
        }
        return result.toString();
    }


    /**
     * Utility method to allow setting parameters of the form
     * {namespaceuri}localName
     * which get mapped to an instance variable in the class
     * Hence  a parameter of the form "{http://foo.bar}xyz"
     * will be replaced with the corresponding values
     * by the BasisLibrary's utility method mapQNametoJavaName
     * and thus get mapped to legal java variable names
     */
    public static String mapQNameToJavaName (String base ) {
       return replace(base, ".-:/{}?#%*",
                      new String[] { "$dot$", "$dash$" ,"$colon$", "$slash$",
                                     "","$colon$","$ques$","$hash$","$per$",
                                     "$aster$"});

    }

    //-- End utility functions
}

Other Java examples (source code examples)

Here is a short list of links related to this Java BasisLibrary.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.