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

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 * Copyright 1999-2004 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.jxpath.ri.axes;

import java.util.HashMap;

import junit.framework.TestCase;

import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.NestedTestBean;
import org.apache.commons.jxpath.Pointer;
import org.apache.commons.jxpath.TestNull;
import org.apache.commons.jxpath.ri.model.NodePointer;
import org.apache.commons.jxpath.ri.model.VariablePointer;
import org.apache.commons.jxpath.ri.model.beans.BeanPointer;
import org.apache.commons.jxpath.ri.model.beans.BeanPropertyPointer;
import org.apache.commons.jxpath.ri.model.beans.CollectionPointer;
import org.apache.commons.jxpath.ri.model.beans.NullElementPointer;
import org.apache.commons.jxpath.ri.model.beans.NullPointer;
import org.apache.commons.jxpath.ri.model.beans.NullPropertyPointer;
import org.apache.commons.jxpath.ri.model.beans.TestBeanFactory;
import org.apache.commons.jxpath.ri.model.dom.DOMNodePointer;
import org.apache.commons.jxpath.ri.model.dynamic.DynamicPointer;
import org.apache.commons.jxpath.ri.model.dynamic.DynamicPropertyPointer;

public class SimplePathInterpreterTest extends TestCase {

    private TestBeanWithNode bean;
    private JXPathContext context;

    /**
     * Constructor for SimplePathInterpreterTest.
     */
    public SimplePathInterpreterTest(String name) {
        super(name);
    }

    public static void main(String[] args) {
        junit.textui.TestRunner.run(SimplePathInterpreterTest.class);
    }

    /**
     * @see TestCase#setUp()
     */
    protected void setUp() throws Exception {
        bean = TestBeanWithNode.createTestBeanWithDOM();
        HashMap submap = new HashMap();
        submap.put("key", new NestedTestBean("Name 9"));
        submap.put("strings", bean.getNestedBean().getStrings());
        bean.getList().add(new int[]{1, 2});
        bean.getList().add(bean.getVendor());
        bean.getMap().put("Key3",
            new Object[]{
                new NestedTestBean("some"),
                new Integer(2),
                bean.getVendor(),
                submap
            }
        );
        bean.getMap().put("Key4", bean.getVendor());
        bean.getMap().put("Key5", submap);
        bean.getMap().put("Key6", new Object[0]);
        context = JXPathContext.newContext(null, bean);
        context.setLenient(true);
        context.setFactory(new TestBeanFactory());
    }

    public void testDoStepNoPredicatesPropertyOwner() {
        // Existing scalar property
        assertValueAndPointer("/int",
                new Integer(1),
                "/int",
                "Bb",
                "BbB");

        // self::
        assertValueAndPointer("/./int",
                new Integer(1),
                "/int",
                "Bb",
                "BbB");

        // Missing property
        assertNullPointer("/foo",
                "/foo",
                "Bn");

        // existingProperty/existingScalarProperty
        assertValueAndPointer("/nestedBean/int",
                new Integer(1),
                "/nestedBean/int",
                "BbBb",
                "BbBbB");

        // existingProperty/collectionProperty
        assertValueAndPointer("/nestedBean/strings",
                bean.getNestedBean().getStrings(),
                "/nestedBean/strings",
                "BbBb",
                "BbBbC");

        // existingProperty/missingProperty
        assertNullPointer("/nestedBean/foo",
                "/nestedBean/foo",
                "BbBn");

        // map/missingProperty
        assertNullPointer("/map/foo",
                "/map[@name='foo']",
                "BbDd");

        // Existing property by search in collection
        assertValueAndPointer("/list/int",
                new Integer(1),
                "/list[3]/int",
                "BbBb",
                "BbBbB");

        // Missing property by search in collection
        assertNullPointer("/list/foo",
                "/list[1]/foo",
                "BbBn");

        // existingProperty/missingProperty/missingProperty
        assertNullPointer("/nestedBean/foo/bar",
                "/nestedBean/foo/bar",
                "BbBnNn");

        // collection/existingProperty/missingProperty
        assertNullPointer("/list/int/bar",
                "/list[3]/int/bar",
                "BbBbBn");

        // collectionProperty/missingProperty/missingProperty
        assertNullPointer("/list/foo/bar",
                "/list[1]/foo/bar",
                "BbBnNn");

        // map/missingProperty/anotherStep
        assertNullPointer("/map/foo/bar",
                "/map[@name='foo']/bar",
                "BbDdNn");

        // Existing dynamic property
        assertValueAndPointer("/map/Key1",
                "Value 1",
                "/map[@name='Key1']",
                "BbDd",
                "BbDdB");

        // collectionProperty
        assertValueAndPointer("/integers",
                bean.getIntegers(),
                "/integers",
                "Bb",
                "BbC");
    }

