com.amalto.commons.core.utils.xpath.ri.JXPathContextReferenceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.amalto.commons.core.utils.xpath.ri.JXPathContextReferenceImpl.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.amalto.commons.core.utils.xpath.ri;

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.amalto.commons.core.utils.xpath.CompiledExpression;
import com.amalto.commons.core.utils.xpath.JXPathContext;
import com.amalto.commons.core.utils.xpath.JXPathException;
import com.amalto.commons.core.utils.xpath.Pointer;
import com.amalto.commons.core.utils.xpath.ri.compiler.Expression;
import com.amalto.commons.core.utils.xpath.ri.compiler.TreeCompiler;

/**
 * The reference implementation of JXPathContext.
 *
 * @author Dmitri Plotnikov
 * @version $Revision: 670727 $ $Date: 2008-06-23 15:10:38 -0500 (Mon, 23 Jun 2008) $
 */
public class JXPathContextReferenceImpl extends JXPathContext {

    /**
     * Change this to <code>false</code> to disable soft caching of
     * CompiledExpressions.
     */
    public static final boolean USE_SOFT_CACHE = true;

    private static final Compiler COMPILER = new TreeCompiler();
    private static Map compiled = new HashMap();
    private static int cleanupCount = 0;

    //    private static NodePointerFactory[] nodeFactoryArray = null;
    // The frequency of the cache cleanup
    private static final int CLEANUP_THRESHOLD = 500;
    //    private static final Vector nodeFactories = new Vector();

    //    static {
    //        nodeFactories.add(new CollectionPointerFactory());
    //        nodeFactories.add(new BeanPointerFactory());
    //        nodeFactories.add(new DynamicPointerFactory());
    //        nodeFactories.add(new VariablePointerFactory());
    //
    //        // DOM  factory is only registered if DOM support is on the classpath
    //        Object domFactory = allocateConditionally(
    //                "org.apache.commons.jxpath.ri.model.dom.DOMPointerFactory",
    //                "org.w3c.dom.Node");
    //        if (domFactory != null) {
    //            nodeFactories.add(domFactory);
    //        }
    //
    //        // JDOM  factory is only registered if JDOM is on the classpath
    //        Object jdomFactory = allocateConditionally(
    //                "org.apache.commons.jxpath.ri.model.jdom.JDOMPointerFactory",
    //                "org.jdom.Document");
    //        if (jdomFactory != null) {
    //            nodeFactories.add(jdomFactory);
    //        }
    //
    //        // DynaBean factory is only registered if BeanUtils are on the classpath
    //        Object dynaBeanFactory =
    //            allocateConditionally(
    //                "org.apache.commons.jxpath.ri.model.dynabeans."
    //                    + "DynaBeanPointerFactory",
    //                "org.apache.commons.beanutils.DynaBean");
    //        if (dynaBeanFactory != null) {
    //            nodeFactories.add(dynaBeanFactory);
    //        }
    //
    //        nodeFactories.add(new ContainerPointerFactory());
    //        createNodeFactoryArray();
    //    }
    //
    //    /**
    //     * Create the default node factory array.
    //     */
    //    private static synchronized void createNodeFactoryArray() {
    //        if (nodeFactoryArray == null) {
    //            nodeFactoryArray =
    //                (NodePointerFactory[]) nodeFactories.
    //                    toArray(new NodePointerFactory[nodeFactories.size()]);
    //            Arrays.sort(nodeFactoryArray, new Comparator() {
    //                public int compare(Object a, Object b) {
    //                    int orderA = ((NodePointerFactory) a).getOrder();
    //                    int orderB = ((NodePointerFactory) b).getOrder();
    //                    return orderA - orderB;
    //                }
    //            });
    //        }
    //    }
    //
    //    /**
    //     * Call this with a custom NodePointerFactory to add support for
    //     * additional types of objects.  Make sure the factory returns
    //     * a name that puts it in the right position on the list of factories.
    //     * @param factory NodePointerFactory to add
    //     */
    //    public static void addNodePointerFactory(NodePointerFactory factory) {
    //        synchronized (nodeFactories) {
    //            nodeFactories.add(factory);
    //            nodeFactoryArray = null;
    //        }
    //    }
    //
    //    /**
    //     * Get the registered NodePointerFactories.
    //     * @return NodePointerFactory[]
    //     */
    //    public static NodePointerFactory[] getNodePointerFactories() {
    //        return nodeFactoryArray;
    //    }

