Announcement Announcement Module
Collapse
No announcement yet.
Possible Roo bug with Converters? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Possible Roo bug with Converters?

    Not sure if this is a bug or not, but when you move a Converter out of the Roo Aspect of a Controller, the call to the converter in registerConverters is removed.

    Example:
    Move OwnerController.getOwnerConverter out of OwnerController_Roo_Controller.aj and into OwnerController.java

    Roo reports Managed OwnerController_Roo_Controller.aj

    Upon looking at the new OwnerController_Roo_Controller.aj, the getOwnerConverter function was removed as expected, but the call to it in OwnerController.registerConverters (in the OwnerController_Roo_Controller.aj) was removed as well.

    I had to move the registerConverters function into OwnerController.java and replace the conversionService.addConverter(getOwnerConverter() ) back in.

    I would think it wouldn't need to remove the conversionService.addConverter call from the registerConverters.


    I also found that moving registerConverters function into the .java file, causes Roo to delete all converters from the Roo_Controller.aj
    Last edited by btlife; Sep 12th, 2010, 12:29 PM.

  • #2
    Well I didn't get a response to this so I am not sure if its a bug or not.

    I installed the new versions:
    Spring Roo: 1.1.0.RELEASE

    My goal was to change how the converter was converting an object to string.

    The default was defined, int ROO_Controller.aj, as:
    Code:
        Converter<Employee, String> getEmployeeConverter() {
            return new Converter<Employee, String>() {
                public String convert(Employee employee) {
                    return new StringBuilder().append(employee.getFirstName()).append(" ").append(employee.getLastName()).append(" ").append(employee.getTelephone()).toString();
                }
            };
        }

    Well say I only want the LastName and FirstName and want to change the order so I get something like "LastName, FirstName" and leave off the telelphone.

    So like normal, I "Push In" the convert function into the Controller.
    Works fine, Roo picks it up and removes it from ROO_Controller.aj.
    Unfortunately, as stated above, the call to the function is removed as well from registerConverters.

    Well, as stated before, I don't think this is supposed to happen, I didn't change or want anything to change in the registerConverters function. But maybe that's something AspectJ needs in order to do its thing.

    So I "Push In" the registerConverters function and add back the call to the employeeConverter.

    Now it complains that it can't find the conversionService variable, it's still in the .aj file defined as:
    Code:
        @Autowired
        private GenericConversionService conversionService;

    Ok so I "Push In" the conversionService variable.

    Roo notices the change and pops up an error.

    [FelixDispatchQueue] Field 'conversionService' already defined in target type 'com.iaim.subaru.web.DealerController' (ITD target 'com.iaim.subaru.web.DealerController_Roo_Controll er')
    So it seems ROO can't move the conversionService variable from the .aj file to the Java File. Not exactly sure why.

    So, again, is this a bug, or am I just doing this wrong? What is the process for adding a Converter, or modifying an existing one, in relation to ROO?

    As stated in the documenation Spring Roo Section 9.1:
    Converter<Person, String> getPersonConverter() {..}
    Creates a better visual representation of Person instances (used to replace the default Roo generated Person.toString() method). This method can be adjusted if different visual representations of the Person instance are desired.
    Well I know can't make the adjustment in the ROO handled .aj file, so what is the process for overriding ROO, so I can make the adjustment, if roo doesn't seem to be handling the "Push In" in this case?

    Thanks a lot for any help!!!

    Comment


    • #3
      I see Converters are being discussed with ROO-1655

      Would still like to know the proper process for changing the logic a Converter uses, or adding a new Converter, in relation to ROO.

      For now I just disabled the converters using

      Code:
      @RooWebScaffold(registerConverters=false)
      Thanks

      Comment


      • #4
        Also found this which describes my issue: ROO-1715

        Looks like a change was made to attempt to resolve Pushing In the registerConverters with 1.1.1.RELEASE and I am using 1.1.0.RELEASE so I'll try the new version.

        Thanks

        Comment


        • #5
          btlife did upgrating to roo 1.1.1.RELEASE fixe this issue for you. I'm using 1.1.0.RELEASE [rev 793f2b0].

          Comment


          • #6
            Originally posted by alaniel View Post
            btlife did upgrating to roo 1.1.1.RELEASE fixe this issue for you. I'm using 1.1.0.RELEASE [rev 793f2b0].

            I haven't tried it yet, since 1.1.1.RELEASE hasn't been "released" yet, I would have to pull the unreleased version. So I worked around it, by not changing the converters and changed the stuff I needed to not use toString or the converters, and use the actual fields.

            It wouldn't let me override the converters because of the issue with the private ConversionService variable, which I guess is fixed in the 1.1.1.RELEASE. The @RooWebScaffold(registerConverters=false) partially worked since it did allow me to use the toString(), but then it left field collections (defined as sets) without a toString() which resulted in unable to convert errors. So I decided to just leave it as is, and just changed things to use specific fields instead of letting it fall through to the toString().

            I'm going to try out 1.1.1.RELEASE once it "officially" comes out.

            I also changed the Roo select.tagx to allow the itemLabel to be passed in, so I could specify which field I wanted as the display field. The Roo generated select.tagx allows you to set the itemValue field which translates to the id part of the option list, and then does a toString()/Converter to determine the display value of the option list. By passing in the itemLabel, I can now tell the select.tagx which field I want displayed in the display part of the option list.

            Hope that all makes sense

            Comment


            • #7
              In case anyone can use it, the lines I added are in bold, everything not in bold, should be exactly what ROO generated:

              Code:
              <jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:spring="http://www.springframework.org/tags" xmlns:form="http://www.springframework.org/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
                <jsp:output omit-xml-declaration="yes" />
              
                <jsp:directive.attribute name="id" type="java.lang.String" required="true" description="The identifier for this tag (do not change!)" />
                <jsp:directive.attribute name="field" type="java.lang.String" required="true" description="The field exposed from the form backing object" />
                <jsp:directive.attribute name="path" type="java.lang.String" required="true" description="The relative path to the referenced resource" />
                <jsp:directive.attribute name="items" type="java.util.Collection" required="true" description="The name of the collection displayed in the select box" />
                <jsp:directive.attribute name="label" type="java.lang.String" required="false" description="The label used for this field, will default to a message bundle if not supplied" />
                <jsp:directive.attribute name="itemValue" type="java.lang.String" required="false" description="The identifier used as value in the select box (defaults to 'id' for non enum types)" />
                <jsp:directive.attribute name="itemLabel" type="java.lang.String" required="false" description="The identifier used as label in the select box (defaults to 'id' for non enum types)" />  <jsp:directive.attribute name="required" type="java.lang.Boolean" required="false" description="Indicates if this field is required (default false)" />
                <jsp:directive.attribute name="disabled" type="java.lang.Boolean" required="false" description="Specify if this field should be enabled" />
                <jsp:directive.attribute name="multiple" type="java.lang.Boolean" required="false" description="Specify if the select box should allow multiple selections" />
                <jsp:directive.attribute name="disableFormBinding" type="java.lang.Boolean" required="false" description="Set to true to disable Spring form binding" />
                <jsp:directive.attribute name="render" type="java.lang.Boolean" required="false" description="Indicate if the contents of this tag and all enclosed tags should be rendered (default 'true')" />
                <jsp:directive.attribute name="z" type="java.lang.String" required="false" description="Used for checking if element has been modified (to recalculate simply provide empty string value)" />
              
                <c:if test="${empty render or render}">
              
                  <c:if test="${empty disabled}">
                    <c:set value="false" var="disabled" />
                  </c:if>
              
                  <c:if test="${empty label}">
                    <spring:message code="label_${fn:toLowerCase(fn:substringAfter(id,'_'))}" var="label" />
                  </c:if>
              
                  <c:if test="${empty required}">
                    <c:set value="false" var="required" />
                  </c:if>
              
                  <c:if test="${empty multiple}">
                    <c:set value="false" var="multiple" />
                  </c:if>
                  
                  <c:set var="sec_field">
                    <spring:escapeBody javaScriptEscape="true" >${field}</spring:escapeBody>
                  </c:set>
              
                  <div id="_${fn:escapeXml(id)}_id">
                    <c:choose>
                      <c:when test="${not empty items}">
                        <label for="_${sec_field}_id">
                          <c:out value="${fn:escapeXml(label)}" />
                          :
                        </label>
                        <c:choose>
                          <c:when test="${empty itemValue}">
                            <c:choose>
                              <c:when test="${disableFormBinding}">
                                <select id="_${sec_field}_id" name="${sec_field}" multiple="${multiple}">
                                  <c:forEach items="${items}" var="item">
                                    <option value="${item}">
                                      <spring:eval expression="item" />
                                    </option>
                                  </c:forEach>
                                </select>
                              </c:when>
                              <c:otherwise>
                              	<c:choose>
                              		<c:when test="${not empty itemLabel }">
                        			     <form:select id="_${sec_field}_id" items="${items}" path="${sec_field}" itemLabel="${itemLabel }" disabled="${disabled}" multiple="${multiple}" />
                                		</c:when>
                                		<c:otherwise>
                          			    <form:select id="_${sec_field}_id" items="${items}" path="${sec_field}" disabled="${disabled}" multiple="${multiple}" />
              			        </c:otherwise>
              		          </c:choose>                  		
                                <br />
                                <form:errors cssClass="errors" id="_${sec_field}_error_id" path="${sec_field}" />
                              </c:otherwise>
                            </c:choose>
                          </c:when>
                          <c:otherwise>
                            <c:choose>
                              <c:when test="${disableFormBinding}">
                                <select id="_${sec_field}_id" name="${sec_field}" multiple="${multiple}">
                                  <c:forEach items="${items}" var="item">
                                    <option value="${item[fn:escapeXml(itemValue)]}">
                                      <spring:eval expression="item" />
                                    </option>
                                  </c:forEach>
                                </select>
                              </c:when>
                              <c:otherwise>
                              	<c:choose>
                              		<c:when test="${not empty itemLabel }">
              				    <form:select id="_${sec_field}_id" items="${items}" path="${sec_field}" disabled="${disabled}" multiple="${multiple}" itemValue="${fn:escapeXml(itemValue)}" itemLabel="${fn:escapeXml(itemLabel)}"/>
                                		</c:when>
                                		<c:otherwise>
              				    <form:select id="_${sec_field}_id" items="${items}" path="${sec_field}" disabled="${disabled}" multiple="${multiple}" itemValue="${fn:escapeXml(itemValue)}" />
              				</c:otherwise>
              			</c:choose>                  		
                                <br />
                                <form:errors cssClass="errors" id="_${sec_field}_error_id" path="${sec_field}" />
                              </c:otherwise>
                            </c:choose>
                          </c:otherwise>
                        </c:choose>
                        <c:choose>
                          <c:when test="${multiple == false}">
                            <script type="text/javascript">Spring.addDecoration(new Spring.ElementDecoration({elementId : '_${sec_field}_id', widgetType: 'dijit.form.FilteringSelect', widgetAttrs : {hasDownArrow : true}})); </script>
                          </c:when>
                          <!-- disabled due to http://jira.springframework.org/browse/ROO-909 <c:otherwise> <script type="text/javascript">Spring.addDecoration(new Spring.ElementDecoration({elementId : '_${field}_id', widgetType: 'dijit.form.MultiSelect', widgetAttrs : {}})); </script> </c:otherwise> -->
                        </c:choose>
                      </c:when>
                      <c:otherwise>
                        <field:reference field="${label}" id="${id}" path="${path}" required="${required}" />
                      </c:otherwise>
                    </c:choose>
                  </div>
                  <br />
              
                </c:if>
              </jsp:root>

              Comment


              • #8
                Thanks btlife. It worked like a charm and its going to do until the next release.

                Comment


                • #9
                  Example please?

                  Hi,

                  I've run into a problem with form/field/select.tagx -- it displays a pretty useless string of choices to the user, ignoring toString() of my entity, and instead displaying "null,null,[email protected]"
                  which looks to be the output of the previous 'toString()' implementation.

                  It ultimately get's the right underlying identifier and works, but the presentation is not acceptable.

                  I grabbed your code, which looks like a good fix, giving me an 'itemLabel' attribute. However, I'm not sure how to use it.


                  <field:select field="partyId" itemLabel="${item['fullLegalName']}" id="c_com_xpertservices_domain_Address_partyId" itemValue="id" items="${partys}" path="/partys" z="MQ1zYsUqg2hN0WWUxXxDlIP+3Uc="/>

                  The example above is attempting to select the Party that owns a given address

                  But that didn't work. I'm not that familar with tag libs. Can you point me to the right expression to use for the label? I'd like to either rely on the toString() method of the
                  item, or a chosen field, such as fullLegalName

                  Also, is there some easy way to filter the lists generated by field:select? If not, I'll have a
                  scalability issue with my user interface

                  Mark

                  Comment


                  • #10
                    Using the pet clinic example, if you run it as is and create an owner, then try and create a pet. The Owner drop-down box displays firstName, lastName, address with a space between each field.

                    After modifying the select.tagx to add the itemLabel attribute, I changed create.jspx in the pets folder.

                    Code:
                    <field:select field="owner" itemLabel="firstName" id="c_com_springsource_petclinic_domain_Pet_owner" itemValue="id" items="${owners}" path="/owners" z="fGzswAP4XXvhPhowJKsRVve929c="/>
                    Setting itemLabel = to firstName causes it to only display the firstName field in the drop down.

                    So in your case it would be itemLabel="fullLegalName".

                    As for the filter, not sure exactly how you are wanting to filter. But you could create a finder that returns the collection you want for the select box.
                    PushIn the populateOwners function from the Roo_Controller.aj into the Controller.java file, and change it to the finder.

                    Example (using clinic.roo):
                    Code:
                    roo> finder add findOwnersByLastNameLike
                    Then "push in" the populateOwners into the PetController.java from the PetController_Roo_Controller.aj and changing it to use the new finder function:
                    Code:
                        @ModelAttribute("owners")
                        public Collection<Owner> populateOwners() {
                            return Owner.findOwnersByLastNameLike("A").getResultList();
                        }
                    I hardcoded an A in there so it will filter and only bring back owners that have an A in their last name.

                    Now when I create a new Pet, only Owners that have an A in their last name are presented in the drop-down.

                    Comment


                    • #11
                      This helps as well showing the build in spring tags available:


                      http://static.springsource.org/sprin...-form.tld.html

                      Following the tag namespace in the jspx created by roo

                      create.jspx has xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields"

                      so field:select is coming from /tags/form/fields/select.tagx

                      In select.tagx xmlns:form="http://www.springframework.org/tags/form"

                      so <form:select is coming from the spring form tag library.

                      The above link is to the documentation for all the spring form tags.

                      Hope this helps.

                      Comment


                      • #12
                        Thanks!!

                        the itemLabel="fullLegalName" works great. I'd actually, like to add the email address if any to make it "Mark Riggins:[email protected]" just in case we have more than one Mark Riggins in the system.

                        Also, Now I need to weave my system together. All roo generated is 32 independent forms,
                        one for each of my entities. Which is totally unusable for anyone unless they know the schema by heart.

                        Is there anyway to generate the forms or integrate the existing forms to do use cases like this:

                        1) Add or Update an Address for the current Party that we are updating
                        2) Add or Update an Phone number for the current Party that we are updating
                        3) Lookup and select one of the Party's Addresses when creating an Order for a Party,
                        to set the Order.shippingAddress

                        Basically, I'd like a bit more of an explorer interface that allows users to create/edit the
                        associated Party children while they are creating/editing the party

                        Comment


                        • #13
                          Is itemLabel standard now?

                          Nice ref page. I'll bookmark that for sure

                          But I had to hand-edit my select.tagx file to add your changes so that it
                          would accept the itemLabel argument. However, on the linked page you just sent me
                          itemLabel is a standard attribute.

                          I downloaded and installed the latest STS 2.5.1.RELEASE about 7 days ago, with roo 1.1.0. Are my tagx files out of date?

                          This all came from ~/springsource/tc-server-developer-2.1.0.RELEASE/spring-insight-instance/wtpwebapps/XpertServices/WEB-INF/tags/form/fields/select.tagx

                          Is that the right release of tc-server-developer?

                          Mark



                          Originally posted by btlife View Post
                          This helps as well showing the build in spring tags available:


                          http://static.springsource.org/sprin...-form.tld.html

                          Following the tag namespace in the jspx created by roo

                          create.jspx has xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields"

                          so field:select is coming from /tags/form/fields/select.tagx

                          In select.tagx xmlns:form="http://www.springframework.org/tags/form"

                          so <form:select is coming from the spring form tag library.

                          The above link is to the documentation for all the spring form tags.

                          Hope this helps.

                          Comment


                          • #14
                            Where does select.tagx reside on my system?

                            Sorry to be such a newbie pest.

                            I'd like to make the edits to select.tagx stick, so that they will become part of any new projects that I create, but I can't seem to find the source file.


                            The spring-webmvc-3.0.4.RELEASE.jar file contains a SelectTag.class file.

                            Mark

                            Comment


                            • #15
                              Originally posted by markriggins View Post
                              the itemLabel="fullLegalName" works great. I'd actually, like to add the email address if any to make it "Mark Riggins:[email protected]" just in case we have more than one Mark Riggins in the system.
                              One way is to create your own "special" tag, like select2Fields.tagx, and add 2 attributes, field1, and field2, then modifiy the code to concat both the fields in the <form:select>.

                              or write your own select.tagx that accepts a list of field name to concat.
                              or copy the code from select.tagx into the jspx file and modify it just for the specific case.

                              Or on the server side, you could create a transient field that concats the fields and then use that field instead on the itemLabel.

                              Code:
                              @Transient
                              public String fullLegalNameAndAddress() {
                              StringBuilder sb = new StringBuilder();
                              sb.append(this.fullLegalName).append(" ").append(this.emailAddress);
                              return sb.toString();
                              }
                              Just depends on what makes most since for your project.

                              Comment

                              Working...
                              X