PDA

View Full Version : CustomCollectionEditor - convertElement Issue



whardwick
Jul 27th, 2009, 11:05 PM
I am currently trying to setup admin pages for Spring Security groups and authorities (or roles and permissions). The page will allow for the selection/deselection of Authorities for a specific Group. I have a GroupFormController where I am registering a CustomCollectionEditor as follows:



@Override
protected void initBinder(HttpServletRequest req, ServletRequestDataBinder binder) throws Exception {
super.initBinder(req, binder);
binder.registerCustomEditor(Set.class, "groups.authorities", new AuthorityEditor(Set.class, authorityDAO));
}


My AuthorityEditor looks like this:


public class AuthorityEditor extends CustomCollectionEditor {

private AuthorityDAO authorityDAO;

public AuthorityEditor(Class collectionType, AuthorityDAO authorityDAO) {
super(collectionType, false);
this.authorityDAO = authorityDAO;
}

@Override
protected Object convertElement(Object element) {
Authority authority = null;
if (element != null)
authority = authorityDAO.getAuthorityById(Long.parseLong((Stri ng)element));
return authority;
}

@Override
protected boolean alwaysCreateNewCollection() {
return true;
}
}


And my JSP form looks like this:


<form:form method="post" action="/admin/editGroup.htm" commandName="group">
<form:hidden path="id"/>
Name: <form:input path="name"/><br/><br/>
Authorities: <form:select path="authorities" multiple="true" size="5">
<form:options items="${group.authorities}" itemLabel="name" itemValue="id"/>
<%--
<c:forEach varStatus="loop" items="${group.authorities}" var="authority">
<form:option value="${authority.id}" label="${authority.name}"/>
</c:forEach>
--%>
</form:select><br/><br/>
<input type="submit" value="Save" />
</form:form>


The page is displaying Authorities properly in a multi-select box, but the save/submit is not working. I have stepped through the Spring code and my convertElement method is not being called, but instead the superclass method is being called, which is basically causing it to return a Set of strings and the attempted save of the group (and thus the Set of Strings) through hibernate fails.

Can someone explain to me or help me figure out why my Override method is not being called?

Thanks.

whardwick
Jul 28th, 2009, 12:05 PM
I found a thread with the same issue, but no resolution, here (http://forum.springsource.org/showthread.php?t=15617&highlight=convertElement).

I don't think I am trying to do anything to extreme, or maybe I'm just missing something with my core Java, but shouldn't the overridden method be called instead of the superclass method?

I am using Spring 2.5, but it seems the thread I referenced above is from 2005 so is probably on 2.0.

whardwick
Jul 28th, 2009, 01:57 PM
I notice that the custom editor I am passing is given a name of "groups.authorities", but in the JSP I am referencing as "group.authorities". Perhaps its possible that the custom editor is never being called (and so my override method isn't either) because of the reference name, so it is using a CustomCollectionEditor by default because it is a set, but it is not using my AuthorityEditor.

I do not have the code in front of me, but will attempt to fix this later. Feel free to pipe in if anyone agrees or disagrees that this could be the problem.

whardwick
Jul 28th, 2009, 05:19 PM
I attempted my last suggestion with no success, so once again I am out of ideas and looking for suggestions. Could somebody please help?

Thanks.

whardwick
Jul 30th, 2009, 08:03 AM
I "fixed" this issue by making my call to the superclass method in initBinder AFTER I register my editor:



@Override
protected void initBinder(HttpServletRequest req, ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(Set.class, "groups.authorities", new AuthorityEditor(Set.class, authorityDAO));
super.initBinder(req, binder);
}


However, now I notice that the convertElement method is being called twice; once BEFORE page load, where it comes in as an Authority object, and once AFTER submit/post, where it comes in as a comma-separated string of IDs. Does anyone know why this is?

Currently, I have a conditional statement in the convertElement method to check if its a string and convert it to a Set of Authority objects, or if its an Authority object to convert it to a string. From my understanding, this method is supposed to becalled on submit/post, but not on page load. Do I have something messed up here?

Thanks.