    /** Namespace resolver */
    //    protected NamespaceResolver namespaceResolver;

    private Pointer rootPointer;
    private Pointer contextPointer;

    /**
     * Create a new JXPathContextReferenceImpl.
     * @param parentContext parent context
     * @param contextBean Object
     */
    protected JXPathContextReferenceImpl(JXPathContext parentContext, Object contextBean) {
        this(parentContext, contextBean, null);
    }

    /**
     * Create a new JXPathContextReferenceImpl.
     * @param parentContext parent context
     * @param contextBean Object
     * @param contextPointer context pointer
     */
    public JXPathContextReferenceImpl(JXPathContext parentContext, Object contextBean, Pointer contextPointer) {
        super(parentContext, contextBean);

        //        synchronized (nodeFactories) {
        //            createNodeFactoryArray();
        //        }

        //        if (contextPointer != null) {
        //            this.contextPointer = contextPointer;
        //            this.rootPointer =
        //                NodePointer.newNodePointer(
        //                    new QName(null, "root"),
        //                    contextPointer.getRootNode(),
        //                    getLocale());
        //        }
        //        else {
        //            this.contextPointer =
        //                NodePointer.newNodePointer(
        //                    new QName(null, "root"),
        //                    contextBean,
        //                    getLocale());
        //            this.rootPointer = this.contextPointer;
        //        }
        //
        //        NamespaceResolver parentNR = null;
        //        if (parentContext instanceof JXPathContextReferenceImpl) {
        //            parentNR = ((JXPathContextReferenceImpl) parentContext).getNamespaceResolver();
        //        }
        //        namespaceResolver = new NamespaceResolver(parentNR);
        //        namespaceResolver
        //                .setNamespaceContextPointer((NodePointer) this.contextPointer);
    }

    /**
     * Returns a static instance of TreeCompiler.
     *
     * Override this to return an alternate compiler.
     * @return Compiler
     */
    protected Compiler getCompiler() {
        return COMPILER;
    }

    protected CompiledExpression compilePath(String xpath) {
        return new JXPathCompiledExpression(xpath, compileExpression(xpath));
    }

    /**
     * Compile the given expression.
     * @param xpath to compile
     * @return Expression
     */
    private Expression compileExpression(String xpath) {
        Expression expr;

        synchronized (compiled) {
            if (USE_SOFT_CACHE) {
                expr = null;
                SoftReference ref = (SoftReference) compiled.get(xpath);
                if (ref != null) {
                    expr = (Expression) ref.get();
                }
            } else {
                expr = (Expression) compiled.get(xpath);
            }
        }

        if (expr != null) {
            return expr;
        }

        expr = (Expression) Parser.parseExpression(xpath, getCompiler());

        synchronized (compiled) {
            if (USE_SOFT_CACHE) {
                if (cleanupCount++ >= CLEANUP_THRESHOLD) {
                    Iterator it = compiled.entrySet().iterator();
                    while (it.hasNext()) {
                        Entry me = (Entry) it.next();
                        if (((SoftReference) me.getValue()).get() == null) {
                            it.remove();
                        }
                    }
                    cleanupCount = 0;
                }
                compiled.put(xpath, new SoftReference(expr));
            } else {
                compiled.put(xpath, expr);
            }
        }

        return expr;
    }

