/**
* License Agreement.
*
* JBoss RichFaces - Ajax4jsf Component Library
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.richfaces.component;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.el.ELException;
import javax.el.ValueExpression;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.component.UIData;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.model.ListDataModel;
import org.ajax4jsf.component.AjaxActionComponent;
import org.ajax4jsf.renderkit.AjaxRendererUtils;
import org.ajax4jsf.renderkit.RendererUtils;
import org.richfaces.component.util.MessageUtil;
import org.richfaces.event.DataFilterSliderAdapter;
import org.richfaces.event.DataFilterSliderEvent;
import org.richfaces.event.DataFilterSliderListener;
import org.richfaces.event.DataFilterSliderSource;
/**
* JSF component class
*/
public abstract class UIDataFltrSlider extends AjaxActionComponent implements DataFilterSliderSource {
/**
* The component type for this component.
*/
public static final String COMPONENT_TYPE = "org.richfaces.DataFilterSlider";
public static final String COMPONENT_FAMILY = "org.richfaces.DataFilterSlider";
private transient boolean _active = false;
public boolean getRendersChildren() {
return true;
}
public void addSliderListener(DataFilterSliderListener listener) {
addFacesListener(listener);
}
public DataFilterSliderListener[] getSliderListeners() {
return (DataFilterSliderListener[]) getFacesListeners(DataFilterSliderListener.class);
}
public void removeSliderListener(DataFilterSliderListener listener) {
removeFacesListener(listener);
}
public void broadcast(FacesEvent event) throws AbortProcessingException {
if (event instanceof DataFilterSliderEvent) {
if (getSliderListeners().length < 1) {
addSliderListener(new DataFilterSliderAdapter(getSliderListener()));
}
}
super.broadcast(event);
}
protected void setupReRender(FacesContext context) {
super.setupReRender(context);
//add data slider itself to rendered list of components
AjaxRendererUtils.addRegionByName(context, this, this.getId());
String forAttr = this.getFor();
RendererUtils rendUtil = RendererUtils.getInstance();
if (forAttr != null) {
AjaxRendererUtils.addRegionByName(context, this, rendUtil.correctForIdReference(forAttr, this));
}
}
public void processDecodes(FacesContext context) {
if (context == null)
throw new NullPointerException();
if (!isRendered())
return;
// decode the Slider component
decode(context);
}
/**
* <p>In addition to the standard <code>processUpdates</code> behavior
* inherited from {@link UIComponentBase}, calls
* <code>updateModel()</code>.
* If the component is invalid afterwards, calls
* {@link FacesContext#renderResponse}.
* If a <code>RuntimeException</code> is thrown during
* update processing, calls {@link FacesContext#renderResponse}
* and re-throw the exception.
* </p>
*
* @throws NullPointerException {@inheritDoc}
*/
public void processUpdates(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
// Skip processing if our rendered flag is false
if (!isRendered()) {
return;
}
super.processUpdates(context);
try {
updateModel(context);
} catch (RuntimeException e) {
context.renderResponse();
throw e;
}
}
protected void updateModel(FacesContext context) {
Integer handleValue = getHandleValue();
if (null != handleValue) {
ValueExpression ve = getValueExpression("handleValue");
if (ve != null) {
try {
ve.setValue(context.getELContext(), handleValue);
setHandleValue(null);
} catch (ELException e) {
String messageStr = e.getMessage();
Throwable result = e.getCause();
while (null != result && result.getClass().isAssignableFrom(ELException.class)) {
messageStr = result.getMessage();
result = result.getCause();
}
FacesMessage message;
if (null == messageStr) {
message =
// not an UIInput, but constant is fine
MessageUtil.getMessage(context, UIInput.UPDATE_MESSAGE_ID, new Object[] { MessageUtil.getLabel(
context, this) });
} else {
message = new FacesMessage(FacesMessage.SEVERITY_ERROR, messageStr, messageStr);
}
context.getExternalContext().log(message.getSummary(), result);
context.addMessage(getClientId(context), message);
context.renderResponse();
} catch (IllegalArgumentException e) {
FacesMessage message = MessageUtil.getMessage(context, UIInput.UPDATE_MESSAGE_ID,
new Object[] { MessageUtil.getLabel(context, this) });
context.getExternalContext().log(message.getSummary(), e);
context.addMessage(getClientId(context), message);
context.renderResponse();
} catch (Exception e) {
FacesMessage message = MessageUtil.getMessage(context, UIInput.UPDATE_MESSAGE_ID,
new Object[] { MessageUtil.getLabel(context, this) });
context.getExternalContext().log(message.getSummary(), e);
context.addMessage(getClientId(context), message);
context.renderResponse();
}
}
}
}
/**
* @return Returns the active.
*/
public boolean isActive() {
return _active;
}
/**
* @param active
* The active to set. This method should never be called from
* user code.
*/
public void setActive(boolean active) {
_active = active;
}
private Map<String, Object> getSession() {
return getFacesContext().getExternalContext().getSessionMap();
}
private transient UIData _UIData;
public UIData getUIData() {
List ajaxSliderList = (ArrayList) getSession().get("UISliderList");
_UIData = getDataTable();
if (ajaxSliderList == null) {
ListDataModel ajaxSliderLDM = new ListDataModel();
ajaxSliderLDM.setWrappedData(_UIData.getValue());
getSession().put("UISliderList", ajaxSliderLDM.getWrappedData());
} else {
_UIData.setValue(ajaxSliderList);
}
return _UIData;
}
/**
* Finds the dataTable which id is mapped to the "for" property
*
* @return the dataTable component
*/
protected UIData getDataTable() {
String forAttribute = getFor();
UIComponent forComp;
if (forAttribute == null) {
// DataScroller may be a child of uiData
forComp = getParent();
} else {
forComp = RendererUtils.getInstance().findComponentFor(this, forAttribute);
}
if (forComp == null) {
throw new IllegalArgumentException("could not find dataTable with id '"
+ forAttribute + "'. If you are outside the naming container, try prepending the form name like for=\"form1:tableName\"");
} else if (!(forComp instanceof UIData)) {
throw new IllegalArgumentException("component with id '" + forAttribute
+ "' must be of type " + UIData.class.getName() + ", not type "
+ forComp.getClass().getName());
}
return (UIData) forComp;
}
public void resetDataTable() {
getSession().remove("UISliderList");
getDataTable().setValue(getDataTable().getValueBinding("#{" + getForValRef() + "}"));
}
public void filterDataTable(int sliderVal) {
UIData dataTable = getUIData();
List filteredDataTable = new ArrayList();
List dataTableList = (ArrayList) dataTable.getValue();
String filterByString;
int objectVal;
for (int i = 0; i < dataTableList.size(); i++) {
Object o = dataTableList.get(i);
try {
filterByString = o.getClass().getMethod(getFilterBy(), null).invoke(o, null).toString();
if (filterByString.indexOf(".") > 0) {
filterByString = filterByString.substring(0, filterByString.indexOf("."));
}
objectVal = Integer.parseInt(filterByString);
if (objectVal < sliderVal) {
filteredDataTable.add(o);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
getDataTable().setValue(filteredDataTable);
}
public String getSliderRange() {
String sliderValues = "";
int segmentTotal;
int segmentTotalStart;
Integer startRange = getStartRange();
Integer endRange = getEndRange();
Integer increment = getIncrement();
if((startRange != null) && (endRange != null) && (increment != null)) {
if (getStartRange().intValue() == 0) {
segmentTotal = (getEndRange().intValue() / getIncrement().intValue());
//set slider start to 0
segmentTotalStart = 0;
} else {
//subtract 1 for 0 based array
segmentTotal = (getEndRange().intValue() / getIncrement().intValue()) - 1;
//set the slider start for the loop
segmentTotalStart = getStartRange().intValue();
}
int j = segmentTotalStart;
for (int i = segmentTotalStart; i <= segmentTotal; i++) {
if (i != 0) {
//Check to see if we are at start of slider
if (i != j){
//increment by number given
j = j + getIncrement().intValue();
}
} else {
//start at specified range
j = getStartRange().intValue();
}
if (i == segmentTotal) {
//this is the end so no comma and exact specified
sliderValues = sliderValues + getEndRange();
} else {
//add to string
sliderValues = sliderValues + j + ",";
}
}
}
return sliderValues;
}
public abstract void setSliderListener(MethodBinding binding);
public abstract MethodBinding getSliderListener();
public abstract String getTrackStyleClass();
public abstract void setTrackStyleClass(String trackStyleClass);
public abstract boolean isSubmitOnSlide();
public abstract void setSubmitOnSlide(boolean value);
public abstract boolean isStoreResults();
public abstract void setStoreResults(boolean storeResults);
public abstract String getForValRef();
public abstract void setForValRef(String forValRef);
public abstract String getFilterBy();
public abstract void setFilterBy(String filterBy);
public abstract String getFor();
public abstract void setFor(String _for);
public abstract void setStyleClass(String styleClass);
public abstract String getStyleClass();
public abstract void setFieldStyleClass(String fieldStyleClass);
public abstract String getFieldStyleClass();
public abstract Integer getStartRange();
public abstract void setStartRange(Integer startRange);
public abstract Integer getEndRange();
public abstract void setEndRange(Integer endRange);
public abstract Integer getIncrement();
public abstract void setIncrement(Integer increment);
public abstract String getRangeStyleClass();
public abstract void setRangeStyleClass(String rangeStyleClass);
public abstract boolean isTrailer();
public abstract void setTrailer(boolean trailer);
public abstract String getTrailerStyleClass();
public abstract void setTrailerStyleClass(String trailerStyleClass);
public abstract String getHandleStyleClass();
public abstract void setHandleStyleClass(String handleStyleClass);
public abstract Integer getHandleValue();
public abstract void setHandleValue(Integer handleValue);
public abstract boolean isManualInput();
public abstract void setManualInput(boolean manualInput);
protected FacesContext getFacesContext() {
return FacesContext.getCurrentInstance();
}
public void decode(FacesContext context) {
super.decode(context);
}
}