    public void testDoStepNoPredicatesStandard() {
        // Existing DOM node
        assertValueAndPointer("/vendor/location/address/city",
                "Fruit Market",
                "/vendor/location[2]/address[1]/city[1]",
                "BbMMMM");

        // Missing DOM node
        assertNullPointer("/vendor/location/address/pity",
                "/vendor/location[1]/address[1]/pity",
                "BbMMMn");

        // Missing DOM node inside a missing element
        assertNullPointer("/vendor/location/address/itty/bitty",
                "/vendor/location[1]/address[1]/itty/bitty",
                "BbMMMnNn");

        // Missing DOM node by search for the best match
        assertNullPointer("/vendor/location/address/city/pretty",
                "/vendor/location[2]/address[1]/city[1]/pretty",
                "BbMMMMn");
    }

    public void testDoStepPredicatesPropertyOwner() {
        // missingProperty[@name=foo]
        assertNullPointer("/foo[@name='foo']",
                "/foo[@name='foo']",
                "BnNn");

        // missingProperty[index]
        assertNullPointer("/foo[3]",
                "/foo[3]",
                "Bn");
    }

    public void testDoStepPredicatesStandard() {
        // Looking for an actual XML attribute called "name"
        // nodeProperty/name[@name=value]
        assertValueAndPointer("/vendor/contact[@name='jack']",
                "Jack",
                "/vendor/contact[2]",
                "BbMM");

        // Indexing in XML
        assertValueAndPointer("/vendor/contact[2]",
                "Jack",
                "/vendor/contact[2]",
                "BbMM");

        // Indexing in XML, no result
        assertNullPointer("/vendor/contact[5]",
                "/vendor/contact[5]",
                "BbMn");

        // Combination of search by name and indexing in XML
        assertValueAndPointer("/vendor/contact[@name='jack'][2]",
                "Jack Black",
                "/vendor/contact[4]",
                "BbMM");

        // Combination of search by name and indexing in XML
        assertValueAndPointer("/vendor/contact[@name='jack'][2]",
                "Jack Black",
                "/vendor/contact[4]",
                "BbMM");
    }

