Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.icefaces.ace.component.list.ACEList Maven / Gradle / Ivy
/*
* Copyright 2004-2014 ICEsoft Technologies Canada Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS
* IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.icefaces.ace.component.list;
import org.icefaces.ace.event.ListMigrateEvent;
import org.icefaces.ace.event.ListMoveEvent;
import org.icefaces.ace.event.ListRemoveEvent;
import org.icefaces.ace.event.ListSelectEvent;
import org.icefaces.ace.json.JSONArray;
import org.icefaces.ace.json.JSONException;
import org.icefaces.ace.model.filter.*;
import org.icefaces.ace.util.collections.*;
import org.icefaces.impl.util.CoreUtils;
import javax.el.ELContext;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.application.NavigationHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UISelectItem;
import javax.faces.component.UISelectItems;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PostValidateEvent;
import javax.faces.event.PreValidateEvent;
import javax.faces.model.*;
import javax.xml.transform.Result;
import java.sql.ResultSet;
import java.util.*;
import org.icefaces.ace.model.SingleExpressionComparator;
import org.icefaces.ace.model.table.SortCriteria;
public class ACEList extends ListBase {
private static Class SQL_RESULT = null;
static {
try {
SQL_RESULT = Class.forName("javax.servlet.jsp.jstl.sql.Result");
} catch (Throwable t) {
//ignore if sql.result not available
}
}
DataModel model;
boolean selectItemModel = false;
transient protected FilterState savedFilterState;
transient protected SortState savedSortState;
transient protected List removedElements = null;
@Override
protected DataModel getDataModel() {
// Return any previously cached DataModel instance
if (this.model != null) {
return (model);
}
// Synthesize a DataModel around our current value if possible
Object current = getValue();
List selectItems = getSelectItems();
if (selectItems != null) {
setSelectItemModel(true);
setDataModel(new ListDataModel(selectItems));
return model;
} else if (current == null) {
setDataModel(new ListDataModel(Collections.EMPTY_LIST));
} else if (current instanceof DataModel) {
setDataModel((DataModel) current);
} else if (current instanceof List) {
setDataModel(new ListDataModel((List) current));
} else if (Object[].class.isAssignableFrom(current.getClass())) {
setDataModel(new ArrayDataModel((Object[]) current));
} else if (current instanceof ResultSet) {
setDataModel(new ResultSetDataModel((ResultSet) current));
} else if ((null != SQL_RESULT) && SQL_RESULT.isInstance(current)) {
DataModel dataModel = new ResultDataModel();
dataModel.setWrappedData(current);
setDataModel(dataModel);
} else {
setDataModel(new ScalarDataModel(current));
}
setSelectItemModel(false);
return (model);
}
@Override
public Object getValue() {
Object superValue = super.getValue();
int superValueHash;
if (superValue != null) superValueHash = superValue.hashCode();
else return null;
// If model is altered or new reapply filters / sorting
if (getValueHashCode() == null || superValueHash != getValueHashCode()) {
setValueHashCode(superValueHash);
javax.el.ValueExpression sortBy = getValueExpression("sortBy");
if (sortBy != null && !"".equals(sortBy.getExpressionString())) {
applySorting();
}
if (getFilteredData() != null) {
applyFilters();
}
}
// If we have filtered data return that instead of the standard collection
// Lazy case should recalculate filters in the persistence layer with every load
List filteredValue = getFilteredData();
if (filteredValue != null)
return filteredValue;
else return superValue;
}
@Override
public void setRowIndex(int i) {
if (i < 0) model = null;
super.setRowIndex(i);
}
@Override
protected void setDataModel(DataModel newModel) {
model = newModel;
}
private List getSelectItems() {
List selectItems = new ArrayList();
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
for (UIComponent c : getChildren())
if (c instanceof UISelectItems)
selectItems.addAll(processUISelectItems(elContext, (UISelectItems) c));
else if (c instanceof UISelectItem) {
SelectItem item = processUISelectItem(elContext, (UISelectItem) c);
if (item != null) selectItems.add(item);
}
return selectItems.size() == 0 ? null : selectItems;
}
private SelectItem processUISelectItem(ELContext elContext, UISelectItem itemComponent) {
ValueExpression itemExpression = null;
SelectItem selectItem = null;
if (itemComponent.getValue() instanceof SelectItem)
selectItem = (SelectItem) itemComponent.getValue();
else if ((itemExpression = itemComponent.getValueExpression("value")) != null &&
itemExpression.getType(elContext).equals(SelectItem.class)) {
selectItem = (SelectItem)itemExpression.getValue(elContext);
} else if (itemComponent.getItemLabel() != null) {
selectItem = new SelectItem(
itemComponent.getItemValue(),
itemComponent.getItemLabel(),
itemComponent.getItemDescription(),
itemComponent.isItemDisabled(),
itemComponent.isItemEscaped(),
itemComponent.isNoSelectionOption()
);
}
return selectItem;
}
private List processUISelectItems(ELContext elContext, UISelectItems c) {
List selectItems = new ArrayList();
UISelectItems itemsComponent = c;
Object value = itemsComponent.getValue();
try {
if (value == null)
value = itemsComponent.getValueExpression("value").getValue(elContext);
} catch (NullPointerException npe) {
// If ValueExpression is null return empty list
return selectItems;
}
if (value instanceof SelectItem)
selectItems.add((SelectItem) value);
else if (value instanceof Collection) {
Collection values = (Collection) value;
for (Iterator itemIter = values.iterator(); itemIter.hasNext();)
selectItems.add((SelectItem) itemIter.next());
} else if (value instanceof SelectItem[]) {
SelectItem[] values = (SelectItem[]) value;
for (SelectItem item : values)
selectItems.add(item);
} else if (value instanceof Map) {
Map itemMap = (Map)value;
for (Iterator keyIter = itemMap.keySet().iterator(); keyIter.hasNext();) {
Object key = keyIter.next();
selectItems.add(new SelectItem(
itemMap.get(key),
key.toString()
));
}
}
return selectItems;
}
@Override
public Boolean isDragging() {
if (isSelectItemModel()) return false;
else return super.isDragging();
}
@Override
public Boolean isControlsEnabled() {
if (isSelectItemModel()) return false;
else return super.isControlsEnabled();
}
@Override
public boolean getRendersChildren() {
return true;
}
@Override
public Set getSelections() {
Set set = super.getSelections();
if (set == null) {
set = new HashSet();
setSelections(set);
}
return set;
}
@Override
public void broadcast(FacesEvent event) throws AbortProcessingException {
super.broadcast(event);
FacesContext context = FacesContext.getCurrentInstance();
String outcome = null;
MethodExpression me = null;
if (event instanceof ListSelectEvent) me = getSelectionListener();
if (me != null) {
if (!context.isValidationFailed()) {
outcome = (String) me.invoke(context.getELContext(), new Object[] {event});
}
if (outcome != null) {
NavigationHandler navHandler = context.getApplication().getNavigationHandler();
navHandler.handleNavigation(context, null, outcome);
context.renderResponse();
}
}
}
@Override
public void queueEvent(FacesEvent event) {
if (event == null) {
throw new NullPointerException();
}
if (event instanceof AjaxBehaviorEvent) {
FacesContext context = FacesContext.getCurrentInstance();
Map params = context.getExternalContext().getRequestParameterMap();
String eventName = params.get("javax.faces.behavior.event");
String clientId = getClientId(context);
if (eventName.equals("move")) {
try {
String raw = params.get(clientId + "_reorderings");
List records = new ArrayList();
JSONArray array = new JSONArray(raw);
for (int i = 0; i < array.length(); i++) {
JSONArray record = array.getJSONArray(i);
int from = record.getInt(0);
int to = record.getInt(1);
records.add(new ListMoveEvent.MoveRecord(from, to));
}
event = new ListMoveEvent((AjaxBehaviorEvent) event, records);
} catch (Exception e) { }
} else if (eventName.equals("migrate")) {
try {
String raw = params.get(clientId + "_immigration");
List records = new ArrayList();
JSONArray data = new JSONArray(raw);
JSONArray array = data.getJSONArray(1);
for (int i = 0; i < array.length(); i++) {
JSONArray record = array.getJSONArray(i);
int from = record.getInt(0);
int to = record.getInt(1);
records.add(new ListMigrateEvent.MigrationRecord(from, to));
}
String srcListClientId = data.getString(0);
ACEList srcList = (ACEList) CoreUtils.findComponentByClientId(context.getViewRoot(), srcListClientId);
event = new ListMigrateEvent((AjaxBehaviorEvent) event, records, srcList);
} catch (Exception e) { }
} else if (eventName.equals("remove")) {
event = new ListRemoveEvent((AjaxBehaviorEvent) event, removedElements);
}
}
super.queueEvent(event);
}
// References to immigrant objects are gathered immediately
List immigrants;
public List getImmigrants() {
return immigrants;
}
public void setImmigrants(List immigrants) {
this.immigrants = immigrants;
}
public boolean isSelectItemModel() {
return selectItemModel;
}
public void setSelectItemModel(boolean isSelect) {
selectItemModel = isSelect;
}
// cause to re-calculate client ID to include naming container ID
protected static void recalculateClientId(UIComponent component) {
component.setId(component.getId());
for (UIComponent child : component.getChildren()) {
recalculateClientId(child);
}
}
@Override
public void processDecodes(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
if (!isRendered()) {
return;
}
pushComponentToEL(context, this);
getDataModel();
iterate(context, PhaseId.APPLY_REQUEST_VALUES);
decode(context);
popComponentFromEL(context);
}
@Override
public void processValidators(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
if (!isRendered()) {
return;
}
pushComponentToEL(context, this);
Application app = context.getApplication();
app.publishEvent(context, PreValidateEvent.class, this);
iterate(context, PhaseId.PROCESS_VALIDATIONS);
app.publishEvent(context, PostValidateEvent.class, this);
popComponentFromEL(context);
}
private void iterate(FacesContext context, PhaseId phaseId) {
// Process each facet of this component exactly once
setRowIndex(-1);
if (getFacetCount() > 0) {
for (UIComponent facet : getFacets().values()) {
if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
facet.processDecodes(context);
} else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
facet.processValidators(context);
} else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
facet.processUpdates(context);
} else {
throw new IllegalArgumentException();
}
}
}
// Iterate over children, once per row
int processed = 0;
int rowIndex = getFirst() - 1;
int rows = getRows();
while (true) {
// Have we processed the requested number of rows?
if ((rows > 0) && (++processed > rows)) {
break;
}
// Expose the current row in the specified request attribute
setRowIndex(++rowIndex);
if (!isRowAvailable()) {
break; // Scrolled past the last row
}
if (getChildCount() > 0) {
for (UIComponent kid : getChildren()) {
if (!kid.isRendered()) {
continue;
}
recalculateClientId(kid);
if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
kid.processDecodes(context);
} else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
kid.processValidators(context);
} else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
kid.processUpdates(context);
} else {
throw new IllegalArgumentException();
}
}
}
}
// Clean up after ourselves
setRowIndex(-1);
}
// ---------------------
// ----- FILTERING -----
// ---------------------
public void applyFilters() {
setApplyingFilters(true);
}
/*
@Property(tlddoc = "Enable to force creation of the filtered data set from the bound " +
"value every render. Alternately attempt to use hashCodes of the " +
"value property to detect changes and prompt refiltering.",
defaultValue = "false", defaultValueType = DefaultValueType.EXPRESSION)
private boolean constantRefilter;
*/
public Boolean isApplyingFilters() {
//if (isConstantRefilter()) return true;
return super.isApplyingFilters();
}
@Override
public void processUpdates(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
if (!isRendered()) {
return;
}
pushComponentToEL(context, this);
iterate(context, PhaseId.UPDATE_MODEL_VALUES);
popComponentFromEL(context);
pushComponentToEL(context, this);
if (isFilterRequest(context)) {
UIComponent filterFacet = getFilterFacet();
if (filterFacet != null) {
filterFacet.processUpdates(context);
}
// after model values have been updated, we save the filter state if using the filter facet,
// since the filter values are decoded independetly in this case,
// so we must now fetch them to use them later at the render response phase
if (savedFilterState != null) {
if (getFilterFacet() != null) {
Object filterValue = getFilterValue();
Object filterValues = getFilterValues();
if (filterValue != null || filterValues != null) {
savedFilterState.saveState(this);
} else {
savedFilterState.saveState(this, getFilterValueMin(), getFilterValueMax());
}
}
}
}
if (isApplyingFilters()) {
if (savedFilterState != null)
savedFilterState.apply(this);
setFilteredData(processFilters(context));
}
if (isApplyingSorts()) {
if (savedSortState != null)
savedSortState.apply(this);
processSorting();
}
popComponentFromEL(context);
}
protected List processFilters(FacesContext context) {
try {
Predicate filterSet = AllPredicate.getInstance(new ArrayList());
FilterType filterType = getFilterType();
if (filterType == FilterType.TEXT || !isRangedFilter()) {
String filterValue = getFilterValue();
if (filterValue != null && !filterValue.equals("")) {
filterSet = new PropertyConstraintPredicate(context,
getValueExpression("filterBy"),
filterValue,
getFilterConstraint(),
this);
}
} else {
Object filterValueMin = getFilterValueMin();
Object filterValueMax = getFilterValueMax();
if (filterValueMin != null || filterValueMax != null) {
filterSet = new RangeConstraintPredicate(context,
getValueExpression("filterBy"),
filterValueMin,
filterValueMax,
filterType);
}
}
List filteredData = new ArrayList();
setFilteredData(null);
try { setDataModel(null); }
catch (UnsupportedOperationException uoe) {
//MyFaces doesn't support this method and throws an UnsupportedOperationException
}
DataModel model = getDataModel();
String var = getVar();
int index = 0;
// UIData Iteration
setRowIndex(index);
while (model.isRowAvailable()) {
Object rowData = model.getRowData();
if (var != null) context.getExternalContext().getRequestMap().put(var, rowData);
if (filterSet.evaluate(rowData)) {
filteredData.add(rowData);
}
index++;
setRowIndex(index);
}
// Iteration clean up
setRowIndex(-1);
if (var != null) context.getExternalContext().getRequestMap().remove(var);
return filteredData;
} finally {
//setForcedUpdateCounter(getForcedUpdateCounter()+1);
setApplyingFilters(false);
}
}
public Locale calculateLocale(FacesContext facesContext) {
Locale locale;
Object userLocale = getFilterDateLocale();
if (userLocale != null) {
if (userLocale instanceof String) {
String[] tokens = ((String) userLocale).split("_");
if (tokens.length == 1)
locale = new Locale(tokens[0], "");
else
locale = new Locale(tokens[0], tokens[1]);
} else if (userLocale instanceof Locale)
locale = (Locale) userLocale;
else
throw new IllegalArgumentException("Type:" + userLocale.getClass() + " is not a valid locale type for column:" + this.getClientId(facesContext));
} else {
locale = facesContext.getViewRoot().getLocale();
}
return locale;
}
public FilterType getFilterType() {
String type = getType();
if ("boolean".equalsIgnoreCase(type)) return FilterType.BOOLEAN;
if ("date".equalsIgnoreCase(type)) return FilterType.DATE;
if ("byte".equalsIgnoreCase(type)) return FilterType.BYTE;
if ("short".equalsIgnoreCase(type)) return FilterType.SHORT;
if ("int".equalsIgnoreCase(type)) return FilterType.INT;
if ("long".equalsIgnoreCase(type)) return FilterType.LONG;
if ("float".equalsIgnoreCase(type)) return FilterType.FLOAT;
if ("double".equalsIgnoreCase(type)) return FilterType.DOUBLE;
return FilterType.TEXT;
}
public FilterConstraint getFilterConstraint() {
String filterMatchMode = getFilterMatchMode();
FilterConstraint filterConstraint;
if (filterMatchMode.equals("startsWith")) {
filterConstraint = new StartsWithFilterConstraint();
} else if (filterMatchMode.equals("endsWith")) {
filterConstraint = new EndsWithFilterConstraint();
} else if (filterMatchMode.equals("contains")) {
filterConstraint = new ContainsFilterConstraint();
} else if (filterMatchMode.equals("exact")) {
filterConstraint = new ExactFilterConstraint();
} else {
filterConstraint = new StartsWithFilterConstraint();
}
return filterConstraint;
}
protected boolean isFilterRequest(FacesContext x) {
return isIdPrefixedParamSet("_filtering", x);
}
private boolean isIdPrefixedParamSet(String param, FacesContext x) {
return x.getExternalContext().getRequestParameterMap().containsKey(this.getClientId(x) + param);
}
// -------------------
// ----- SORTING -----
// -------------------
public void applySorting() {
setApplyingSorts(true);
}
protected void processSorting() {
Object value = getValue();
if (value instanceof List) {
List list = (List)value;
SortCriteria criteria = getSortCriteria();
String rowVar = getVar();
if (criteria != null) {
if (list.size() > 0 && list.get(0) instanceof Map.Entry)
Collections.sort(list, new EntryKeyComparatorWrapper(new SingleExpressionComparator(criteria, rowVar)));
else
Collections.sort(list, new SingleExpressionComparator(criteria, rowVar));
}
}
//setForcedUpdateCounter(getForcedUpdateCounter()+1);
setApplyingSorts(false);
}
protected SortCriteria getSortCriteria() {
SortCriteria criteria;
Comparator comp = getSortFunction();
if (comp == null) criteria = new SortCriteria(getValueExpression("sortBy"), isSortAscending());
else criteria = new SortCriteria(getValueExpression("sortBy"), isSortAscending(), comp);
return criteria;
}
private class EntryKeyComparatorWrapper implements Comparator {
Comparator comparator;
public EntryKeyComparatorWrapper(Comparator comparator) {
this.comparator = comparator;
}
public int compare(Object o1, Object o2) {
return comparator.compare(((Map.Entry) o1).getKey(), ((Map.Entry) o2).getKey());
}
}
}