Ignacio
Ignacio

Reputation: 131

Error Omnifaces o:validateOrder with Rich Faces Calendar component

I have a problem when try to validate the rich:calendar component with o:validateOrder.

Code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:tablas="http://java.sun.com/jsf/composite/tablas"
    xmlns:o="http://omnifaces.org/ui"
    xmlns:of="http://omnifaces.org/functions"
    xmlns:templates="http://java.sun.com/jsf/composite/templates"
    >

<body>

    <f:metadata>
        <f:event type="preRenderView" listener="#{baseController.iniciarConversacion()}" />
    </f:metadata>

    <ui:composition template="/templates/TemplateABM.xhtml">
        <ui:define name="title">
                #{msgs['facturacion.abm.generacion.factura.individual.pagina.titulo']}
            </ui:define>
        <ui:define name="top">
            <h1>#{msgs['facturacion.abm.generacion.factura.individual.titulo']}</h1>
        </ui:define>
        <ui:define name="content">

            <h:form id="formFacturaIndividual">


                <h:panelGroup id="panelFechas">
                    <h:inputHidden id="fechaInicioFactura" value="#{facturaController.fechaInicioFactura}">
                        <f:convertDateTime type="date" pattern="dd/MM/yy"/>
                    </h:inputHidden>

                    <h:inputHidden id="fechaFinFactura" value="#{facturaController.fechaFinFactura}">
                        <f:convertDateTime type="date" pattern="dd/MM/yy"/>
                    </h:inputHidden>            

                    <h:inputHidden id="fechaEmisionComprobanteUltima" value="#{comprobanteController.fechaEmisionComprobanteUltima}">
                        <f:convertDateTime type="date" pattern="dd/MM/yy"/>
                    </h:inputHidden>            
                </h:panelGroup>

                <o:validateOrder id="validacionFechaFacturaMenorAFechaInicioFactura" type="gte" components="fechaFactura fechaInicioFactura" 
                message="#{msgs['comun.abm.fecha.factura.menor.limite.dia']}" showMessageFor="fechaFactura" />
                <o:validateOrder id="validacionFechaFacturaMayorAFechaFinFactura" type="lte" components="fechaFactura fechaFinFactura" 
                message="#{msgs['comun.abm.fecha.factura.menor.limite.dia']}" showMessageFor="fechaFactura" />                             
                <o:validateOrder id="validacionFechaFacturaMayorAFechaEmisionUltimoComprobante" type="gte" components="fechaFactura fechaEmisionComprobanteUltima" 
                message="#{of:format1(msgs['comun.abm.fecha.factura.menor.ultimo.comprobante'], comprobanteController.fechaEmisionComprobanteUltima)}" showMessageFor="fechaFactura" />

                <o:massAttribute name="disabled" value="#{tipoComprobanteController.entidad == null}">
                    <rich:panel id="panelDatosFactura" header="#{msgs['facturacion.abm.generacion.padron.panel.datos.factura']}">

                        <h:panelGrid id="DatosFactura" columns="3">

                            <h:outputLabel value="#{msgs['facturacion.abm.generacion.padron.fecha.factura']}" for="fechaFactura"/>  
                            <rich:calendar
                                id="fechaFactura"
                                datePattern="dd/MM/yyyy"
                                showWeeksBar="false"
                                enableManualInput="true"
                                value="#{generacionFacturacionIndividualController.facturaBean.fechaFactura}"
                                required="true"
                                requiredMessage="La Fecha de la Factura es Obligatoria" >
    <a4j:ajax event="change" execute="@form"  />
                            </rich:calendar>
                            <h:panelGroup>
                                <rich:message for="fechaFactura"/>
                            </h:panelGroup>

                        </h:panelGrid>

                    </rich:panel>
                </o:massAttribute>


            </h:form>

        </ui:define>
    </ui:composition>

</body>
</html>

Exception:

java.lang.IllegalArgumentException: All values must implement java.lang.Comparable.
    at org.omnifaces.component.validator.ValidateOrder.validateValues(ValidateOrder.java:142)
    at org.omnifaces.component.validator.ValidateMultipleFields.validateComponents(ValidateMultipleFields.java:213)
    at org.omnifaces.component.validator.ValidatorFamily.processValidators(ValidatorFamily.java:63)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1216)
    at javax.faces.component.UIForm.processValidators(UIForm.java:253)
    at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:536)
    at org.richfaces.context.MetaComponentProcessingVisitCallback.visit(MetaComponentProcessingVisitCallback.java:73)
    at org.richfaces.context.BaseExtendedVisitContext.invokeVisitCallback(BaseExtendedVisitContext.java:103)
    at org.richfaces.context.ExtendedExecuteVisitContext.invokeVisitCallback(ExtendedExecuteVisitContext.java:55)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1652)
    at javax.faces.component.UIForm.visitTree(UIForm.java:371)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1663)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1663)
    at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:383)
    at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:257)
    at org.richfaces.context.ExtendedPartialViewContext.processPartial(ExtendedPartialViewContext.java:263)
    at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
    at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1162)
    at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at ar.com.filter.HibernateSessionRequestFilter.doFilter(HibernateSessionRequestFilter.java:35)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String
    at java.lang.String.compareTo(String.java:108)
    at java.util.Collections$ReverseComparator.compare(Collections.java:3578)
    at java.util.Collections$ReverseComparator.compare(Collections.java:3569)
    at java.util.TimSort.countRunAndMakeAscending(TimSort.java:324)
    at java.util.TimSort.sort(TimSort.java:189)
    at java.util.TimSort.sort(TimSort.java:173)
    at java.util.Arrays.sort(Arrays.java:659)
    at java.util.Collections.sort(Collections.java:217)
    at org.omnifaces.component.validator.ValidateOrder$Type$4.invoke(ValidateOrder.java:99)
    at org.omnifaces.component.validator.ValidateOrder$Type$4.invoke(ValidateOrder.java:95)
    at org.omnifaces.component.validator.ValidateOrder$Type.validateOrder(ValidateOrder.java:111)
    at org.omnifaces.component.validator.ValidateOrder.validateValues(ValidateOrder.java:139)
    ... 44 more

I debuged the code and the problem is that the rich:calendar component send String instead Date type, this doesn't happen me in other pages i dont know is omnifaces problem or richfaces. Any ideas?

Upvotes: 2

Views: 305

Answers (1)

BalusC
BalusC

Reputation: 1109222

The <o:validateXxx> components are sensitive to their location relative to the target input components. This is very useful to prioritize validation depending on component's own converter and validators.

When placed before the target input components, then they will validate the raw unsubmitted values, and they will run before any of component's own validators.

When placed after the target input components, then they will validate the converted values (if any converter is involved), and they will run after any of component's own validators.

In your particular case, you placed the <o:validateOrder> between those components. This is not the recommended approach. You will end up getting a List filled with Date instances from components above the validator and String instances from components below the validator.

See also the ValidateMultipleFields javadoc (emphasis mine):

This validator can be placed anywhere in the form, but keep in mind that the components will be validated in the order as they appear in the form. So if this validator is been placed before all of the components, then it will be executed before any of the component's own validators. If this validator fails, then the component's own validators will not be fired. If this validator is been placed after all of the components, then it will be executed after any of the component's own validators. If any of them fails, then this validator will not be exeucted. It is not recommended to put this validator somewhere in between the referenced components as the resulting behaviour may be confusing. Put this validator either before or after all of the components, depending on how you would like to prioritize the validation.

Upvotes: 1

Related Questions