The Source for Java Technology Collaboration
User: Password:



Rich Unger

Rich Unger's Blog

Bean Browsing with JXPath

Posted by richunger on June 14, 2005 at 02:03 PM | Comments (4)

Here's a little trick I've found useful for browsing the contents of my JAXB model, though it works just as well with any java beans. It's a GUI for testing JXPath expressions on a given Object. Try it out on any old object, and start with the XPath expression for the context node, which is just '.' (not quoted).

For example, if you create a new PathTestFrame(new java.util.Date()), and give it the expression '.', you'll see the bean properties of the Date object. Then, if you change the expression to, say 'time', you'll get the results of Date.getTime(). This is not very helpful, as the only bean property of a primitive type, as far as JXPath is concerned, is "class", but you get the idea.

It gets better. Let's say you've got an Object with a bean property called "dateList", a List of Dates. The first date in the list will be 'dateList[1]' (XPath is 1-indexed, not 0-indexed).

You can browse through a very large heirarchy of beans, and even edit the bean property values using the property sheet. Neat, eh?

import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.beans.IntrospectionException;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.openide.DialogDisplayer;
import org.openide.ErrorManager;
import org.openide.NotifyDescriptor;
import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
import org.apache.commons.jxpath.JXPathContext;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import org.openide.nodes.BeanNode;
import org.openide.explorer.propertysheet.PropertySheet;

public class PathTestFrame extends JPanel
{
    private JXPathContext m_jxPathContext;
    
    private JTextField m_inputField;
    private JButton m_btn;
    private PropertySheet m_propsheet;
    
    public PathTestFrame(Object model)
    {
        super();
        setLayout(new BorderLayout());

        m_btn = new JButton("Test Path");
        m_inputField = new JTextField(50);
        m_propsheet = new PropertySheet();
        m_btn.addActionListener(new ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent e) {
                update();
            }
        });
        
        JPanel top = new JPanel();
        top.add(m_inputField);
        top.add(m_btn);
        add(top, BorderLayout.NORTH);
        add(m_propsheet, BorderLayout.CENTER);
        
        m_jxPathContext = JXPathContext.newContext(model);
    }
    
    private void update()
    {
        Iterator values = m_jxPathContext.iterate(m_inputField.getText());
        List l = new ArrayList();
        while (values.hasNext())
        {
            l.add(values.next());
        }
        
        Node[] nodes = new Node[l.size()];

        try
        {
            for (int i=0; i < nodes.length; i++)
            {
                nodes[i] = new BeanNode(l.get(i));
            }
            m_propsheet.setNodes(nodes);
        }
        catch (IntrospectionException ex)
        {
            ErrorManager.getDefault().notify(ex);
        }

    }
}

The class was written to be used in Netbeans, but can be used standalone as long as you have openide.jar in your classpath (and, of course, you need jxpath regardless).


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Do yourself a favor and use XmlBeans instead of JAXB. You gain native XPath navigation.

    Posted by: c_jinx on June 15, 2005 at 07:38 AM

  • Well, that's quite a statement to make, for someone who knows nothing about what other requirements my app might have, to someone who's been using jaxb successfully for two years on this project.

    At any rate, this approach is useful for all kinds of in-memory data structures, such as caches, object databases, and the netbeans system filesystem.

    Posted by: richunger on June 15, 2005 at 11:10 AM


  • Let's not overreact, shall we?
    I understand that you have made a significant investment in JAXB, and I guess it's human to be defensive when someone questions your choices.


    Your blog entry is about navigating javabean objects using XPath expressions. I agree with you that JXPath is good framework for this. The motivation you gave was that you wanted to navigate your bean model (generated by JAXB). I was pointing out that you have a better alternative (i.e. XmlBeans).


    There is no point of hiding behind "what other requirements my app might have", because you didn't talk about them in your post. Since I did not know about them, I couldn't have taken them into account, now could I?


    Based on technical merits, XmlBeans is superior than JAXB (except if you need to work with Relax NG). You made a post on your blog, and I gave you feedback on that. That's all.


    Peace.

    Posted by: c_jinx on June 16, 2005 at 03:59 AM

  • Oh, I didn't mean to come across that way. It just seemed an odd statement to make ("do yourself a favor"). XmlBeans is great stuff. In fact, there's quite a proliferation of xml data binding libraries out there. Most of them didn't exist when we started the project, and there's little reason to go changing it now.
    But xml data binding really wasn't the point of the post at all. I can use the same technique to, say, browse my voicexml interpreter's page cache.

    Posted by: richunger on June 16, 2005 at 11:33 AM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds