-1

I have an object graph and one of the accessor methods returns a java Optional and as a result my XPath expression stops from that point onwards.

The xpath is data/someData[1]/optionalObject/field

How can I get JXPath to return the actual object rather than the Optional or does JXPath pre date java Optionals and so it will never work?

juckky
  • 493
  • 3
  • 13

1 Answers1

0

If anyone is interested I solved the issue with Optional objects by creating a custom NodePointerFactory instance. I could not find any documentation on doing this, but I hope the below helps anyone who comes across this problem as well.

Steps are as follows.

  1. Register the instance with the call

    JXPathContextReferenceImpl.addNodePointerFactory(new OptionalHandlerPointerFactory());

  2. The implementation

    private static class OptionalHandlerPointerFactory implements NodePointerFactory {

    @Override
    public int getOrder() {
        //Insert before the bean pointer factory
        return BeanPointerFactory.BEAN_POINTER_FACTORY_ORDER - 1;
    }
    
    @Override
    public NodePointer createNodePointer(QName name, Object bean, Locale locale) {
        if(bean != null && bean instanceof Optional) {
            if(!((Optional)bean).isPresent()) {
                return new NullPointer(name, locale);           
            }
    
            final Object beanObject = ((Optional)bean).get();
            final Class beanClass  = beanObject.getClass();
    
            JXPathBeanInfo bi = JXPathIntrospector.getBeanInfo(beanClass);
            return new BeanPointer(name, beanObject, bi, locale);               
        }
    
        return null;
    }       
    
    @Override
    public NodePointer createNodePointer(NodePointer parent, QName name, Object bean) {
        if(bean != null && bean instanceof Optional ) {
            if(!((Optional)bean).isPresent()) {
                return new NullPointer(parent, name);                   
            }
    
            final Object beanObject = ((Optional)bean).get();
            final Class beanClass  = beanObject.getClass();
    
            final JXPathBeanInfo bi = JXPathIntrospector.getBeanInfo(beanClass);
            return new BeanPointer(parent, name, beanObject, bi);                   
        }
    
        return null;
    }       
    

    }

juckky
  • 493
  • 3
  • 13