    //    /**
    //     * Traverses the xpath and returns the resulting object. Primitive
    //     * types are wrapped into objects.
    //     * @param xpath expression
    //     * @return Object found
    //     */
    //    public Object getValue(String xpath) {
    //        Expression expression = compileExpression(xpath);
    //// TODO: (work in progress) - trying to integrate with Xalan
    ////        Object ctxNode = getNativeContextNode(expression);
    ////        if (ctxNode != null) {
    ////            System.err.println("WILL USE XALAN: " + xpath);
    ////            CachedXPathAPI api = new CachedXPathAPI();
    ////            try {
    ////                if (expression instanceof Path) {
    ////                    Node node = api.selectSingleNode((Node)ctxNode, xpath);
    ////                    System.err.println("NODE: " + node);
    ////                    if (node == null) {
    ////                        return null;
    ////                    }
    ////                    return new DOMNodePointer(node, null).getValue();
    ////                }
    ////                else {
    ////                    XObject object = api.eval((Node)ctxNode, xpath);
    ////                    switch (object.getType()) {
    ////                    case XObject.CLASS_STRING: return object.str();
    ////                    case XObject.CLASS_NUMBER: return new Double(object.num());
    ////                    case XObject.CLASS_BOOLEAN: return new Boolean(object.bool());
    ////                    default:
    ////                        System.err.println("OTHER TYPE: " + object.getTypeString());
    ////                    }
    ////                }
    ////            }
    ////            catch (TransformerException e) {
    ////                // TODO Auto-generated catch block
    ////                e.printStackTrace();
    ////            }
    ////            return
    ////        }
    //
    //        return getValue(xpath, expression);
    //    }
    //
    ////    private Object getNativeContextNode(Expression expression) {
    ////        Object node = getNativeContextNode(getContextBean());
    ////        if (node == null) {
    ////            return null;
    ////        }
    ////
    ////        List vars = expression.getUsedVariables();
    ////        if (vars != null) {
    ////            return null;
    ////        }
    ////
    ////        return node;
    ////    }
    //
    ////    private Object getNativeContextNode(Object bean) {
    ////        if (bean instanceof Number || bean instanceof String || bean instanceof Boolean) {
    ////            return bean;
    ////        }
    ////        if (bean instanceof Node) {
    ////            return (Node)bean;
    ////        }
    ////
    ////        if (bean instanceof Container) {
    ////            bean = ((Container)bean).getValue();
    ////            return getNativeContextNode(bean);
    ////        }
    ////
    ////        return null;
    ////    }
    //
    //    /**
    //     * Get the value indicated.
    //     * @param xpath String
    //     * @param expr Expression
    //     * @return Object
    //     */
    //    public Object getValue(String xpath, Expression expr) {
    //        Object result = expr.computeValue(getEvalContext());
    //        if (result == null) {
    //            if (expr instanceof Path && !isLenient()) {
    //                throw new JXPathNotFoundException("No value for xpath: "
    //                        + xpath);
    //            }
    //            return null;
    //        }
    //        if (result instanceof EvalContext) {
    //            EvalContext ctx = (EvalContext) result;
    //            result = ctx.getSingleNodePointer();
    //            if (!isLenient() && result == null) {
    //                throw new JXPathNotFoundException("No value for xpath: "
    //                        + xpath);
    //            }
    //        }
    //        if (result instanceof NodePointer) {
    //            result = ((NodePointer) result).getValuePointer();
    //            if (!isLenient() && !((NodePointer) result).isActual()) {
    //                // We need to differentiate between pointers representing
    //                // a non-existing property and ones representing a property
    //                // whose value is null.  In the latter case, the pointer
    //                // is going to have isActual == false, but its parent,
    //                // which is a non-node pointer identifying the bean property,
    //                // will return isActual() == true.
    //                NodePointer parent =
    //                    ((NodePointer) result).getImmediateParentPointer();
    //                if (parent == null
    //                    || !parent.isContainer()
    //                    || !parent.isActual()) {
    //                    throw new JXPathNotFoundException("No value for xpath: "
    //                            + xpath);
    //                }
    //            }
    //            result = ((NodePointer) result).getValue();
    //        }
    //        return result;
    //    }
    //
    //    /**
    //     * Calls getValue(xpath), converts the result to the required type
    //     * and returns the result of the conversion.
    //     * @param xpath expression
    //     * @param requiredType Class
    //     * @return Object
    //     */
    //    public Object getValue(String xpath, Class requiredType) {
    //        Expression expr = compileExpression(xpath);
    //        return getValue(xpath, expr, requiredType);
    //    }
    //
    //    /**
    //     * Get the value indicated.
    //     * @param xpath expression
    //     * @param expr compiled Expression
    //     * @param requiredType Class
    //     * @return Object
    //     */
    //    public Object getValue(String xpath, Expression expr, Class requiredType) {
    //        Object value = getValue(xpath, expr);
    //        if (value != null && requiredType != null) {
    //            if (!TypeUtils.canConvert(value, requiredType)) {
    //                throw new JXPathTypeConversionException(
    //                    "Invalid expression type. '"
    //                        + xpath
    //                        + "' returns "
    //                        + value.getClass().getName()
    //                        + ". It cannot be converted to "
    //                        + requiredType.getName());
    //            }
    //            value = TypeUtils.convert(value, requiredType);
    //        }
    //        return value;
    //    }
    //
    //    /**
    //     * Traverses the xpath and returns a Iterator of all results found
    //     * for the path. If the xpath matches no properties
    //     * in the graph, the Iterator will not be null.
    //     * @param xpath expression
    //     * @return Iterator
    //     */
    //    public Iterator iterate(String xpath) {
    //        return iterate(xpath, compileExpression(xpath));
    //    }
    //
    //    /**
    //     * Traverses the xpath and returns a Iterator of all results found
    //     * for the path. If the xpath matches no properties
    //     * in the graph, the Iterator will not be null.
    //     * @param xpath expression
    //     * @param expr compiled Expression
    //     * @return Iterator
    //     */
    //    public Iterator iterate(String xpath, Expression expr) {
    //        return expr.iterate(getEvalContext());
    //    }
    //
    //    public Pointer getPointer(String xpath) {
    //        return getPointer(xpath, compileExpression(xpath));
    //    }
    //
    //    /**
    //     * Get a pointer to the specified path/expression.
    //     * @param xpath String
    //     * @param expr compiled Expression
    //     * @return Pointer
    //     */
    //    public Pointer getPointer(String xpath, Expression expr) {
    //        Object result = expr.computeValue(getEvalContext());
    //        if (result instanceof EvalContext) {
    //            result = ((EvalContext) result).getSingleNodePointer();
    //        }
    //        if (result instanceof Pointer) {
    //            if (!isLenient() && !((NodePointer) result).isActual()) {
    //                throw new JXPathNotFoundException("No pointer for xpath: "
    //                        + xpath);
    //            }
    //            return (Pointer) result;
    //        }
    //        return NodePointer.newNodePointer(null, result, getLocale());
    //    }
    //
    //    public void setValue(String xpath, Object value) {
    //        setValue(xpath, compileExpression(xpath), value);
    //    }
    //
    //    /**
    //     * Set the value of xpath to value.
    //     * @param xpath path
    //     * @param expr compiled Expression
    //     * @param value Object
    //     */
    //    public void setValue(String xpath, Expression expr, Object value) {
    //        try {
    //            setValue(xpath, expr, value, false);
    //        }
    //        catch (Throwable ex) {
    //            throw new JXPathException(
    //                "Exception trying to set value with xpath " + xpath, ex);
    //        }
    //    }
    //
    //    public Pointer createPath(String xpath) {
    //        return createPath(xpath, compileExpression(xpath));
    //    }
    //
    //    /**
    //     * Create the given path.
    //     * @param xpath String
    //     * @param expr compiled Expression
    //     * @return resulting Pointer
    //     */
    //    public Pointer createPath(String xpath, Expression expr) {
    //        try {
    //            Object result = expr.computeValue(getEvalContext());
    //            Pointer pointer = null;
    //
    //            if (result instanceof Pointer) {
    //                pointer = (Pointer) result;
    //            }
    //            else if (result instanceof EvalContext) {
    //                EvalContext ctx = (EvalContext) result;
    //                pointer = ctx.getSingleNodePointer();
    //            }
    //            else {
    //                checkSimplePath(expr);
    //                // This should never happen
    //                throw new JXPathException("Cannot create path:" + xpath);
    //            }
    //            return ((NodePointer) pointer).createPath(this);
    //        }
    //        catch (Throwable ex) {
    //            throw new JXPathException(
    //                "Exception trying to create xpath " + xpath,
    //                ex);
    //        }
    //    }
    //
    //    public Pointer createPathAndSetValue(String xpath, Object value) {
    //        return createPathAndSetValue(xpath, compileExpression(xpath), value);
    //    }
    //
    //    /**
    //     * Create the given path setting its value to value.
    //     * @param xpath String
    //     * @param expr compiled Expression
    //     * @param value Object
    //     * @return resulting Pointer
    //     */
    //    public Pointer createPathAndSetValue(String xpath, Expression expr,
    //            Object value) {
    //        try {
    //            return setValue(xpath, expr, value, true);
    //        }
    //        catch (Throwable ex) {
    //            throw new JXPathException(
    //                "Exception trying to create xpath " + xpath,
    //                ex);
    //        }
    //    }
    //
    //    /**
    //     * Set the specified value.
    //     * @param xpath path
    //     * @param expr compiled Expression
    //     * @param value destination value
    //     * @param create whether to create missing node(s)
    //     * @return Pointer created
    //     */
    //    private Pointer setValue(String xpath, Expression expr, Object value,
    //            boolean create) {
    //        Object result = expr.computeValue(getEvalContext());
    //        Pointer pointer = null;
    //
    //        if (result instanceof Pointer) {
    //            pointer = (Pointer) result;
    //        }
    //        else if (result instanceof EvalContext) {
    //            EvalContext ctx = (EvalContext) result;
    //            pointer = ctx.getSingleNodePointer();
    //        }
    //        else {
    //            if (create) {
    //                checkSimplePath(expr);
    //            }
    //
    //            // This should never happen
    //            throw new JXPathException("Cannot set value for xpath: " + xpath);
    //        }
    //        if (create) {
    //            pointer = ((NodePointer) pointer).createPath(this, value);
    //        }
    //        else {
    //            pointer.setValue(value);
    //        }
    //        return pointer;
    //    }
    //
    //    /**
    //     * Checks if the path follows the JXPath restrictions on the type
    //     * of path that can be passed to create... methods.
    //     * @param expr Expression to check
    //     */
    //    private void checkSimplePath(Expression expr) {
    //        if (!(expr instanceof LocationPath)
    //            || !((LocationPath) expr).isSimplePath()) {
    //            throw new JXPathInvalidSyntaxException(
    //                "JXPath can only create a path if it uses exclusively "
    //                    + "the child:: and attribute:: axes and has "
    //                    + "no context-dependent predicates");
    //        }
    //    }
    //
    //    /**
    //     * Traverses the xpath and returns an Iterator of Pointers.
    //     * A Pointer provides easy access to a property.
    //     * If the xpath matches no properties
    //     * in the graph, the Iterator be empty, but not null.
    //     * @param xpath expression
    //     * @return Iterator
    //     */
    //    public Iterator iteratePointers(String xpath) {
    //        return iteratePointers(xpath, compileExpression(xpath));
    //    }
    //
    //    /**
    //     * Traverses the xpath and returns an Iterator of Pointers.
    //     * A Pointer provides easy access to a property.
    //     * If the xpath matches no properties
    //     * in the graph, the Iterator be empty, but not null.
    //     * @param xpath expression
    //     * @param expr compiled Expression
    //     * @return Iterator
    //     */
    //    public Iterator iteratePointers(String xpath, Expression expr) {
    //        return expr.iteratePointers(getEvalContext());
    //    }
    //
    //    public void removePath(String xpath) {
    //        removePath(xpath, compileExpression(xpath));
    //    }
    //
    //    /**
    //     * Remove the specified path.
    //     * @param xpath expression
    //     * @param expr compiled Expression
    //     */
    //    public void removePath(String xpath, Expression expr) {
    //        try {
    //            NodePointer pointer = (NodePointer) getPointer(xpath, expr);
    //            if (pointer != null) {
    //                ((NodePointer) pointer).remove();
    //            }
    //        }
    //        catch (Throwable ex) {
    //            throw new JXPathException(
    //                "Exception trying to remove xpath " + xpath,
    //                ex);
    //        }
    //    }
    //
    //    public void removeAll(String xpath) {
    //        removeAll(xpath, compileExpression(xpath));
    //    }
    //
    //    /**
    //     * Remove all matching nodes.
    //     * @param xpath expression
    //     * @param expr compiled Expression
    //     */
    //    public void removeAll(String xpath, Expression expr) {
    //        try {
    //            ArrayList list = new ArrayList();
    //            Iterator it = expr.iteratePointers(getEvalContext());
    //            while (it.hasNext()) {
    //                list.add(it.next());
    //            }
    //            Collections.sort(list, ReverseComparator.INSTANCE);
    //            it = list.iterator();
    //            if (it.hasNext()) {
    //                NodePointer pointer = (NodePointer) it.next();
    //                pointer.remove();
    //                while (it.hasNext()) {
    //                    removePath(((NodePointer) it.next()).asPath());
    //                }
    //            }
    //        }
    //        catch (Throwable ex) {
    //            throw new JXPathException(
    //                "Exception trying to remove all for xpath " + xpath,
    //                ex);
    //        }
    //    }
    //
    //    public JXPathContext getRelativeContext(Pointer pointer) {
    //        Object contextBean = pointer.getNode();
    //        if (contextBean == null) {
    //            throw new JXPathException(
    //                "Cannot create a relative context for a non-existent node: "
    //                    + pointer);
    //        }
    //        return new JXPathContextReferenceImpl(this, contextBean, pointer);
    //    }
    //
    //    public Pointer getContextPointer() {
    //        return contextPointer;
    //    }
    //
    //    /**
    //     * Get absolute root pointer.
    //     * @return NodePointer
    //     */
    //    private NodePointer getAbsoluteRootPointer() {
    //        return (NodePointer) rootPointer;
    //    }
    //
    //    /**
    //     * Get the evaluation context.
    //     * @return EvalContext
    //     */
    //    private EvalContext getEvalContext() {
    //        return new InitialContext(new RootContext(this,
    //                (NodePointer) getContextPointer()));
    //    }
    //
    //    /**
    //     * Get the absolute root context.
    //     * @return EvalContext
    //     */
    //    public EvalContext getAbsoluteRootContext() {
    //        return new InitialContext(new RootContext(this,
    //                getAbsoluteRootPointer()));
    //    }
    //
    //    /**
    //     * Get a VariablePointer for the given variable name.
    //     * @param name variable name
    //     * @return NodePointer
    //     */
    //    public NodePointer getVariablePointer(QName name) {
    //        return NodePointer.newNodePointer(name, VariablePointerFactory
    //                .contextWrapper(this), getLocale());
    //    }
    //
    //    /**
    //     * Get the named Function.
    //     * @param functionName name
    //     * @param parameters function args
    //     * @return Function
    //     */
    //    public Function getFunction(QName functionName, Object[] parameters) {
    //        String namespace = functionName.getPrefix();
    //        String name = functionName.getName();
    //        JXPathContext funcCtx = this;
    //        Function func = null;
    //        Functions funcs;
    //        while (funcCtx != null) {
    //            funcs = funcCtx.getFunctions();
    //            if (funcs != null) {
    //                func = funcs.getFunction(namespace, name, parameters);
    //                if (func != null) {
    //                    return func;
    //                }
    //            }
    //            funcCtx = funcCtx.getParentContext();
    //        }
    //        throw new JXPathFunctionNotFoundException(
    //            "Undefined function: " + functionName.toString());
    //    }
    //
    //    public void registerNamespace(String prefix, String namespaceURI) {
    //        if (namespaceResolver.isSealed()) {
    //            namespaceResolver = (NamespaceResolver) namespaceResolver.clone();
    //        }
    //        namespaceResolver.registerNamespace(prefix, namespaceURI);
    //    }
    //
    //    public String getNamespaceURI(String prefix) {
    //        return namespaceResolver.getNamespaceURI(prefix);
    //    }
    //
    //    /**
    //     * {@inheritDoc}
    //     * @see org.apache.commons.jxpath.JXPathContext#getPrefix(java.lang.String)
    //     */
    //    public String getPrefix(String namespaceURI) {
    //        return namespaceResolver.getPrefix(namespaceURI);
    //    }
    //
    //    public void setNamespaceContextPointer(Pointer pointer) {
    //        if (namespaceResolver.isSealed()) {
    //            namespaceResolver = (NamespaceResolver) namespaceResolver.clone();
    //        }
    //        namespaceResolver.setNamespaceContextPointer((NodePointer) pointer);
    //    }
    //
    //    public Pointer getNamespaceContextPointer() {
    //        return namespaceResolver.getNamespaceContextPointer();
    //    }
    //
    //    /**
    //     * Get the namespace resolver.
    //     * @return NamespaceResolver
    //     */
    //    public NamespaceResolver getNamespaceResolver() {
    //        namespaceResolver.seal();
    //        return namespaceResolver;
    //    }

    /**
     * Checks if existenceCheckClass exists on the class path. If so, allocates
     * an instance of the specified class, otherwise returns null.
     * @param className to instantiate
     * @param existenceCheckClassName guard class
     * @return className instance
     */
    public static Object allocateConditionally(String className, String existenceCheckClassName) {
        try {
            try {
                Class.forName(existenceCheckClassName);
            } catch (ClassNotFoundException ex) {
                return null;
            }
            Class cls = Class.forName(className);
            return cls.newInstance();
        } catch (Exception ex) {
            throw new JXPathException("Cannot allocate " + className, ex);
        }
    }
}