I am coming across a problem testing the JXPath binding. Here is some context

Home.page
=========
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE page-specification PUBLIC
  "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
  "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd";>
<page-specification class="org.openvpms.app.tapestry.pages.Home">
  <inject property="archetypeService" object="spring:archetypeService"/>
  <property name="descriptor"/>
  <property name="archetypeDescriptors" />
</page-specification>

Home.html
=========
<span jwcid="@Border">
<h1>Welcome to the OpenVPMS Test Application</h1>

<ul class="archetypeList">
        <div class="archetypeList" jwcid="@For"
                source="jxpath:archetypeService/archetypeDescriptors"
                value="jxpath:descriptor">
        <li><a href="#" jwcid="@openvpms:NewLink"
                archetypeName="jxpath:descriptor/name" /></li>
        </div>
</ul>
</span>

Output
======


    * New entityRelationship.familyMember
    * New entityRelationship.familyMember
    * New entityRelationship.familyMember
    * New entityRelationship.familyMember
    * New entityRelationship.familyMember
    * New entityRelationship.familyMember
    * New entityRelationship.familyMember
    * New entityRelationship.familyMember
    * New entityRelationship.familyMember




The problem I am getting is that the component renders a list as expected but each eisntry in th list is the same. When I trace through the JXPathBinding code I see that the getObject is called once and the setObject is called multiple times, once for each iteration in the @For component. I am mostly stuck at this stage.


I have included the JXPathBinding code below.

// common-jxpath
import java.util.StringTokenizer;

import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.lang.StringUtils;

// jakarta-hivemind
import org.apache.hivemind.Location;
import org.apache.hivemind.util.PropertyUtils;

// log4j
import org.apache.log4j.Logger;

// jakarta-tapestrty
import org.apache.tapestry.IComponent;
import org.apache.tapestry.binding.AbstractBinding;
import org.apache.tapestry.coerce.ValueConverter;

/**
 * This class supports JXPath value bindings in Tapestry
 *
 * @author <a href="mailto:[EMAIL PROTECTED]">OpenVPMS Team</a>
 * @version $LastChangedDate$
 */
public class JXPathBinding extends AbstractBinding {
    @SuppressWarnings("unused")
    private static final Logger logger = Logger
            .getLogger(JXPathBinding.class);


    private IComponent root;

    private String contextObjectName;

    private String path;

public JXPathBinding(String description, ValueConverter valueConverter,
            Location location, IComponent root, String path) {
        super(description, valueConverter, location);

        if (StringUtils.isEmpty(path)) {
            throw new JXPathBindingException(
                    JXPathBindingException.ErrorCode.InvalidPathSpecified,
                    new Object[] {path, root.getPage().getPageName()});
        }

        StringTokenizer tokens = new StringTokenizer(path, "/");
        if (tokens.countTokens() == 0) {
            // means that there are no forward slashes and that the
            // complete path references a property on the page.
            this.contextObjectName = path;
            this.root = root;
            this.path = null;
        } else {
            this.contextObjectName = tokens.nextToken();
            this.root = root;

            // concatenate the remaining tokens to make the path
            StringBuffer buf = new StringBuffer();
            while (tokens.hasMoreTokens()) {
                if (buf.length() > 0) {
                    buf.append("/");
                }
                buf.append(tokens.nextToken());
            }

            this.path = buf.toString();
        }
    }

    public Object getObject() {
        if (logger.isDebugEnabled()) {
            logger.debug("JXPathBinding.getObject is called with " +
                    contextObjectName);
        }

        Object object = PropertyUtils.read(root, contextObjectName);
        if (!StringUtils.isEmpty(path)) {
            object  = JXPathContext.newContext(object).getValue(path);
        }

        return object;
    }

    @Override
    public void setObject(Object value) {
        if (logger.isDebugEnabled()) {
            logger.debug("JXPathBinding.setObject is called.");
        }

        if (StringUtils.isEmpty(path)) {
            // we are setting a root object for the page
            PropertyUtils.write(root, contextObjectName, value);
        } else {
            JXPathContext.newContext(PropertyUtils
                    .read(root, contextObjectName)).setValue(path, value);
        }
    }

    @Override
    public boolean isInvariant() {
        // disable caching at this stage
        return false;
    }
}


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to