Hi all,

I'm working on a property editor block. My Patient object contains an embeddable PersonName object.

@Embeddable
public class PersonName {
  String prefix;
  String given;
  String family;

  public String getFormattedName() {
    String s = this.prefix;
    if (!s.isEmpty()) {
      s += " ";
    }
    s += this.given;
    if (!s.isEmpty()) {
      s += " ";
    }
    s += this.family;

    return s;

  }

I want BeanEditor to automatically generate 3 text boxes, one for each string.

I've written an AppPropertyEditBlock.java
package au.gov.nehta.eps.pages;


import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Field;
import org.apache.tapestry5.FieldTranslator;
import org.apache.tapestry5.FieldValidator;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.TextField;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.PropertyEditContext;

import au.gov.nehta.eps.entities.PersonName;

public class AppPropertyEditBlocks {
  @Property
  @Environmental
  private PropertyEditContext context;

  @Component(parameters =
  { "label=prop:context.label",
"translate=prop:prefixTranslator", "validate=prop:prefixValidator", "clientId=prop:context.propertyId", "annotationProvider=context" })
  private TextField prefix;

  @Component(parameters =
  { "label=prop:context.label",
"translate=prop:prefixTranslator", "validate=prop:prefixValidator", "clientId=prop:context.propertyId", "annotationProvider=context" })
  private TextField given;

  @Component(parameters =
  { "label=prop:context.label",
"translate=prop:prefixTranslator", "validate=prop:prefixValidator", "clientId=prop:context.propertyId", "annotationProvider=context" })
  private TextField family;

  @Inject
  private ComponentResources resources;

  public FieldValidator getPrefixValidator()
  {
    return this.context.getValidator((Field) this.prefix);
  }

  public FieldTranslator getPrefixTranslator()
  {
    return this.context.getTranslator((Field) this.prefix);
  }

  public PersonName getPersonName() {
    return (PersonName) this.context.getPropertyValue();
  }
}

With page template:
<html t:type="layout" title="sampleImpl Index"
      t:sidebarTitle="Current Time"
      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";
      xmlns:p="tapestry:parameter">

<t:block id="personName">
<t:label for="prefix"/>
<t:textfield t:id="prefix" size="10" t:value="personName.prefix"/>
<t:textfield t:id="given" size="10" t:value="personName.given"/>
<t:textfield t:id="family" size="10" t:value="personName.family"/>
</t:block>

</html>


I've also written a translator:
package au.gov.nehta.eps.translators;

import org.apache.tapestry5.Field;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.ValidationException;
import org.apache.tapestry5.internal.translator.AbstractTranslator;
import org.apache.tapestry5.services.FormSupport;

import au.gov.nehta.eps.entities.PersonName;

public class PersonNameTranslator extends AbstractTranslator<PersonName> {

  public PersonNameTranslator() {
    super("personName", PersonName.class, "personname-format-exception");
  }

  @Override
  public String toClient(PersonName value) {

    return value == null ? null : value.getFormattedName();
  }

  @Override
public PersonName parseClient(Field field, String clientValue, String message)
      throws ValidationException {
    if (clientValue == null) {
      return null;
    }

    PersonName name = new PersonName();
    name.setPrefix(clientValue);

    return name;
  }

  @Override
  public void render(Field field, String message, MarkupWriter writer,
      FormSupport formSupport) {
    // TODO Auto-generated method stub

  }


}

AppModule contains:
    /**
     * Contribution to the BeanBlockSource service to tell the BeanEditForm
     * component about the editors.
     */
    public static void contributeBeanBlockSource(
            Configuration<BeanBlockContribution> configuration) {
        configuration.add(new EditBlockContribution("personname",
                "AppPropertyEditBlocks", "personname"));
    }

    @SuppressWarnings("rawtypes")
public static void contributeTranslatorSource(MappedConfiguration<Class, Translator> configuration) {
        configuration.add(PersonName.class, new PersonNameTranslator());
    }

But when I go to the page with the BeanEdit block I get:


 An unexpected application exception has occurred.

   * org.apache.tapestry5.internal.services.RenderQueueException
     Render queue error in BeginRender[AppPropertyEditBlocks:prefix]:
     Could not find a coercion from type java.lang.String to type
     au.gov.nehta.eps.entities.PersonName.

