/*
* $Header: /cvsroot/jvalidate/jvalidate-framework/jvalidate-jsf/src/main/java/nl/knowlogy/validation/jsf/component/field/FieldMessageComponent.java,v 1.5 2007/06/01 09:06:58 roberthofstra Exp $
* $Revision: 1.5 $
* $Date: 2007/06/01 09:06:58 $
*
*
* Created on Oct 6, 2004
*
* All right reserved(c) 2004, Knowlogy
*
* Copyright 2004 - 2005 Knowlogy, the Netherlands. All rights reserved.
* All Knowlogy brand and product names are trademarks or registered trademarks
* of Knowlogy in the Netherlands and other countries.
*
* No part of this publication may be reproduced, transmitted, stored in a retrieval system,
* or translated into any human or computer language, in any form, or by any means, electronic,
* mechanical, magnetic, optical, chemical, manual, or otherwise,
* without the prior written permission of the copyright owner, Knowlogy.
*
*/
package nl.knowlogy.validation.jsf.component.field;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import nl.knowlogy.validation.Messages;
import nl.knowlogy.validation.jsf.MessagesUtil;
import nl.knowlogy.validation.jsf.utils.JsfUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
*
* @author <a href="mailto:arjen.van.staalduinen@knowlogy.nl">Arjen van Staalduinen, Knowlogy</a>
*
*/
public class FieldMessageComponent extends UIComponentBase {
public static final String STYLE_EXCLAMATION = "exclamation";
private Boolean objectLevelOnly = Boolean.FALSE;
private String forComponent;
private String fieldName;
List errorMessages;
List errorList;
private String messageStyle;
private String objectExpression;
private boolean initializedObjectExpression = false;
//private boolean hasDeterminedErrors;
private static final Log log = LogFactory.getLog(FieldMessageComponent.class);
/**
* @return Returns the objectLevelOnly.
*/
public Boolean getObjectLevelOnly() {
return objectLevelOnly;
}
/**
* @param objectLevelOnly The objectLevelOnly to set.
*/
public void setObjectLevelOnly(Boolean objectLevelOnly) {
this.objectLevelOnly = objectLevelOnly;
}
/**
* @return Returns the forObject.
*/
public Object getForObject(FacesContext context) {
ValueBinding valueBinding = getValueBinding("forObject");
if (valueBinding == null) {
String objectExpresion = getObjectExpression(context);
if (objectExpresion != null){
return JsfUtils.getBindedObject(context, objectExpresion);
}
return null;
}
return valueBinding.getValue(context);
}
private String getObjectExpression(FacesContext context) {
if (!initializedObjectExpression) {
if (forComponent != null) {
UIComponent forUIComponent = getForComponent(context,
forComponent, this);
objectExpression = JsfUtils.getObjectPart(forUIComponent);
fieldName = JsfUtils.getPropertyNamePart(forUIComponent);
}
initializedObjectExpression = true;
}
return objectExpression;
}
public FieldMessageComponent (){
}
public String getRendererType() {
if (StringUtils.isBlank(messageStyle) || STYLE_EXCLAMATION.equals(messageStyle)) {
return "nl.knowlogy.validation.FieldMessage.exclamation";
} else {
return "nl.knowlogy.validation.FieldMessage.flat";
}
}
public String getFamily() {
return "nl.knowlogy.validation.FieldMessage";
}
public Object saveState(FacesContext context) {
Object values[] = new Object[6];
values[0] = super.saveState(context);
values[1] = forComponent;
values[2] = fieldName;
values[3] = messageStyle;
values[4] = objectExpression;
values[5] = objectLevelOnly;
return ((Object) (values));
}
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
forComponent = (String) values[1];
fieldName = (String) values[2];
messageStyle = (String) values[3];
objectExpression = (String) values[4];
objectLevelOnly = (Boolean)values[5];
}
public void encodeBegin(FacesContext context) throws IOException {
if (context == null) {
throw new NullPointerException();
}
if (!isRendered()) {
return;
}
//if (!hasDeterminedErrors) {
determineErrors(context);
//}
String rendererType = getRendererType();
if (rendererType != null) {
getRenderer(context).encodeBegin(context, this);
}
}
protected Iterator getMessageIter(FacesContext context,
String forComponent, UIComponent component) {
Iterator messageIter = null;
// Attempt to use the "for" attribute to locate
// messages. Three possible scenarios here:
// 1. valid "for" attribute - messages returned
// for valid component identified by "for" expression.
// 2. zero length "for" expression - global errors
// not associated with any component returned
// 3. no "for" expression - all messages returned.
if (null != forComponent) {
if (forComponent.length() == 0) {
messageIter = context.getMessages(null);
} else {
UIComponent result = getForComponent(context, forComponent,
component);
if (result == null) {
messageIter = Collections.EMPTY_LIST.iterator();
} else {
messageIter = context.getMessages(result
.getClientId(context));
}
}
}else{
messageIter = Collections.EMPTY_LIST.iterator();
}
return messageIter;
}
/**
* Locates the component identified by <code>forComponent</code>
*
* @param forComponent -
* the component to search for
* @param component -
* the starting point in which to begin the search
* @return the component with the the <code>id</code that matches
* <code>forComponent</code> otheriwse null if no match is found.
*/
protected UIComponent getForComponent(FacesContext context,
String forComponent, UIComponent component) {
UIComponent result = JsfUtils.getForComponent(context, forComponent, this);
//
// if (null == forComponent || forComponent.length() == 0) {
// return null;
// }
//
// UIComponent result = null;
// UIComponent currentParent = component;
// try {
// // Check the naming container of the current
// // component for component identified by
// // 'forComponent'
// while (currentParent != null) {
// // If the current component is a NamingContainer,
// // see if it contains what we're looking for.
// result = currentParent.findComponent(forComponent);
// if (result != null)
// break;
// // if not, start checking further up in the view
// currentParent = currentParent.getParent();
// }
//
// // no hit from above, scan for a NamingContainer
// // that contains the component we're looking for from the root.
// if (result == null) {
// result = findUIComponentBelow(context.getViewRoot(),
// forComponent);
// }
// } catch (Throwable t) {
// //Object[] params = { forComponent };
// throw new RuntimeException(""
// //Util.getExceptionMessageString(Util.COMPONENT_NOT_FOUND_ERROR_MESSAGE_ID, params)
// );
// }
// log a message if we were unable to find the specified
// component (probably a misconfigured 'for' attribute
if (result == null) {
if (log.isWarnEnabled()) {
log.warn("COMPONENT_NOT_FOUND_IN_VIEW_WARNING_ID"
//Util.getExceptionMessageString( Util.COMPONENT_NOT_FOUND_IN_VIEW_WARNING_ID,
//new Object[] { forComponent })
);
}
}
return result;
}
public String getForComponent() {
return forComponent;
}
public void setForComponent(String componentId) {
this.forComponent = componentId;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String propertyName) {
this.fieldName = propertyName;
}
public List getErrorMessages() {
return errorMessages;
}
public void setErrorMessages(List errorMessages) {
this.errorMessages = errorMessages;
}
public List getErrorList() {
return errorList;
}
public void setErrorList(List errorList) {
this.errorList = errorList;
}
/* (non-Javadoc)
* @see javax.faces.component.UIComponent#processDecodes(javax.faces.context.FacesContext)
*/
public void processDecodes(FacesContext context) {
//hasDeterminedErrors = false;
super.processDecodes(context);
}
/* (non-Javadoc)
* @see nl.iza.common.jsf.component.field.ValidationDisplayingComponent#determineErrors(javax.faces.context.FacesContext)
*/
public void determineErrors(FacesContext context) {
errorMessages = new ArrayList();
errorList = new ArrayList();
Iterator iter = getMessageIter(context, forComponent, this);
while (iter.hasNext()) {
FacesMessage element = (FacesMessage) iter.next();
errorMessages.add(element.getDetail());
}
ValueBinding valueBinding = context.getApplication().createValueBinding(MessagesUtil.VALUE_BINDING_NAME);
Object object = valueBinding.getValue(context);
if (object != null && object instanceof Messages) {
Messages messages = (Messages) object;
List propertyErrors = null;
Object forObject = getForObject(context);
if (forObject != null) {
if (log.isDebugEnabled()) {
log.debug("Retrieved object " + forObject + " fieldName " + fieldName + " objectLevelOnly " + objectLevelOnly);
}
if (fieldName != null) {
propertyErrors = messages.getMessages(forObject, fieldName);
} else {
propertyErrors = messages.getMessages(forObject, objectLevelOnly.booleanValue());
}
}
if (propertyErrors!=null) {
for (Iterator iterator = propertyErrors.iterator(); iterator.hasNext();) {
errorList.add( iterator.next());
}
}
}
//hasDeterminedErrors = true;
}
public String getMessageStyle() {
return messageStyle;
}
public void setMessageStyle(String messageStyle) {
this.messageStyle = messageStyle;
}
}
|