Hello!

I'm using JXPath as part of a little DSL that is supposed to be maintained by 
non-developers. Therefore, it would be handy if I could validate the JXPath 
expressions against the interface of the object tree that they should match. 
Ideally that should happen before the actual object instances are created.

I tried to get along setting lenient to false, thus evaluating the exceptions. 
The problem with this approach that I can't distinguish whether I get a 
JXPathNotFoundException due to a missing object instance or due to an invalid 
property name, when the XPath expression steps across a null return value or an 
empty list. The unit test below illustrates this behavior.

So my question is if, given the object tree interface, there is a possibility 
to tell whether the JXPath expression describes a possible path along that 
tree. It would be very helpful to detect typos or missing steps.

Thank you!
Heike


import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathNotFoundException;
import org.junit.Test;

public class LenientJXPathTest
{

    public static class MyBean
    {
        public String getValue()
        {
            return "Hello World!";
        }

        public MyOtherBean getNull()
        {
            return null;
        }

        public List<MyOtherBean> getList()
        {
            return Collections.<MyOtherBean> emptyList();
        }

        public List<MyOtherBean> getNonEmptyList()
        {
            final ArrayList<MyOtherBean> list = new ArrayList<MyOtherBean>();
            list.add(new MyOtherBean());
            return list;
        }

        public List<Object> getNullList()
        {
            return null;
        }

    }

    public static class MyOtherBean
    {
        public String getValue()
        {
            return "Hello World!";
        }
    }

    static final MyBean bean = new MyBean();

    /* Can't distinguish the cause of the exception from the cause in the 
following test case. */
    @Test(expected = JXPathNotFoundException.class)
    public void testExceptionBecauseOfMissingObjectWhenPathGoesAcrossEmptyList()
    {
        final JXPathContext context = JXPathContext.newContext(bean);
        context.setLenient(false);

        context.getValue("/list[@value='Hello World!']");
    }

    /* Can't distinguish the cause of the exception from the cause in the 
preceding test case. */
    @Test(expected = JXPathNotFoundException.class)
    public void testExceptionDueToBadPropertyNameWhenPathGoesAcrossEmptyList()
    {
        final JXPathContext context = JXPathContext.newContext(bean);
        context.setLenient(false);

        context.getValue("/nonEmptyList[@dosentexist='Hello World!']");
    }

    /* Can't tell whether I get the exception due to a null instance or an 
invalid property name. */
    @Test(expected = JXPathNotFoundException.class)
    public void testExceptionBecauseOfMissingObjectWhenPathGoesAcrossNull()
    {
        final JXPathContext context = JXPathContext.newContext(bean);
        context.setLenient(false);

        context.getValue("/null/doesnotexist");
    }

}






Reply via email to