     activeComponents
             o patients/Detail (class
               au.gov.nehta.eps.pages.patients.Detail)
             o patients/Detail:layout (class
               au.gov.nehta.eps.components.Layout)
               classpath:au/gov/nehta/eps/pages/patients/Detail.tml,
               line 4
               1        <html t:type="layout" title="sampleImpl Index"
               2        t:sidebarTitle="Current Time"
               3
               xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";

               4        xmlns:p="tapestry:parameter">
               5        
               6        <h2>Patient Detail</h2>
               7        <br/>
               8        
               9        <t:beaneditform t:id="patient" object="patient"
               include="patientName,ihi,born,gender"
               submitLabel="Save"/><br/>

             o patients/Detail:patient (class
               org.apache.tapestry5.corelib.components.BeanEditForm)
               classpath:au/gov/nehta/eps/pages/patients/Detail.tml,
               line 9
               4        xmlns:p="tapestry:parameter">
               5        
               6        <h2>Patient Detail</h2>
               7        <br/>
               8        
               9        <t:beaneditform t:id="patient" object="patient"
               include="patientName,ihi,born,gender"
               submitLabel="Save"/><br/>
               10       <br/>
               11       
               12       <h2>Prescriptions</h2>
               13       <br/>
               14       

             o patients/Detail:patient.form (class
               org.apache.tapestry5.corelib.components.Form)
               
classpath:org/apache/tapestry5/corelib/components/BeanEditForm.tml,
               line 2
               1        <form t:id="form" validate="object"
               2
               xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>

               3        <t:errors/>
               4        
               5        <div class="t-beaneditor">
               6        
               7        <t:beaneditor t:id="editor" object="object"
               model="model" overrides="this"/>

             o patients/Detail:patient.editor (class
               org.apache.tapestry5.corelib.components.BeanEditor)
               
classpath:org/apache/tapestry5/corelib/components/BeanEditForm.tml,
               line 7
               2
               xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>

               3        <t:errors/>
               4        
               5        <div class="t-beaneditor">
               6        
               7        <t:beaneditor t:id="editor" object="object"
               model="model" overrides="this"/>
               8        
               9        <div class="t-beaneditor-row">
               10       <input type="submit" class="t-beaneditor-submit"
               value="${submitLabel}"/>
               11       <t:if test="cancel">
               12       <t:submit t:id="cancel" mode="cancel"
               value="message:cancel-label"/>

             o patients/Detail:patient.editor.loop (class
               org.apache.tapestry5.corelib.components.Loop)
               classpath:org/apache/tapestry5/corelib/components/BeanEditor.tml,
               line 2
               1        <div
               xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";
               xml:space="default" class="t-beaneditor-row"
               2        t:type="loop" t:source="model.propertyNames"
               t:formState="ITERATION" t:value="propertyName">
               3        <t:propertyEditor property="propertyName"
               object="object" model="model" overrides="overrides"/>
               4        </div>

             o patients/Detail:patient.editor.propertyeditor (class
               org.apache.tapestry5.corelib.components.PropertyEditor)
               classpath:org/apache/tapestry5/corelib/components/BeanEditor.tml,
               line 3
               1        <div
               xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";
               xml:space="default" class="t-beaneditor-row"
               2        t:type="loop" t:source="model.propertyNames"
               t:formState="ITERATION" t:value="propertyName">
               3        <t:propertyEditor property="propertyName"
               object="object" model="model" overrides="overrides"/>
               4        </div>

             o AppPropertyEditBlocks:prefix (class
               org.apache.tapestry5.corelib.components.TextField)
               classpath:au/gov/nehta/eps/pages/AppPropertyEditBlocks.tml,
               line 8
               3
               xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";

               4        xmlns:p="tapestry:parameter">
               5        
               6        <t:block id="personName">
               7        <t:label for="prefix"/>
               8        <t:textfield t:id="prefix" size="10"
               t:value="personName.prefix"/>
               9        <t:textfield t:id="given" size="10"
               t:value="personName.given"/>
               10       <t:textfield t:id="family" size="10"
               t:value="personName.family"/>
               11       </t:block>
               12       
               13       </html>


I don't understand why I need a type coercer from String to PersonName. I've read the BeanEditForm Guide here: http://tapestry.apache.org/beaneditform-guide.html

The documentation is a little out of date as it mentions BeanBlockContribution when it should refer to EditBlockContribution and perhaps DisplayBlockContribution as BeanBlockContribution is deprecated.

I'd appreciate any assistance.

Regards,

Greg

Reply via email to