    public void testDoPredicateName() {
        // existingProperty[@name=existingProperty]
        assertValueAndPointer("/nestedBean[@name='int']",
                new Integer(1),
                "/nestedBean/int",
                "BbBb",
                "BbBbB");

        // /self::node()[@name=existingProperty]
        assertValueAndPointer("/.[@name='int']",
                new Integer(1),
                "/int",
                "Bb",
                "BbB");

        // dynamicProperty[@name=existingProperty]
        assertValueAndPointer("/map[@name='Key1']",
                "Value 1",
                "/map[@name='Key1']",
                "BbDd",
                "BbDdB");

        // existingProperty[@name=collectionProperty]
        assertValueAndPointer("/nestedBean[@name='strings']",
                bean.getNestedBean().getStrings(),
                "/nestedBean/strings",
                "BbBb",
                "BbBbC");

        // existingProperty[@name=missingProperty]
        assertNullPointer("/nestedBean[@name='foo']",
                "/nestedBean[@name='foo']",
                "BbBn");

        // map[@name=collectionProperty]
        assertValueAndPointer("/map[@name='Key3']",
                bean.getMap().get("Key3"),
                "/map[@name='Key3']",
                "BbDd",
                "BbDdC");
                
        // map[@name=missingProperty]
        assertNullPointer("/map[@name='foo']",
                "/map[@name='foo']",
                "BbDd");

        // collectionProperty[@name=...] (find node)
        assertValueAndPointer("/list[@name='fruitco']",
                context.getValue("/vendor"),
                "/list[5]",
                "BbCM");

        // collectionProperty[@name=...] (find map entry)
        assertValueAndPointer("/map/Key3[@name='key']/name",
                "Name 9",
                "/map[@name='Key3'][4][@name='key']/name",
                "BbDdCDdBb",
                "BbDdCDdBbB");

        // map/collectionProperty[@name...]
        assertValueAndPointer("map/Key3[@name='fruitco']",
                context.getValue("/vendor"),
                "/map[@name='Key3'][3]",
                "BbDdCM");

        // Bean property -> DOM Node, name match
        assertValueAndPointer("/vendor[@name='fruitco']",
                context.getValue("/vendor"),
                "/vendor",
                "BbM");

        // Bean property -> DOM Node, name mismatch
        assertNullPointer("/vendor[@name='foo']",
                "/vendor[@name='foo']",
                "BbMn");

        assertNullPointer("/vendor[@name='foo'][3]",
                "/vendor[@name='foo'][3]",
                "BbMn");

        // existingProperty(bean)[@name=missingProperty]/anotherStep
        assertNullPointer("/nestedBean[@name='foo']/bar",
                "/nestedBean[@name='foo']/bar",
                "BbBnNn");

        // map[@name=missingProperty]/anotherStep
        assertNullPointer("/map[@name='foo']/bar",
                "/map[@name='foo']/bar",
                "BbDdNn");

        // existingProperty(node)[@name=missingProperty]/anotherStep
        assertNullPointer("/vendor[@name='foo']/bar",
                "/vendor[@name='foo']/bar",
                "BbMnNn");

        // existingProperty(node)[@name=missingProperty][index]/anotherStep
        assertNullPointer("/vendor[@name='foo'][3]/bar",
                "/vendor[@name='foo'][3]/bar",
                "BbMnNn");

        // Existing dynamic property + existing property
        assertValueAndPointer("/map[@name='Key2'][@name='name']",
                "Name 6",
                "/map[@name='Key2']/name",
                "BbDdBb",
                "BbDdBbB");

        // Existing dynamic property + existing property + index
        assertValueAndPointer("/map[@name='Key2'][@name='strings'][2]",
                "String 2",
                "/map[@name='Key2']/strings[2]",
                "BbDdBb",
                "BbDdBbB");

        // bean/map/map/property
        assertValueAndPointer("map[@name='Key5'][@name='key']/name",
                "Name 9",
                "/map[@name='Key5'][@name='key']/name",
                "BbDdDdBb",
                "BbDdDdBbB");

        assertNullPointer("map[@name='Key2'][@name='foo']",
                "/map[@name='Key2'][@name='foo']",
                "BbDdBn");

        assertNullPointer("map[@name='Key2'][@name='foo'][@name='bar']",
                "/map[@name='Key2'][@name='foo'][@name='bar']",
                "BbDdBnNn");

        // bean/map/node
        assertValueAndPointer("map[@name='Key4'][@name='fruitco']",
                context.getValue("/vendor"),
                "/map[@name='Key4']",
                "BbDdM");
    }

    public void testDoPredicatesStandard() {
        // bean/map/collection/node
        assertValueAndPointer("map[@name='Key3'][@name='fruitco']",
                context.getValue("/vendor"),
                "/map[@name='Key3'][3]",
                "BbDdCM");

        // bean/map/collection/missingNode
        assertNullPointer("map[@name='Key3'][@name='foo']",
                "/map[@name='Key3'][4][@name='foo']",
                "BbDdCDd");

        // bean/map/node
        assertValueAndPointer("map[@name='Key4'][@name='fruitco']",
                context.getValue("/vendor"),
                "/map[@name='Key4']",
                "BbDdM");

        // bean/map/emptyCollection[@name=foo]
        assertNullPointer("map[@name='Key6'][@name='fruitco']",
                "/map[@name='Key6'][@name='fruitco']",
                "BbDdCn");

        // bean/node[@name=foo][index]
        assertValueAndPointer("/vendor/contact[@name='jack'][2]",
                "Jack Black",
                "/vendor/contact[4]",
                "BbMM");

        // bean/node[@name=foo][missingIndex]
        assertNullPointer("/vendor/contact[@name='jack'][5]",
                "/vendor/contact[@name='jack'][5]",
                "BbMnNn");

        // bean/node/.[@name=foo][index]
        assertValueAndPointer("/vendor/contact/.[@name='jack']",
                "Jack",
                "/vendor/contact[2]",
                "BbMM");
    }

    public void testDoPredicateIndex() {
        // Existing dynamic property + existing property + index
        assertValueAndPointer("/map[@name='Key2'][@name='strings'][2]",
                "String 2",
                "/map[@name='Key2']/strings[2]",
                "BbDdBb",
                "BbDdBbB");

        // existingProperty[@name=collectionProperty][index]
        assertValueAndPointer("/nestedBean[@name='strings'][2]",
                bean.getNestedBean().getStrings()[1],
                "/nestedBean/strings[2]",
                "BbBb",
                "BbBbB");

        // existingProperty[@name=missingProperty][index]
        assertNullPointer("/nestedBean[@name='foo'][3]",
                "/nestedBean[@name='foo'][3]",
                "BbBn");

        // existingProperty[@name=collectionProperty][missingIndex]
        assertNullPointer("/nestedBean[@name='strings'][5]",
                "/nestedBean/strings[5]",
                "BbBbE");

        // map[@name=collectionProperty][index]
        assertValueAndPointer("/map[@name='Key3'][2]",
                new Integer(2),
                "/map[@name='Key3'][2]",
                "BbDd",
                "BbDdB");

        // map[@name=collectionProperty][missingIndex]
        assertNullPointer("/map[@name='Key3'][5]",
                "/map[@name='Key3'][5]",
                "BbDdE");

        // map[@name=collectionProperty][missingIndex]/property
        assertNullPointer("/map[@name='Key3'][5]/foo",
                "/map[@name='Key3'][5]/foo",
                "BbDdENn");

        // map[@name=map][@name=collection][index]
        assertValueAndPointer("/map[@name='Key5'][@name='strings'][2]",
                "String 2",
                "/map[@name='Key5'][@name='strings'][2]",
                "BbDdDd",
                "BbDdDdB");

        // map[@name=map][@name=collection][missingIndex]
        assertNullPointer("/map[@name='Key5'][@name='strings'][5]",
                "/map[@name='Key5'][@name='strings'][5]",
                "BbDdDdE");

        // Existing dynamic property + indexing
        assertValueAndPointer("/map[@name='Key3'][2]",
                new Integer(2),
                "/map[@name='Key3'][2]",
                "BbDd",
                "BbDdB");

        // Existing dynamic property + indexing
        assertValueAndPointer("/map[@name='Key3'][1]/name",
                "some",
                "/map[@name='Key3'][1]/name",
                "BbDdBb",
                "BbDdBbB");

        // map[@name=missingProperty][index]
        assertNullPointer("/map[@name='foo'][3]",
                "/map[@name='foo'][3]",
                "BbDdE");

        // collectionProperty[index]
        assertValueAndPointer("/integers[2]",
                new Integer(2),
                "/integers[2]",
                "Bb",
                "BbB");

        // existingProperty/collectionProperty[index]
        assertValueAndPointer("/nestedBean/strings[2]",
                bean.getNestedBean().getStrings()[1],
                "/nestedBean/strings[2]",
                "BbBb",
                "BbBbB");

        // existingProperty[index]/existingProperty
        assertValueAndPointer("/list[3]/int",
                new Integer(1),
                "/list[3]/int",
                "BbBb",
                "BbBbB");

        // existingProperty[missingIndex]
        assertNullPointer("/list[6]",
                "/list[6]",
                "BbE");

        // existingProperty/missingProperty[index]
        assertNullPointer("/nestedBean/foo[3]",
                "/nestedBean/foo[3]",
                "BbBn");

        // map[@name=missingProperty][index]
        assertNullPointer("/map/foo[3]",
                "/map[@name='foo'][3]",
                "BbDdE");

        // existingProperty/collectionProperty[missingIndex]
        assertNullPointer("/nestedBean/strings[5]",
                "/nestedBean/strings[5]",
                "BbBbE");

        // map/collectionProperty[missingIndex]/property
        assertNullPointer("/map/Key3[5]/foo",
                "/map[@name='Key3'][5]/foo",
                "BbDdENn");

        // map[@name=map]/collection[index]
        assertValueAndPointer("/map[@name='Key5']/strings[2]",
                "String 2",
                "/map[@name='Key5'][@name='strings'][2]",
                "BbDdDd",
                "BbDdDdB");

        // map[@name=map]/collection[missingIndex]
        assertNullPointer("/map[@name='Key5']/strings[5]",
                "/map[@name='Key5'][@name='strings'][5]",
                "BbDdDdE");

        // scalarPropertyAsCollection[index]
        assertValueAndPointer("/int[1]",
                new Integer(1),
                "/int",
                "Bb",
                "BbB");

        // scalarPropertyAsCollection[index]
        assertValueAndPointer(".[1]/int",
                new Integer(1),
                "/int",
                "Bb",
                "BbB");
    }

