-
1. Re: h:selectOneRadio and converting to Short problem
kragoth Mar 24, 2010 12:13 AM (in response to sburgula1)You really don't need to post your question on the forums more then once.
Anyways, I'm pretty sure there is plenty of documentation about how to write a converter.
So, if you can't figure out how to get the default converter working for you then write your own.
They are very very simple to write.Here is my String converter (yes I have a String converter just to make blank/white space only/empty strings become null.)
@Name(StringConverter.SEAM_ID) @org.jboss.seam.annotations.faces.Converter(id = "GekkoStringConverter") @SpringAutowirable public class StringConverter implements Converter { public static final String SEAM_ID = "StringConverter"; @Override public Object getAsObject( FacesContext context, UIComponent component, String value) { if (StringUtils.isBlank(value)) { return null; } return value; } @Override public String getAsString( FacesContext context, UIComponent component, Object value) { if (!(value instanceof String)) { throw new ConverterException(MessageFactory.getMessage( context, "STRING_CONVERSION_ERROR, value, MessageFactory.getLabel(context, component))); } if (StringUtils.isBlank((String)value)) { return ""; } return (String)value; } }
Now, all you have to do is change it to make it convert Shorts instead of Strings.
Then in your h:selectOneRadio make sure you specify converter=
TheIdThatYouSpecifiedInThe @org.jboss.seam.annotations.faces.Converter Annotation
-
2. Re: h:selectOneRadio and converting to Short problem
sburgula1 Mar 24, 2010 6:52 PM (in response to sburgula1)Thanks for your reply. I noticed you used @SpringAutowirable. Is it that this can be used with Spring Framework also.
-
3. Re: h:selectOneRadio and converting to Short problem
kragoth Mar 24, 2010 11:58 PM (in response to sburgula1)The @SpringAutowirable is my own annotation that allows Spring beans to be @Autowired into my Seam Beans.
If you would like to learn how to do this then see the code below.
OK, so first the annotation class.
@SpringAutowirable
package gekko.web.services; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; import org.jboss.seam.annotations.intercept.Interceptors; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target(TYPE) @Retention(RUNTIME) @Inherited @Interceptors(GekkoSpringInjector.class) public @interface SpringAutowirable {}
So all this basically does is adds a Seam interceptor (GekkoSpringInjector.class) to all Seam Beans annotated with this annotation.
Now the interceptor itself.
GekkoSpringInjector.class
package gekko.web.services; import java.lang.reflect.InvocationTargetException; import org.apache.log4j.Logger; import org.jboss.seam.annotations.intercept.Interceptor; import org.jboss.seam.intercept.AbstractInterceptor; import org.jboss.seam.intercept.InvocationContext; import gekko.util.ExceptionUtils; import gekko.web.utils.SeamUtils; import gekko.web.utils.WebUtils; @Interceptor public class GekkoSpringInjector extends AbstractInterceptor { final private static Logger log = Logger.getLogger(GekkoSpringInjector.class); final private static Logger exceptionLog = Logger.getLogger( ExceptionUtils.EXCEPTION_STACK_PREFIX + "." + GekkoSpringInjector.class.getName()); private static final String ERROR_STRING = " Seam bean method execution threw an error"; @Override public Object aroundInvoke(InvocationContext invocation) throws Exception { // NOPMD Object target = invocation.getTarget(); WebUtils.autowireSpringBeans(target); Object result; try { result = invocation.proceed(); } catch (InvocationTargetException ite){ String debugMethodInfo = SeamUtils.constructDebugSignatureWithChoppedParams(invocation); log.error(debugMethodInfo + ERROR_STRING); exceptionLog.error(debugMethodInfo+ERROR_STRING, ite); throw ite; } catch (Exception e) { String debugMethodInfo = SeamUtils.constructDebugSignatureWithChoppedParams(invocation); log.error(debugMethodInfo + ERROR_STRING); exceptionLog.error(debugMethodInfo+ERROR_STRING, e); throw e; } return result; } @Override public boolean isInterceptorEnabled() { return true; } }
As you can see in that class I'm making some calls to some of my own Util classes. These calls are not important. They are just making exceptions easier to work with. I'm sure you can work out what info you want when something goes wrong.
The only really important one is the call to WebUtils.autowireSpringBeans(target) so, I'll provide that code.
From WebUtils.class
public static void autowireSpringBeans(Object target) { GekkoContainer container = WebContextListener.getGekkoContainer( (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext() ); container.getAutowireBeanFactory().autowireBeanProperties( target, AutowireCapableBeanFactory.AUTOWIRE_NO, false); }
Now obviously here is where it gets a bit tricky because it is application specific. Essentially all that it is doing is getting the ApplicationContext and from that making the call to getAutowireCapableBeanFactory and then calling autowireBeanProperties on that passing in the Seam Bean.
This does mean that you need to have a SpringApplicationContext (ours is a ClassPathXmlApplicationContext.class) available in your web layer. Hopefully you know enough about Spring to set all that up because I don't really have time to go into how our application is structured.
After all that I think it is actually a mistake for me to have this interceptor on my converter. In fact the converter should probably be annotated with @BypassInterceptors, so, don't copy my bad practice. :P