@ Override public void validate ( final FacesContext context ) { // iterate over submitted values and attempt to convert to the proper // data type. For successful values, remove from submitted and add to // local values map. for failures, add a conversion message and leave in // the submitted state final Iterator < Entry < SheetRowColIndex , String > > entries = submittedValues . entrySet ( ) . iterator ( ) ; final boolean hadBadUpdates = ! getInvalidUpdates ( ) . isEmpty ( ) ; getInvalidUpdates ( ) . clear ( ) ; while ( entries . hasNext ( ) ) { final Entry < SheetRowColIndex , String > entry = entries . next ( ) ; final SheetColumn column = getColumns ( ) . get ( entry . getKey ( ) . getColIndex ( ) ) ; final String newValue = entry . getValue ( ) ; final String rowKey = entry . getKey ( ) . getRowKey ( ) ; final int col = entry . getKey ( ) . getColIndex ( ) ; setRowVar ( context , rowKey ) ; // attempt to convert new value from string to correct object type // based on column converter. Use PF util as helper final Converter converter = ComponentUtils . getConverter ( context , column ) ; // assume string value if converter not found Object newValueObj = newValue ; if ( converter != null ) { try { newValueObj = converter . getAsObject ( context , this , newValue ) ; } catch ( final ConverterException e ) { // add offending cell to list of bad updates // and to a StringBuilder for error messages (so we have one // message for the component) setValid ( false ) ; FacesMessage message = e . getFacesMessage ( ) ; if ( message == null ) { message = new FacesMessage ( FacesMessage . SEVERITY_ERROR , e . getMessage ( ) , e . getMessage ( ) ) ; } context . addMessage ( this . getClientId ( context ) , message ) ; final String messageText = message . getDetail ( ) ; getInvalidUpdates ( ) . add ( new SheetInvalidUpdate ( getRowKeyValue ( context ) , col , column , newValue , messageText ) ) ; continue ; } } // value is fine, no further validations (again, not to be confused // with validators. until we have a "required" or something like // that, nothing else to do). setLocalValue ( rowKey , col , newValueObj ) ; // process validators on column column . setValue ( newValueObj ) ; try { column . validate ( context ) ; } finally { column . resetValue ( ) ; } entries . remove ( ) ; } setRowVar ( context , null ) ; final boolean newBadUpdates = ! getInvalidUpdates ( ) . isEmpty ( ) ; final String errorMessage = getErrorMessage ( ) ; if ( hadBadUpdates || newBadUpdates ) { // update the bad data var if partial request if ( context . getPartialViewContext ( ) . isPartialRequest ( ) ) { renderBadUpdateScript ( context ) ; } } if ( newBadUpdates && errorMessage != null ) { final FacesMessage message = new FacesMessage ( FacesMessage . SEVERITY_ERROR , errorMessage , errorMessage ) ; context . addMessage ( null , message ) ; } }
Converts each submitted value into a local value and stores it back in the hash . If all values convert without error then the component is valid and we can proceed to the processUpdates .