    public void testInterpretExpressionPath() {
        context.getVariables().declareVariable("array", new String[]{"Value1"});
        context.getVariables().declareVariable("testnull", new TestNull());

        assertNullPointer("$testnull/nothing[2]",
                "$testnull/nothing[2]",
                "VBbE");
    }

    private void assertValueAndPointer(
            String path, Object expectedValue, String expectedPath,
            String expectedSignature)
    {
        assertValueAndPointer(
            path,
            expectedValue,
            expectedPath,
            expectedSignature,
            expectedSignature);
    }
    
    private void assertValueAndPointer(
            String path, Object expectedValue, String expectedPath,
            String expectedSignature, String expectedValueSignature)
    {
        Object value = context.getValue(path);
        assertEquals("Checking value: " + path, expectedValue, value);

        Pointer pointer = context.getPointer(path);
        assertEquals("Checking pointer: " + path,
                expectedPath, pointer.toString());

        assertEquals("Checking signature: " + path,
                expectedSignature, pointerSignature(pointer));
        
        Pointer vPointer = ((NodePointer) pointer).getValuePointer();
        assertEquals("Checking value pointer signature: " + path,
                expectedValueSignature, pointerSignature(vPointer));
    }

    private void assertNullPointer(String path, String expectedPath,
            String expectedSignature)
    {
        Pointer pointer = context.getPointer(path);
        assertNotNull("Null path exists: " + path,
                    pointer);
        assertEquals("Null path as path: " + path,
                    expectedPath, pointer.asPath());
        assertEquals("Checking Signature: " + path,
                    expectedSignature, pointerSignature(pointer));
                
        Pointer vPointer = ((NodePointer) pointer).getValuePointer();
        assertTrue("Null path is null: " + path,
                    !((NodePointer) vPointer).isActual());
        assertEquals("Checking value pointer signature: " + path,
                    expectedSignature + "N", pointerSignature(vPointer));
    }

    /**
     * Since we need to test the internal Signature of a pointer,
     * we will get a signature which will contain a single character
     * per pointer in the chain, representing that pointer's type.
     */
    private String pointerSignature(Pointer pointer) {
        if (pointer == null) {
            return "";
        }

        char type = '?';
        if (pointer instanceof NullPointer) {                 type = 'N'; }
        else if (pointer instanceof NullPropertyPointer) {    type = 'n'; }
        else if (pointer instanceof NullElementPointer) {     type = 'E'; }
        else if (pointer instanceof VariablePointer) {        type = 'V'; }
        else if (pointer instanceof CollectionPointer) {      type = 'C'; }
        else if (pointer instanceof BeanPointer) {            type = 'B'; }
        else if (pointer instanceof BeanPropertyPointer) {    type = 'b'; }
        else if (pointer instanceof DynamicPointer) {         type = 'D'; }
        else if (pointer instanceof DynamicPropertyPointer) { type = 'd'; }
        else if (pointer instanceof DOMNodePointer) {         type = 'M'; }
        else {
            System.err.println("UNKNOWN TYPE: " + pointer.getClass());
        }
        NodePointer parent = 
            ((NodePointer) pointer).getImmediateParentPointer();
        return pointerSignature(parent) + type;
    }
}

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

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2024 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.