Results 1 to 10 of 10

Thread: Nested object's properties labels & validation

  1. #1
    Join Date
    Nov 2004
    Posts
    14

    Default Nested object's properties labels & validation

    I am having two (related) problems with nested object properties. The first is that the form is not displaying the labels for a nested object's properties. The second is that no validations (i.e. RuleSource...) are applied to the nested object's properties either. If the nested object is put on the form by itself, the labels and validation show up on the form.

    Example,

    Code:
    class Aggregate
     Child child;
     Child getChild() {return child;}
    
    class Child
     String value;
     String getValue(){return value;}
    In the message file,
    Code:
    value.label=Value:
    If an instance of Child is put on to a form, the label "Value:" show up.

    On the form for Aggregate, I have added "child.value" on the form but the label for value did not show up. The string "child.value.label" is displayed instead. The validation for value is not applied to the field either.

    I have found two workarounds so far for the labels part of the problem; both of which seem rather kludgy. The first, is to add another entry in the message file... i.e.

    Code:
    child.value.label=Value
    value.label=Value
    Shouldn't it be able to pick up the label for value for the nested object child instead of having to duplicate the entries in the message file?

    The second is for a to "nest" itself. e.g.

    Code:
    class Child
    {
      String value;
      String getValue(){return value;}
      Child getChild()
      {
          return this;
      }
    }
    This way I can have 1 entry in the message file, but writing a getter to get a reference to an instance of myself seems a bit odd.

    Any comments, folks?
    Thanks

    Henry

  2. #2
    Join Date
    Aug 2004
    Location
    Melbourne, Australia
    Posts
    335

    Default

    hszetu,

    I've refined the message key lookup strategy; it will now try to "unroll" any nested form property paths e.g. for the path "child.value" the system will first check for a message with key "child.value.label" and if that fails it will check for the key "value.label".

    I'm not sure about the validation problem you should probably file a bug in Jira.

    Ollie

  3. #3
    Join Date
    Nov 2004
    Posts
    14

    Default

    Thanks Ollie for your prompt response.

    Another question?

    If I have a common field name that I want to have different labels, how would I specify it in the message.properties file? For example, class Customer and class Employee, both have the field called "name". How do I configure my messages.properties file (and other files) such that the customer form displays "Customer Name" and the Employee form displays "Employee Name"?

    Currently, the only way I have found to do this is to introduce a "self-nesting" method into each class - i.e. in the Customer class I add a "getCustomer()" method that returns "this", and similarly in the Employee class I add a "getEmployee()" method that returns "this". "This" being an instance to its respective object.

    Then in my messages.properties file, I have the following:
    employee.name.label=Employee Name
    customer.name.label=Customer Name

    Although this works, and seems quite elegant in most places, it seems a bit funny that I have to code a getXXXX() methods that return instances of themselves...

    Any better way of doing this or other thoughts?

    Henry

  4. #4
    Join Date
    Aug 2004
    Location
    Melbourne, Australia
    Posts
    335

    Default

    If your customer/employee forms have an id then this will be also used for the message key lookup. So say the customer form has id "customerForm" then the folowing messages keys will be used to resolve the label:

    customerForm.name.label
    name.label

    HTH

    Ollie

  5. #5

    Default

    Quote Originally Posted by oliverhutchison
    If your customer/employee forms have an id then this will be also used for the message key lookup. So say the customer form has id "customerForm" then the folowing messages keys will be used to resolve the label:

    customerForm.name.label
    name.label
    Ollie, this is good idea. I thinking is good to also allow message key lookup based on class name of domain object. That way, if you having Customer on more than one form (may seem strange but is actually common), you have to put its "Customer Name" in message file only once.

    So, you can have something like this:
    Code:
    Customer.class.name.label=Customer Name
    Instead of this:
    Code:
    customerForm.name.label=Customer Name
    anotherCustomerForm.name.label=Customer Name
    andYesYetAnotherCustomerForm.name.label=Customer Name
    What you thinking about this one?
    Stefano Rossi

    "If I want your opinion, I'll give it to you."

  6. #6
    Join Date
    Nov 2004
    Posts
    14

    Default

    I would agree with Stefano, that is a very nice feature to have if labels can be also based on domain object classes. As the client name will eventually be put on many other forms that display other info related to the client. So, we don't have to add the label for each form in the message file.


    I have just got Ollie's update from CVS, when I run the app, I got this exception.
    Code:
    java.lang.ArrayIndexOutOfBoundsException: 2
    	at org.springframework.binding.form.support.MessageSourceFormPropertyFaceDescriptorSource.insertKeys(MessageSourceFormPropertyFaceDescriptorSource.java:167)
    	at org.springframework.binding.form.support.MessageSourceFormPropertyFaceDescriptorSource.getMessageKeys(MessageSourceFormPropertyFaceDescriptorSource.java:157)
    	at org.springframework.binding.form.support.MessageSourceFormPropertyFaceDescriptorSource.getMessage(MessageSourceFormPropertyFaceDescriptorSource.java:137)
    	at org.springframework.binding.form.support.MessageSourceFormPropertyFaceDescriptorSource.loadFormPropertyFaceDescriptor(MessageSourceFormPropertyFaceDescriptorSource.java:89)
    	at org.springframework.binding.form.support.AbstractCachingPropertyFaceDescriptorSource.getFormPropertyFaceDescriptor(AbstractCachingPropertyFaceDescriptorSource.java:56)
    	at org.springframework.binding.form.support.AbstractFormModel.getFormPropertyFaceDescriptor(AbstractFormModel.java:200)
    	at org.springframework.richclient.forms.SwingFormModel.getFormPropertyFaceDescriptor(SwingFormModel.java:302)
    	at org.springframework.richclient.forms.SwingFormModel.createLabel(SwingFormModel.java:465)
    	at org.springframework.richclient.form.builder.AbstractFormBuilder.getLabelFor(AbstractFormBuilder.java:86)
    	at org.springframework.richclient.forms.JGoodiesBeanFormBuilder.add(JGoodiesBeanFormBuilder.java:59)
    ...
    The problem seems to be in the class MessageSourceFormPropertyFaceDescriptorSource

    Code:
    protected String[] getMessageKeys(FormModel formModel, String formPropertyPath, String faceDescriptorProperty) {
            boolean hasFormId = StringUtils.hasText(formModel.getId());
            String[] formPropertyPathElements = StringUtils.delimitedListToStringArray(formPropertyPath, ".");
            String[] keys = new String[hasFormId ? 2*formPropertyPathElements.length : formPropertyPathElements.length];
            int keyCount = 0;
            if (hasFormId) {
                String prefix = formModel.getId() + '.';
                insertKeys(keys, 0, prefix, formPropertyPathElements, faceDescriptorProperty);            
            }
            insertKeys(keys, formPropertyPathElements.length, "", formPropertyPathElements, faceDescriptorProperty);   
            return keys;
        }

    My form might not have a form id and using formPropertyPathElements.length as startIndex throws that exception. The proposed fix is

    Code:
            int startIndex = 0;
            if (hasFormId) {
                String prefix = formModel.getId() + '.';
                insertKeys(keys, startIndex, prefix, formPropertyPathElements, faceDescriptorProperty);
                startIndex = formPropertyPathElements.length;
            }
            insertKeys(keys, startIndex, "", formPropertyPathElements, faceDescriptorProperty);   
            return keys;

  7. #7
    Join Date
    Aug 2004
    Location
    Melbourne, Australia
    Posts
    335

    Default

    I would agree with Stefano, that is a very nice feature to have if labels can be also based on domain object classes. As the client name will eventually be put on many other forms that display other info related to the client. So, we don't have to add the label for each form in the message file.
    If someone has the time to write a patch for this I'll be happy to review and commit the change.

    I have just got Ollie's update from CVS
    :oops: i obviously only tested with a form id. fixed.

    Ollie

  8. #8
    Join Date
    Sep 2006
    Location
    Belgium
    Posts
    70

    Default

    Hi,

    I have form with id='searchForm' and in this form I have a model with a property 'reference'. Now I want to set a label for this property.

    If add in the message.properties:

    Code:
    reference.label=&Reference
    it works

    but with

    Code:
    searchForm.reference.label=&Reference
    it does'nt?!?

    This prevent me to have the same propertyname in different forms having different label, because the formId is not taking into account in the search lable key.

    The form extends AbstractForm and it is create with

    Code:
            SearchForm searchForm = new SearchForm(searchFormModel,"searchForm");
    Any Idea?

  9. #9
    Join Date
    Jan 2006
    Location
    Vilnius, Lithuania
    Posts
    68

    Default

    I think that labels are looked up by FormModel id, not Form id. Try passing "searchForm" to your model's constructor, or calling formModel.setId(...), if your model is a ConfigurableFormModel.

  10. #10
    Join Date
    Sep 2006
    Location
    Belgium
    Posts
    70

    Default

    Thanks it works, I added a parameter in the creation method

    Code:
    ValidatingFormModel searchFormModel = FormModelHelper
    				.createFormModel(searchModel,"searchFormModel");
    and then I can use:

    Code:
    searchFormModel.reference.label=&Reference
    Thanks
    Dominique

Similar Threads

  1. FlowExecutionStorage in a DB
    By cacho in forum Web Flow
    Replies: 7
    Last Post: Oct 19th, 2009, 03:36 PM
  2. Binding composite properties with DataBinder
    By dhewitt in forum Architecture
    Replies: 16
    Last Post: Jun 1st, 2007, 06:22 AM
  3. Replies: 2
    Last Post: Oct 10th, 2005, 05:12 PM
  4. Context initialization failed
    By kanonmicke in forum Container
    Replies: 7
    Last Post: Sep 29th, 2005, 12:35 AM
  5. Replies: 0
    Last Post: Oct 29th, 2004, 04:53 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •