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.
JSF components and utilities that can be used with any JSF implementation.
This library is based on the JSF1.1 version of Tomahawk, but with minor source code and build
changes to take advantage of JSF2.1 features. A JSF2.1 implementation is required to use this
version of the Tomahawk library.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.myfaces.component.html.ext;
import java.io.IOException;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.component.ContextCallback;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.component.UIPanel;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFacet;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
import org.apache.myfaces.component.NewspaperTable;
import org.apache.myfaces.component.UserRoleAware;
import org.apache.myfaces.component.UserRoleUtils;
import org.apache.myfaces.custom.column.HtmlSimpleColumn;
import org.apache.myfaces.custom.crosstable.UIColumns;
import org.apache.myfaces.custom.sortheader.HtmlCommandSortHeader;
import org.apache.myfaces.renderkit.html.ext.HtmlTableRenderer;
import org.apache.myfaces.renderkit.html.util.TableContext;
import org.apache.myfaces.shared_tomahawk.util.ClassUtils;
/**
* The MyFacesDataTable extends the standard JSF DataTable by two
* important features:
*
*
*
Possiblity to save the state of the DataModel.
*
*
Support for clickable sort headers (see SortHeader
* component).
*
*
* Extended data_table that adds some additional features to the
* standard data_table action: see attribute descriptions for
* preserveDataModel, sortColumn, sortAscending and preserveSort.
*
* Unless otherwise specified, all attributes accept static values or EL expressions.
*
* @since 1.1.7
* @author Thomas Spiegl (latest modification by $Author: lu4242 $)
* @author Manfred Geiler
* @version $Revision: 691856 $ $Date: 2008-09-03 21:40:30 -0500 (mié, 03 sep 2008) $
*/
@JSFComponent(
name = "t:dataTable",
clazz = "org.apache.myfaces.component.html.ext.HtmlDataTable",
tagClass = "org.apache.myfaces.generated.taglib.html.ext.HtmlDataTableTag",
tagHandler = "org.apache.myfaces.component.html.ext.HtmlDataTableTagHandler")
public abstract class AbstractHtmlDataTable extends HtmlDataTableHack
implements UserRoleAware, NewspaperTable, DetailTogglerModel
{
private static final Log log = LogFactory.getLog(AbstractHtmlDataTable.class);
private static final int PROCESS_DECODES = 1;
private static final int PROCESS_VALIDATORS = 2;
private static final int PROCESS_UPDATES = 3;
private static final boolean DEFAULT_SORTASCENDING = true;
private static final boolean DEFAULT_SORTABLE = false;
private static final boolean DEFAULT_EMBEDDED = false;
private static final boolean DEFAULT_DETAILSTAMP_EXPANDED = false;
private static final Class OBJECT_ARRAY_CLASS = (new Object[0]).getClass();
private static final Integer DEFAULT_NEWSPAPER_COLUMNS = new Integer(1);
private static final String DEFAULT_NEWSPAPER_ORIENTATION = "vertical";
private static final String DEFAULT_DETAILSTAMP_LOCATION = "after";
private static final String SKIP_ITERATION_HINT = "javax.faces.visit.SKIP_ITERATION";
/**
* the property names
*/
public static final String NEWSPAPER_COLUMNS_PROPERTY = "newspaperColumns";
public static final String SPACER_FACET_NAME = "spacer";
public static final String NEWSPAPER_ORIENTATION_PROPERTY = "newspaperOrientation";
public static final String DETAIL_STAMP_FACET_NAME = "detailStamp";
public static final String DETAIL_STAMP_ROW_FACET_NAME = "detailStampRow";
public static final String TABLE_ROW_FACET_NAME = "row";
public static final String TABLE_BODY_FACET_NAME = "tbody_element";
// BEGIN Reset mode saveState
static final int RESET_MODE_OFF = 0;
static final int RESET_MODE_SOFT = 1;
static final int RESET_MODE_HARD = 2;
static final String RESET_SAVE_STATE_MODE_KEY =
"oam.view.resetSaveStateMode";
// END Reset mode saveState
private _SerializableDataModel _preservedDataModel;
private boolean _isValidChildren = true;
//private Map _detailRowStates = new HashMap();
private TableContext _tableContext = null;
public TableContext getTableContext()
{
if (_tableContext == null)
{
_tableContext = new TableContext();
}
return _tableContext;
}
public void setDetailStamp(UIComponent facet)
{
getFacets().put(DETAIL_STAMP_FACET_NAME, facet);
}
/**
* This facet renders an additional row after or before (according
* to detailStampLocation value) the current row, usually containing
* additional information of the related row. It is toggled usually
* using varDetailToggler variable and the method toggleDetail().
*
* @JSFFacet name="detailStamp"
*/
public UIComponent getDetailStamp()
{
return (UIComponent) getFacets().get(DETAIL_STAMP_FACET_NAME);
}
@Override
public String getContainerClientId(FacesContext context)
{
String standardClientId = super.getContainerClientId(context);
int rowIndex = getRowIndex();
if (rowIndex == -1)
{
return standardClientId;
}
String forcedIdIndex = getForceIdIndexFormula();
if (forcedIdIndex == null || forcedIdIndex.length() == 0)
return standardClientId;
// we can get the index less client id directly, because only
// getContainerClientId() adds the row index, getClientId() does not.
final String indexLessClientId = getClientId(context);
//noinspection UnnecessaryLocalVariable
String parsedForcedClientId = indexLessClientId + forcedIdIndex;
return parsedForcedClientId;
}
public UIComponent findComponent(String expr)
{
if (expr.length() > 0 && Character.isDigit(expr.charAt(0)))
{
char separator = UINamingContainer.getSeparatorChar(getFacesContext());
int separatorIndex = expr.indexOf(separator);
String rowIndexStr = expr;
String remainingPart = null;
if (separatorIndex != -1)
{
rowIndexStr = expr.substring(0, separatorIndex);
remainingPart = expr.substring(separatorIndex + 1);
}
int rowIndex = Integer.valueOf(rowIndexStr).intValue();
if (remainingPart == null)
{
log.error("Wrong syntax of expression : " + expr +
" rowIndex was provided, but no component name.");
return null;
}
UIComponent comp = super.findComponent(remainingPart);
if (comp == null)
return null;
//noinspection UnnecessaryLocalVariable
UIComponentPerspective perspective = new UIComponentPerspective(this, comp, rowIndex);
return perspective;
}
else
{
return super.findComponent(expr);
}
}
@Override
public boolean invokeOnComponent(FacesContext context, String clientId,
ContextCallback callback) throws FacesException
{
if (context == null || clientId == null || callback == null)
{
throw new NullPointerException();
}
final String baseClientId = getClientId(context);
// searching for this component?
boolean returnValue = baseClientId.equals(clientId);
pushComponentToEL(context, this);
try
{
if (returnValue)
{
try
{
callback.invokeContextCallback(context, this);
return true;
}
catch (Exception e)
{
throw new FacesException(e);
}
}
// Now Look throught facets on this UIComponent
for (Iterator it = this.getFacets().values().iterator(); !returnValue && it.hasNext();)
{
returnValue = it.next().invokeOnComponent(context, clientId, callback);
}
if (returnValue)
{
return returnValue;
}
// is the component an inner component?
if (clientId.startsWith(baseClientId))
{
// Check if the clientId for the component, which we
// are looking for, has a rowIndex attached
char separator = UINamingContainer.getSeparatorChar(context);
ValueExpression rowKeyVE = getValueExpression("rowKey");
boolean rowKeyFound = false;
if (rowKeyVE != null)
{
int oldRow = this.getRowIndex();
try
{
// iterate over the rows
int rowsToProcess = getRows();
// if getRows() returns 0, all rows have to be processed
if (rowsToProcess == 0)
{
rowsToProcess = getRowCount();
}
int rowIndex = getFirst();
for (int rowsProcessed = 0; rowsProcessed < rowsToProcess; rowsProcessed++, rowIndex++)
{
setRowIndex(rowIndex);
if (!isRowAvailable())
{
break;
}
if (clientId.startsWith(getContainerClientId(context)))
{
rowKeyFound = true;
break;
}
}
if (rowKeyFound)
{
returnValue = invokeOnComponentTraverseRow(context, clientId, callback);
}
}
finally
{
this.setRowIndex(oldRow);
}
}
if (rowKeyVE == null && clientId.matches(baseClientId + separator+"[0-9]+"+separator+".*"))
{
String subId = clientId.substring(baseClientId.length() + 1);
String clientRow = subId.substring(0, subId.indexOf(separator));
//Now we save the current position
int oldRow = this.getRowIndex();
// try-finally --> make sure, that the old row index is restored
try
{
//The conversion is safe, because its already checked on the
//regular expresion
this.setRowIndex(Integer.parseInt(clientRow));
// check, if the row is available
if (!isRowAvailable())
{
return false;
}
returnValue = invokeOnComponentTraverseRow(context, clientId, callback);
}
finally
{
//Restore the old position. Doing this prevent
//side effects.
this.setRowIndex(oldRow);
}
}
else if (!rowKeyFound) //If rowKeyVE == null --> rowKeyFound = false
{
// MYFACES-2370: search the component in the childrens' facets too.
// We have to check the childrens' facets here, because in MyFaces
// the rowIndex is not attached to the clientId for the children of
// facets of the UIColumns. However, in RI the rowIndex is
// attached to the clientId of UIColumns' Facets' children.
for (Iterator itChildren = this.getChildren().iterator();
!returnValue && itChildren.hasNext();)
{
UIComponent child = itChildren.next();
// This is the only part different to UIData.invokeOnComponent. Since we have
// an auto wrapping on columns feature, it is necessary to check columns ids
// without row for invokeOnComponent, but do not traverse all elements, so
// save/restore algorithm could be able to remove / add them.
if (child instanceof UIColumn && clientId.equals(child.getClientId(context)))
{
try {
callback.invokeContextCallback(context, child);
} catch (Exception e) {
throw new FacesException(e);
}
returnValue = true;
}
// process the child's facets
for (Iterator itChildFacets = child.getFacets().values().iterator();
!returnValue && itChildFacets.hasNext();)
{
//recursive call to find the component
returnValue = itChildFacets.next().invokeOnComponent(context, clientId, callback);
}
}
}
}
}
finally
{
//all components must call popComponentFromEl after visiting is finished
popComponentFromEL(context);
}
return returnValue;
}
private boolean invokeOnComponentTraverseRow(FacesContext context, String clientId,
ContextCallback callback)
{
boolean returnValue = false;
for (Iterator it1 = getChildren().iterator();
!returnValue && it1.hasNext();)
{
//recursive call to find the component
returnValue = it1.next().invokeOnComponent(context, clientId, callback);
}
if (!returnValue)
{
UIComponent detailStampRowFacet = getFacet(DETAIL_STAMP_ROW_FACET_NAME);
if (detailStampRowFacet != null)
{
returnValue = detailStampRowFacet.invokeOnComponent(context, clientId, callback);
}
UIComponent detailStampFacet = getFacet(DETAIL_STAMP_FACET_NAME);
if (detailStampFacet != null)
{
returnValue = detailStampFacet.invokeOnComponent(context, clientId, callback);
}
UIComponent tableRowFacet = getFacet(TABLE_ROW_FACET_NAME);
if (tableRowFacet != null)
{
returnValue = tableRowFacet.invokeOnComponent(context, clientId, callback);
}
}
return returnValue;
}
public boolean visitTree(VisitContext context, VisitCallback callback)
{
if (!isVisitable(context))
{
return false;
}
// save the current row index
int oldRowIndex = getRowIndex();
// set row index to -1 to process the facets and to get the rowless clientId
setRowIndex(-1);
// push the Component to EL
pushComponentToEL(context.getFacesContext(), this);
try
{
VisitResult visitResult = context.invokeVisitCallback(this,
callback);
switch (visitResult)
{
//we are done nothing has to be processed anymore
case COMPLETE:
return true;
case REJECT:
return false;
//accept
default:
// determine if we need to visit our children
Collection subtreeIdsToVisit = context
.getSubtreeIdsToVisit(this);
boolean doVisitChildren = subtreeIdsToVisit != null
&& !subtreeIdsToVisit.isEmpty();
if (doVisitChildren)
{
// visit the facets of the component
for (UIComponent facet : getFacets().values())
{
if (facet.visitTree(context, callback))
{
return true;
}
}
Boolean skipIterationHint = (Boolean) context.getFacesContext().getAttributes().get(SKIP_ITERATION_HINT);
if (skipIterationHint != null && skipIterationHint.booleanValue())
{
// If SKIP_ITERATION is enabled, do not take into account rows.
if (getChildCount() > 0) {
for (UIComponent child : getChildren()) {
if (child.visitTree(context, callback)) {
return true;
}
}
}
}
else
{
// visit every column directly without visiting its children
// (the children of every UIColumn will be visited later for
// every row) and also visit the column's facets
for (UIComponent child : getChildren())
{
if (child instanceof UIColumn)
{
VisitResult columnResult = context.invokeVisitCallback(child, callback);
if (columnResult == VisitResult.COMPLETE)
{
return true;
}
for (UIComponent facet : child.getFacets().values())
{
if (facet.visitTree(context, callback))
{
return true;
}
}
}
}
boolean visitDetailStamp = (getFacet(DETAIL_STAMP_FACET_NAME) != null);
boolean visitDetailStampRow = (getFacet(DETAIL_STAMP_ROW_FACET_NAME) != null);
boolean visitTableRow = (getFacet(TABLE_ROW_FACET_NAME) != null);
// iterate over the rows
int rowsToProcess = getRows();
// if getRows() returns 0, all rows have to be processed
if (rowsToProcess == 0)
{
rowsToProcess = getRowCount();
}
int rowIndex = getFirst();
for (int rowsProcessed = 0; rowsProcessed < rowsToProcess; rowsProcessed++, rowIndex++)
{
setRowIndex(rowIndex);
if (!isRowAvailable())
{
return false;
}
// visit the children of every child of the UIData that is an instance of UIColumn
for (UIComponent child : getChildren())
{
if (child instanceof UIColumn)
{
for (UIComponent grandchild : child
.getChildren())
{
if (grandchild.visitTree(context, callback))
{
return true;
}
}
}
}
if (visitDetailStampRow)
{
UIComponent detailStampRowFacet = getFacet(DETAIL_STAMP_ROW_FACET_NAME);
if (detailStampRowFacet.visitTree(context, callback))
{
return true;
}
}
if (visitDetailStamp)
{
UIComponent detailStampFacet = getFacet(DETAIL_STAMP_FACET_NAME);
if (detailStampFacet.visitTree(context, callback))
{
return true;
}
}
if (visitTableRow)
{
UIComponent tableRowFacet = getFacet(TABLE_ROW_FACET_NAME);
if (tableRowFacet.visitTree(context, callback))
{
return true;
}
}
}
}
}
}
}
finally
{
// pop the component from EL and restore the old row index
popComponentFromEL(context.getFacesContext());
setRowIndex(oldRowIndex);
}
// Return false to allow the visiting to continue
return false;
}
public void setRowIndex(int rowIndex)
{
//FacesContext facesContext = FacesContext.getCurrentInstance();
if (rowIndex < -1)
{
throw new IllegalArgumentException("rowIndex is less than -1");
}
//UIComponent facet = getFacet(HtmlTableRenderer.DETAIL_STAMP_FACET_NAME);
/*Just for obtaining an iterator which must be passed to saveDescendantComponentStates()*/
//ArrayList detailStampList = new ArrayList(1);
//detailStampList.add(facet);
//if (getRowIndex() != -1 && facet != null)
//{
// _detailRowStates.put(getContainerClientId(facesContext), saveDescendantComponentStates(detailStampList.iterator(), false));
//}
String rowIndexVar = getRowIndexVar();
String rowCountVar = getRowCountVar();
String previousRowDataVar = getPreviousRowDataVar();
if (rowIndexVar != null || rowCountVar != null || previousRowDataVar != null)
{
Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
if (previousRowDataVar != null && rowIndex >= 0) //we only need to provide the previousRowDataVar for a valid rowIndex
{
if (isRowAvailable())
{
//previous row is available
requestMap.put(previousRowDataVar, getRowData());
}
else
{
//no previous row available
requestMap.put(previousRowDataVar, null);
}
}
super.setRowIndex(rowIndex);
if (rowIndex >= 0)
{
//regular row index, update request scope variables
if (rowIndexVar != null)
{
requestMap.put(rowIndexVar, new Integer(rowIndex));
}
if (rowCountVar != null)
{
requestMap.put(rowCountVar, new Integer(getRowCount()));
}
}
else
{
//rowIndex == -1 means end of loop --> remove request scope variables
if (rowIndexVar != null)
{
requestMap.remove(rowIndexVar);
}
if (rowCountVar != null)
{
requestMap.remove(rowCountVar);
}
if (previousRowDataVar != null)
{
requestMap.remove(previousRowDataVar);
}
}
}
else
{
// no extended var attributes defined, no special treatment
super.setRowIndex(rowIndex);
}
//if (rowIndex != -1 && facet != null)
//{
// Object rowState = _detailRowStates.get(getContainerClientId(facesContext));
// restoreDescendantComponentStates(detailStampList.iterator(),
// rowState, false);
//}
UIComponent detailStampRowFacet = getFacet(DETAIL_STAMP_ROW_FACET_NAME);
if (detailStampRowFacet != null)
{
detailStampRowFacet.setId(detailStampRowFacet.getId());
}
UIComponent tableRowFacet = getFacet(TABLE_ROW_FACET_NAME);
if (tableRowFacet != null){
tableRowFacet.setId(tableRowFacet.getId());
}
if (getStateHelper().get(PropertyKeys.varDetailToggler) != null)
{
Map requestMap = getFacesContext().getExternalContext().getRequestMap();
requestMap.put(getStateHelper().get(PropertyKeys.varDetailToggler), this);
}
}
@Override
protected Object saveDescendantComponentStates()
{
if (getFacetCount() > 0)
{
UIComponent detailStampFacet = getFacet(DETAIL_STAMP_FACET_NAME);
if (detailStampFacet != null)
{
return saveDescendantComponentStates(new _DetailStampFacetAndChildrenIterator(detailStampFacet, getChildren()), false);
}
}
return super.saveDescendantComponentStates();
}
@Override
protected void restoreDescendantComponentStates(Object state)
{
if (getFacetCount() > 0)
{
UIComponent detailStampFacet = getFacet(DETAIL_STAMP_FACET_NAME);
if (detailStampFacet != null)
{
restoreDescendantComponentStates(new _DetailStampFacetAndChildrenIterator(detailStampFacet, getChildren()), state, false);
return;
}
}
super.restoreDescendantComponentStates(state);
}
@Override
protected void restoreFullDescendantComponentDeltaStates(FacesContext facesContext,
Map rowState, Object initialState)
{
if (getFacetCount() > 0)
{
UIComponent detailStampFacet = getFacet(DETAIL_STAMP_FACET_NAME);
if (detailStampFacet != null)
{
restoreFullDescendantComponentDeltaStates(facesContext, new _DetailStampFacetAndChildrenIterator(detailStampFacet, getChildren()), rowState, initialState, false, getContainerClientId(facesContext));
return;
}
}
super.restoreFullDescendantComponentDeltaStates(facesContext, rowState, initialState);
}
@Override
protected void restoreFullDescendantComponentStates(FacesContext facesContext,
Object initialState)
{
if (getFacetCount() > 0)
{
UIComponent detailStampFacet = getFacet(DETAIL_STAMP_FACET_NAME);
if (detailStampFacet != null)
{
restoreFullDescendantComponentStates(facesContext, new _DetailStampFacetAndChildrenIterator(detailStampFacet, getChildren()), initialState, false);
return;
}
}
super.restoreFullDescendantComponentStates(facesContext, initialState);
}
@Override
protected Collection