dinsdag 17 april 2007

implementing many2many

I'm currently trying to implement a many2many relationship. Using jsf's selectMany thingy. Apparantly jboss seam does have something similar integrated in seam, now I've to use selectitems, converters and what's more. I tried the seam implementation a while ago, but I couldnt get it to work it also had a beta in the name, which is discouraging.

As the myfaces/icefaces combination also has shown some weird behavior I decided to download both and add them as projects in eclipse, so I can do some debugging, and add logging. A feature with both products seriously lack.
Myfaces is build with maven :
D:\projects\seamice\myfaces\core> d:\programs\maven-2.0.4\bin\mvn 
produces the api and impl files, which can be copied:
 copy /Y  impl\target\myfaces-impl-1.1.6-SNAPSHOT.jar d:\programs\jboss-4.0.5.GA\server\default\deploy\jbossweb-tomcat55.sar\jsf-libs\myfaces-impl.jar 

(and repeat cmd above for the api jars, donot copy the source jars).

The first obstacle I encountered was the output.
I did do something like:
SelectItem item = new SelectItem();
But the output in the html both value and label as the label.

codesnippet MenuRenderer:

if (logger.isTraceEnabled()) {
logger.trace(LogUtil.getLogMsg(methodName, LogUtil.VERSION
,"start to render option for '" + uiComponent.getId() + "' and item label '" + selectItem.getLabel() + "' and itemvalue '" + selectItem.getValue() + "'"));
DOMContext domContext =
DOMContext.attachDOMContext(facesContext, uiComponent);

Element select = (Element) domContext.getRootNode();
Element option = domContext.createElement("option");

if (optionGroup == null) {
} else {

String valueString = formatComponentValue(facesContext, uiComponent,
if (logger.isDebugEnabled()) {
logger.debug(LogUtil.getLogMsg(methodName, LogUtil.VERSION
, "created option gets value assigned of '" + valueString + "'"));

And the logging output:

15:16:05,593 TRACE [com.icesoft.faces.renderkit.dom_html_basic.MenuRenderer] renderOption[0.1]:start to render option for '_id61' and item label 'Spuyt' and itemvalue '1'
15:16:05,656 TRACE [javax.faces.component.UISelectMany] getValueBinding[0.1]:start with 'converter'
15:16:05,671 INFO [nl.jeroen.testdb.persist.SubjectMgrBean] getting as string for '1' class java.lang.Integer'
15:16:05,671 INFO [nl.jeroen.testdb.persist.SubjectMgrBean] getting as string for '1' class java.lang.Integer'
15:16:05,671 DEBUG [nl.jeroen.testdb.persist.SubjectMgrBean] [getRoleValues: ]0.1: starting ''
15:16:05,687 DEBUG [com.icesoft.faces.renderkit.dom_html_basic.MenuRenderer] renderOption[0.1]:created option gets value assigned of 'Spuyt'
In between something is going wrong and apparantly its the converter.getAsString method is being called, and this nicely retrieves the role with the passed argument as id, and returns the name.
But this is exactly why I switched back to Integers instead of the Roles because the conversion back (getAsObject) is not working as expected.
Because after submitting the form, I'd expect the getAsObject method to be called before the HTMLSelectManyListbox(UISelectMany).validateValue() (part of myfaces) but that's not happening.
validateValue's signature is:

validateValue(FacesContext context, Object convertedValues)

but my own logging states:

validateValue[0.1]:validate Value '[2, 6]'

convertedValues would expect that the values have been converter.getAsObject(..) but alas..
iceface's blocking servlet is doing in rendercycle, lifecycle.execute();

UISelectMany does contain a getConvertedValue method which delegates the conversion of the submitted values to a renderer (MenuRender in our case). This menurenderer is not calling the converter.getAsObject so there's the error!

Why is eclipse code formatter putting all the operands on the end of the line? I would prefer it to put at the start of the line, in case of long lines you don't have to scroll right. (I use the term operands here for characters like + . , etc)

Geen opmerkingen: