JBoss Rich Faces SVN: r15954 - branches/community/3.3.X.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2009-11-21 21:11:34 -0500 (Sat, 21 Nov 2009)
New Revision: 15954
Modified:
branches/community/3.3.X/deployRelease.sh
Log:
Framework: merged from 3.3.x_jsf2 branch
Modified: branches/community/3.3.X/deployRelease.sh
===================================================================
--- branches/community/3.3.X/deployRelease.sh 2009-11-22 02:09:59 UTC (rev 15953)
+++ branches/community/3.3.X/deployRelease.sh 2009-11-22 02:11:34 UTC (rev 15954)
@@ -11,6 +11,8 @@
mvn -s $settings -P local,docs,release clean deploy
cd $PROJECT_DIR/framework
mvn -s $settings -P local,docs,release clean deploy
+cd $PROJECT_DIR/framework/impl
+mvn -s $settings -P local,docs,release,jsf2_0 clean deploy
cd $PROJECT_DIR/ui
mvn -s $settings -P local,docs,release clean deploy -N
mvn -s $settings -P local,docs,release clean install
15 years, 1 month
JBoss Rich Faces SVN: r15953 - in branches/community/3.3.X/framework: api and 15 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2009-11-21 21:09:59 -0500 (Sat, 21 Nov 2009)
New Revision: 15953
Added:
branches/community/3.3.X/framework/impl/src/main/java-jsf12/
branches/community/3.3.X/framework/impl/src/main/java-jsf12/org/
branches/community/3.3.X/framework/impl/src/main/java-jsf12/org/ajax4jsf/
branches/community/3.3.X/framework/impl/src/main/java-jsf12/org/ajax4jsf/component/
branches/community/3.3.X/framework/impl/src/main/java-jsf12/org/ajax4jsf/component/UIDataAdaptor.java
branches/community/3.3.X/framework/impl/src/main/java-jsf20/
branches/community/3.3.X/framework/impl/src/main/java-jsf20/org/
branches/community/3.3.X/framework/impl/src/main/java-jsf20/org/ajax4jsf/
branches/community/3.3.X/framework/impl/src/main/java-jsf20/org/ajax4jsf/component/
branches/community/3.3.X/framework/impl/src/main/java-jsf20/org/ajax4jsf/component/UIDataAdaptor.java
branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/UIDataAdaptorBase.java
branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/AbstractJsfTestCase.java
branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/Ajax4JsfMockApplicationFactory.java
branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/Ajax4JsfMockFacesContextFactory.java
branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/MockApplication20.java
branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/MockFacesContext20.java
Removed:
branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/UIDataAdaptor.java
Modified:
branches/community/3.3.X/framework/api/pom.xml
branches/community/3.3.X/framework/impl/pom.xml
branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/AjaxViewRoot.java
branches/community/3.3.X/framework/impl/src/main/java/org/richfaces/component/UIRangedNumberInput.java
branches/community/3.3.X/framework/jsf-test/pom.xml
branches/community/3.3.X/framework/pom.xml
branches/community/3.3.X/framework/test/pom.xml
branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/AbstractAjax4JsfTestCase.java
Log:
Framework: merged from 3.3.x_jsf2 branch
Modified: branches/community/3.3.X/framework/api/pom.xml
===================================================================
--- branches/community/3.3.X/framework/api/pom.xml 2009-11-21 00:23:45 UTC (rev 15952)
+++ branches/community/3.3.X/framework/api/pom.xml 2009-11-22 02:09:59 UTC (rev 15953)
@@ -9,8 +9,14 @@
<artifactId>richfaces-api</artifactId>
<name>Java Server Faces AJAX framework API</name>
<version>3.3.3-SNAPSHOT</version>
+
<dependencies>
<dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
Modified: branches/community/3.3.X/framework/impl/pom.xml
===================================================================
--- branches/community/3.3.X/framework/impl/pom.xml 2009-11-21 00:23:45 UTC (rev 15952)
+++ branches/community/3.3.X/framework/impl/pom.xml 2009-11-22 02:09:59 UTC (rev 15953)
@@ -20,6 +20,25 @@
</resource>
</resources>
<plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.4</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${frameworkAdditionalSourceFolder}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>javacc-maven-plugin</artifactId>
@@ -133,6 +152,45 @@
</plugins>
</build>
</profile>
+ <profile>
+ <id>jsf2_0</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <classifier>jsf2</classifier>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <properties>
+ <frameworkAdditionalSourceFolder>src/main/java-jsf20</frameworkAdditionalSourceFolder>
+ </properties>
+ </profile>
+ <profile>
+ <id>jsf1_2</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <properties>
+ <frameworkAdditionalSourceFolder>src/main/java-jsf12</frameworkAdditionalSourceFolder>
+ </properties>
+ </profile>
</profiles>
<dependencies>
<dependency>
Modified: branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/AjaxViewRoot.java
===================================================================
--- branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/AjaxViewRoot.java 2009-11-21 00:23:45 UTC (rev 15952)
+++ branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/AjaxViewRoot.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -253,7 +253,7 @@
}
}
// Broadcast phase events.
- broadcastEvents(context, phase);
+ broadcastEventsForPhase(context, phase);
// Process afterPhase listeners.
processPhaseListeners(context, phase, false);
}
@@ -283,7 +283,7 @@
* @param phaseId -
* phase, for which events must be processed.
*/
- void broadcastEvents(FacesContext context, PhaseId phaseId) {
+ void broadcastEventsForPhase(FacesContext context, PhaseId phaseId) {
EventsQueue[] events = getEvents();
EventsQueue anyPhaseEvents = events[PhaseId.ANY_PHASE.getOrdinal()];
EventsQueue phaseEvents = events[phaseId.getOrdinal()];
Deleted: branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/UIDataAdaptor.java
===================================================================
--- branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/UIDataAdaptor.java 2009-11-21 00:23:45 UTC (rev 15952)
+++ branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/UIDataAdaptor.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -1,1639 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * 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.ajax4jsf.component;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import javax.el.ELContext;
-import javax.el.ValueExpression;
-import javax.faces.FacesException;
-import javax.faces.application.FacesMessage;
-import javax.faces.component.ContextCallback;
-import javax.faces.component.EditableValueHolder;
-import javax.faces.component.NamingContainer;
-import javax.faces.component.StateHolder;
-import javax.faces.component.UIColumn;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIData;
-import javax.faces.context.FacesContext;
-import javax.faces.convert.Converter;
-import javax.faces.convert.ConverterException;
-import javax.faces.event.AbortProcessingException;
-import javax.faces.event.FacesEvent;
-import javax.faces.event.FacesListener;
-import javax.faces.event.PhaseId;
-import javax.faces.model.DataModel;
-import javax.faces.model.ListDataModel;
-import javax.faces.render.Renderer;
-
-import org.ajax4jsf.model.DataComponentState;
-import org.ajax4jsf.model.DataVisitor;
-import org.ajax4jsf.model.ExtendedDataModel;
-import org.ajax4jsf.model.SerializableDataModel;
-import org.ajax4jsf.renderkit.AjaxChildrenRenderer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Base class for iterable components, like dataTable, Tomahawk dataList,
- * Facelets repeat, tree etc., with support for partial rendering on AJAX
- * responces for one or more selected iterations.
- *
- * @author shura
- *
- */
-public abstract class UIDataAdaptor extends UIData implements AjaxDataEncoder {
-
- /**
- *
- */
- public static final String COMPONENT_STATE_ATTRIBUTE = "componentState";
-
- public final static DataModel EMPTY_MODEL = new ListDataModel(
- Collections.EMPTY_LIST);
-
- private static final Log _log = LogFactory.getLog(UIDataAdaptor.class);
-
- /**
- * Base class for visit data model at phases decode, validation and update
- * model
- *
- * @author shura
- *
- */
- protected abstract class ComponentVisitor implements DataVisitor {
-
- public void process(FacesContext context, Object rowKey, Object argument)
- throws IOException {
- setRowKey(context, rowKey);
- if (isRowAvailable()) {
- Iterator<UIComponent> childIterator = dataChildren();
- while (childIterator.hasNext()) {
- UIComponent component = childIterator.next();
- if (UIColumn.class.equals(component.getClass())) {
- for (UIComponent children : component.getChildren()) {
- processComponent(context, children, argument);
- }
- } else {
- processComponent(context, component, argument);
- }
- }
-
- }
- }
-
- public abstract void processComponent(FacesContext context,
- UIComponent c, Object argument) throws IOException;
-
- }
-
- /**
- * Visitor for process decode on children components.
- */
- protected ComponentVisitor decodeVisitor = new ComponentVisitor() {
-
- public void processComponent(FacesContext context, UIComponent c,
- Object argument) {
- c.processDecodes(context);
- }
-
- };
-
- /**
- * Visitor for process validation phase
- */
- protected ComponentVisitor validateVisitor = new ComponentVisitor() {
-
- public void processComponent(FacesContext context, UIComponent c,
- Object argument) {
- c.processValidators(context);
- }
-
- };
-
- /**
- * Visitor for process update model phase.
- */
- protected ComponentVisitor updateVisitor = new ComponentVisitor() {
-
- public void processComponent(FacesContext context, UIComponent c,
- Object argument) {
- c.processUpdates(context);
- }
-
- };
-
- /**
- * Base client id's of this component, for wich invoked encode... methods.
- * Component will save state and serialisable models for this keys only.
- */
- private Set<String> _encoded;
-
- /**
- * Storage for data model instances with different client id's of this
- * component. In case of child for UIData component, this map will keep data
- * models for different iterations between phases.
- */
- private Map<String, ExtendedDataModel> _modelsMap = new HashMap<String, ExtendedDataModel>();
-
- /**
- * Reference for curent data model
- */
- private ExtendedDataModel _currentModel = null;
-
- /**
- * States of this component for diferent iterations, same as for models.
- */
- private Map<String, DataComponentState> _statesMap = new HashMap<String, DataComponentState>();
-
- /**
- * Reference for current component state.
- */
- private DataComponentState _currentState = null;
-
- /**
- * Name of EL variable for current component state.
- */
- private String _stateVar;
-
- private String _rowKeyVar;
-
- /**
- * Key for current value in model.
- */
- private Object _rowKey = null;
-
-
- private Converter _rowKeyConverter = null;
-
- /**
- * Values of row keys, encoded on ajax response rendering.
- */
- private Set<Object> _ajaxKeys = null;
-
- /**
- * Internal set of row keys, encoded on ajax response rendering and cleared after response complete
- */
- private Set<Object> _ajaxRequestKeys = null;
-
- private Object _ajaxRowKey = null;
-
- private Map<String, Object> _ajaxRowKeysMap = new HashMap<String, Object>();
-
- /**
- * Get name of EL variable for component state.
- *
- * @return the varState
- */
- public String getStateVar() {
- return _stateVar;
- }
-
- /**
- * @param varStatus
- * the varStatus to set
- */
- public void setStateVar(String varStatus) {
- this._stateVar = varStatus;
- }
-
- /**
- * @return the rowKeyVar
- */
- public String getRowKeyVar() {
- return this._rowKeyVar;
- }
-
- /**
- * @param rowKeyVar
- * the rowKeyVar to set
- */
- public void setRowKeyVar(String rowKeyVar) {
- this._rowKeyVar = rowKeyVar;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.faces.component.UIData#getRowCount()
- */
- public int getRowCount() {
- return getExtendedDataModel().getRowCount();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.faces.component.UIData#getRowData()
- */
- public Object getRowData() {
- return getExtendedDataModel().getRowData();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.faces.component.UIData#isRowAvailable()
- */
- public boolean isRowAvailable() {
- return this.getExtendedDataModel().isRowAvailable();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.faces.component.UIData#setRowIndex(int)
- */
- public void setRowIndex(int index) {
- FacesContext faces = FacesContext.getCurrentInstance();
- ExtendedDataModel localModel = getExtendedDataModel();
-
- boolean rowAvailable = isRowAvailable();
-
-
-// if (rowAvailable) {
- // save child state
- this.saveChildState(faces);
-// }
-
- // Set current model row by int, but immediately get value from model.
- // for compability, complex models must provide values map between
- // integer and key value.
- localModel.setRowIndex(index);
-
- rowAvailable = isRowAvailable();
- this._rowKey = localModel.getRowKey();
- this._clientId = null;
-
- boolean rowSelected = this._rowKey != null && rowAvailable;
-
- setupVariable(faces, localModel, rowSelected);
-
-// if (rowAvailable ) {
- // restore child state
- this.restoreChildState(faces);
-// }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.faces.component.UIData#getRowIndex()
- */
- public int getRowIndex() {
- return getExtendedDataModel().getRowIndex();
- }
-
- /**
- * Same as for int index, but for complex model key.
- *
- * @return
- */
- public Object getRowKey() {
- return this._rowKey;
- }
-
- public void setRowKey(Object key) {
- setRowKey(FacesContext.getCurrentInstance(), key);
- }
-
- /**
- * Setup current row by key. Perform same functionality as
- * {@link UIData#setRowIndex(int)}, but for key object - it may be not only
- * row number in sequence data, but, for example - path to current node in
- * tree.
- *
- * @param faces -
- * current FacesContext
- * @param key
- * new key value.
- */
- public void setRowKey(FacesContext faces, Object key) {
- ExtendedDataModel localModel = getExtendedDataModel();
-
- boolean rowAvailable = isRowAvailable();
-
-// if (rowAvailable) {
- // save child state
- this.saveChildState(faces);
-// }
-
- this._rowKey = key;
- this._clientId = null;
-
- localModel.setRowKey(key);
-
- rowAvailable = isRowAvailable();
- boolean rowSelected = key != null && rowAvailable;
-
- //XXX check for row availability
- setupVariable(faces, localModel, rowSelected);
-
-// if (rowAvailable ) {
- // restore child state
- this.restoreChildState(faces);
-// }
- }
-
- /**
- * @return the rowKeyConverter
- */
- public Converter getRowKeyConverter() {
- Converter converter = _rowKeyConverter;
- if (null == converter) {
- ValueExpression ve = getValueExpression("rowKeyConverter");
- if (null != ve) {
- converter = (Converter) ve.getValue(getFacesContext().getELContext());
- }
- }
- return converter;
- }
-
- /**
- * @param rowKeyConverter the rowKeyConverter to set
- */
- public void setRowKeyConverter(Converter rowKeyConverter) {
- _rowKeyConverter = rowKeyConverter;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.ajax4jsf.ajax.repeat.AjaxDataEncoder#getAjaxKeys()
- */
- @SuppressWarnings("unchecked")
- public Set<Object> getAjaxKeys() {
- Set<Object> keys = null;
- if (this._ajaxKeys != null) {
- keys = (this._ajaxKeys);
- } else {
- ValueExpression vb = getValueExpression("ajaxKeys");
- if (vb != null) {
- keys = (Set<Object>) (vb.getValue(getFacesContext().getELContext()));
- } else if (null != _ajaxRowKey) {
- // If none of above exist , use row with submitted AjaxComponent
- keys = new HashSet<Object>(1);
- keys.add(_ajaxRowKey);
- }
- }
- return keys;
- }
-
- public Set<Object> getAllAjaxKeys() {
- Set<Object> ajaxKeys = getAjaxKeys();
-
- Set<Object> allAjaxKeys = null;
- if (ajaxKeys != null) {
- allAjaxKeys = new HashSet<Object>();
- allAjaxKeys.addAll(ajaxKeys);
- }
-
- if (_ajaxRequestKeys != null) {
- if (allAjaxKeys == null) {
- allAjaxKeys = new HashSet<Object>();
- }
-
- allAjaxKeys.addAll(_ajaxRequestKeys);
- }
-
- return allAjaxKeys;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.ajax4jsf.ajax.repeat.AjaxDataEncoder#setAjaxKeys(java.util.Set)
- */
- public void setAjaxKeys(Set<Object> ajaxKeys) {
- this._ajaxKeys = ajaxKeys;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.ajax4jsf.framework.ajax.AjaxChildrenEncoder#encodeAjaxChild(javax.faces.context.FacesContext,
- * java.lang.String, java.util.Set, java.util.Set)
- */
- public void encodeAjaxChild(FacesContext context, String path,
- final Set<String> ids, final Set<String> renderedAreas) throws IOException {
-
- Renderer renderer = getRenderer(context);
- if (null != renderer && renderer instanceof AjaxChildrenRenderer) {
- // If renderer support partial encoding - call them.
- if(_log.isDebugEnabled()){
- _log.debug("Component "+getClientId(context)+" has delegated Encode children components by AjaxChildrenRenderer for path "+path);
- }
- AjaxChildrenRenderer childrenRenderer = (AjaxChildrenRenderer) renderer;
- childrenRenderer.encodeAjaxChildren(context, this, path, ids,
- renderedAreas);
- } else {
- if(_log.isDebugEnabled()){
- _log.debug("Component "+getClientId(context)+" do Encode children components for path "+path);
- }
- // Use simple ajax children encoding for iterate other keys.
- final AjaxChildrenRenderer childrenRenderer = getChildrenRenderer();
- final String childrenPath = path + getId()
- + NamingContainer.SEPARATOR_CHAR;
- ComponentVisitor ajaxVisitor = new ComponentVisitor() {
-
- public void processComponent(FacesContext context,
- UIComponent c, Object argument) throws IOException {
- childrenRenderer.encodeAjaxComponent(context, c,
- childrenPath, ids, renderedAreas);
- }
-
- };
- Set<Object> ajaxKeys = getAllAjaxKeys();
- if (null != ajaxKeys) {
- if(_log.isDebugEnabled()){
- _log.debug("Component "+getClientId(context)+" Encode children components for a keys "+ajaxKeys);
- }
- captureOrigValue();
- Object savedKey = getRowKey();
- setRowKey(context, null);
- Iterator<UIComponent> fixedChildren = fixedChildren();
- while (fixedChildren.hasNext()) {
- UIComponent component = fixedChildren.next();
- ajaxVisitor.processComponent(context, component, null);
- }
- for (Iterator<Object> iter = ajaxKeys.iterator(); iter.hasNext();) {
- Object key = iter.next();
- ajaxVisitor.process(context, key, null);
- }
- setRowKey(context,savedKey);
- restoreOrigValue(context);
- } else {
- if(_log.isDebugEnabled()){
- _log.debug("Component "+getClientId(context)+" children components for all rows");
- }
- iterate(context, ajaxVisitor, null);
- }
- }
- }
-
- /**
- * Instance of default renderer in ajax responses.
- */
- private static final AjaxChildrenRenderer _childrenRenderer = new AjaxChildrenRenderer() {
-
- protected Class<? extends UIComponent> getComponentClass() {
- return UIDataAdaptor.class;
- }
-
- };
-
- /**
- * getter for simple {@link AjaxChildrenRenderer} instance in case of ajax
- * responses. If default renderer not support search of children for encode
- * in ajax response, component will use this instance by default.
- *
- * @return
- */
- protected AjaxChildrenRenderer getChildrenRenderer() {
- return _childrenRenderer;
- }
-
- /**
- * @return Set of values for clientId's of this component, for wich was
- * invoked "encode" methods.
- */
- protected Set<String> getEncodedIds() {
- if (_encoded == null) {
- _encoded = new HashSet<String>();
- }
-
- return _encoded;
- }
-
- /**
- * Setup EL variable for different iteration. Value of row data and
- * component state will be put into request scope attributes with names
- * given by "var" and "varState" bean properties.
- *
- * Changed: does not check for row availability now
- *
- * @param faces
- * current faces context
- * @param localModel
- * @param rowSelected
- */
- protected void setupVariable(FacesContext faces, DataModel localModel,
- boolean rowSelected) {
- Map<String, Object> attrs = faces.getExternalContext().getRequestMap();
- if (rowSelected/*&& isRowAvailable()*/) {
- // Current row data.
- setupVariable(getVar(), attrs, localModel.getRowData());
- // Component state variable.
- setupVariable(getStateVar(), attrs, getComponentState());
- // Row key Data variable.
- setupVariable(getRowKeyVar(), attrs, getRowKey());
-
- } else {
- removeVariable(getVar(), attrs);
- removeVariable(getStateVar(), attrs);
- removeVariable(getRowKeyVar(), attrs);
- }
- }
-
- /**
- * @param var
- * @param attrs
- * @param rowData
- */
- private void setupVariable(String var, Map<String, Object> attrs, Object rowData) {
- if (var != null) {
- attrs.put(var, rowData);
- }
- }
-
- /**
- * @param var
- * @param attrs
- * @param rowData
- */
- private void removeVariable(String var, Map<String, Object> attrs) {
- if (var != null) {
- attrs.remove(var);
- }
- }
-
- /**
- * Reset data model. this method must be called twice per request - before
- * decode phase and before component encoding.
- */
- protected void resetDataModel() {
- this._currentModel = null;
- _modelsMap.clear();
- }
-
- /**
- * Set data model. Model value will be stored in Map with key as current
- * clientId for this component, to keep models between phases for same
- * iteration in case if this component child for other UIData
- *
- * @param model
- */
- protected void setExtendedDataModel(ExtendedDataModel model) {
- this._currentModel = model;
- this._modelsMap.put(getBaseClientId(getFacesContext()), model);
- }
-
- /**
- * Get current data model, or create it by {@link #createDataModel()}
- * method. For different iterations in ancestor UIData ( if present ) will
- * be returned different models.
- *
- * @return current data model.
- */
- protected ExtendedDataModel getExtendedDataModel() {
- if (this._currentModel == null) {
- String baseClientId = getBaseClientId(getFacesContext());
- ExtendedDataModel model;
- model = (ExtendedDataModel) this._modelsMap.get(baseClientId);
- if (null == model) {
- model = createDataModel();
- this._modelsMap.put(baseClientId, model);
- }
- this._currentModel = model;
- }
- return this._currentModel;
- }
-
- /**
- * Hook mathod for create data model in concrete implementations.
- *
- * @return
- */
- protected abstract ExtendedDataModel createDataModel();
-
- /**
- * Set current state ( at most cases, visual representation ) of this
- * component. Same as for DataModel, component will keep states for
- * different iterations.
- *
- * @param state
- */
- public void setComponentState(DataComponentState state) {
- this._currentState = state;
- this._statesMap.put(getBaseClientId(getFacesContext()),
- this._currentState);
- }
-
- /**
- * @return current state of this component.
- */
- public DataComponentState getComponentState() {
- DataComponentState state = null;
- if (this._currentState == null) {
- // Check for binding state to user bean.
- ValueExpression valueBinding = getValueExpression(UIDataAdaptor.COMPONENT_STATE_ATTRIBUTE);
- FacesContext facesContext = getFacesContext();
- ELContext elContext = facesContext.getELContext();
- if (null != valueBinding) {
- state = (DataComponentState) valueBinding
- .getValue(elContext);
- if (null == state) {
- // Create default state
- state = createComponentState();
- if (!valueBinding.isReadOnly(elContext)) {
- // Store created state in user bean.
- valueBinding.setValue(elContext, state);
- }
- }
- } else {
- // Check for stored state in map for parent iterations
- String baseClientId = getBaseClientId(facesContext);
- state = (DataComponentState) this._statesMap.get(baseClientId);
- if (null == state) {
- // Create default component state
- state = createComponentState();
- this._statesMap.put(baseClientId, state);
- }
- this._currentState = state;
- }
- } else {
- state = this._currentState;
- }
- return state;
- }
-
- /**
- * Hook method for create default state in concrete implementations.
- *
- * @return
- */
- protected abstract DataComponentState createComponentState();
-
- private String _clientId = null;
-
- public String getClientId(FacesContext faces) {
- if (null == _clientId) {
- StringBuilder id = new StringBuilder(getBaseClientId(faces));
- Object rowKey = getRowKey();
- if (rowKey != null) {
- // Use converter to get String representation ot the row key.
- Converter rowKeyConverter = getRowKeyConverter();
- if(null == rowKeyConverter){
- // Create default converter for a row key.
- rowKeyConverter = faces.getApplication().createConverter(rowKey.getClass());
- // Store converter for a invokeOnComponents call.
- if(null != rowKeyConverter){
- setRowKeyConverter(rowKeyConverter);
- }
- }
- String rowKeyString;
- if (null !=rowKeyConverter) {
- // Temporary set clientId, to avoid infinite calls from converter.
- _clientId = id.toString();
- rowKeyString = rowKeyConverter.getAsString(faces, this, rowKey);
- } else {
- rowKeyString = rowKey.toString();
- }
- id.append(NamingContainer.SEPARATOR_CHAR).append(
- rowKeyString);
- }
- Renderer renderer;
- if (null != (renderer = getRenderer(faces))) {
- _clientId = renderer.convertClientId(faces, id.toString());
- } else {
- _clientId = id.toString();
- }
-
- }
- return _clientId;
- }
-
- private String _baseClientId = null;
-
- /**
- * Get base clietntId of this component ( withowt iteration part )
- *
- * @param faces
- * @return
- */
- public String getBaseClientId(FacesContext faces) {
- // Return any previously cached client identifier
- if (_baseClientId == null) {
-
- // Search for an ancestor that is a naming container
- UIComponent ancestorContainer = this;
- StringBuilder parentIds = new StringBuilder();
- while (null != (ancestorContainer = ancestorContainer.getParent())) {
- if (ancestorContainer instanceof NamingContainer) {
- String containerClientId = ancestorContainer.getContainerClientId(faces);
- // skip case when clientId of ancestor container is null
- if(containerClientId != null) {
- parentIds.append(containerClientId).append(NamingContainer.SEPARATOR_CHAR);
- }
- break;
- }
- }
- String id = getId();
- if (null != id) {
- _baseClientId = parentIds.append(id).toString();
- } else {
- id = faces.getViewRoot().createUniqueId();
- super.setId(id);
- _baseClientId = parentIds.append(
- getId()).toString();
- }
- }
- return (_baseClientId);
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.faces.component.UIComponentBase#setId(java.lang.String)
- */
- public void setId(String id) {
- // If component created by restoring tree or JSP, initial Id is null.
- boolean haveId = null != super.getId();
- String baseClientId;
-// baseClientId = haveId ? getBaseClientId(getFacesContext())
-// : null;
- super.setId(id);
- _baseClientId = null;
- _clientId = null;
- if (haveId) {
- // parent UIData ( if present ) will be set same Id at iteration
- // -
- // we use it for
- // switch to different model and state.
- // Step one - save old values.
-// this._statesMap.put(baseClientId, this._currentState);
-// this._modelsMap.put(baseClientId, this._currentModel);
-// this._ajaxRowKeysMap.put(baseClientId, this._ajaxRowKey);
- // Step two - restore values for a new clientId.
- baseClientId = getBaseClientId(getFacesContext());
- this._currentState = (DataComponentState) this._statesMap
- .get(baseClientId);
- this._currentModel = (ExtendedDataModel) this._modelsMap
- .get(baseClientId);
- if (null != this._currentModel) {
- this._rowKey = this._currentModel.getRowKey();
- // restoreChildState();
- }
- // Restore value for row with submitted AjaxComponent.
- this._ajaxRowKey = _ajaxRowKeysMap.get(baseClientId);
- }
- }
-
- private Object origValue;
-
- /**
- * Save current state of data variable.
- */
- public void captureOrigValue() {
- captureOrigValue(FacesContext.getCurrentInstance());
- }
-
- /**
- * Save current state of data variable.
- *
- * @param faces
- * current faces context
- */
- public void captureOrigValue(FacesContext faces) {
- String var = getVar();
- if (var != null) {
- Map<String, Object> attrs = faces.getExternalContext().getRequestMap();
- this.origValue = attrs.get(var);
- }
- }
-
- /**
- * Restore value of data variable after processing phase.
- */
- public void restoreOrigValue() {
- restoreOrigValue(FacesContext.getCurrentInstance());
- }
-
- /**
- * Restore value of data variable after processing phase.
- *
- * @param faces
- * current faces context
- */
- public void restoreOrigValue(FacesContext faces) {
- String var = getVar();
- if (var != null) {
- Map<String, Object> attrs = faces.getExternalContext().getRequestMap();
- if (this.origValue != null) {
- attrs.put(var, this.origValue);
- } else {
- attrs.remove(var);
- }
- }
- }
-
- /**
- * Saved values of {@link EditableValueHolder} fields per iterations.
- */
- private Map<String, Map<String, SavedState>> childState;
-
- /**
- * @param faces
- * @return Saved values of {@link EditableValueHolder} fields per
- * iterations.
- */
- protected Map<String, SavedState> getChildState(FacesContext faces) {
- if (this.childState == null) {
- this.childState = new HashMap<String, Map<String,SavedState>>();
- }
- String baseClientId = getBaseClientId(faces);
- Map<String, SavedState> currentChildState = childState.get(baseClientId);
- if (null == currentChildState) {
- currentChildState = new HashMap<String, SavedState>();
- childState.put(baseClientId, currentChildState);
- }
- return currentChildState;
- }
-
- /**
- * Save values of {@link EditableValueHolder} fields before change current
- * row.
- *
- * @param faces
- */
- protected void saveChildState(FacesContext faces) {
-
- Iterator<UIComponent> itr = dataChildren();
- Map<String, SavedState> childState = this.getChildState(faces);
- while (itr.hasNext()) {
- this.saveChildState(faces, (UIComponent) itr.next(), childState);
- }
- }
-
- /**
- * Recursive method for Iterate on children for save
- * {@link EditableValueHolder} fields states.
- *
- * @param faces
- * @param c
- * @param childState
- */
- private void saveChildState(FacesContext faces, UIComponent c,
- Map<String, SavedState> childState) {
-
- if (!c.isTransient() && (c instanceof EditableValueHolder||c instanceof IterationStateHolder)) {
- String clientId = c.getClientId(faces);
- SavedState ss = childState.get(clientId);
- if (ss == null) {
- ss = new SavedState();
- childState.put(clientId, ss);
- }
- if (c instanceof EditableValueHolder) {
- ss.populate((EditableValueHolder) c);
- }
- if(c instanceof IterationStateHolder){
- ss.populate((IterationStateHolder) c);
- }
- }
- // continue hack
- Iterator<UIComponent> itr = c.getChildren().iterator();
- while (itr.hasNext()) {
- saveChildState(faces, (UIComponent) itr.next(), childState);
- }
- itr = c.getFacets().values().iterator();
- while (itr.hasNext()) {
- saveChildState(faces, (UIComponent) itr.next(), childState);
- }
- }
-
- /**
- * Restore values of {@link EditableValueHolder} fields after change current
- * row.
- *
- * @param faces
- */
- protected void restoreChildState(FacesContext faces) {
-
- Iterator<UIComponent> itr = dataChildren();
- Map<String, SavedState> childState = this.getChildState(faces);
- while (itr.hasNext()) {
- this.restoreChildState(faces, (UIComponent) itr.next(), childState);
- }
- }
-
- /**
- * Recursive part of
- * {@link #restoreChildState(FacesContext, UIComponent, Map)}
- *
- * @param faces
- * @param c
- * @param childState
- *
- */
- private void restoreChildState(FacesContext faces, UIComponent c,
- Map<String, SavedState> childState) {
- // reset id
- String id = c.getId();
- c.setId(id);
-
- // hack
- if (c instanceof EditableValueHolder || c instanceof IterationStateHolder) {
- String clientId = c.getClientId(faces);
- SavedState ss = childState.get(clientId);
- if (ss == null) {
- ss=NullState;
- }
- if (c instanceof EditableValueHolder) {
- EditableValueHolder evh = (EditableValueHolder) c;
- ss.apply(evh);
- }
- if (c instanceof IterationStateHolder) {
- IterationStateHolder ish = (IterationStateHolder) c;
- ss.apply(ish);
- }
- }
-
- // continue hack
- for (UIComponent child : c.getChildren()) {
- restoreChildState(faces, child, childState);
- }
- for (UIComponent facet : c.getFacets().values()) {
- restoreChildState(faces, facet, childState);
- }
- }
-
- /**
- * Check for validation errors on children components. If true, saved values
- * must be keep on render phase
- *
- * @param context
- * @return
- */
- protected boolean keepSaved(FacesContext context) {
- // For an any validation errors, children components state should be preserved
- FacesMessage.Severity sev = context.getMaximumSeverity();
- return (sev != null && (FacesMessage.SEVERITY_ERROR.compareTo(sev) >= 0));
- }
-
- /**
- * Perform iteration on all children components and all data rows with given
- * visitor.
- *
- * @param faces
- * @param visitor
- */
- protected void iterate(FacesContext faces, ComponentVisitor visitor,
- Object argument) {
-
- // stop if not rendered
- if (!this.isRendered()) {
- return;
- }
- // reset rowIndex
- this.captureOrigValue(faces);
- this.setRowKey(faces, null);
- try {
- Iterator<UIComponent> fixedChildren = fixedChildren();
- while (fixedChildren.hasNext()) {
- UIComponent component = fixedChildren.next();
- visitor.processComponent(faces, component, argument);
- }
-
- walk(faces, visitor, argument);
- } catch (Exception e) {
- throw new FacesException(e);
- } finally {
- this.setRowKey(faces, null);
- this.restoreOrigValue(faces);
- }
- }
-
- /**
- * Extracts segment of component client identifier containing row key
- *
- * @param context current faces context
- * @param tailId substring of component client identifier with base client identifier removed
- * @return segment containing row key or <code>null</code>
- */
- protected String extractKeySegment(FacesContext context, String tailId) {
- int indexOfSecondColon = tailId.indexOf(NamingContainer.SEPARATOR_CHAR);
-
- return (indexOfSecondColon > 0 ? tailId.substring(0, indexOfSecondColon) : null);
- }
-
- /**
- * Returns iterator of components to search through
- * in {@link #invokeOnComponent(FacesContext, String, ContextCallback)}.
- *
- * @return
- */
- protected Iterator<UIComponent> invocableChildren() {
- return getFacetsAndChildren();
- }
-
- @Override
- public boolean invokeOnComponent(FacesContext context, String clientId,
- ContextCallback callback) throws FacesException {
- if( null == context || null == clientId || null == callback){
- throw new NullPointerException();
- }
- boolean found = false;
- Object oldRowKey = getRowKey();
- String baseClientId = getBaseClientId(context);
- if (clientId.equals(baseClientId)) {
- // This is call for a same data component.
- try {
- if (null != oldRowKey) {
- captureOrigValue(context);
- setRowKey(context,null);
- }
- callback.invokeContextCallback(context, this);
- found = true;
- } catch (Exception e) {
- throw new FacesException(e);
- } finally {
- if (null != oldRowKey) {
- try {
- setRowKey(context,oldRowKey);
- restoreOrigValue(context);
- } catch (Exception e) {
- context.getExternalContext().log(e.getMessage(), e);
- }
- }
- }
- } else {
- String baseId = baseClientId + NamingContainer.SEPARATOR_CHAR;
- if (clientId.startsWith(baseId)) {
- Object newRowKey = null;
- // Call for a child component - try to detect row key
- String rowKeyString = extractKeySegment(context,
- clientId.substring(baseId.length()));
- if (rowKeyString != null) {
- Converter keyConverter = getRowKeyConverter();
- if (null != keyConverter) {
- try {
- newRowKey = keyConverter.getAsObject(context, this,
- rowKeyString);
- } catch (ConverterException e) {
- // TODO: log error
- }
- }
- }
- if( null != oldRowKey || null != newRowKey){
- captureOrigValue(context);
- setRowKey(newRowKey);
- }
- Iterator<UIComponent> itr = invocableChildren();
- while (itr.hasNext() && !found) {
- found = itr.next().invokeOnComponent(context, clientId,
- callback);
- }
- if( null != oldRowKey || null != newRowKey){
- setRowKey(oldRowKey);
- restoreOrigValue(context);
- }
- }
- }
-
- return found;
- }
-
- /**
- * Walk ( visit ) this component on all data-avare children for each row.
- *
- * @param faces
- * @param visitor
- * @throws IOException
- */
- public void walk(FacesContext faces, DataVisitor visitor, Object argument)
- throws IOException {
- getExtendedDataModel().walk(faces, visitor,
- getComponentState().getRange(), argument);
- }
-
- protected void processDecodes(FacesContext faces, Object argument) {
- if (!this.isRendered())
- return;
- this.iterate(faces, decodeVisitor, argument);
- this.decode(faces);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.faces.component.UIData#processDecodes(javax.faces.context.FacesContext)
- */
- public void processDecodes(FacesContext faces) {
- processDecodes(faces, null);
- }
-
- /**
- * Reset per-request fields in component.
- *
- * @param faces
- *
- */
- protected void resetComponent(FacesContext faces) {
- // resetDataModel();
- if (null != this.childState) {
- childState.remove(getBaseClientId(faces));
- }
- this._encoded = null;
- }
-
- protected void processUpdates(FacesContext faces, Object argument) {
- if (!this.isRendered())
- return;
- this.iterate(faces, updateVisitor, argument);
- ExtendedDataModel dataModel = getExtendedDataModel();
- // If no validation errors, update values for serializable model,
- // restored from view.
- if (dataModel instanceof SerializableDataModel && (!keepSaved(faces))) {
- SerializableDataModel serializableModel = (SerializableDataModel) dataModel;
- serializableModel.update();
- }
-
- }
-
- public void processUpdates(FacesContext faces) {
- processUpdates(faces, null);
- // resetComponent(faces);
- }
-
- protected void processValidators(FacesContext faces, Object argument) {
- if (!this.isRendered())
- return;
- this.iterate(faces, validateVisitor, argument);
- }
-
- public void processValidators(FacesContext faces) {
- processValidators(faces, null);
- }
-
- public void encodeBegin(FacesContext context) throws IOException {
- // Mark component as used, if parent UIData change own range states not
- // accessed at
- // encode phase must be unsaved.
- getEncodedIds().add(getBaseClientId(context));
- // getComponentState().setUsed(true);
- super.encodeBegin(context);
- }
-
- /**
- * This method must create iterator for all non-data avare children of this
- * component ( header/footer facets for components and columns in dataTable,
- * facets for tree etc.
- *
- * @return iterator for all components not sensitive for row data.
- */
- protected abstract Iterator<UIComponent> fixedChildren();
-
- /**
- * This method must create iterator for all children components, processed
- * "per row" It can be children of UIColumn in dataTable, nodes in tree
- *
- * @return iterator for all components processed per row.
- */
- protected abstract Iterator<UIComponent> dataChildren();
-
- private final static SavedState NullState = new SavedState();
-
- // from RI
- /**
- * This class keep values of {@link EditableValueHolder} row-sensitive
- * fields.
- *
- * @author shura
- *
- */
- private final static class SavedState implements Serializable {
-
- private Object submittedValue;
-
- private Object iterationState;
-
- private static final long serialVersionUID = 2920252657338389849L;
-
- Object getSubmittedValue() {
- return (this.submittedValue);
- }
-
- void setSubmittedValue(Object submittedValue) {
- this.submittedValue = submittedValue;
- }
-
- private boolean valid = true;
-
- boolean isValid() {
- return (this.valid);
- }
-
- void setValid(boolean valid) {
- this.valid = valid;
- }
-
- private Object value;
-
- Object getValue() {
- return (this.value);
- }
-
- public void setValue(Object value) {
- this.value = value;
- }
-
- private boolean localValueSet;
-
- boolean isLocalValueSet() {
- return (this.localValueSet);
- }
-
- public void setLocalValueSet(boolean localValueSet) {
- this.localValueSet = localValueSet;
- }
-
- public Object getIterationState() {
- return iterationState;
- }
-
- public void setIterationState(Object iterationState) {
- this.iterationState = iterationState;
- }
-
- public String toString() {
- return ("submittedValue: " + submittedValue + " value: " + value
- + " localValueSet: " + localValueSet);
- }
-
- public void populate(EditableValueHolder evh) {
- this.value = evh.getLocalValue();
- this.valid = evh.isValid();
- this.submittedValue = evh.getSubmittedValue();
- this.localValueSet = evh.isLocalValueSet();
- }
-
-
- public void populate(IterationStateHolder ish) {
- this.iterationState = ish.getIterationState();
- }
-
- public void apply(EditableValueHolder evh) {
- evh.setValue(this.value);
- evh.setValid(this.valid);
- evh.setSubmittedValue(this.submittedValue);
- evh.setLocalValueSet(this.localValueSet);
- }
-
- public void apply(IterationStateHolder ish) {
- ish.setIterationState(this.iterationState);
- }
-
- }
-
- protected void addAjaxKeyEvent(FacesEvent event) {
- Object eventRowKey = getRowKey();
- if (null != eventRowKey) {
- this._ajaxRowKey = eventRowKey;
- this._ajaxRowKeysMap.put(getBaseClientId(getFacesContext()),
- eventRowKey);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.faces.component.UIData#queueEvent(javax.faces.event.FacesEvent)
- */
- public void queueEvent(FacesEvent event) {
- if (event.getComponent() != this) {
- // For Ajax events, keep row value.
- if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
- addAjaxKeyEvent(event);
- }
- event = new IndexedEvent(this, event, getRowKey());
- }
- // Send event directly to parent, to avoid wrapping in superclass.
- UIComponent parent = getParent();
- if (parent == null) {
- throw new IllegalStateException("No parent component for queue event");
- } else {
- parent.queueEvent(event);
- }
- }
-
- public void broadcast(FacesEvent event) throws AbortProcessingException {
- if (!(event instanceof IndexedEvent)) {
- if (!broadcastLocal(event)) {
- super.broadcast(event);
- }
- return;
- }
-
- // Set up the correct context and fire our wrapped event
- IndexedEvent revent = (IndexedEvent) event;
- Object oldRowKey = getRowKey();
- FacesContext faces = FacesContext.getCurrentInstance();
- captureOrigValue(faces);
- Object eventRowKey = revent.getKey();
- setRowKey(faces, eventRowKey);
- FacesEvent rowEvent = revent.getTarget();
-
- rowEvent.getComponent().broadcast(rowEvent);
-
- setRowKey(faces, oldRowKey);
- restoreOrigValue(faces);
- }
-
- /**
- * Process events targetted for concrete implementation. Hook method called
- * from {@link #broadcast(FacesEvent)}
- *
- * @param event -
- * processed event.
- * @return true if event processed, false if component must continue
- * processing.
- */
- protected boolean broadcastLocal(FacesEvent event) {
- return false;
- }
-
- /**
- * Wrapper for event from child component, with value of current row key.
- *
- * @author shura
- *
- */
- protected static final class IndexedEvent extends FacesEvent {
-
- private static final long serialVersionUID = -8318895390232552385L;
-
- private final FacesEvent target;
-
- private final Object key;
-
- public IndexedEvent(UIDataAdaptor owner, FacesEvent target, Object key) {
- super(owner);
- this.target = target;
- this.key = key;
- }
-
- public PhaseId getPhaseId() {
- return (this.target.getPhaseId());
- }
-
- public void setPhaseId(PhaseId phaseId) {
- this.target.setPhaseId(phaseId);
- }
-
- public boolean isAppropriateListener(FacesListener listener) {
- return this.target.isAppropriateListener(listener);
- }
-
- public void processListener(FacesListener listener) {
- UIDataAdaptor owner = (UIDataAdaptor) this.getComponent();
- Object prevIndex = owner._rowKey;
- try {
- owner.setRowKey(this.key);
- this.target.processListener(listener);
- } finally {
- owner.setRowKey(prevIndex);
- }
- }
-
- public Object getKey() {
- return key;
- }
-
- public FacesEvent getTarget() {
- return target;
- }
-
- }
-
- /**
- * "memento" pattern class for state of component.
- *
- * @author shura
- *
- */
- private static class DataState implements Serializable {
-
- /**
- *
- */
- private static final long serialVersionUID = 17070532L;
-
- private Object superState;
-
- private Map<String, PerIdState> componentStates = new HashMap<String, PerIdState>();
-
- private Set<Object> ajaxKeys;
-
- public String rowKeyVar;
-
- public String stateVar;
-
- private Map<String, Map<String, SavedState>> childStates;
-
- public Object rowKeyConverter;
-
- }
-
- /**
- * Serialisable model and component state per iteration of parent UIData.
- *
- * @author shura
- *
- */
- private static class PerIdState implements Serializable {
- /**
- *
- */
- private static final long serialVersionUID = 9037454770537726418L;
-
- /**
- * Flag setted to true if componentState implements StateHolder
- */
- private boolean stateInHolder = false;
-
- /**
- * Serializable componentState or
- */
- private Object componentState;
-
- private SerializableDataModel model;
- }
-
- public void restoreState(FacesContext faces, Object object) {
- DataState state = (DataState) object;
- super.restoreState(faces, state.superState);
- this._ajaxKeys = state.ajaxKeys;
- this._statesMap = new HashMap<String, DataComponentState>();
- this._rowKeyVar = state.rowKeyVar;
- this._stateVar = state.stateVar;
- this.childState = state.childStates;
- if (null != state.rowKeyConverter) {
- this._rowKeyConverter = (Converter) restoreAttachedState(faces,
- state.rowKeyConverter);
- }
- // Restore serializable models and component states for all rows of
- // parent UIData ( single if this
- // component not child of iterable )
- for (Iterator<Entry<String, PerIdState>> iter = state.componentStates.entrySet().iterator(); iter
- .hasNext();) {
- Entry<String, PerIdState> stateEntry = iter.next();
- PerIdState idState = stateEntry.getValue();
- DataComponentState compState;
- if (idState.stateInHolder) {
- // TODO - change RichFaces Tree component, for remove reference
- // to component from state.
- compState = createComponentState();
- ((StateHolder) compState).restoreState(faces,
- idState.componentState);
- } else {
- compState = (DataComponentState) idState.componentState;
- }
- String key = stateEntry.getKey();
- this._statesMap.put(key, compState);
- this._modelsMap.put(key, idState.model);
- }
- }
-
- public Object saveState(FacesContext faces) {
- DataState state = new DataState();
- state.superState = super.saveState(faces);
- state.ajaxKeys = this._ajaxKeys;
- state.rowKeyVar = this._rowKeyVar;
- state.stateVar = this._stateVar;
- state.childStates = this.childState;
- if (null != this._rowKeyConverter) {
- state.rowKeyConverter = saveAttachedState(faces,this._rowKeyConverter);
- }
- Set<String> encodedIds = getEncodedIds();
- // Save all states of component and data model for all valies of
- // clientId, encoded in this request.
-// this._statesMap.put(getBaseClientId(faces), this._currentState);
-// this._modelsMap.put(getBaseClientId(faces), this._currentModel);
- for (Iterator<Entry<String, DataComponentState>> iter = this._statesMap.entrySet().iterator(); iter
- .hasNext();) {
- Entry<String, DataComponentState> stateEntry = iter.next();
- DataComponentState dataComponentState = stateEntry.getValue();
- String stateKey = stateEntry.getKey();
- if (encodedIds.isEmpty() || encodedIds.contains(stateKey)) {
- PerIdState idState = new PerIdState();
- // Save component state , depended if implemented interfaces.
- if (null == dataComponentState) {
- idState.componentState = null;
- } else {
- if (dataComponentState instanceof Serializable) {
- idState.componentState = dataComponentState;
- } else if (dataComponentState instanceof StateHolder) {
- idState.componentState = ((StateHolder) dataComponentState)
- .saveState(faces);
- idState.stateInHolder = true;
- }
- ExtendedDataModel extendedDataModel = (ExtendedDataModel) this._modelsMap
- .get(stateKey);
- if (null != extendedDataModel) {
- idState.model = extendedDataModel
- .getSerializableModel(dataComponentState
- .getRange());
-
- }
- }
- if (null != idState.model || null != idState.componentState) {
- state.componentStates.put(stateKey, idState);
- }
- }
- }
- return state;
- }
-
- public void setParent(UIComponent parent) {
- super.setParent(parent);
- this._clientId = null;
- this._baseClientId = null;
- }
-
- /**
- * Adds argument key to AJAX internal request keys set
- * @param key key to add
- */
- public void addRequestKey(Object key) {
- if (_ajaxRequestKeys == null) {
- _ajaxRequestKeys = new HashSet<Object>();
- }
-
- _ajaxRequestKeys.add(key);
- }
-
- /**
- * Removes argument key from AJAX internal request keys set
- * @param key key to remove
- */
- public void removeRequestKey(Object key) {
- if (_ajaxRequestKeys != null && key != null) {
- _ajaxRequestKeys.remove(key);
- }
- }
-
- /**
- * Checks whether AJAX internal request keys set contains argument key
- * @param key key to check
- * @return <code>true</code> if set contains key, <code>false</code> - otherwise
- */
- public boolean containsRequestKey(Object key) {
- if (_ajaxRequestKeys != null && key != null) {
- return _ajaxRequestKeys.contains(key);
- }
-
- return false;
- }
-
- /**
- * Clears AJAX internal request keys set
- */
- public void clearRequestKeysSet() {
- _ajaxRequestKeys = null;
- }
-
- public Object getValue() {
- return super.getValue();
- }
-
- public void setValue(Object value) {
- setExtendedDataModel(null);
- super.setValue(value);
- }
-
- public void beforeRenderResponse(FacesContext context) {
- resetDataModel();
- this._encoded = null;
- if (null != childState && !keepSaved(context)) {
- childState.clear();
- }
- }
-}
Copied: branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/UIDataAdaptorBase.java (from rev 15949, branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/UIDataAdaptor.java)
===================================================================
--- branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/UIDataAdaptorBase.java (rev 0)
+++ branches/community/3.3.X/framework/impl/src/main/java/org/ajax4jsf/component/UIDataAdaptorBase.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -0,0 +1,1639 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * 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.ajax4jsf.component;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.ContextCallback;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.NamingContainer;
+import javax.faces.component.StateHolder;
+import javax.faces.component.UIColumn;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIData;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.FacesListener;
+import javax.faces.event.PhaseId;
+import javax.faces.model.DataModel;
+import javax.faces.model.ListDataModel;
+import javax.faces.render.Renderer;
+
+import org.ajax4jsf.model.DataComponentState;
+import org.ajax4jsf.model.DataVisitor;
+import org.ajax4jsf.model.ExtendedDataModel;
+import org.ajax4jsf.model.SerializableDataModel;
+import org.ajax4jsf.renderkit.AjaxChildrenRenderer;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Base class for iterable components, like dataTable, Tomahawk dataList,
+ * Facelets repeat, tree etc., with support for partial rendering on AJAX
+ * responces for one or more selected iterations.
+ *
+ * @author shura
+ *
+ */
+public abstract class UIDataAdaptorBase extends UIData implements AjaxDataEncoder {
+
+ /**
+ *
+ */
+ public static final String COMPONENT_STATE_ATTRIBUTE = "componentState";
+
+ public final static DataModel EMPTY_MODEL = new ListDataModel(
+ Collections.EMPTY_LIST);
+
+ private static final Log _log = LogFactory.getLog(UIDataAdaptor.class);
+
+ /**
+ * Base class for visit data model at phases decode, validation and update
+ * model
+ *
+ * @author shura
+ *
+ */
+ protected abstract class ComponentVisitor implements DataVisitor {
+
+ public void process(FacesContext context, Object rowKey, Object argument)
+ throws IOException {
+ setRowKey(context, rowKey);
+ if (isRowAvailable()) {
+ Iterator<UIComponent> childIterator = dataChildren();
+ while (childIterator.hasNext()) {
+ UIComponent component = childIterator.next();
+ if (UIColumn.class.equals(component.getClass())) {
+ for (UIComponent children : component.getChildren()) {
+ processComponent(context, children, argument);
+ }
+ } else {
+ processComponent(context, component, argument);
+ }
+ }
+
+ }
+ }
+
+ public abstract void processComponent(FacesContext context,
+ UIComponent c, Object argument) throws IOException;
+
+ }
+
+ /**
+ * Visitor for process decode on children components.
+ */
+ protected ComponentVisitor decodeVisitor = new ComponentVisitor() {
+
+ public void processComponent(FacesContext context, UIComponent c,
+ Object argument) {
+ c.processDecodes(context);
+ }
+
+ };
+
+ /**
+ * Visitor for process validation phase
+ */
+ protected ComponentVisitor validateVisitor = new ComponentVisitor() {
+
+ public void processComponent(FacesContext context, UIComponent c,
+ Object argument) {
+ c.processValidators(context);
+ }
+
+ };
+
+ /**
+ * Visitor for process update model phase.
+ */
+ protected ComponentVisitor updateVisitor = new ComponentVisitor() {
+
+ public void processComponent(FacesContext context, UIComponent c,
+ Object argument) {
+ c.processUpdates(context);
+ }
+
+ };
+
+ /**
+ * Base client id's of this component, for wich invoked encode... methods.
+ * Component will save state and serialisable models for this keys only.
+ */
+ private Set<String> _encoded;
+
+ /**
+ * Storage for data model instances with different client id's of this
+ * component. In case of child for UIData component, this map will keep data
+ * models for different iterations between phases.
+ */
+ private Map<String, ExtendedDataModel> _modelsMap = new HashMap<String, ExtendedDataModel>();
+
+ /**
+ * Reference for curent data model
+ */
+ private ExtendedDataModel _currentModel = null;
+
+ /**
+ * States of this component for diferent iterations, same as for models.
+ */
+ private Map<String, DataComponentState> _statesMap = new HashMap<String, DataComponentState>();
+
+ /**
+ * Reference for current component state.
+ */
+ private DataComponentState _currentState = null;
+
+ /**
+ * Name of EL variable for current component state.
+ */
+ private String _stateVar;
+
+ private String _rowKeyVar;
+
+ /**
+ * Key for current value in model.
+ */
+ private Object _rowKey = null;
+
+
+ private Converter _rowKeyConverter = null;
+
+ /**
+ * Values of row keys, encoded on ajax response rendering.
+ */
+ private Set<Object> _ajaxKeys = null;
+
+ /**
+ * Internal set of row keys, encoded on ajax response rendering and cleared after response complete
+ */
+ private Set<Object> _ajaxRequestKeys = null;
+
+ private Object _ajaxRowKey = null;
+
+ private Map<String, Object> _ajaxRowKeysMap = new HashMap<String, Object>();
+
+ /**
+ * Get name of EL variable for component state.
+ *
+ * @return the varState
+ */
+ public String getStateVar() {
+ return _stateVar;
+ }
+
+ /**
+ * @param varStatus
+ * the varStatus to set
+ */
+ public void setStateVar(String varStatus) {
+ this._stateVar = varStatus;
+ }
+
+ /**
+ * @return the rowKeyVar
+ */
+ public String getRowKeyVar() {
+ return this._rowKeyVar;
+ }
+
+ /**
+ * @param rowKeyVar
+ * the rowKeyVar to set
+ */
+ public void setRowKeyVar(String rowKeyVar) {
+ this._rowKeyVar = rowKeyVar;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.component.UIData#getRowCount()
+ */
+ public int getRowCount() {
+ return getExtendedDataModel().getRowCount();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.component.UIData#getRowData()
+ */
+ public Object getRowData() {
+ return getExtendedDataModel().getRowData();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.component.UIData#isRowAvailable()
+ */
+ public boolean isRowAvailable() {
+ return this.getExtendedDataModel().isRowAvailable();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.component.UIData#setRowIndex(int)
+ */
+ public void setRowIndex(int index) {
+ FacesContext faces = FacesContext.getCurrentInstance();
+ ExtendedDataModel localModel = getExtendedDataModel();
+
+ boolean rowAvailable = isRowAvailable();
+
+
+// if (rowAvailable) {
+ // save child state
+ this.saveChildState(faces);
+// }
+
+ // Set current model row by int, but immediately get value from model.
+ // for compability, complex models must provide values map between
+ // integer and key value.
+ localModel.setRowIndex(index);
+
+ rowAvailable = isRowAvailable();
+ this._rowKey = localModel.getRowKey();
+ this._clientId = null;
+
+ boolean rowSelected = this._rowKey != null && rowAvailable;
+
+ setupVariable(faces, localModel, rowSelected);
+
+// if (rowAvailable ) {
+ // restore child state
+ this.restoreChildState(faces);
+// }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.component.UIData#getRowIndex()
+ */
+ public int getRowIndex() {
+ return getExtendedDataModel().getRowIndex();
+ }
+
+ /**
+ * Same as for int index, but for complex model key.
+ *
+ * @return
+ */
+ public Object getRowKey() {
+ return this._rowKey;
+ }
+
+ public void setRowKey(Object key) {
+ setRowKey(FacesContext.getCurrentInstance(), key);
+ }
+
+ /**
+ * Setup current row by key. Perform same functionality as
+ * {@link UIData#setRowIndex(int)}, but for key object - it may be not only
+ * row number in sequence data, but, for example - path to current node in
+ * tree.
+ *
+ * @param faces -
+ * current FacesContext
+ * @param key
+ * new key value.
+ */
+ public void setRowKey(FacesContext faces, Object key) {
+ ExtendedDataModel localModel = getExtendedDataModel();
+
+ boolean rowAvailable = isRowAvailable();
+
+// if (rowAvailable) {
+ // save child state
+ this.saveChildState(faces);
+// }
+
+ this._rowKey = key;
+ this._clientId = null;
+
+ localModel.setRowKey(key);
+
+ rowAvailable = isRowAvailable();
+ boolean rowSelected = key != null && rowAvailable;
+
+ //XXX check for row availability
+ setupVariable(faces, localModel, rowSelected);
+
+// if (rowAvailable ) {
+ // restore child state
+ this.restoreChildState(faces);
+// }
+ }
+
+ /**
+ * @return the rowKeyConverter
+ */
+ public Converter getRowKeyConverter() {
+ Converter converter = _rowKeyConverter;
+ if (null == converter) {
+ ValueExpression ve = getValueExpression("rowKeyConverter");
+ if (null != ve) {
+ converter = (Converter) ve.getValue(getFacesContext().getELContext());
+ }
+ }
+ return converter;
+ }
+
+ /**
+ * @param rowKeyConverter the rowKeyConverter to set
+ */
+ public void setRowKeyConverter(Converter rowKeyConverter) {
+ _rowKeyConverter = rowKeyConverter;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.ajax4jsf.ajax.repeat.AjaxDataEncoder#getAjaxKeys()
+ */
+ @SuppressWarnings("unchecked")
+ public Set<Object> getAjaxKeys() {
+ Set<Object> keys = null;
+ if (this._ajaxKeys != null) {
+ keys = (this._ajaxKeys);
+ } else {
+ ValueExpression vb = getValueExpression("ajaxKeys");
+ if (vb != null) {
+ keys = (Set<Object>) (vb.getValue(getFacesContext().getELContext()));
+ } else if (null != _ajaxRowKey) {
+ // If none of above exist , use row with submitted AjaxComponent
+ keys = new HashSet<Object>(1);
+ keys.add(_ajaxRowKey);
+ }
+ }
+ return keys;
+ }
+
+ public Set<Object> getAllAjaxKeys() {
+ Set<Object> ajaxKeys = getAjaxKeys();
+
+ Set<Object> allAjaxKeys = null;
+ if (ajaxKeys != null) {
+ allAjaxKeys = new HashSet<Object>();
+ allAjaxKeys.addAll(ajaxKeys);
+ }
+
+ if (_ajaxRequestKeys != null) {
+ if (allAjaxKeys == null) {
+ allAjaxKeys = new HashSet<Object>();
+ }
+
+ allAjaxKeys.addAll(_ajaxRequestKeys);
+ }
+
+ return allAjaxKeys;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.ajax4jsf.ajax.repeat.AjaxDataEncoder#setAjaxKeys(java.util.Set)
+ */
+ public void setAjaxKeys(Set<Object> ajaxKeys) {
+ this._ajaxKeys = ajaxKeys;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.ajax4jsf.framework.ajax.AjaxChildrenEncoder#encodeAjaxChild(javax.faces.context.FacesContext,
+ * java.lang.String, java.util.Set, java.util.Set)
+ */
+ public void encodeAjaxChild(FacesContext context, String path,
+ final Set<String> ids, final Set<String> renderedAreas) throws IOException {
+
+ Renderer renderer = getRenderer(context);
+ if (null != renderer && renderer instanceof AjaxChildrenRenderer) {
+ // If renderer support partial encoding - call them.
+ if(_log.isDebugEnabled()){
+ _log.debug("Component "+getClientId(context)+" has delegated Encode children components by AjaxChildrenRenderer for path "+path);
+ }
+ AjaxChildrenRenderer childrenRenderer = (AjaxChildrenRenderer) renderer;
+ childrenRenderer.encodeAjaxChildren(context, this, path, ids,
+ renderedAreas);
+ } else {
+ if(_log.isDebugEnabled()){
+ _log.debug("Component "+getClientId(context)+" do Encode children components for path "+path);
+ }
+ // Use simple ajax children encoding for iterate other keys.
+ final AjaxChildrenRenderer childrenRenderer = getChildrenRenderer();
+ final String childrenPath = path + getId()
+ + NamingContainer.SEPARATOR_CHAR;
+ ComponentVisitor ajaxVisitor = new ComponentVisitor() {
+
+ public void processComponent(FacesContext context,
+ UIComponent c, Object argument) throws IOException {
+ childrenRenderer.encodeAjaxComponent(context, c,
+ childrenPath, ids, renderedAreas);
+ }
+
+ };
+ Set<Object> ajaxKeys = getAllAjaxKeys();
+ if (null != ajaxKeys) {
+ if(_log.isDebugEnabled()){
+ _log.debug("Component "+getClientId(context)+" Encode children components for a keys "+ajaxKeys);
+ }
+ captureOrigValue();
+ Object savedKey = getRowKey();
+ setRowKey(context, null);
+ Iterator<UIComponent> fixedChildren = fixedChildren();
+ while (fixedChildren.hasNext()) {
+ UIComponent component = fixedChildren.next();
+ ajaxVisitor.processComponent(context, component, null);
+ }
+ for (Iterator<Object> iter = ajaxKeys.iterator(); iter.hasNext();) {
+ Object key = iter.next();
+ ajaxVisitor.process(context, key, null);
+ }
+ setRowKey(context,savedKey);
+ restoreOrigValue(context);
+ } else {
+ if(_log.isDebugEnabled()){
+ _log.debug("Component "+getClientId(context)+" children components for all rows");
+ }
+ iterate(context, ajaxVisitor, null);
+ }
+ }
+ }
+
+ /**
+ * Instance of default renderer in ajax responses.
+ */
+ private static final AjaxChildrenRenderer _childrenRenderer = new AjaxChildrenRenderer() {
+
+ protected Class<? extends UIComponent> getComponentClass() {
+ return UIDataAdaptor.class;
+ }
+
+ };
+
+ /**
+ * getter for simple {@link AjaxChildrenRenderer} instance in case of ajax
+ * responses. If default renderer not support search of children for encode
+ * in ajax response, component will use this instance by default.
+ *
+ * @return
+ */
+ protected AjaxChildrenRenderer getChildrenRenderer() {
+ return _childrenRenderer;
+ }
+
+ /**
+ * @return Set of values for clientId's of this component, for wich was
+ * invoked "encode" methods.
+ */
+ protected Set<String> getEncodedIds() {
+ if (_encoded == null) {
+ _encoded = new HashSet<String>();
+ }
+
+ return _encoded;
+ }
+
+ /**
+ * Setup EL variable for different iteration. Value of row data and
+ * component state will be put into request scope attributes with names
+ * given by "var" and "varState" bean properties.
+ *
+ * Changed: does not check for row availability now
+ *
+ * @param faces
+ * current faces context
+ * @param localModel
+ * @param rowSelected
+ */
+ protected void setupVariable(FacesContext faces, DataModel localModel,
+ boolean rowSelected) {
+ Map<String, Object> attrs = faces.getExternalContext().getRequestMap();
+ if (rowSelected/*&& isRowAvailable()*/) {
+ // Current row data.
+ setupVariable(getVar(), attrs, localModel.getRowData());
+ // Component state variable.
+ setupVariable(getStateVar(), attrs, getComponentState());
+ // Row key Data variable.
+ setupVariable(getRowKeyVar(), attrs, getRowKey());
+
+ } else {
+ removeVariable(getVar(), attrs);
+ removeVariable(getStateVar(), attrs);
+ removeVariable(getRowKeyVar(), attrs);
+ }
+ }
+
+ /**
+ * @param var
+ * @param attrs
+ * @param rowData
+ */
+ private void setupVariable(String var, Map<String, Object> attrs, Object rowData) {
+ if (var != null) {
+ attrs.put(var, rowData);
+ }
+ }
+
+ /**
+ * @param var
+ * @param attrs
+ * @param rowData
+ */
+ private void removeVariable(String var, Map<String, Object> attrs) {
+ if (var != null) {
+ attrs.remove(var);
+ }
+ }
+
+ /**
+ * Reset data model. this method must be called twice per request - before
+ * decode phase and before component encoding.
+ */
+ protected void resetDataModel() {
+ this._currentModel = null;
+ _modelsMap.clear();
+ }
+
+ /**
+ * Set data model. Model value will be stored in Map with key as current
+ * clientId for this component, to keep models between phases for same
+ * iteration in case if this component child for other UIData
+ *
+ * @param model
+ */
+ protected void setExtendedDataModel(ExtendedDataModel model) {
+ this._currentModel = model;
+ this._modelsMap.put(getBaseClientId(getFacesContext()), model);
+ }
+
+ /**
+ * Get current data model, or create it by {@link #createDataModel()}
+ * method. For different iterations in ancestor UIData ( if present ) will
+ * be returned different models.
+ *
+ * @return current data model.
+ */
+ protected ExtendedDataModel getExtendedDataModel() {
+ if (this._currentModel == null) {
+ String baseClientId = getBaseClientId(getFacesContext());
+ ExtendedDataModel model;
+ model = (ExtendedDataModel) this._modelsMap.get(baseClientId);
+ if (null == model) {
+ model = createDataModel();
+ this._modelsMap.put(baseClientId, model);
+ }
+ this._currentModel = model;
+ }
+ return this._currentModel;
+ }
+
+ /**
+ * Hook mathod for create data model in concrete implementations.
+ *
+ * @return
+ */
+ protected abstract ExtendedDataModel createDataModel();
+
+ /**
+ * Set current state ( at most cases, visual representation ) of this
+ * component. Same as for DataModel, component will keep states for
+ * different iterations.
+ *
+ * @param state
+ */
+ public void setComponentState(DataComponentState state) {
+ this._currentState = state;
+ this._statesMap.put(getBaseClientId(getFacesContext()),
+ this._currentState);
+ }
+
+ /**
+ * @return current state of this component.
+ */
+ public DataComponentState getComponentState() {
+ DataComponentState state = null;
+ if (this._currentState == null) {
+ // Check for binding state to user bean.
+ ValueExpression valueBinding = getValueExpression(UIDataAdaptor.COMPONENT_STATE_ATTRIBUTE);
+ FacesContext facesContext = getFacesContext();
+ ELContext elContext = facesContext.getELContext();
+ if (null != valueBinding) {
+ state = (DataComponentState) valueBinding
+ .getValue(elContext);
+ if (null == state) {
+ // Create default state
+ state = createComponentState();
+ if (!valueBinding.isReadOnly(elContext)) {
+ // Store created state in user bean.
+ valueBinding.setValue(elContext, state);
+ }
+ }
+ } else {
+ // Check for stored state in map for parent iterations
+ String baseClientId = getBaseClientId(facesContext);
+ state = (DataComponentState) this._statesMap.get(baseClientId);
+ if (null == state) {
+ // Create default component state
+ state = createComponentState();
+ this._statesMap.put(baseClientId, state);
+ }
+ this._currentState = state;
+ }
+ } else {
+ state = this._currentState;
+ }
+ return state;
+ }
+
+ /**
+ * Hook method for create default state in concrete implementations.
+ *
+ * @return
+ */
+ protected abstract DataComponentState createComponentState();
+
+ private String _clientId = null;
+
+ public String getClientId(FacesContext faces) {
+ if (null == _clientId) {
+ StringBuilder id = new StringBuilder(getBaseClientId(faces));
+ Object rowKey = getRowKey();
+ if (rowKey != null) {
+ // Use converter to get String representation ot the row key.
+ Converter rowKeyConverter = getRowKeyConverter();
+ if(null == rowKeyConverter){
+ // Create default converter for a row key.
+ rowKeyConverter = faces.getApplication().createConverter(rowKey.getClass());
+ // Store converter for a invokeOnComponents call.
+ if(null != rowKeyConverter){
+ setRowKeyConverter(rowKeyConverter);
+ }
+ }
+ String rowKeyString;
+ if (null !=rowKeyConverter) {
+ // Temporary set clientId, to avoid infinite calls from converter.
+ _clientId = id.toString();
+ rowKeyString = rowKeyConverter.getAsString(faces, this, rowKey);
+ } else {
+ rowKeyString = rowKey.toString();
+ }
+ id.append(NamingContainer.SEPARATOR_CHAR).append(
+ rowKeyString);
+ }
+ Renderer renderer;
+ if (null != (renderer = getRenderer(faces))) {
+ _clientId = renderer.convertClientId(faces, id.toString());
+ } else {
+ _clientId = id.toString();
+ }
+
+ }
+ return _clientId;
+ }
+
+ private String _baseClientId = null;
+
+ /**
+ * Get base clietntId of this component ( withowt iteration part )
+ *
+ * @param faces
+ * @return
+ */
+ public String getBaseClientId(FacesContext faces) {
+ // Return any previously cached client identifier
+ if (_baseClientId == null) {
+
+ // Search for an ancestor that is a naming container
+ UIComponent ancestorContainer = this;
+ StringBuilder parentIds = new StringBuilder();
+ while (null != (ancestorContainer = ancestorContainer.getParent())) {
+ if (ancestorContainer instanceof NamingContainer) {
+ String containerClientId = ancestorContainer.getContainerClientId(faces);
+ // skip case when clientId of ancestor container is null
+ if(containerClientId != null) {
+ parentIds.append(containerClientId).append(NamingContainer.SEPARATOR_CHAR);
+ }
+ break;
+ }
+ }
+ String id = getId();
+ if (null != id) {
+ _baseClientId = parentIds.append(id).toString();
+ } else {
+ id = faces.getViewRoot().createUniqueId();
+ super.setId(id);
+ _baseClientId = parentIds.append(
+ getId()).toString();
+ }
+ }
+ return (_baseClientId);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.component.UIComponentBase#setId(java.lang.String)
+ */
+ public void setId(String id) {
+ // If component created by restoring tree or JSP, initial Id is null.
+ boolean haveId = null != super.getId();
+ String baseClientId;
+// baseClientId = haveId ? getBaseClientId(getFacesContext())
+// : null;
+ super.setId(id);
+ _baseClientId = null;
+ _clientId = null;
+ if (haveId) {
+ // parent UIData ( if present ) will be set same Id at iteration
+ // -
+ // we use it for
+ // switch to different model and state.
+ // Step one - save old values.
+// this._statesMap.put(baseClientId, this._currentState);
+// this._modelsMap.put(baseClientId, this._currentModel);
+// this._ajaxRowKeysMap.put(baseClientId, this._ajaxRowKey);
+ // Step two - restore values for a new clientId.
+ baseClientId = getBaseClientId(getFacesContext());
+ this._currentState = (DataComponentState) this._statesMap
+ .get(baseClientId);
+ this._currentModel = (ExtendedDataModel) this._modelsMap
+ .get(baseClientId);
+ if (null != this._currentModel) {
+ this._rowKey = this._currentModel.getRowKey();
+ // restoreChildState();
+ }
+ // Restore value for row with submitted AjaxComponent.
+ this._ajaxRowKey = _ajaxRowKeysMap.get(baseClientId);
+ }
+ }
+
+ private Object origValue;
+
+ /**
+ * Save current state of data variable.
+ */
+ public void captureOrigValue() {
+ captureOrigValue(FacesContext.getCurrentInstance());
+ }
+
+ /**
+ * Save current state of data variable.
+ *
+ * @param faces
+ * current faces context
+ */
+ public void captureOrigValue(FacesContext faces) {
+ String var = getVar();
+ if (var != null) {
+ Map<String, Object> attrs = faces.getExternalContext().getRequestMap();
+ this.origValue = attrs.get(var);
+ }
+ }
+
+ /**
+ * Restore value of data variable after processing phase.
+ */
+ public void restoreOrigValue() {
+ restoreOrigValue(FacesContext.getCurrentInstance());
+ }
+
+ /**
+ * Restore value of data variable after processing phase.
+ *
+ * @param faces
+ * current faces context
+ */
+ public void restoreOrigValue(FacesContext faces) {
+ String var = getVar();
+ if (var != null) {
+ Map<String, Object> attrs = faces.getExternalContext().getRequestMap();
+ if (this.origValue != null) {
+ attrs.put(var, this.origValue);
+ } else {
+ attrs.remove(var);
+ }
+ }
+ }
+
+ /**
+ * Saved values of {@link EditableValueHolder} fields per iterations.
+ */
+ private Map<String, Map<String, SavedState>> childState;
+
+ /**
+ * @param faces
+ * @return Saved values of {@link EditableValueHolder} fields per
+ * iterations.
+ */
+ protected Map<String, SavedState> getChildState(FacesContext faces) {
+ if (this.childState == null) {
+ this.childState = new HashMap<String, Map<String,SavedState>>();
+ }
+ String baseClientId = getBaseClientId(faces);
+ Map<String, SavedState> currentChildState = childState.get(baseClientId);
+ if (null == currentChildState) {
+ currentChildState = new HashMap<String, SavedState>();
+ childState.put(baseClientId, currentChildState);
+ }
+ return currentChildState;
+ }
+
+ /**
+ * Save values of {@link EditableValueHolder} fields before change current
+ * row.
+ *
+ * @param faces
+ */
+ protected void saveChildState(FacesContext faces) {
+
+ Iterator<UIComponent> itr = dataChildren();
+ Map<String, SavedState> childState = this.getChildState(faces);
+ while (itr.hasNext()) {
+ this.saveChildState(faces, (UIComponent) itr.next(), childState);
+ }
+ }
+
+ /**
+ * Recursive method for Iterate on children for save
+ * {@link EditableValueHolder} fields states.
+ *
+ * @param faces
+ * @param c
+ * @param childState
+ */
+ private void saveChildState(FacesContext faces, UIComponent c,
+ Map<String, SavedState> childState) {
+
+ if (!c.isTransient() && (c instanceof EditableValueHolder||c instanceof IterationStateHolder)) {
+ String clientId = c.getClientId(faces);
+ SavedState ss = childState.get(clientId);
+ if (ss == null) {
+ ss = new SavedState();
+ childState.put(clientId, ss);
+ }
+ if (c instanceof EditableValueHolder) {
+ ss.populate((EditableValueHolder) c);
+ }
+ if(c instanceof IterationStateHolder){
+ ss.populate((IterationStateHolder) c);
+ }
+ }
+ // continue hack
+ Iterator<UIComponent> itr = c.getChildren().iterator();
+ while (itr.hasNext()) {
+ saveChildState(faces, (UIComponent) itr.next(), childState);
+ }
+ itr = c.getFacets().values().iterator();
+ while (itr.hasNext()) {
+ saveChildState(faces, (UIComponent) itr.next(), childState);
+ }
+ }
+
+ /**
+ * Restore values of {@link EditableValueHolder} fields after change current
+ * row.
+ *
+ * @param faces
+ */
+ protected void restoreChildState(FacesContext faces) {
+
+ Iterator<UIComponent> itr = dataChildren();
+ Map<String, SavedState> childState = this.getChildState(faces);
+ while (itr.hasNext()) {
+ this.restoreChildState(faces, (UIComponent) itr.next(), childState);
+ }
+ }
+
+ /**
+ * Recursive part of
+ * {@link #restoreChildState(FacesContext, UIComponent, Map)}
+ *
+ * @param faces
+ * @param c
+ * @param childState
+ *
+ */
+ private void restoreChildState(FacesContext faces, UIComponent c,
+ Map<String, SavedState> childState) {
+ // reset id
+ String id = c.getId();
+ c.setId(id);
+
+ // hack
+ if (c instanceof EditableValueHolder || c instanceof IterationStateHolder) {
+ String clientId = c.getClientId(faces);
+ SavedState ss = childState.get(clientId);
+ if (ss == null) {
+ ss=NullState;
+ }
+ if (c instanceof EditableValueHolder) {
+ EditableValueHolder evh = (EditableValueHolder) c;
+ ss.apply(evh);
+ }
+ if (c instanceof IterationStateHolder) {
+ IterationStateHolder ish = (IterationStateHolder) c;
+ ss.apply(ish);
+ }
+ }
+
+ // continue hack
+ for (UIComponent child : c.getChildren()) {
+ restoreChildState(faces, child, childState);
+ }
+ for (UIComponent facet : c.getFacets().values()) {
+ restoreChildState(faces, facet, childState);
+ }
+ }
+
+ /**
+ * Check for validation errors on children components. If true, saved values
+ * must be keep on render phase
+ *
+ * @param context
+ * @return
+ */
+ protected boolean keepSaved(FacesContext context) {
+ // For an any validation errors, children components state should be preserved
+ FacesMessage.Severity sev = context.getMaximumSeverity();
+ return (sev != null && (FacesMessage.SEVERITY_ERROR.compareTo(sev) >= 0));
+ }
+
+ /**
+ * Perform iteration on all children components and all data rows with given
+ * visitor.
+ *
+ * @param faces
+ * @param visitor
+ */
+ protected void iterate(FacesContext faces, ComponentVisitor visitor,
+ Object argument) {
+
+ // stop if not rendered
+ if (!this.isRendered()) {
+ return;
+ }
+ // reset rowIndex
+ this.captureOrigValue(faces);
+ this.setRowKey(faces, null);
+ try {
+ Iterator<UIComponent> fixedChildren = fixedChildren();
+ while (fixedChildren.hasNext()) {
+ UIComponent component = fixedChildren.next();
+ visitor.processComponent(faces, component, argument);
+ }
+
+ walk(faces, visitor, argument);
+ } catch (Exception e) {
+ throw new FacesException(e);
+ } finally {
+ this.setRowKey(faces, null);
+ this.restoreOrigValue(faces);
+ }
+ }
+
+ /**
+ * Extracts segment of component client identifier containing row key
+ *
+ * @param context current faces context
+ * @param tailId substring of component client identifier with base client identifier removed
+ * @return segment containing row key or <code>null</code>
+ */
+ protected String extractKeySegment(FacesContext context, String tailId) {
+ int indexOfSecondColon = tailId.indexOf(NamingContainer.SEPARATOR_CHAR);
+
+ return (indexOfSecondColon > 0 ? tailId.substring(0, indexOfSecondColon) : null);
+ }
+
+ /**
+ * Returns iterator of components to search through
+ * in {@link #invokeOnComponent(FacesContext, String, ContextCallback)}.
+ *
+ * @return
+ */
+ protected Iterator<UIComponent> invocableChildren() {
+ return getFacetsAndChildren();
+ }
+
+ @Override
+ public boolean invokeOnComponent(FacesContext context, String clientId,
+ ContextCallback callback) throws FacesException {
+ if( null == context || null == clientId || null == callback){
+ throw new NullPointerException();
+ }
+ boolean found = false;
+ Object oldRowKey = getRowKey();
+ String baseClientId = getBaseClientId(context);
+ if (clientId.equals(baseClientId)) {
+ // This is call for a same data component.
+ try {
+ if (null != oldRowKey) {
+ captureOrigValue(context);
+ setRowKey(context,null);
+ }
+ callback.invokeContextCallback(context, this);
+ found = true;
+ } catch (Exception e) {
+ throw new FacesException(e);
+ } finally {
+ if (null != oldRowKey) {
+ try {
+ setRowKey(context,oldRowKey);
+ restoreOrigValue(context);
+ } catch (Exception e) {
+ context.getExternalContext().log(e.getMessage(), e);
+ }
+ }
+ }
+ } else {
+ String baseId = baseClientId + NamingContainer.SEPARATOR_CHAR;
+ if (clientId.startsWith(baseId)) {
+ Object newRowKey = null;
+ // Call for a child component - try to detect row key
+ String rowKeyString = extractKeySegment(context,
+ clientId.substring(baseId.length()));
+ if (rowKeyString != null) {
+ Converter keyConverter = getRowKeyConverter();
+ if (null != keyConverter) {
+ try {
+ newRowKey = keyConverter.getAsObject(context, this,
+ rowKeyString);
+ } catch (ConverterException e) {
+ // TODO: log error
+ }
+ }
+ }
+ if( null != oldRowKey || null != newRowKey){
+ captureOrigValue(context);
+ setRowKey(newRowKey);
+ }
+ Iterator<UIComponent> itr = invocableChildren();
+ while (itr.hasNext() && !found) {
+ found = itr.next().invokeOnComponent(context, clientId,
+ callback);
+ }
+ if( null != oldRowKey || null != newRowKey){
+ setRowKey(oldRowKey);
+ restoreOrigValue(context);
+ }
+ }
+ }
+
+ return found;
+ }
+
+ /**
+ * Walk ( visit ) this component on all data-avare children for each row.
+ *
+ * @param faces
+ * @param visitor
+ * @throws IOException
+ */
+ public void walk(FacesContext faces, DataVisitor visitor, Object argument)
+ throws IOException {
+ getExtendedDataModel().walk(faces, visitor,
+ getComponentState().getRange(), argument);
+ }
+
+ protected void processDecodes(FacesContext faces, Object argument) {
+ if (!this.isRendered())
+ return;
+ this.iterate(faces, decodeVisitor, argument);
+ this.decode(faces);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.component.UIData#processDecodes(javax.faces.context.FacesContext)
+ */
+ public void processDecodes(FacesContext faces) {
+ processDecodes(faces, null);
+ }
+
+ /**
+ * Reset per-request fields in component.
+ *
+ * @param faces
+ *
+ */
+ protected void resetComponent(FacesContext faces) {
+ // resetDataModel();
+ if (null != this.childState) {
+ childState.remove(getBaseClientId(faces));
+ }
+ this._encoded = null;
+ }
+
+ protected void processUpdates(FacesContext faces, Object argument) {
+ if (!this.isRendered())
+ return;
+ this.iterate(faces, updateVisitor, argument);
+ ExtendedDataModel dataModel = getExtendedDataModel();
+ // If no validation errors, update values for serializable model,
+ // restored from view.
+ if (dataModel instanceof SerializableDataModel && (!keepSaved(faces))) {
+ SerializableDataModel serializableModel = (SerializableDataModel) dataModel;
+ serializableModel.update();
+ }
+
+ }
+
+ public void processUpdates(FacesContext faces) {
+ processUpdates(faces, null);
+ // resetComponent(faces);
+ }
+
+ protected void processValidators(FacesContext faces, Object argument) {
+ if (!this.isRendered())
+ return;
+ this.iterate(faces, validateVisitor, argument);
+ }
+
+ public void processValidators(FacesContext faces) {
+ processValidators(faces, null);
+ }
+
+ public void encodeBegin(FacesContext context) throws IOException {
+ // Mark component as used, if parent UIData change own range states not
+ // accessed at
+ // encode phase must be unsaved.
+ getEncodedIds().add(getBaseClientId(context));
+ // getComponentState().setUsed(true);
+ super.encodeBegin(context);
+ }
+
+ /**
+ * This method must create iterator for all non-data avare children of this
+ * component ( header/footer facets for components and columns in dataTable,
+ * facets for tree etc.
+ *
+ * @return iterator for all components not sensitive for row data.
+ */
+ protected abstract Iterator<UIComponent> fixedChildren();
+
+ /**
+ * This method must create iterator for all children components, processed
+ * "per row" It can be children of UIColumn in dataTable, nodes in tree
+ *
+ * @return iterator for all components processed per row.
+ */
+ protected abstract Iterator<UIComponent> dataChildren();
+
+ private final static SavedState NullState = new SavedState();
+
+ // from RI
+ /**
+ * This class keep values of {@link EditableValueHolder} row-sensitive
+ * fields.
+ *
+ * @author shura
+ *
+ */
+ private final static class SavedState implements Serializable {
+
+ private Object submittedValue;
+
+ private Object iterationState;
+
+ private static final long serialVersionUID = 2920252657338389849L;
+
+ Object getSubmittedValue() {
+ return (this.submittedValue);
+ }
+
+ void setSubmittedValue(Object submittedValue) {
+ this.submittedValue = submittedValue;
+ }
+
+ private boolean valid = true;
+
+ boolean isValid() {
+ return (this.valid);
+ }
+
+ void setValid(boolean valid) {
+ this.valid = valid;
+ }
+
+ private Object value;
+
+ Object getValue() {
+ return (this.value);
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ private boolean localValueSet;
+
+ boolean isLocalValueSet() {
+ return (this.localValueSet);
+ }
+
+ public void setLocalValueSet(boolean localValueSet) {
+ this.localValueSet = localValueSet;
+ }
+
+ public Object getIterationState() {
+ return iterationState;
+ }
+
+ public void setIterationState(Object iterationState) {
+ this.iterationState = iterationState;
+ }
+
+ public String toString() {
+ return ("submittedValue: " + submittedValue + " value: " + value
+ + " localValueSet: " + localValueSet);
+ }
+
+ public void populate(EditableValueHolder evh) {
+ this.value = evh.getLocalValue();
+ this.valid = evh.isValid();
+ this.submittedValue = evh.getSubmittedValue();
+ this.localValueSet = evh.isLocalValueSet();
+ }
+
+
+ public void populate(IterationStateHolder ish) {
+ this.iterationState = ish.getIterationState();
+ }
+
+ public void apply(EditableValueHolder evh) {
+ evh.setValue(this.value);
+ evh.setValid(this.valid);
+ evh.setSubmittedValue(this.submittedValue);
+ evh.setLocalValueSet(this.localValueSet);
+ }
+
+ public void apply(IterationStateHolder ish) {
+ ish.setIterationState(this.iterationState);
+ }
+
+ }
+
+ protected void addAjaxKeyEvent(FacesEvent event) {
+ Object eventRowKey = getRowKey();
+ if (null != eventRowKey) {
+ this._ajaxRowKey = eventRowKey;
+ this._ajaxRowKeysMap.put(getBaseClientId(getFacesContext()),
+ eventRowKey);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.component.UIData#queueEvent(javax.faces.event.FacesEvent)
+ */
+ public void queueEvent(FacesEvent event) {
+ if (event.getComponent() != this) {
+ // For Ajax events, keep row value.
+ if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
+ addAjaxKeyEvent(event);
+ }
+ event = new IndexedEvent(this, event, getRowKey());
+ }
+ // Send event directly to parent, to avoid wrapping in superclass.
+ UIComponent parent = getParent();
+ if (parent == null) {
+ throw new IllegalStateException("No parent component for queue event");
+ } else {
+ parent.queueEvent(event);
+ }
+ }
+
+ public void broadcast(FacesEvent event) throws AbortProcessingException {
+ if (!(event instanceof IndexedEvent)) {
+ if (!broadcastLocal(event)) {
+ super.broadcast(event);
+ }
+ return;
+ }
+
+ // Set up the correct context and fire our wrapped event
+ IndexedEvent revent = (IndexedEvent) event;
+ Object oldRowKey = getRowKey();
+ FacesContext faces = FacesContext.getCurrentInstance();
+ captureOrigValue(faces);
+ Object eventRowKey = revent.getKey();
+ setRowKey(faces, eventRowKey);
+ FacesEvent rowEvent = revent.getTarget();
+
+ rowEvent.getComponent().broadcast(rowEvent);
+
+ setRowKey(faces, oldRowKey);
+ restoreOrigValue(faces);
+ }
+
+ /**
+ * Process events targetted for concrete implementation. Hook method called
+ * from {@link #broadcast(FacesEvent)}
+ *
+ * @param event -
+ * processed event.
+ * @return true if event processed, false if component must continue
+ * processing.
+ */
+ protected boolean broadcastLocal(FacesEvent event) {
+ return false;
+ }
+
+ /**
+ * Wrapper for event from child component, with value of current row key.
+ *
+ * @author shura
+ *
+ */
+ protected static final class IndexedEvent extends FacesEvent {
+
+ private static final long serialVersionUID = -8318895390232552385L;
+
+ private final FacesEvent target;
+
+ private final Object key;
+
+ public IndexedEvent(UIDataAdaptorBase owner, FacesEvent target, Object key) {
+ super(owner);
+ this.target = target;
+ this.key = key;
+ }
+
+ public PhaseId getPhaseId() {
+ return (this.target.getPhaseId());
+ }
+
+ public void setPhaseId(PhaseId phaseId) {
+ this.target.setPhaseId(phaseId);
+ }
+
+ public boolean isAppropriateListener(FacesListener listener) {
+ return this.target.isAppropriateListener(listener);
+ }
+
+ public void processListener(FacesListener listener) {
+ UIDataAdaptorBase owner = (UIDataAdaptorBase) this.getComponent();
+ Object prevIndex = owner._rowKey;
+ try {
+ owner.setRowKey(this.key);
+ this.target.processListener(listener);
+ } finally {
+ owner.setRowKey(prevIndex);
+ }
+ }
+
+ public Object getKey() {
+ return key;
+ }
+
+ public FacesEvent getTarget() {
+ return target;
+ }
+
+ }
+
+ /**
+ * "memento" pattern class for state of component.
+ *
+ * @author shura
+ *
+ */
+ private static class DataState implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 17070532L;
+
+ private Object superState;
+
+ private Map<String, PerIdState> componentStates = new HashMap<String, PerIdState>();
+
+ private Set<Object> ajaxKeys;
+
+ public String rowKeyVar;
+
+ public String stateVar;
+
+ private Map<String, Map<String, SavedState>> childStates;
+
+ public Object rowKeyConverter;
+
+ }
+
+ /**
+ * Serialisable model and component state per iteration of parent UIData.
+ *
+ * @author shura
+ *
+ */
+ private static class PerIdState implements Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 9037454770537726418L;
+
+ /**
+ * Flag setted to true if componentState implements StateHolder
+ */
+ private boolean stateInHolder = false;
+
+ /**
+ * Serializable componentState or
+ */
+ private Object componentState;
+
+ private SerializableDataModel model;
+ }
+
+ public void restoreState(FacesContext faces, Object object) {
+ DataState state = (DataState) object;
+ super.restoreState(faces, state.superState);
+ this._ajaxKeys = state.ajaxKeys;
+ this._statesMap = new HashMap<String, DataComponentState>();
+ this._rowKeyVar = state.rowKeyVar;
+ this._stateVar = state.stateVar;
+ this.childState = state.childStates;
+ if (null != state.rowKeyConverter) {
+ this._rowKeyConverter = (Converter) restoreAttachedState(faces,
+ state.rowKeyConverter);
+ }
+ // Restore serializable models and component states for all rows of
+ // parent UIData ( single if this
+ // component not child of iterable )
+ for (Iterator<Entry<String, PerIdState>> iter = state.componentStates.entrySet().iterator(); iter
+ .hasNext();) {
+ Entry<String, PerIdState> stateEntry = iter.next();
+ PerIdState idState = stateEntry.getValue();
+ DataComponentState compState;
+ if (idState.stateInHolder) {
+ // TODO - change RichFaces Tree component, for remove reference
+ // to component from state.
+ compState = createComponentState();
+ ((StateHolder) compState).restoreState(faces,
+ idState.componentState);
+ } else {
+ compState = (DataComponentState) idState.componentState;
+ }
+ String key = stateEntry.getKey();
+ this._statesMap.put(key, compState);
+ this._modelsMap.put(key, idState.model);
+ }
+ }
+
+ public Object saveState(FacesContext faces) {
+ DataState state = new DataState();
+ state.superState = super.saveState(faces);
+ state.ajaxKeys = this._ajaxKeys;
+ state.rowKeyVar = this._rowKeyVar;
+ state.stateVar = this._stateVar;
+ state.childStates = this.childState;
+ if (null != this._rowKeyConverter) {
+ state.rowKeyConverter = saveAttachedState(faces,this._rowKeyConverter);
+ }
+ Set<String> encodedIds = getEncodedIds();
+ // Save all states of component and data model for all valies of
+ // clientId, encoded in this request.
+// this._statesMap.put(getBaseClientId(faces), this._currentState);
+// this._modelsMap.put(getBaseClientId(faces), this._currentModel);
+ for (Iterator<Entry<String, DataComponentState>> iter = this._statesMap.entrySet().iterator(); iter
+ .hasNext();) {
+ Entry<String, DataComponentState> stateEntry = iter.next();
+ DataComponentState dataComponentState = stateEntry.getValue();
+ String stateKey = stateEntry.getKey();
+ if (encodedIds.isEmpty() || encodedIds.contains(stateKey)) {
+ PerIdState idState = new PerIdState();
+ // Save component state , depended if implemented interfaces.
+ if (null == dataComponentState) {
+ idState.componentState = null;
+ } else {
+ if (dataComponentState instanceof Serializable) {
+ idState.componentState = dataComponentState;
+ } else if (dataComponentState instanceof StateHolder) {
+ idState.componentState = ((StateHolder) dataComponentState)
+ .saveState(faces);
+ idState.stateInHolder = true;
+ }
+ ExtendedDataModel extendedDataModel = (ExtendedDataModel) this._modelsMap
+ .get(stateKey);
+ if (null != extendedDataModel) {
+ idState.model = extendedDataModel
+ .getSerializableModel(dataComponentState
+ .getRange());
+
+ }
+ }
+ if (null != idState.model || null != idState.componentState) {
+ state.componentStates.put(stateKey, idState);
+ }
+ }
+ }
+ return state;
+ }
+
+ public void setParent(UIComponent parent) {
+ super.setParent(parent);
+ this._clientId = null;
+ this._baseClientId = null;
+ }
+
+ /**
+ * Adds argument key to AJAX internal request keys set
+ * @param key key to add
+ */
+ public void addRequestKey(Object key) {
+ if (_ajaxRequestKeys == null) {
+ _ajaxRequestKeys = new HashSet<Object>();
+ }
+
+ _ajaxRequestKeys.add(key);
+ }
+
+ /**
+ * Removes argument key from AJAX internal request keys set
+ * @param key key to remove
+ */
+ public void removeRequestKey(Object key) {
+ if (_ajaxRequestKeys != null && key != null) {
+ _ajaxRequestKeys.remove(key);
+ }
+ }
+
+ /**
+ * Checks whether AJAX internal request keys set contains argument key
+ * @param key key to check
+ * @return <code>true</code> if set contains key, <code>false</code> - otherwise
+ */
+ public boolean containsRequestKey(Object key) {
+ if (_ajaxRequestKeys != null && key != null) {
+ return _ajaxRequestKeys.contains(key);
+ }
+
+ return false;
+ }
+
+ /**
+ * Clears AJAX internal request keys set
+ */
+ public void clearRequestKeysSet() {
+ _ajaxRequestKeys = null;
+ }
+
+ public Object getValue() {
+ return super.getValue();
+ }
+
+ public void setValue(Object value) {
+ setExtendedDataModel(null);
+ super.setValue(value);
+ }
+
+ public void beforeRenderResponse(FacesContext context) {
+ resetDataModel();
+ this._encoded = null;
+ if (null != childState && !keepSaved(context)) {
+ childState.clear();
+ }
+ }
+}
Modified: branches/community/3.3.X/framework/impl/src/main/java/org/richfaces/component/UIRangedNumberInput.java
===================================================================
--- branches/community/3.3.X/framework/impl/src/main/java/org/richfaces/component/UIRangedNumberInput.java 2009-11-21 00:23:45 UTC (rev 15952)
+++ branches/community/3.3.X/framework/impl/src/main/java/org/richfaces/component/UIRangedNumberInput.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -102,7 +102,7 @@
return new Double(object.toString());
}
- private boolean isEmpty(Object newValue) {
+ public static boolean isEmpty(Object newValue) {
if (newValue == null) {
return true;
}
Added: branches/community/3.3.X/framework/impl/src/main/java-jsf12/org/ajax4jsf/component/UIDataAdaptor.java
===================================================================
--- branches/community/3.3.X/framework/impl/src/main/java-jsf12/org/ajax4jsf/component/UIDataAdaptor.java (rev 0)
+++ branches/community/3.3.X/framework/impl/src/main/java-jsf12/org/ajax4jsf/component/UIDataAdaptor.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -0,0 +1,31 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.ajax4jsf.component;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class UIDataAdaptor extends UIDataAdaptorBase {
+
+}
Added: branches/community/3.3.X/framework/impl/src/main/java-jsf20/org/ajax4jsf/component/UIDataAdaptor.java
===================================================================
--- branches/community/3.3.X/framework/impl/src/main/java-jsf20/org/ajax4jsf/component/UIDataAdaptor.java (rev 0)
+++ branches/community/3.3.X/framework/impl/src/main/java-jsf20/org/ajax4jsf/component/UIDataAdaptor.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -0,0 +1,79 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.ajax4jsf.component;
+
+import java.util.Iterator;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitResult;
+import javax.faces.context.FacesContext;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class UIDataAdaptor extends UIDataAdaptorBase {
+
+ public boolean visitTree(VisitContext context, VisitCallback callback) {
+
+ // First check to see whether we are visitable. If not
+ // short-circuit out of this subtree, though allow the
+ // visit to proceed through to other subtrees.
+ if (!isVisitable(context))
+ return false;
+
+ // Push ourselves to EL before visiting
+ FacesContext facesContext = context.getFacesContext();
+ pushComponentToEL(facesContext, null);
+
+ try {
+ // Visit ourselves. Note that we delegate to the
+ // VisitContext to actually perform the visit.
+ VisitResult result = context.invokeVisitCallback(this, callback);
+
+ // If the visit is complete, short-circuit out and end the visit
+ if (result == VisitResult.COMPLETE)
+ return true;
+
+ // Visit children if necessary
+ if (result == VisitResult.ACCEPT) {
+ Iterator<UIComponent> kids = this.getFacetsAndChildren();
+
+ while (kids.hasNext()) {
+ boolean done = kids.next().visitTree(context, callback);
+
+ // If any kid visit returns true, we are done.
+ if (done)
+ return true;
+ }
+ }
+ } finally {
+ // Pop ourselves off the EL stack
+ popComponentFromEL(facesContext);
+ }
+
+ // Return false to allow the visit to continue
+ return false;
+ }
+}
Modified: branches/community/3.3.X/framework/jsf-test/pom.xml
===================================================================
--- branches/community/3.3.X/framework/jsf-test/pom.xml 2009-11-21 00:23:45 UTC (rev 15952)
+++ branches/community/3.3.X/framework/jsf-test/pom.xml 2009-11-22 02:09:59 UTC (rev 15953)
@@ -1,135 +1,134 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <artifactId>framework</artifactId>
- <groupId>org.richfaces</groupId>
- <version>3.3.3-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>jsf-test</artifactId>
- <name>jsf-test</name>
- <version>3.3.3-SNAPSHOT</version>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.5</version>
- </dependency>
- <dependency>
- <groupId>net.sourceforge.htmlunit</groupId>
- <artifactId>htmlunit</artifactId>
- <version>2.4</version>
- </dependency>
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-impl</artifactId>
- <version>1.2_12</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>el-impl</groupId>
- <artifactId>el-impl</artifactId>
- <version>1.0</version>
- </dependency>
- <dependency>
- <groupId>commons-httpclient</groupId>
- <artifactId>commons-httpclient</artifactId>
- <version>3.1</version>
- </dependency>
- <dependency>
- <groupId>net.sourceforge.htmlunit</groupId>
- <artifactId>htmlunit-core-js</artifactId>
- <version>2.4</version>
- </dependency>
- <dependency>
- <groupId>net.sourceforge.cssparser</groupId>
- <artifactId>cssparser</artifactId>
- <version>0.9.5</version>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>1.4</version>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.4</version>
- </dependency>
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- <version>3.2.1</version>
- </dependency>
- <dependency>
- <groupId>net.sourceforge.nekohtml</groupId>
- <artifactId>nekohtml</artifactId>
- <version>1.9.11</version>
- <exclusions>
- <exclusion>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- </exclusion>
- <!--
- <exclusion> <groupId>xerces</groupId>
- <artifactId>xercesImpl</artifactId> </exclusion>
- -->
- </exclusions>
- </dependency>
- <dependency>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- <version>1.0</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>2.5</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>jsp-api</artifactId>
- <version>2.1</version>
- </dependency>
- <dependency>
- <groupId>jstl</groupId>
- <artifactId>jstl</artifactId>
- <version>1.2</version>
- </dependency>
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <version>1.2_12</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>jsr250-api</artifactId>
- <version>1.0</version>
- </dependency>
- <dependency>
- <groupId>xalan</groupId>
- <artifactId>xalan</artifactId>
- <version>2.7.1</version>
- <exclusions>
- <exclusion>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>de.berlios.jsunit</groupId>
- <artifactId>jsunit</artifactId>
- <version>1.3</version>
- <exclusions>
- <exclusion>
- <groupId>rhino</groupId>
- <artifactId>js</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
-</project>
\ No newline at end of file
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>framework</artifactId>
+ <groupId>org.richfaces</groupId>
+ <version>3.3.3-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>jsf-test</artifactId>
+ <name>jsf-test</name>
+ <version>3.3.3-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.5</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sourceforge.htmlunit</groupId>
+ <artifactId>htmlunit</artifactId>
+ <version>2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>el-impl</groupId>
+ <artifactId>el-impl</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sourceforge.htmlunit</groupId>
+ <artifactId>htmlunit-core-js</artifactId>
+ <version>2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sourceforge.cssparser</groupId>
+ <artifactId>cssparser</artifactId>
+ <version>0.9.5</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>3.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>net.sourceforge.nekohtml</groupId>
+ <artifactId>nekohtml</artifactId>
+ <version>1.9.11</version>
+ <exclusions>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ <!--
+ <exclusion> <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId> </exclusion>
+ -->
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet.jsp</groupId>
+ <artifactId>jsp-api</artifactId>
+ <version>2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>jstl</groupId>
+ <artifactId>jstl</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>jsr250-api</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>xalan</groupId>
+ <artifactId>xalan</artifactId>
+ <version>2.7.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>de.berlios.jsunit</groupId>
+ <artifactId>jsunit</artifactId>
+ <version>1.3</version>
+ <exclusions>
+ <exclusion>
+ <groupId>rhino</groupId>
+ <artifactId>js</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+</project>
Modified: branches/community/3.3.X/framework/pom.xml
===================================================================
--- branches/community/3.3.X/framework/pom.xml 2009-11-21 00:23:45 UTC (rev 15952)
+++ branches/community/3.3.X/framework/pom.xml 2009-11-22 02:09:59 UTC (rev 15953)
@@ -10,6 +10,32 @@
<version>3.3.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Java Server Faces AJAX framework</name>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>2.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ <version>2.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>1.2_12</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ <version>1.2_12</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<build>
<plugins>
<plugin>
@@ -64,7 +90,7 @@
<dependency>
<groupId>com.sun.facelets</groupId>
<artifactId>jsf-facelets</artifactId>
- <version>1.1.14</version>
+ <version>1.1.15.B1</version>
<optional>true</optional>
</dependency>
<dependency>
@@ -97,12 +123,6 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <version>1.2_12</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
@@ -120,4 +140,5 @@
<module>test</module>
<module>jsf-test</module>
</modules>
-</project>
\ No newline at end of file
+
+</project>
Modified: branches/community/3.3.X/framework/test/pom.xml
===================================================================
--- branches/community/3.3.X/framework/test/pom.xml 2009-11-21 00:23:45 UTC (rev 15952)
+++ branches/community/3.3.X/framework/test/pom.xml 2009-11-22 02:09:59 UTC (rev 15953)
@@ -1,4 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>framework</artifactId>
<groupId>org.richfaces</groupId>
@@ -10,8 +11,20 @@
<version>3.3.3-SNAPSHOT</version>
<name>Ajax4Jsf test framework</name>
<url>https://ajax4jsf.dev.java.net</url>
+
+
<dependencies>
<dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
@@ -45,11 +58,6 @@
<version>3.3.3-SNAPSHOT</version>
</dependency>
<dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-impl</artifactId>
- <version>1.2_12</version>
- </dependency>
- <dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>1.14</version>
@@ -64,7 +72,7 @@
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>
- </dependency>
+ </dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
@@ -93,4 +101,4 @@
</plugin>
</plugins>
</build>
-</project>
\ No newline at end of file
+</project>
Modified: branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/AbstractAjax4JsfTestCase.java
===================================================================
--- branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/AbstractAjax4JsfTestCase.java 2009-11-21 00:23:45 UTC (rev 15952)
+++ branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/AbstractAjax4JsfTestCase.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -74,7 +74,6 @@
import org.ajax4jsf.webapp.BaseXMLFilter;
import org.ajax4jsf.webapp.HtmlParser;
import org.ajax4jsf.webapp.WebXml;
-import org.apache.shale.test.base.AbstractJsfTestCase;
import org.apache.shale.test.mock.MockApplication;
import org.apache.shale.test.mock.MockPrintWriter;
import org.apache.shale.test.mock.MockResponseWriter;
@@ -128,6 +127,15 @@
String message = condition.getMessage();
assertTrue(message, condition.isConditionTrue());
}
+
+ @Override
+ protected void setupFactories() {
+ super.setupFactories();
+
+ FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY, Ajax4JsfMockFacesContextFactory.class.getName());
+ FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, Ajax4JsfMockApplicationFactory.class.getName());
+ }
+
/**
* @param name
*/
Added: branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/AbstractJsfTestCase.java
===================================================================
--- branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/AbstractJsfTestCase.java (rev 0)
+++ branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/AbstractJsfTestCase.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -0,0 +1,202 @@
+/*
+ * 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.ajax4jsf.tests;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import javax.faces.FactoryFinder;
+import javax.faces.application.ApplicationFactory;
+import javax.faces.component.UIViewRoot;
+import javax.faces.lifecycle.LifecycleFactory;
+import javax.faces.render.RenderKitFactory;
+
+import junit.framework.TestCase;
+
+import org.apache.shale.test.mock.MockApplication;
+import org.apache.shale.test.mock.MockExternalContext;
+import org.apache.shale.test.mock.MockFacesContext;
+import org.apache.shale.test.mock.MockFacesContextFactory;
+import org.apache.shale.test.mock.MockHttpServletRequest;
+import org.apache.shale.test.mock.MockHttpServletResponse;
+import org.apache.shale.test.mock.MockHttpSession;
+import org.apache.shale.test.mock.MockLifecycle;
+import org.apache.shale.test.mock.MockLifecycleFactory;
+import org.apache.shale.test.mock.MockRenderKit;
+import org.apache.shale.test.mock.MockServletConfig;
+import org.apache.shale.test.mock.MockServletContext;
+
+/**
+ * <p>Abstract JUnit test case base class, which sets up the JavaServer Faces
+ * mock object environment for a particular simulated request. The following
+ * protected variables are initialized in the <code>setUp()</code> method, and
+ * cleaned up in the <code>tearDown()</code> method:</p>
+ * <ul>
+ * <li><code>application</code> (<code>MockApplication</code>)</li>
+ * <li><code>config</code> (<code>MockServletConfig</code>)</li>
+ * <li><code>externalContext</code> (<code>MockExternalContext</code>)</li>
+ * <li><code>facesContext</code> (<code>MockFacesContext</code>)</li>
+ * <li><code>lifecycle</code> (<code>MockLifecycle</code>)</li>
+ * <li><code>request</code> (<code>MockHttpServletRequest</code></li>
+ * <li><code>response</code> (<code>MockHttpServletResponse</code>)</li>
+ * <li><code>servletContext</code> (<code>MockServletContext</code>)</li>
+ * <li><code>session</code> (<code>MockHttpSession</code>)</li>
+ * </ul>
+ *
+ * <p>In addition, appropriate factory classes will have been registered with
+ * <code>javax.faces.FactoryFinder</code> for <code>Application</code> and
+ * <code>RenderKit</code> instances. The created <code>FacesContext</code>
+ * instance will also have been registered in the apppriate thread local
+ * variable, to simulate what a servlet container would do.</p>
+ *
+ * <p><strong>WARNING</strong> - If you choose to subclass this class, be sure
+ * your <code>setUp()</code> and <code>tearDown()</code> methods call
+ * <code>super.setUp()</code> and <code>super.tearDown()</code> respectively,
+ * and that you implement your own <code>suite()</code> method that exposes
+ * the test methods for your test case.</p>
+ */
+
+public abstract class AbstractJsfTestCase extends TestCase {
+
+
+ // ------------------------------------------------------------ Constructors
+
+
+ /**
+ * <p>Construct a new instance of this test case.</p>
+ *
+ * @param name Name of this test case
+ */
+ public AbstractJsfTestCase(String name) {
+ super(name);
+ }
+
+ protected void setupFactories() {
+ // Set up JSF API Objects
+ FactoryFinder.releaseFactories();
+ FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
+ "org.apache.shale.test.mock.MockApplicationFactory");
+ FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
+ "org.apache.shale.test.mock.MockFacesContextFactory");
+ FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY,
+ "org.apache.shale.test.mock.MockLifecycleFactory");
+ FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
+ "org.apache.shale.test.mock.MockRenderKitFactory");
+ }
+
+
+ // ---------------------------------------------------- Overall Test Methods
+
+
+ /**
+ * <p>Set up instance variables required by this test case.</p>
+ */
+ protected void setUp() throws Exception {
+
+ // Set up a new thread context class loader
+ threadContextClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(new URLClassLoader(new URL[0],
+ this.getClass().getClassLoader()));
+
+ // Set up Servlet API Objects
+ servletContext = new MockServletContext();
+ config = new MockServletConfig(servletContext);
+ session = new MockHttpSession();
+ session.setServletContext(servletContext);
+ request = new MockHttpServletRequest(session);
+ request.setServletContext(servletContext);
+ response = new MockHttpServletResponse();
+
+ setupFactories();
+
+ externalContext =
+ new MockExternalContext(servletContext, request, response);
+ lifecycleFactory = (MockLifecycleFactory)
+ FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+ lifecycle = (MockLifecycle)
+ lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
+ facesContextFactory = (MockFacesContextFactory)
+ FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
+ facesContext = (MockFacesContext)
+ facesContextFactory.getFacesContext(servletContext,
+ request,
+ response,
+ lifecycle);
+ externalContext = (MockExternalContext) facesContext.getExternalContext();
+ UIViewRoot root = new UIViewRoot();
+ root.setViewId("/viewId");
+ root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
+ facesContext.setViewRoot(root);
+ ApplicationFactory applicationFactory = (ApplicationFactory)
+ FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
+ application = (MockApplication) applicationFactory.getApplication();
+ facesContext.setApplication(application);
+ RenderKitFactory renderKitFactory = (RenderKitFactory)
+ FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+ renderKit = new MockRenderKit();
+ renderKitFactory.addRenderKit(RenderKitFactory.HTML_BASIC_RENDER_KIT, renderKit);
+
+ }
+
+
+ /**
+ * <p>Tear down instance variables required by this test case.</p>
+ */
+ protected void tearDown() throws Exception {
+
+ application = null;
+ config = null;
+ externalContext = null;
+ facesContext.release();
+ facesContext = null;
+ lifecycle = null;
+ lifecycleFactory = null;
+ renderKit = null;
+ request = null;
+ response = null;
+ servletContext = null;
+ session = null;
+ FactoryFinder.releaseFactories();
+
+ Thread.currentThread().setContextClassLoader(threadContextClassLoader);
+ threadContextClassLoader = null;
+
+ }
+
+
+ // ------------------------------------------------------ Instance Variables
+
+
+ // Mock object instances for our tests
+ protected MockApplication application = null;
+ protected MockServletConfig config = null;
+ protected MockExternalContext externalContext = null;
+ protected MockFacesContext facesContext = null;
+ protected MockFacesContextFactory facesContextFactory = null;
+ protected MockLifecycle lifecycle = null;
+ protected MockLifecycleFactory lifecycleFactory = null;
+ protected MockRenderKit renderKit = null;
+ protected MockHttpServletRequest request = null;
+ protected MockHttpServletResponse response = null;
+ protected MockServletContext servletContext = null;
+ protected MockHttpSession session = null;
+
+ // Thread context class loader saved and restored after each test
+ private ClassLoader threadContextClassLoader = null;
+
+}
Added: branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/Ajax4JsfMockApplicationFactory.java
===================================================================
--- branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/Ajax4JsfMockApplicationFactory.java (rev 0)
+++ branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/Ajax4JsfMockApplicationFactory.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.ajax4jsf.tests;
+
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+
+import org.apache.shale.test.mock.MockApplication;
+
+public class Ajax4JsfMockApplicationFactory extends org.apache.shale.test.mock.MockApplicationFactory {
+
+ private Application application;
+
+ public Ajax4JsfMockApplicationFactory() {
+ super();
+ }
+
+ @Override
+ public Application getApplication() {
+ if (application != null) {
+ return application;
+ }
+
+ Class<? extends Application> clazz = null;
+ try {
+ clazz = this.getClass().getClassLoader().loadClass("org.ajax4jsf.tests.MockApplication20").
+ asSubclass(Application.class);
+
+ //force loading classes for fields
+ clazz.getDeclaredFields();
+
+ application = (MockApplication) clazz.newInstance();
+
+ return application;
+ } catch (NoClassDefFoundError e) {
+ clazz = null; // We are not running in a JSF 2.0 environment
+ } catch (ClassNotFoundException e) {
+ clazz = null; // Same as above
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new FacesException(e);
+ }
+
+ return super.getApplication();
+ }
+
+ @Override
+ public void setApplication(Application application) {
+ this.application = application;
+ }
+}
Added: branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/Ajax4JsfMockFacesContextFactory.java
===================================================================
--- branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/Ajax4JsfMockFacesContextFactory.java (rev 0)
+++ branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/Ajax4JsfMockFacesContextFactory.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -0,0 +1,92 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.ajax4jsf.tests;
+
+import java.lang.reflect.Constructor;
+
+import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.lifecycle.Lifecycle;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shale.test.mock.MockExternalContext12;
+import org.apache.shale.test.mock.MockFacesContextFactory;
+
+public class Ajax4JsfMockFacesContextFactory extends MockFacesContextFactory {
+
+ private Constructor<? extends FacesContext> constructor = null;
+
+ private static Class<?>[] facesContextSignature = new Class[] {
+ ExternalContext.class, Lifecycle.class
+ };
+
+ public Ajax4JsfMockFacesContextFactory() {
+ Class<? extends FacesContext> clazz = null;
+
+ // Try to load the 2.0 version of our mock FacesContext class
+ try {
+ clazz = this.getClass().getClassLoader().loadClass("org.ajax4jsf.tests.MockFacesContext20").
+ asSubclass(FacesContext.class);
+ //force loading classes for fields
+ clazz.getDeclaredFields();
+
+ constructor = clazz.getConstructor(facesContextSignature);
+ } catch (NoClassDefFoundError e) {
+ // We are not running on JSF 2.0
+ clazz = null;
+ constructor = null;
+ } catch (ClassNotFoundException e) {
+ // Same as above
+ clazz = null;
+ constructor = null;
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new FacesException(e);
+ }
+ }
+
+ @Override
+ public FacesContext getFacesContext(Object context, Object request,
+ Object response, Lifecycle lifecycle) throws FacesException {
+
+ if (constructor != null) {
+
+ try {
+ MockExternalContext12 mockExternalContext12 = new MockExternalContext12((ServletContext) context,
+ (HttpServletRequest) request, (HttpServletResponse) response);
+
+ return constructor.newInstance(mockExternalContext12, lifecycle);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new FacesException(e.getMessage(), e);
+ }
+ }
+
+ return super.getFacesContext(context, request, response, lifecycle);
+ }
+}
Copied: branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/MockApplication20.java (from rev 15949, branches/sandbox/3.3.X_JSF2/framework/test/src/main/java/org/ajax4jsf/tests/MockApplication2.java)
===================================================================
--- branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/MockApplication20.java (rev 0)
+++ branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/MockApplication20.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.ajax4jsf.tests;
+
+import javax.el.ValueExpression;
+import javax.faces.application.Resource;
+import javax.faces.application.ResourceHandler;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.event.SystemEvent;
+import javax.faces.event.SystemEventListener;
+
+
+public class MockApplication20 extends MockApplication {
+
+ private ResourceHandler resourceHandler = null;
+
+ public MockApplication20() {
+ super();
+ }
+
+ @Override
+ public ResourceHandler getResourceHandler() {
+ return resourceHandler;
+ }
+
+ @Override
+ public void setResourceHandler(ResourceHandler resourceHandler) {
+ this.resourceHandler = resourceHandler;
+ }
+
+ @Override
+ public void publishEvent(FacesContext context,
+ Class<? extends SystemEvent> systemEventClass,
+ Class<?> sourceBaseType, Object source) {
+
+ //do nothing
+ }
+
+ @Override
+ public void publishEvent(FacesContext context,
+ Class<? extends SystemEvent> systemEventClass, Object source) {
+
+ //do nothing
+ }
+
+ @Override
+ public void subscribeToEvent(Class<? extends SystemEvent> systemEventClass,
+ Class<?> sourceClass, SystemEventListener listener) {
+
+ //do nothing
+ }
+
+ @Override
+ public void subscribeToEvent(Class<? extends SystemEvent> systemEventClass,
+ SystemEventListener listener) {
+
+ //do nothing
+ }
+
+ @Override
+ public void unsubscribeFromEvent(
+ Class<? extends SystemEvent> systemEventClass,
+ Class<?> sourceClass, SystemEventListener listener) {
+
+ //do nothing
+ }
+
+ @Override
+ public void unsubscribeFromEvent(
+ Class<? extends SystemEvent> systemEventClass,
+ SystemEventListener listener) {
+
+ //do nothing
+ }
+
+ @Override
+ public UIComponent createComponent(ValueExpression componentExpression,
+ FacesContext context,
+ String componentType,
+ String rendererType) {
+
+ //do nothing
+ return null;
+ }
+
+ @Override
+ public UIComponent createComponent(FacesContext context,
+ String componentType,
+ String rendererType) {
+
+ //do nothing
+ return null;
+ }
+
+ @Override
+ public UIComponent createComponent(FacesContext context,
+ Resource componentResource) {
+
+ //do nothing
+ return null;
+ }
+
+}
Copied: branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/MockFacesContext20.java (from rev 15949, branches/sandbox/3.3.X_JSF2/framework/test/src/main/java/org/ajax4jsf/tests/MockFacesContext2.java)
===================================================================
--- branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/MockFacesContext20.java (rev 0)
+++ branches/community/3.3.X/framework/test/src/main/java/org/ajax4jsf/tests/MockFacesContext20.java 2009-11-22 02:09:59 UTC (rev 15953)
@@ -0,0 +1,142 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.ajax4jsf.tests;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.FactoryFinder;
+import javax.faces.application.FacesMessage;
+import javax.faces.application.ViewHandler;
+import javax.faces.context.ExceptionHandler;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.PartialViewContext;
+import javax.faces.context.PartialViewContextFactory;
+import javax.faces.event.PhaseId;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.render.RenderKit;
+
+import org.apache.shale.test.mock.MockFacesContext12;
+
+import com.sun.faces.renderkit.RenderKitUtils;
+
+public class MockFacesContext20 extends MockFacesContext12 {
+
+ private Map<Object, Object> attributes = new HashMap<Object, Object>();
+ private ExceptionHandler exceptionHandler = null;
+ private boolean validationFailed = false;
+ private PhaseId phaseId = null;
+ private PartialViewContext partialViewContext = null;
+
+ public MockFacesContext20(ExternalContext externalContext, Lifecycle lifecycle) {
+ super(externalContext, lifecycle);
+ }
+
+ @Override
+ public Map<Object, Object> getAttributes() {
+ return attributes;
+ }
+
+ @Override
+ public PartialViewContext getPartialViewContext() {
+ if (partialViewContext == null) {
+ PartialViewContextFactory partialViewContextFactory = (PartialViewContextFactory) FactoryFinder.
+ getFactory(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY);
+
+ partialViewContext = partialViewContextFactory.getPartialViewContext(this);
+ }
+
+ return partialViewContext;
+ }
+
+ @Override
+ public ExceptionHandler getExceptionHandler() {
+ return exceptionHandler;
+ }
+
+ @Override
+ public void setExceptionHandler(ExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ private List<FacesMessage> createMessageList(Iterator<?> messagesIterator) {
+ List<FacesMessage> result = new ArrayList<FacesMessage>();
+ while (messagesIterator.hasNext()) {
+ FacesMessage nextMessage = (FacesMessage) messagesIterator.next();
+ result.add(nextMessage);
+ }
+
+ return Collections.unmodifiableList(result);
+ }
+
+ @Override
+ public List<FacesMessage> getMessageList() {
+ return createMessageList(getMessages());
+ }
+
+ @Override
+ public List<FacesMessage> getMessageList(String clientId) {
+ return createMessageList(getMessages(clientId));
+ }
+
+ @Override
+ public boolean isValidationFailed() {
+ return validationFailed;
+ }
+
+ @Override
+ public void validationFailed() {
+ validationFailed = true;
+ }
+
+ @Override
+ public boolean isPostback() {
+ RenderKit rk = this.getRenderKit();
+ boolean postback;
+ if (rk != null) {
+ postback = rk.getResponseStateManager().isPostback(this);
+ } else {
+ // ViewRoot hasn't been set yet, so calculate the RK
+ ViewHandler vh = this.getApplication().getViewHandler();
+ String rkId = vh.calculateRenderKitId(this);
+ postback = RenderKitUtils.getResponseStateManager(this, rkId).isPostback(this);
+ }
+
+ return postback;
+ }
+
+ @Override
+ public PhaseId getCurrentPhaseId() {
+ return phaseId;
+ }
+
+ @Override
+ public void setCurrentPhaseId(PhaseId currentPhaseId) {
+ phaseId = currentPhaseId;
+ }
+
+}
15 years, 1 month
JBoss Rich Faces SVN: r15952 - branches/community/3.3.X.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2009-11-20 19:23:45 -0500 (Fri, 20 Nov 2009)
New Revision: 15952
Modified:
branches/community/3.3.X/pom.xml
Log:
Added dev.java.net M2 repository into root pom.xml
Modified: branches/community/3.3.X/pom.xml
===================================================================
--- branches/community/3.3.X/pom.xml 2009-11-21 00:20:44 UTC (rev 15951)
+++ branches/community/3.3.X/pom.xml 2009-11-21 00:23:45 UTC (rev 15952)
@@ -113,13 +113,23 @@
<url>http://download.java.net/maven/1</url>
<layout>legacy</layout>
</repository>
-
<repository>
<releases />
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
+ <id>maven2-repository.dev.java.net</id>
+ <name>Java.net Repository for Maven</name>
+ <url>http://download.java.net/maven/2/</url>
+ <layout>default</layout>
+ </repository>
+ <repository>
+ <releases />
+ <snapshots>
+ <enabled>false</enabled>
+ <updatePolicy>never</updatePolicy>
+ </snapshots>
<id>repository.jboss.org</id>
<url>http://repository.jboss.org/maven2</url>
</repository>
15 years, 1 month
JBoss Rich Faces SVN: r15950 - in root/cdk/trunk/plugins/maven-cdk-plugin/src/it: annotated-component/src/main/java/org and 7 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: alexsmirnov
Date: 2009-11-20 18:36:08 -0500 (Fri, 20 Nov 2009)
New Revision: 15950
Added:
root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/src/main/java/org/ajax4jsf/
root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/src/main/java/org/ajax4jsf/renderkit/
root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/src/main/java/org/
root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/src/main/java/org/ajax4jsf/
root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/src/main/java/org/ajax4jsf/renderkit/
root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
Modified:
root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/pom.xml
root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/pom.xml
Log:
fix integration test builds
Modified: root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/pom.xml
===================================================================
--- root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/pom.xml 2009-11-20 17:15:37 UTC (rev 15949)
+++ root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/pom.xml 2009-11-20 23:36:08 UTC (rev 15950)
@@ -30,8 +30,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- http://maven.apache.org/plugins/maven-compiler-plugin/ -->
- <source>1.5</source>
- <target>1.5</target>
+ <source>1.6</source>
+ <target>1.6</target>
</configuration>
</plugin>
</plugins>
Added: root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
===================================================================
--- root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java (rev 0)
+++ root/cdk/trunk/plugins/maven-cdk-plugin/src/it/annotated-component/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java 2009-11-20 23:36:08 UTC (rev 15950)
@@ -0,0 +1,988 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * 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.ajax4jsf.renderkit;
+
+
+import java.io.IOException;
+
+import java.lang.reflect.Array;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.FacesException;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+import javax.faces.component.UIParameter;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.ValueHolder;
+import javax.faces.component.behavior.ClientBehaviorContext.Parameter;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.Converter;
+
+/**
+ * Util class for common render operations - render passthru html attributes,
+ * iterate over child components etc.
+ *
+ * @author asmirnov(a)exadel.com (latest modification by $Author: alexsmirnov $)
+ * @version $Revision: 1.1.2.6 $ $Date: 2007/02/08 19:07:16 $
+ *
+ */
+public class RendererUtils {
+ public static final String DUMMY_FORM_ID = ":_form";
+
+ // we'd better use this instance multithreadly quickly
+ private static final RendererUtils INSTANCE = new RendererUtils();
+
+ /**
+ * Substitutions for components properies names and HTML attributes names.
+ */
+ private static Map<String, String> substitutions = new HashMap<String, String>();
+ private static Set<String> requiredAttributes = new HashSet<String>();
+
+ static {
+ substitutions.put(HTML.CLASS_ATTRIBUTE, "styleClass");
+ requiredAttributes.add(HTML.ALT_ATTRIBUTE);
+ Arrays.sort(HTML.PASS_THRU);
+ Arrays.sort(HTML.PASS_THRU_EVENTS);
+ Arrays.sort(HTML.PASS_THRU_BOOLEAN);
+ Arrays.sort(HTML.PASS_THRU_URI);
+ }
+
+ // can be created by subclasses;
+ // administratively restricted to be created by package members ;)
+ protected RendererUtils() {
+ super();
+ }
+
+ /**
+ * Use this method to get singleton instance of RendererUtils
+ * @return singleton instance
+ */
+ public static RendererUtils getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Encode id attribute with clientId component property
+ *
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ public void encodeId(FacesContext context, UIComponent component) throws IOException {
+ encodeId(context, component, HTML.ID_ATTRIBUTE);
+ }
+
+ /**
+ * Encode clientId to custom attribute ( for example, to control name )
+ *
+ * @param context
+ * @param component
+ * @param attribute
+ * @throws IOException
+ */
+ public void encodeId(FacesContext context, UIComponent component, String attribute) throws IOException {
+ String clientId = null;
+
+ try {
+ clientId = component.getClientId(context);
+ } catch (Exception e) {
+
+ // just ignore if clientId wasn't inited yet
+ }
+
+ if (null != clientId) {
+ context.getResponseWriter().writeAttribute(attribute, clientId,
+ (String) getComponentAttributeName(attribute));
+ }
+ }
+
+ /**
+ * Encode id attribute with clientId component property. Encoded only if id
+ * not auto generated.
+ *
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ public void encodeCustomId(FacesContext context, UIComponent component) throws IOException {
+ if ((component.getId() != null) && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) {
+ context.getResponseWriter().writeAttribute(HTML.ID_ATTRIBUTE, component.getClientId(context),
+ HTML.ID_ATTRIBUTE);
+ }
+ }
+
+ public Map<String, Object> createParametersMap(FacesContext context, UIComponent component) {
+ Map<String, Object> parameters = new LinkedHashMap<String, Object>();
+
+
+ return parameters;
+ }
+
+ private void encodeBehaviors(FacesContext context, ClientBehaviorHolder behaviorHolder,
+ String defaultHtmlEventName, String[] attributesExclusions)
+ throws IOException {
+
+ }
+
+ /**
+ * Encode common pass-thru html attributes.
+ *
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ public void encodePassThru(FacesContext context, UIComponent component, String defaultHtmlEvent)
+ throws IOException {
+
+ encodeAttributesFromArray(context, component, HTML.PASS_THRU);
+
+ if (component instanceof ClientBehaviorHolder) {
+ ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
+
+ encodeBehaviors(context, clientBehaviorHolder, defaultHtmlEvent, null);
+ } else {
+ encodeAttributesFromArray(context, component, HTML.PASS_THRU_EVENTS);
+ }
+ }
+
+ /**
+ * Encode pass-through attributes except specified ones
+ *
+ * @param context
+ * @param component
+ * @param exclusions
+ * @throws IOException
+ */
+ public void encodePassThruWithExclusions(FacesContext context, UIComponent component, String exclusions,
+ String defaultHtmlEvent) throws IOException {
+
+ if (null != exclusions) {
+ String[] exclusionsArray = exclusions.split(",");
+
+ encodePassThruWithExclusionsArray(context, component, exclusionsArray, defaultHtmlEvent);
+ }
+ }
+
+ public void encodePassThruWithExclusionsArray(FacesContext context, UIComponent component, String[] exclusions,
+ String defaultHtmlEvent) throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ Map<String, Object> attributes = component.getAttributes();
+
+ Arrays.sort(exclusions);
+
+ for (int i = 0; i < HTML.PASS_THRU.length; i++) {
+ String attribute = HTML.PASS_THRU[i];
+
+ if (Arrays.binarySearch(exclusions, attribute) < 0) {
+ encodePassThruAttribute(context, attributes, writer, attribute);
+ }
+ }
+
+ if (component instanceof ClientBehaviorHolder) {
+ ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
+
+ encodeBehaviors(context, clientBehaviorHolder, defaultHtmlEvent, exclusions);
+ } else {
+ for (int i = 0; i < HTML.PASS_THRU_EVENTS.length; i++) {
+ String attribute = HTML.PASS_THRU_EVENTS[i];
+
+ if (Arrays.binarySearch(exclusions, attribute) < 0) {
+ encodePassThruAttribute(context, attributes, writer, attribute);
+ }
+ }
+ }
+ }
+
+ /**
+ * Encode one pass-thru attribute, with plain/boolean/url value, got from
+ * properly component attribute.
+ *
+ * @param context
+ * @param writer
+ * @param attribute
+ * @throws IOException
+ */
+ public void encodePassThruAttribute(FacesContext context, Map<String, Object> attributes, ResponseWriter writer,
+ String attribute) throws IOException {
+
+ Object value = attributeValue(attribute, attributes.get(getComponentAttributeName(attribute)));
+
+ if ((null != value) && shouldRenderAttribute(attribute, value)) {
+ if (Arrays.binarySearch(HTML.PASS_THRU_URI, attribute) >= 0) {
+ String url = context.getApplication().getViewHandler().getResourceURL(context, value.toString());
+
+ url = context.getExternalContext().encodeResourceURL(url);
+ writer.writeURIAttribute(attribute, url, attribute);
+ } else {
+ writer.writeAttribute(attribute, value, attribute);
+ }
+ }
+ }
+
+ public void encodeAttributesFromArray(FacesContext context, UIComponent component, String[] attrs)
+ throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ Map<String, Object> attributes = component.getAttributes();
+
+ for (int i = 0; i < attrs.length; i++) {
+ String attribute = attrs[i];
+
+ encodePassThruAttribute(context, attributes, writer, attribute);
+ }
+ }
+
+ /**
+ * Encode attributes given by comma-separated string list.
+ *
+ * @param context
+ * current JSF context
+ * @param component
+ * for with render attributes values
+ * @param attrs
+ * comma separated list of attributes
+ * @throws IOException
+ */
+ public void encodeAttributes(FacesContext context, UIComponent component, String attrs) throws IOException {
+ if (null != attrs) {
+ String[] attrsArray = attrs.split(",");
+
+ encodeAttributesFromArray(context, component, attrsArray);
+ }
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @param property
+ * @param attributeName
+ *
+ * @throws IOException
+ */
+ public void encodeAttribute(FacesContext context, UIComponent component, Object property, String attributeName)
+ throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ Object value = component.getAttributes().get(property);
+
+ if (shouldRenderAttribute(attributeName, value)) {
+ writer.writeAttribute(attributeName, value, property.toString());
+ }
+ }
+
+ public void encodeAttribute(FacesContext context, UIComponent component, String attribute) throws IOException {
+ encodeAttribute(context, component, getComponentAttributeName(attribute), attribute);
+ }
+
+ public void writeText(ResponseWriter writer, Object value, String property) throws IOException {
+ if (value != null) {
+ writer.writeText(value, property);
+ }
+ }
+
+ /**
+ * Write html-attribute
+ *
+ * @param writer
+ * @param attribute
+ * @param value
+ * @throws IOException
+ */
+ public void writeAttribute(ResponseWriter writer, String attribute, Object value) throws IOException {
+ if (shouldRenderAttribute(attribute, value)) {
+ writer.writeAttribute(attribute, value.toString(), attribute);
+ }
+ }
+
+ /**
+ * @return true if and only if the argument <code>attributeVal</code> is
+ * an instance of a wrapper for a primitive type and its value is
+ * equal to the default value for that type as given in the spec.
+ */
+ public boolean shouldRenderAttribute(Object attributeVal) {
+ if (null == attributeVal) {
+ return false;
+ } else if ((attributeVal instanceof Boolean)
+ && ((Boolean) attributeVal).booleanValue() == Boolean.FALSE.booleanValue()) {
+ return false;
+ } else if (attributeVal.toString().length() == 0) {
+ return false;
+ } else {
+ return isValidProperty(attributeVal);
+ }
+ }
+
+ public boolean shouldRenderAttribute(String attributeName, Object attributeVal) {
+ if (!requiredAttributes.contains(attributeName)) {
+ return shouldRenderAttribute(attributeVal);
+ } else {
+ if (null == attributeVal) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Test for valid value of property. by default, for non-setted properties
+ * with Java primitive types of JSF component return appropriate MIN_VALUE .
+ *
+ * @param property -
+ * value of property returned from
+ * {@link UIComponent#getAttributes()}
+ * @return true for setted property, false otherthise.
+ */
+ public boolean isValidProperty(Object property) {
+ if (null == property) {
+ return false;
+ } else if ((property instanceof Integer) && ((Integer) property).intValue() == Integer.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Double) && ((Double) property).doubleValue() == Double.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Character) && ((Character) property).charValue() == Character.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Float) && ((Float) property).floatValue() == Float.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Short) && ((Short) property).shortValue() == Short.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Byte) && ((Byte) property).byteValue() == Byte.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Long) && ((Long) property).longValue() == Long.MIN_VALUE) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks if the argument passed in is empty or not.
+ * Object is empty if it is: <br />
+ * - <code>null<code><br />
+ * - zero-length string<br />
+ * - empty collection<br />
+ * - empty map<br />
+ * - zero-length array<br />
+ *
+ * @param o object to check for emptiness
+ * @since 3.3.2
+ * @return <code>true</code> if the argument is empty, <code>false</code> otherwise
+ */
+ public boolean isEmpty(Object o) {
+ if (null == o) {
+ return true;
+ }
+
+ if (o instanceof String) {
+ return 0 == ((String) o).length();
+ }
+
+ if (o instanceof Collection<?>) {
+ return ((Collection<?>) o).isEmpty();
+ }
+
+ if (o instanceof Map<?, ?>) {
+ return ((Map<?, ?>) o).isEmpty();
+ }
+
+ if (o.getClass().isArray()) {
+ return Array.getLength(o) == 0;
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert HTML attribute name to component property name.
+ *
+ * @param key
+ * @return
+ */
+ protected Object getComponentAttributeName(Object key) {
+ Object converted = substitutions.get(key);
+
+ if (null == converted) {
+ return key;
+ } else {
+ return converted;
+ }
+ }
+
+ /**
+ * Convert attribute value to proper object. For known html boolean
+ * attributes return name for true value, otherthise - null. For non-boolean
+ * attributes return same value.
+ *
+ * @param name
+ * attribute name.
+ * @param value
+ * @return
+ */
+ protected Object attributeValue(String name, Object value) {
+ if (null == value || Arrays.binarySearch(HTML.PASS_THRU_BOOLEAN, name) < 0) {
+ return value;
+ }
+
+ boolean checked;
+
+ if (value instanceof Boolean) {
+ checked = ((Boolean) value).booleanValue();
+ } else {
+ checked = Boolean.parseBoolean(value.toString());
+ }
+
+ return checked ? name : null;
+ }
+
+ /**
+ * Get boolean value of logical attribute
+ *
+ * @param component
+ * @param name
+ * attribute name
+ * @return true if attribute is equals Boolean.TRUE or String "true" , false
+ * otherwise.
+ */
+ public boolean isBooleanAttribute(UIComponent component, String name) {
+ Object attrValue = component.getAttributes().get(name);
+ boolean result = false;
+
+ if (null != attrValue) {
+ if (attrValue instanceof String) {
+ result = "true".equalsIgnoreCase((String) attrValue);
+ } else {
+ result = Boolean.TRUE.equals(attrValue);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Return converted value for {@link javax.faces.component.ValueHolder} as
+ * String, perform nessesary convertions.
+ *
+ * @param context
+ * @param component
+ * @return
+ */
+ public String getValueAsString(FacesContext context, UIComponent component) {
+
+ // First - get submitted value for input components
+ if (component instanceof EditableValueHolder) {
+ EditableValueHolder input = (EditableValueHolder) component;
+ String submittedValue = (String) input.getSubmittedValue();
+
+ if (null != submittedValue) {
+ return submittedValue;
+ }
+ }
+
+ // If no submitted value presented - convert same for UIInput/UIOutput
+ if (component instanceof ValueHolder) {
+ return formatValue(context, component, ((ValueHolder) component).getValue());
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Convert any object value to string. If component instance of
+ * {@link ValueHolder } got {@link Converter} for formatting. If not,
+ * attempt to use converter based on value type.
+ *
+ * @param context
+ * @param component
+ * @return
+ */
+ public String formatValue(FacesContext context, UIComponent component, Object value) {
+ if (value instanceof String) {
+ return (String) value;
+ }
+
+ Converter converter = null;
+
+ if (component instanceof ValueHolder) {
+ ValueHolder holder = (ValueHolder) component;
+
+ converter = holder.getConverter();
+ }
+
+ if ((null == converter) && (null != value)) {
+ try {
+ converter = context.getApplication().createConverter(value.getClass());
+ } catch (FacesException e) {
+
+ // TODO - log converter exception.
+ }
+ }
+
+ if (null == converter) {
+ if (null != value) {
+ return value.toString();
+ }
+ } else {
+ return converter.getAsString(context, component, value);
+ }
+
+ return "";
+ }
+
+ public String encodePx(String value) {
+ return null;
+ }
+
+ /**
+ * formats given value to
+ *
+ * @param value
+ *
+ * @return
+ */
+ public String encodePctOrPx(String value) {
+ if (value.indexOf('%') > 0) {
+ return value;
+ } else {
+ return encodePx(value);
+ }
+ }
+
+ /**
+ * Find nested form for given component
+ *
+ * @param component
+ * @return nested <code>UIForm</code> component, or <code>null</code>
+ */
+ public UIForm getNestingForm(FacesContext context, UIComponent component) {
+ UIComponent parent = component.getParent();
+
+ while ((parent != null) && !(parent instanceof UIForm)) {
+ parent = parent.getParent();
+ }
+
+ UIForm nestingForm = null;
+
+ if (parent != null) {
+
+ // link is nested inside a form
+ nestingForm = (UIForm) parent;
+ }
+
+ return nestingForm;
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @return
+ * @throws IOException
+ */
+ public void encodeBeginFormIfNessesary(FacesContext context, UIComponent component) throws IOException {
+ UIForm form = getNestingForm(context, component);
+
+ if (null == form) {
+ ResponseWriter writer = context.getResponseWriter();
+ String clientId = component.getClientId(context) + DUMMY_FORM_ID;
+
+ encodeBeginForm(context, component, writer, clientId);
+
+ // writer.writeAttribute(HTML.STYLE_ATTRIBUTE, "margin:0;
+ // padding:0;", null);
+ }
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @param writer
+ * @param clientId
+ * @throws IOException
+ */
+ public void encodeBeginForm(FacesContext context, UIComponent component, ResponseWriter writer, String clientId)
+ throws IOException {
+
+ String actionURL = getActionUrl(context);
+ String encodeActionURL = context.getExternalContext().encodeActionURL(actionURL);
+
+ writer.startElement(HTML.FORM_ELEMENT, component);
+ writer.writeAttribute(HTML.ID_ATTRIBUTE, clientId, null);
+ writer.writeAttribute(HTML.NAME_ATTRIBUTE, clientId, null);
+ writer.writeAttribute(HTML.METHOD_ATTRIBUTE, "post", null);
+ writer.writeAttribute(HTML.STYLE_ATTRIBUTE, "margin:0; padding:0; display: inline;", null);
+ writer.writeURIAttribute(HTML.ACTION_ATTRIBUTE, encodeActionURL, "action");
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ public void encodeEndFormIfNessesary(FacesContext context, UIComponent component) throws IOException {
+ UIForm form = getNestingForm(context, component);
+
+ if (null == form) {
+ ResponseWriter writer = context.getResponseWriter();
+
+ // TODO - hidden form parameters ?
+ encodeEndForm(context, writer);
+ }
+ }
+
+ /**
+ * @param context
+ * @param writer
+ * @throws IOException
+ */
+ public void encodeEndForm(FacesContext context, ResponseWriter writer) throws IOException {
+ }
+
+ /**
+ * @param facesContext
+ * @return String A String representing the action URL
+ */
+ public String getActionUrl(FacesContext facesContext) {
+ ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
+ String viewId = facesContext.getViewRoot().getViewId();
+
+ return viewHandler.getActionURL(facesContext, viewId);
+ }
+
+ /**
+ * Simplified version of {@link encodeId}
+ *
+ * @param context
+ * @param component
+ * @return client id of current component
+ */
+ public String clientId(FacesContext context, UIComponent component) {
+ String clientId = "";
+
+ try {
+ clientId = component.getClientId(context);
+ } catch (Exception e) {
+
+ // just ignore
+ }
+
+ return clientId;
+ }
+
+ /**
+ * Wtrie JavaScript with start/end elements and type.
+ *
+ * @param context
+ * @param component
+ * @param script
+ */
+ public void writeScript(FacesContext context, UIComponent component, Object script) throws IOException {
+ ResponseWriter writer = context.getResponseWriter();
+
+ writer.startElement(HTML.SCRIPT_ELEM, component);
+ writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", "type");
+ writer.writeText(script, null);
+ writer.endElement(HTML.SCRIPT_ELEM);
+ }
+
+ /**
+ * @param ids
+ * @param keyword
+ * @since 4.0
+ *
+ * @return
+ */
+ private static boolean checkKeyword(Collection<String> ids, String keyword) {
+ if (ids.contains(keyword)) {
+ if (ids.size() != 1) {
+ //TODO log
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @param shortIds
+ * @since 4.0
+ * @return
+ */
+ public Collection<String> findComponentsFor(FacesContext context, UIComponent component,
+ Collection<String> shortIds) {
+
+ // TODO - implement
+ // TODO add support for @*
+ Set<String> result = new LinkedHashSet<String>(shortIds.size());
+
+
+ return result;
+ }
+
+ public UIComponent findComponentFor(FacesContext context, UIComponent component, String id) {
+ return findComponentFor(component, id);
+ }
+
+ /**
+ * @param component
+ * @param id
+ * @return
+ */
+ public UIComponent findComponentFor(UIComponent component, String id) {
+ if (id == null) {
+ throw new NullPointerException("id is null!");
+ }
+
+ if (id.length() == 0) {
+ return null;
+ }
+
+ UIComponent target = null;
+ UIComponent parent = component;
+ UIComponent root = component;
+
+ while ((null == target) && (null != parent)) {
+ target = parent.findComponent(id);
+ root = parent;
+ parent = parent.getParent();
+ }
+
+ if (null == target) {
+ target = findUIComponentBelow(root, id);
+ }
+
+ return target;
+ }
+
+ /**
+ * If target component contains generated id and for doesn't, correct for id
+ * @param forAttr
+ * @param component
+ *
+ */
+ public String correctForIdReference(String forAttr, UIComponent component) {
+ int contains = forAttr.indexOf(UIViewRoot.UNIQUE_ID_PREFIX);
+
+ if (contains <= 0) {
+ String id = component.getId();
+ int pos = id.indexOf(UIViewRoot.UNIQUE_ID_PREFIX);
+
+ if (pos > 0) {
+ return forAttr.concat(id.substring(pos));
+ }
+ }
+
+ return forAttr;
+ }
+
+ private UIComponent findUIComponentBelow(UIComponent root, String id) {
+ UIComponent target = null;
+
+ for (Iterator<UIComponent> iter = root.getFacetsAndChildren(); iter.hasNext(); ) {
+ UIComponent child = (UIComponent) iter.next();
+
+ if (child instanceof NamingContainer) {
+ try {
+ target = child.findComponent(id);
+ } catch (IllegalArgumentException iae) {
+ continue;
+ }
+ }
+
+ if (target == null) {
+ if ((child.getChildCount() > 0) || (child.getFacetCount() > 0)) {
+ target = findUIComponentBelow(child, id);
+ }
+ }
+
+ if (target != null) {
+ break;
+ }
+ }
+
+ return target;
+ }
+
+ public static void writeEventHandlerFunction(FacesContext context, UIComponent component, String eventName)
+ throws IOException {
+
+ }
+
+ /**
+ * Common HTML elements and attributes names.
+ *
+ * @author asmirnov(a)exadel.com (latest modification by $Author: alexsmirnov $)
+ * @version $Revision: 1.1.2.6 $ $Date: 2007/02/08 19:07:16 $
+ *
+ */
+ public interface HTML {
+ public static final String ACCEPT_ATTRIBUTE = "accept";
+ public static final String ACCEPT_CHARSET_ATTRIBUTE = "accept-charset";
+ public static final String ACCESSKEY_ATTRIBUTE = "accesskey";
+ public static final String ACTION_ATTRIBUTE = "action";
+ public static final String ALIGN_ATTRIBUTE = "align";
+ public static final String ALT_ATTRIBUTE = "alt";
+ public static final String AUTOCOMPLETE_ATTRIBUTE = "autocomplete";
+ public static final String A_ELEMENT = "a";
+ public static final String BGCOLOR_ATTRIBUTE = "bgcolor";
+ public static final String BODY_ELEMENT = "body";
+ public static final String BORDER_ATTRIBUTE = "border";
+
+ // elements
+ public static final String BUTTON = "button";
+ public static final String CAPTION_ELEMENT = "caption";
+ public static final String CELLPADDING_ATTRIBUTE = "cellpadding";
+ public static final String CELLSPACING_ATTRIBUTE = "cellspacing";
+ public static final String CHARSET_ATTR = "charset";
+ public static final String CLASS_ATTRIBUTE = "class";
+ public static final String COLS_ATTRIBUTE = "cols";
+ public static final String COORDS_ATTR = "coords";
+ public static final String DIR_ATTRIBUTE = "dir";
+ public static final String DISABLED_ATTR = "disabled";
+ public static final String DIV_ELEM = "div";
+ public static final String DL_ELEMENT = "dl";
+ public static final String DT_ELEMENT = "dt";
+ public static final String ENCTYPE_ATTRIBUTE = "enctype";
+ public static final String FORM_ELEMENT = "form";
+ public static final String FRAME_ATTRIBUTE = "frame";
+ public static final String HEAD_ELEMENT = "head";
+ public static final String HEIGHT_ATTRIBUTE = "height";
+ public static final String HREFLANG_ATTR = "hreflang";
+ public static final String HREF_ATTR = "href";
+ public static final String HTML_ELEMENT = "html";
+
+ // attributes
+ public static final String ID_ATTRIBUTE = "id";
+ public static final String IMG_ELEMENT = "img";
+ public static final String INPUT_ELEM = "input";
+ public static final Object INPUT_TYPE_HIDDEN = "hidden";
+ public static final String LANG_ATTRIBUTE = "lang";
+ public static final String LINK_ELEMENT = "link";
+ public static final String LONGDESC_ATTRIBUTE = "longdesc";
+ public static final String MAXLENGTH_ATTRIBUTE = "maxlength";
+ public static final String MEDIA_ATTRIBUTE = "media";
+ public static final String METHOD_ATTRIBUTE = "method";
+ public static final String NAME_ATTRIBUTE = "name";
+ public static final String NOWRAP_ATTRIBUTE = "nowrap";
+ public static final String ONBLUR_ATTRIBUTE = "onblur";
+ public static final String ONCHANGE_ATTRIBUTE = "onchange";
+ public static final String ONCLICK_ATTRIBUTE = "onclick";
+ public static final String ONDBLCLICK_ATTRIBUTE = "ondblclick";
+ public static final String ONFOCUS_ATTRIBUTE = "onfocus";
+ public static final String ONKEYDOWN_ATTRIBUTE = "onkeydown";
+ public static final String ONKEYPRESS_ATTRIBUTE = "onkeypress";
+ public static final String ONKEYUP_ATTRIBUTE = "onkeyup";
+ public static final String ONLOAD_ATTRIBUTE = "onload";
+ public static final String ONMOUSEDOWN_ATTRIBUTE = "onmousedown";
+ public static final String ONMOUSEMOVE_ATTRIBUTE = "onmousemove";
+ public static final String ONMOUSEOUT_ATTRIBUTE = "onmouseout";
+ public static final String ONMOUSEOVER_ATTRIBUTE = "onmouseover";
+ public static final String ONMOUSEUP_ATTRIBUTE = "onmouseup";
+ public static final String ONRESET_ATTRIBUTE = "onreset";
+ public static final String ONSELECT_ATTRIBUTE = "onselect";
+ public static final String ONSUBMIT_ATTRIBUTE = "onsubmit";
+ public static final String ONUNLOAD_ATTRIBUTE = "onunload";
+
+ // public static final String ONRESET_ATTRIBUTE = "onreset";
+ // attributes sets.
+ public static final String[] PASS_THRU = {
+
+ // DIR_ATTRIBUTE,
+ // LANG_ATTRIBUTE,
+ // STYLE_ATTRIBUTE,
+ // TITLE_ATTRIBUTE
+ "accesskey", "alt", "cols", "height", "lang", "longdesc", "maxlength", "rows", "size", "tabindex", "title",
+ "width", "dir", "rules", "frame", "border", "cellspacing", "cellpadding", "summary", "bgcolor", "usemap",
+ "enctype", "accept-charset", "accept", "target", "charset", "coords", "hreflang", "rel", "rev", "shape",
+ "disabled", "readonly", "ismap", "align"
+ };
+
+ /**
+ * HTML attributes allowed boolean-values only
+ */
+ public static final String[] PASS_THRU_BOOLEAN = {
+ "disabled", "declare", "readonly", "compact", "ismap", "selected", "checked", "nowrap", "noresize",
+ "nohref", "noshade", "multiple"
+ };
+ public static final String[] PASS_THRU_EVENTS = {
+ "onblur", "onchange", "onclick", "ondblclick", "onfocus", "onkeydown", "onkeypress", "onkeyup", "onload",
+ "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onreset", "onselect", "onsubmit",
+ "onunload"
+ };
+ public static final String[] PASS_THRU_STYLES = {"style", "class", };
+
+ /**
+ * all HTML attributes with URI value.
+ */
+ public static final String[] PASS_THRU_URI = {
+ "usemap", "background", "codebase", "cite", "data", "classid", "href", "longdesc", "profile", "src"
+ };
+ public static final String READONLY_ATTRIBUTE = "readonly";
+ public static final String REL_ATTR = "rel";
+ public static final String REV_ATTR = "rev";
+ public static final String ROWS_ATTRIBUTE = "rows";
+ public static final String RULES_ATTRIBUTE = "rules";
+ public static final String SCRIPT_ELEM = "script";
+ public static final String SHAPE_ATTR = "shape";
+ public static final String SIZE_ATTRIBUTE = "size";
+ public static final String SPAN_ELEM = "span";
+ public static final String SRC_ATTRIBUTE = "src";
+ public static final String STYLE_ATTRIBUTE = "style";
+ public static final String STYLE_CLASS_ATTR = "styleClass";
+ public static final String SUMMARY_ATTRIBUTE = "summary";
+ public static final String TABINDEX_ATTRIBUTE = "tabindex";
+ public static final String TABLE_ELEMENT = "table";
+ public static final String TARGET_ATTRIBUTE = "target";
+ public static final String TBOBY_ELEMENT = "tbody";
+ public static final String TD_ELEM = "td";
+ public static final String TEXT_JAVASCRIPT_TYPE = "text/javascript";
+ public static final String TFOOT_ELEMENT = "tfoot";
+ public static final String THEAD_ELEMENT = "thead";
+ public static final String TH_ELEM = "th";
+ public static final String TITLE_ATTRIBUTE = "title";
+ public static final String TITLE_ELEM = "title";
+ public static final String TR_ELEMENT = "tr";
+ public static final String TYPE_ATTR = "type";
+ public static final String USEMAP_ATTRIBUTE = "usemap";
+ public static final String VALIGN_ATTRIBUTE = "valign";
+ public static final String VALUE_ATTRIBUTE = "value";
+ public static final String WIDTH_ATTRIBUTE = "width";
+ }
+}
Modified: root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/pom.xml
===================================================================
--- root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/pom.xml 2009-11-20 17:15:37 UTC (rev 15949)
+++ root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/pom.xml 2009-11-20 23:36:08 UTC (rev 15950)
@@ -31,8 +31,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- http://maven.apache.org/plugins/maven-compiler-plugin/ -->
- <source>1.5</source>
- <target>1.5</target>
+ <source>1.6</source>
+ <target>1.6</target>
</configuration>
</plugin>
</plugins>
Added: root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
===================================================================
--- root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java (rev 0)
+++ root/cdk/trunk/plugins/maven-cdk-plugin/src/it/xml-configured-component/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java 2009-11-20 23:36:08 UTC (rev 15950)
@@ -0,0 +1,988 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * 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.ajax4jsf.renderkit;
+
+
+import java.io.IOException;
+
+import java.lang.reflect.Array;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.FacesException;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+import javax.faces.component.UIParameter;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.ValueHolder;
+import javax.faces.component.behavior.ClientBehaviorContext.Parameter;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.Converter;
+
+/**
+ * Util class for common render operations - render passthru html attributes,
+ * iterate over child components etc.
+ *
+ * @author asmirnov(a)exadel.com (latest modification by $Author: alexsmirnov $)
+ * @version $Revision: 1.1.2.6 $ $Date: 2007/02/08 19:07:16 $
+ *
+ */
+public class RendererUtils {
+ public static final String DUMMY_FORM_ID = ":_form";
+
+ // we'd better use this instance multithreadly quickly
+ private static final RendererUtils INSTANCE = new RendererUtils();
+
+ /**
+ * Substitutions for components properies names and HTML attributes names.
+ */
+ private static Map<String, String> substitutions = new HashMap<String, String>();
+ private static Set<String> requiredAttributes = new HashSet<String>();
+
+ static {
+ substitutions.put(HTML.CLASS_ATTRIBUTE, "styleClass");
+ requiredAttributes.add(HTML.ALT_ATTRIBUTE);
+ Arrays.sort(HTML.PASS_THRU);
+ Arrays.sort(HTML.PASS_THRU_EVENTS);
+ Arrays.sort(HTML.PASS_THRU_BOOLEAN);
+ Arrays.sort(HTML.PASS_THRU_URI);
+ }
+
+ // can be created by subclasses;
+ // administratively restricted to be created by package members ;)
+ protected RendererUtils() {
+ super();
+ }
+
+ /**
+ * Use this method to get singleton instance of RendererUtils
+ * @return singleton instance
+ */
+ public static RendererUtils getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Encode id attribute with clientId component property
+ *
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ public void encodeId(FacesContext context, UIComponent component) throws IOException {
+ encodeId(context, component, HTML.ID_ATTRIBUTE);
+ }
+
+ /**
+ * Encode clientId to custom attribute ( for example, to control name )
+ *
+ * @param context
+ * @param component
+ * @param attribute
+ * @throws IOException
+ */
+ public void encodeId(FacesContext context, UIComponent component, String attribute) throws IOException {
+ String clientId = null;
+
+ try {
+ clientId = component.getClientId(context);
+ } catch (Exception e) {
+
+ // just ignore if clientId wasn't inited yet
+ }
+
+ if (null != clientId) {
+ context.getResponseWriter().writeAttribute(attribute, clientId,
+ (String) getComponentAttributeName(attribute));
+ }
+ }
+
+ /**
+ * Encode id attribute with clientId component property. Encoded only if id
+ * not auto generated.
+ *
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ public void encodeCustomId(FacesContext context, UIComponent component) throws IOException {
+ if ((component.getId() != null) && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) {
+ context.getResponseWriter().writeAttribute(HTML.ID_ATTRIBUTE, component.getClientId(context),
+ HTML.ID_ATTRIBUTE);
+ }
+ }
+
+ public Map<String, Object> createParametersMap(FacesContext context, UIComponent component) {
+ Map<String, Object> parameters = new LinkedHashMap<String, Object>();
+
+
+ return parameters;
+ }
+
+ private void encodeBehaviors(FacesContext context, ClientBehaviorHolder behaviorHolder,
+ String defaultHtmlEventName, String[] attributesExclusions)
+ throws IOException {
+
+ }
+
+ /**
+ * Encode common pass-thru html attributes.
+ *
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ public void encodePassThru(FacesContext context, UIComponent component, String defaultHtmlEvent)
+ throws IOException {
+
+ encodeAttributesFromArray(context, component, HTML.PASS_THRU);
+
+ if (component instanceof ClientBehaviorHolder) {
+ ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
+
+ encodeBehaviors(context, clientBehaviorHolder, defaultHtmlEvent, null);
+ } else {
+ encodeAttributesFromArray(context, component, HTML.PASS_THRU_EVENTS);
+ }
+ }
+
+ /**
+ * Encode pass-through attributes except specified ones
+ *
+ * @param context
+ * @param component
+ * @param exclusions
+ * @throws IOException
+ */
+ public void encodePassThruWithExclusions(FacesContext context, UIComponent component, String exclusions,
+ String defaultHtmlEvent) throws IOException {
+
+ if (null != exclusions) {
+ String[] exclusionsArray = exclusions.split(",");
+
+ encodePassThruWithExclusionsArray(context, component, exclusionsArray, defaultHtmlEvent);
+ }
+ }
+
+ public void encodePassThruWithExclusionsArray(FacesContext context, UIComponent component, String[] exclusions,
+ String defaultHtmlEvent) throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ Map<String, Object> attributes = component.getAttributes();
+
+ Arrays.sort(exclusions);
+
+ for (int i = 0; i < HTML.PASS_THRU.length; i++) {
+ String attribute = HTML.PASS_THRU[i];
+
+ if (Arrays.binarySearch(exclusions, attribute) < 0) {
+ encodePassThruAttribute(context, attributes, writer, attribute);
+ }
+ }
+
+ if (component instanceof ClientBehaviorHolder) {
+ ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
+
+ encodeBehaviors(context, clientBehaviorHolder, defaultHtmlEvent, exclusions);
+ } else {
+ for (int i = 0; i < HTML.PASS_THRU_EVENTS.length; i++) {
+ String attribute = HTML.PASS_THRU_EVENTS[i];
+
+ if (Arrays.binarySearch(exclusions, attribute) < 0) {
+ encodePassThruAttribute(context, attributes, writer, attribute);
+ }
+ }
+ }
+ }
+
+ /**
+ * Encode one pass-thru attribute, with plain/boolean/url value, got from
+ * properly component attribute.
+ *
+ * @param context
+ * @param writer
+ * @param attribute
+ * @throws IOException
+ */
+ public void encodePassThruAttribute(FacesContext context, Map<String, Object> attributes, ResponseWriter writer,
+ String attribute) throws IOException {
+
+ Object value = attributeValue(attribute, attributes.get(getComponentAttributeName(attribute)));
+
+ if ((null != value) && shouldRenderAttribute(attribute, value)) {
+ if (Arrays.binarySearch(HTML.PASS_THRU_URI, attribute) >= 0) {
+ String url = context.getApplication().getViewHandler().getResourceURL(context, value.toString());
+
+ url = context.getExternalContext().encodeResourceURL(url);
+ writer.writeURIAttribute(attribute, url, attribute);
+ } else {
+ writer.writeAttribute(attribute, value, attribute);
+ }
+ }
+ }
+
+ public void encodeAttributesFromArray(FacesContext context, UIComponent component, String[] attrs)
+ throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ Map<String, Object> attributes = component.getAttributes();
+
+ for (int i = 0; i < attrs.length; i++) {
+ String attribute = attrs[i];
+
+ encodePassThruAttribute(context, attributes, writer, attribute);
+ }
+ }
+
+ /**
+ * Encode attributes given by comma-separated string list.
+ *
+ * @param context
+ * current JSF context
+ * @param component
+ * for with render attributes values
+ * @param attrs
+ * comma separated list of attributes
+ * @throws IOException
+ */
+ public void encodeAttributes(FacesContext context, UIComponent component, String attrs) throws IOException {
+ if (null != attrs) {
+ String[] attrsArray = attrs.split(",");
+
+ encodeAttributesFromArray(context, component, attrsArray);
+ }
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @param property
+ * @param attributeName
+ *
+ * @throws IOException
+ */
+ public void encodeAttribute(FacesContext context, UIComponent component, Object property, String attributeName)
+ throws IOException {
+
+ ResponseWriter writer = context.getResponseWriter();
+ Object value = component.getAttributes().get(property);
+
+ if (shouldRenderAttribute(attributeName, value)) {
+ writer.writeAttribute(attributeName, value, property.toString());
+ }
+ }
+
+ public void encodeAttribute(FacesContext context, UIComponent component, String attribute) throws IOException {
+ encodeAttribute(context, component, getComponentAttributeName(attribute), attribute);
+ }
+
+ public void writeText(ResponseWriter writer, Object value, String property) throws IOException {
+ if (value != null) {
+ writer.writeText(value, property);
+ }
+ }
+
+ /**
+ * Write html-attribute
+ *
+ * @param writer
+ * @param attribute
+ * @param value
+ * @throws IOException
+ */
+ public void writeAttribute(ResponseWriter writer, String attribute, Object value) throws IOException {
+ if (shouldRenderAttribute(attribute, value)) {
+ writer.writeAttribute(attribute, value.toString(), attribute);
+ }
+ }
+
+ /**
+ * @return true if and only if the argument <code>attributeVal</code> is
+ * an instance of a wrapper for a primitive type and its value is
+ * equal to the default value for that type as given in the spec.
+ */
+ public boolean shouldRenderAttribute(Object attributeVal) {
+ if (null == attributeVal) {
+ return false;
+ } else if ((attributeVal instanceof Boolean)
+ && ((Boolean) attributeVal).booleanValue() == Boolean.FALSE.booleanValue()) {
+ return false;
+ } else if (attributeVal.toString().length() == 0) {
+ return false;
+ } else {
+ return isValidProperty(attributeVal);
+ }
+ }
+
+ public boolean shouldRenderAttribute(String attributeName, Object attributeVal) {
+ if (!requiredAttributes.contains(attributeName)) {
+ return shouldRenderAttribute(attributeVal);
+ } else {
+ if (null == attributeVal) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Test for valid value of property. by default, for non-setted properties
+ * with Java primitive types of JSF component return appropriate MIN_VALUE .
+ *
+ * @param property -
+ * value of property returned from
+ * {@link UIComponent#getAttributes()}
+ * @return true for setted property, false otherthise.
+ */
+ public boolean isValidProperty(Object property) {
+ if (null == property) {
+ return false;
+ } else if ((property instanceof Integer) && ((Integer) property).intValue() == Integer.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Double) && ((Double) property).doubleValue() == Double.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Character) && ((Character) property).charValue() == Character.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Float) && ((Float) property).floatValue() == Float.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Short) && ((Short) property).shortValue() == Short.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Byte) && ((Byte) property).byteValue() == Byte.MIN_VALUE) {
+ return false;
+ } else if ((property instanceof Long) && ((Long) property).longValue() == Long.MIN_VALUE) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks if the argument passed in is empty or not.
+ * Object is empty if it is: <br />
+ * - <code>null<code><br />
+ * - zero-length string<br />
+ * - empty collection<br />
+ * - empty map<br />
+ * - zero-length array<br />
+ *
+ * @param o object to check for emptiness
+ * @since 3.3.2
+ * @return <code>true</code> if the argument is empty, <code>false</code> otherwise
+ */
+ public boolean isEmpty(Object o) {
+ if (null == o) {
+ return true;
+ }
+
+ if (o instanceof String) {
+ return 0 == ((String) o).length();
+ }
+
+ if (o instanceof Collection<?>) {
+ return ((Collection<?>) o).isEmpty();
+ }
+
+ if (o instanceof Map<?, ?>) {
+ return ((Map<?, ?>) o).isEmpty();
+ }
+
+ if (o.getClass().isArray()) {
+ return Array.getLength(o) == 0;
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert HTML attribute name to component property name.
+ *
+ * @param key
+ * @return
+ */
+ protected Object getComponentAttributeName(Object key) {
+ Object converted = substitutions.get(key);
+
+ if (null == converted) {
+ return key;
+ } else {
+ return converted;
+ }
+ }
+
+ /**
+ * Convert attribute value to proper object. For known html boolean
+ * attributes return name for true value, otherthise - null. For non-boolean
+ * attributes return same value.
+ *
+ * @param name
+ * attribute name.
+ * @param value
+ * @return
+ */
+ protected Object attributeValue(String name, Object value) {
+ if (null == value || Arrays.binarySearch(HTML.PASS_THRU_BOOLEAN, name) < 0) {
+ return value;
+ }
+
+ boolean checked;
+
+ if (value instanceof Boolean) {
+ checked = ((Boolean) value).booleanValue();
+ } else {
+ checked = Boolean.parseBoolean(value.toString());
+ }
+
+ return checked ? name : null;
+ }
+
+ /**
+ * Get boolean value of logical attribute
+ *
+ * @param component
+ * @param name
+ * attribute name
+ * @return true if attribute is equals Boolean.TRUE or String "true" , false
+ * otherwise.
+ */
+ public boolean isBooleanAttribute(UIComponent component, String name) {
+ Object attrValue = component.getAttributes().get(name);
+ boolean result = false;
+
+ if (null != attrValue) {
+ if (attrValue instanceof String) {
+ result = "true".equalsIgnoreCase((String) attrValue);
+ } else {
+ result = Boolean.TRUE.equals(attrValue);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Return converted value for {@link javax.faces.component.ValueHolder} as
+ * String, perform nessesary convertions.
+ *
+ * @param context
+ * @param component
+ * @return
+ */
+ public String getValueAsString(FacesContext context, UIComponent component) {
+
+ // First - get submitted value for input components
+ if (component instanceof EditableValueHolder) {
+ EditableValueHolder input = (EditableValueHolder) component;
+ String submittedValue = (String) input.getSubmittedValue();
+
+ if (null != submittedValue) {
+ return submittedValue;
+ }
+ }
+
+ // If no submitted value presented - convert same for UIInput/UIOutput
+ if (component instanceof ValueHolder) {
+ return formatValue(context, component, ((ValueHolder) component).getValue());
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Convert any object value to string. If component instance of
+ * {@link ValueHolder } got {@link Converter} for formatting. If not,
+ * attempt to use converter based on value type.
+ *
+ * @param context
+ * @param component
+ * @return
+ */
+ public String formatValue(FacesContext context, UIComponent component, Object value) {
+ if (value instanceof String) {
+ return (String) value;
+ }
+
+ Converter converter = null;
+
+ if (component instanceof ValueHolder) {
+ ValueHolder holder = (ValueHolder) component;
+
+ converter = holder.getConverter();
+ }
+
+ if ((null == converter) && (null != value)) {
+ try {
+ converter = context.getApplication().createConverter(value.getClass());
+ } catch (FacesException e) {
+
+ // TODO - log converter exception.
+ }
+ }
+
+ if (null == converter) {
+ if (null != value) {
+ return value.toString();
+ }
+ } else {
+ return converter.getAsString(context, component, value);
+ }
+
+ return "";
+ }
+
+ public String encodePx(String value) {
+ return null;
+ }
+
+ /**
+ * formats given value to
+ *
+ * @param value
+ *
+ * @return
+ */
+ public String encodePctOrPx(String value) {
+ if (value.indexOf('%') > 0) {
+ return value;
+ } else {
+ return encodePx(value);
+ }
+ }
+
+ /**
+ * Find nested form for given component
+ *
+ * @param component
+ * @return nested <code>UIForm</code> component, or <code>null</code>
+ */
+ public UIForm getNestingForm(FacesContext context, UIComponent component) {
+ UIComponent parent = component.getParent();
+
+ while ((parent != null) && !(parent instanceof UIForm)) {
+ parent = parent.getParent();
+ }
+
+ UIForm nestingForm = null;
+
+ if (parent != null) {
+
+ // link is nested inside a form
+ nestingForm = (UIForm) parent;
+ }
+
+ return nestingForm;
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @return
+ * @throws IOException
+ */
+ public void encodeBeginFormIfNessesary(FacesContext context, UIComponent component) throws IOException {
+ UIForm form = getNestingForm(context, component);
+
+ if (null == form) {
+ ResponseWriter writer = context.getResponseWriter();
+ String clientId = component.getClientId(context) + DUMMY_FORM_ID;
+
+ encodeBeginForm(context, component, writer, clientId);
+
+ // writer.writeAttribute(HTML.STYLE_ATTRIBUTE, "margin:0;
+ // padding:0;", null);
+ }
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @param writer
+ * @param clientId
+ * @throws IOException
+ */
+ public void encodeBeginForm(FacesContext context, UIComponent component, ResponseWriter writer, String clientId)
+ throws IOException {
+
+ String actionURL = getActionUrl(context);
+ String encodeActionURL = context.getExternalContext().encodeActionURL(actionURL);
+
+ writer.startElement(HTML.FORM_ELEMENT, component);
+ writer.writeAttribute(HTML.ID_ATTRIBUTE, clientId, null);
+ writer.writeAttribute(HTML.NAME_ATTRIBUTE, clientId, null);
+ writer.writeAttribute(HTML.METHOD_ATTRIBUTE, "post", null);
+ writer.writeAttribute(HTML.STYLE_ATTRIBUTE, "margin:0; padding:0; display: inline;", null);
+ writer.writeURIAttribute(HTML.ACTION_ATTRIBUTE, encodeActionURL, "action");
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ public void encodeEndFormIfNessesary(FacesContext context, UIComponent component) throws IOException {
+ UIForm form = getNestingForm(context, component);
+
+ if (null == form) {
+ ResponseWriter writer = context.getResponseWriter();
+
+ // TODO - hidden form parameters ?
+ encodeEndForm(context, writer);
+ }
+ }
+
+ /**
+ * @param context
+ * @param writer
+ * @throws IOException
+ */
+ public void encodeEndForm(FacesContext context, ResponseWriter writer) throws IOException {
+ }
+
+ /**
+ * @param facesContext
+ * @return String A String representing the action URL
+ */
+ public String getActionUrl(FacesContext facesContext) {
+ ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
+ String viewId = facesContext.getViewRoot().getViewId();
+
+ return viewHandler.getActionURL(facesContext, viewId);
+ }
+
+ /**
+ * Simplified version of {@link encodeId}
+ *
+ * @param context
+ * @param component
+ * @return client id of current component
+ */
+ public String clientId(FacesContext context, UIComponent component) {
+ String clientId = "";
+
+ try {
+ clientId = component.getClientId(context);
+ } catch (Exception e) {
+
+ // just ignore
+ }
+
+ return clientId;
+ }
+
+ /**
+ * Wtrie JavaScript with start/end elements and type.
+ *
+ * @param context
+ * @param component
+ * @param script
+ */
+ public void writeScript(FacesContext context, UIComponent component, Object script) throws IOException {
+ ResponseWriter writer = context.getResponseWriter();
+
+ writer.startElement(HTML.SCRIPT_ELEM, component);
+ writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", "type");
+ writer.writeText(script, null);
+ writer.endElement(HTML.SCRIPT_ELEM);
+ }
+
+ /**
+ * @param ids
+ * @param keyword
+ * @since 4.0
+ *
+ * @return
+ */
+ private static boolean checkKeyword(Collection<String> ids, String keyword) {
+ if (ids.contains(keyword)) {
+ if (ids.size() != 1) {
+ //TODO log
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @param context
+ * @param component
+ * @param shortIds
+ * @since 4.0
+ * @return
+ */
+ public Collection<String> findComponentsFor(FacesContext context, UIComponent component,
+ Collection<String> shortIds) {
+
+ // TODO - implement
+ // TODO add support for @*
+ Set<String> result = new LinkedHashSet<String>(shortIds.size());
+
+
+ return result;
+ }
+
+ public UIComponent findComponentFor(FacesContext context, UIComponent component, String id) {
+ return findComponentFor(component, id);
+ }
+
+ /**
+ * @param component
+ * @param id
+ * @return
+ */
+ public UIComponent findComponentFor(UIComponent component, String id) {
+ if (id == null) {
+ throw new NullPointerException("id is null!");
+ }
+
+ if (id.length() == 0) {
+ return null;
+ }
+
+ UIComponent target = null;
+ UIComponent parent = component;
+ UIComponent root = component;
+
+ while ((null == target) && (null != parent)) {
+ target = parent.findComponent(id);
+ root = parent;
+ parent = parent.getParent();
+ }
+
+ if (null == target) {
+ target = findUIComponentBelow(root, id);
+ }
+
+ return target;
+ }
+
+ /**
+ * If target component contains generated id and for doesn't, correct for id
+ * @param forAttr
+ * @param component
+ *
+ */
+ public String correctForIdReference(String forAttr, UIComponent component) {
+ int contains = forAttr.indexOf(UIViewRoot.UNIQUE_ID_PREFIX);
+
+ if (contains <= 0) {
+ String id = component.getId();
+ int pos = id.indexOf(UIViewRoot.UNIQUE_ID_PREFIX);
+
+ if (pos > 0) {
+ return forAttr.concat(id.substring(pos));
+ }
+ }
+
+ return forAttr;
+ }
+
+ private UIComponent findUIComponentBelow(UIComponent root, String id) {
+ UIComponent target = null;
+
+ for (Iterator<UIComponent> iter = root.getFacetsAndChildren(); iter.hasNext(); ) {
+ UIComponent child = (UIComponent) iter.next();
+
+ if (child instanceof NamingContainer) {
+ try {
+ target = child.findComponent(id);
+ } catch (IllegalArgumentException iae) {
+ continue;
+ }
+ }
+
+ if (target == null) {
+ if ((child.getChildCount() > 0) || (child.getFacetCount() > 0)) {
+ target = findUIComponentBelow(child, id);
+ }
+ }
+
+ if (target != null) {
+ break;
+ }
+ }
+
+ return target;
+ }
+
+ public static void writeEventHandlerFunction(FacesContext context, UIComponent component, String eventName)
+ throws IOException {
+
+ }
+
+ /**
+ * Common HTML elements and attributes names.
+ *
+ * @author asmirnov(a)exadel.com (latest modification by $Author: alexsmirnov $)
+ * @version $Revision: 1.1.2.6 $ $Date: 2007/02/08 19:07:16 $
+ *
+ */
+ public interface HTML {
+ public static final String ACCEPT_ATTRIBUTE = "accept";
+ public static final String ACCEPT_CHARSET_ATTRIBUTE = "accept-charset";
+ public static final String ACCESSKEY_ATTRIBUTE = "accesskey";
+ public static final String ACTION_ATTRIBUTE = "action";
+ public static final String ALIGN_ATTRIBUTE = "align";
+ public static final String ALT_ATTRIBUTE = "alt";
+ public static final String AUTOCOMPLETE_ATTRIBUTE = "autocomplete";
+ public static final String A_ELEMENT = "a";
+ public static final String BGCOLOR_ATTRIBUTE = "bgcolor";
+ public static final String BODY_ELEMENT = "body";
+ public static final String BORDER_ATTRIBUTE = "border";
+
+ // elements
+ public static final String BUTTON = "button";
+ public static final String CAPTION_ELEMENT = "caption";
+ public static final String CELLPADDING_ATTRIBUTE = "cellpadding";
+ public static final String CELLSPACING_ATTRIBUTE = "cellspacing";
+ public static final String CHARSET_ATTR = "charset";
+ public static final String CLASS_ATTRIBUTE = "class";
+ public static final String COLS_ATTRIBUTE = "cols";
+ public static final String COORDS_ATTR = "coords";
+ public static final String DIR_ATTRIBUTE = "dir";
+ public static final String DISABLED_ATTR = "disabled";
+ public static final String DIV_ELEM = "div";
+ public static final String DL_ELEMENT = "dl";
+ public static final String DT_ELEMENT = "dt";
+ public static final String ENCTYPE_ATTRIBUTE = "enctype";
+ public static final String FORM_ELEMENT = "form";
+ public static final String FRAME_ATTRIBUTE = "frame";
+ public static final String HEAD_ELEMENT = "head";
+ public static final String HEIGHT_ATTRIBUTE = "height";
+ public static final String HREFLANG_ATTR = "hreflang";
+ public static final String HREF_ATTR = "href";
+ public static final String HTML_ELEMENT = "html";
+
+ // attributes
+ public static final String ID_ATTRIBUTE = "id";
+ public static final String IMG_ELEMENT = "img";
+ public static final String INPUT_ELEM = "input";
+ public static final Object INPUT_TYPE_HIDDEN = "hidden";
+ public static final String LANG_ATTRIBUTE = "lang";
+ public static final String LINK_ELEMENT = "link";
+ public static final String LONGDESC_ATTRIBUTE = "longdesc";
+ public static final String MAXLENGTH_ATTRIBUTE = "maxlength";
+ public static final String MEDIA_ATTRIBUTE = "media";
+ public static final String METHOD_ATTRIBUTE = "method";
+ public static final String NAME_ATTRIBUTE = "name";
+ public static final String NOWRAP_ATTRIBUTE = "nowrap";
+ public static final String ONBLUR_ATTRIBUTE = "onblur";
+ public static final String ONCHANGE_ATTRIBUTE = "onchange";
+ public static final String ONCLICK_ATTRIBUTE = "onclick";
+ public static final String ONDBLCLICK_ATTRIBUTE = "ondblclick";
+ public static final String ONFOCUS_ATTRIBUTE = "onfocus";
+ public static final String ONKEYDOWN_ATTRIBUTE = "onkeydown";
+ public static final String ONKEYPRESS_ATTRIBUTE = "onkeypress";
+ public static final String ONKEYUP_ATTRIBUTE = "onkeyup";
+ public static final String ONLOAD_ATTRIBUTE = "onload";
+ public static final String ONMOUSEDOWN_ATTRIBUTE = "onmousedown";
+ public static final String ONMOUSEMOVE_ATTRIBUTE = "onmousemove";
+ public static final String ONMOUSEOUT_ATTRIBUTE = "onmouseout";
+ public static final String ONMOUSEOVER_ATTRIBUTE = "onmouseover";
+ public static final String ONMOUSEUP_ATTRIBUTE = "onmouseup";
+ public static final String ONRESET_ATTRIBUTE = "onreset";
+ public static final String ONSELECT_ATTRIBUTE = "onselect";
+ public static final String ONSUBMIT_ATTRIBUTE = "onsubmit";
+ public static final String ONUNLOAD_ATTRIBUTE = "onunload";
+
+ // public static final String ONRESET_ATTRIBUTE = "onreset";
+ // attributes sets.
+ public static final String[] PASS_THRU = {
+
+ // DIR_ATTRIBUTE,
+ // LANG_ATTRIBUTE,
+ // STYLE_ATTRIBUTE,
+ // TITLE_ATTRIBUTE
+ "accesskey", "alt", "cols", "height", "lang", "longdesc", "maxlength", "rows", "size", "tabindex", "title",
+ "width", "dir", "rules", "frame", "border", "cellspacing", "cellpadding", "summary", "bgcolor", "usemap",
+ "enctype", "accept-charset", "accept", "target", "charset", "coords", "hreflang", "rel", "rev", "shape",
+ "disabled", "readonly", "ismap", "align"
+ };
+
+ /**
+ * HTML attributes allowed boolean-values only
+ */
+ public static final String[] PASS_THRU_BOOLEAN = {
+ "disabled", "declare", "readonly", "compact", "ismap", "selected", "checked", "nowrap", "noresize",
+ "nohref", "noshade", "multiple"
+ };
+ public static final String[] PASS_THRU_EVENTS = {
+ "onblur", "onchange", "onclick", "ondblclick", "onfocus", "onkeydown", "onkeypress", "onkeyup", "onload",
+ "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onreset", "onselect", "onsubmit",
+ "onunload"
+ };
+ public static final String[] PASS_THRU_STYLES = {"style", "class", };
+
+ /**
+ * all HTML attributes with URI value.
+ */
+ public static final String[] PASS_THRU_URI = {
+ "usemap", "background", "codebase", "cite", "data", "classid", "href", "longdesc", "profile", "src"
+ };
+ public static final String READONLY_ATTRIBUTE = "readonly";
+ public static final String REL_ATTR = "rel";
+ public static final String REV_ATTR = "rev";
+ public static final String ROWS_ATTRIBUTE = "rows";
+ public static final String RULES_ATTRIBUTE = "rules";
+ public static final String SCRIPT_ELEM = "script";
+ public static final String SHAPE_ATTR = "shape";
+ public static final String SIZE_ATTRIBUTE = "size";
+ public static final String SPAN_ELEM = "span";
+ public static final String SRC_ATTRIBUTE = "src";
+ public static final String STYLE_ATTRIBUTE = "style";
+ public static final String STYLE_CLASS_ATTR = "styleClass";
+ public static final String SUMMARY_ATTRIBUTE = "summary";
+ public static final String TABINDEX_ATTRIBUTE = "tabindex";
+ public static final String TABLE_ELEMENT = "table";
+ public static final String TARGET_ATTRIBUTE = "target";
+ public static final String TBOBY_ELEMENT = "tbody";
+ public static final String TD_ELEM = "td";
+ public static final String TEXT_JAVASCRIPT_TYPE = "text/javascript";
+ public static final String TFOOT_ELEMENT = "tfoot";
+ public static final String THEAD_ELEMENT = "thead";
+ public static final String TH_ELEM = "th";
+ public static final String TITLE_ATTRIBUTE = "title";
+ public static final String TITLE_ELEM = "title";
+ public static final String TR_ELEMENT = "tr";
+ public static final String TYPE_ATTR = "type";
+ public static final String USEMAP_ATTRIBUTE = "usemap";
+ public static final String VALIGN_ATTRIBUTE = "valign";
+ public static final String VALUE_ATTRIBUTE = "value";
+ public static final String WIDTH_ATTRIBUTE = "width";
+ }
+}
15 years, 1 month
JBoss Rich Faces SVN: r15949 - in root/examples-sandbox/trunk/components/tables/src/main: webapp and 1 other directory.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2009-11-20 12:15:37 -0500 (Fri, 20 Nov 2009)
New Revision: 15949
Modified:
root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/DataBean.java
root/examples-sandbox/trunk/components/tables/src/main/webapp/home.xhtml
Log:
toggleListener
Modified: root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/DataBean.java
===================================================================
--- root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/DataBean.java 2009-11-20 17:14:19 UTC (rev 15948)
+++ root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/DataBean.java 2009-11-20 17:15:37 UTC (rev 15949)
@@ -7,6 +7,7 @@
import org.richfaces.demo.model.Employee;
import org.richfaces.demo.utils.EmployeeUtils;
+import org.richfaces.event.ToggleEvent;
@ManagedBean(name="dataBean")
@SessionScoped
@@ -26,4 +27,9 @@
return employeeList;
}
+ public void processToggle(ToggleEvent event) {
+ System.out.println("DataBean.processToggle()");
+ }
+
+
}
Modified: root/examples-sandbox/trunk/components/tables/src/main/webapp/home.xhtml
===================================================================
--- root/examples-sandbox/trunk/components/tables/src/main/webapp/home.xhtml 2009-11-20 17:14:19 UTC (rev 15948)
+++ root/examples-sandbox/trunk/components/tables/src/main/webapp/home.xhtml 2009-11-20 17:15:37 UTC (rev 15949)
@@ -29,7 +29,7 @@
<h:outputText id="columnHeader1" value="Column Header Facet"/>
</f:facet>
- <rich:toggleControl forId="expandedSubTable" expandControl="resources/images/+.gif" collapseControl="resources/images/-.gif"/>
+ <rich:toggleControl forId="expandedSubTable" expandControl="resources/images/+.gif" collapseControl="resources/images/-.gif" />
<h:outputText value="#{record.name}" />
<f:facet name="footer">
<h:outputText id="columnFooter1" value="Column Footer Facet"/>
@@ -46,7 +46,7 @@
- <rich:subTable id="expandedSubTable" var="company" value="#{record.company}" rows="20" expanded="true" switchType="client">
+ <rich:subTable id="expandedSubTable" var="company" value="#{record.company}" rows="20" expanded="true" switchType="client" toggleListener="#{dataBean.processToggle}">
<f:facet name="header">
<rich:colGroup id="headerFacet1" >
<rich:column><h:outputText id="headerFacet12" value="company"> </h:outputText></rich:column>
@@ -77,6 +77,7 @@
</f:facet>
</rich:dataTable>
+ <h:commandButton value="submit" />
</h:form>
</h:body>
15 years, 1 month
JBoss Rich Faces SVN: r15948 - in root/ui-sandbox/trunk/components/tables/ui/src/main: java/org/richfaces/component and 6 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2009-11-20 12:14:19 -0500 (Fri, 20 Nov 2009)
New Revision: 15948
Added:
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/Expandable.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/event/
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/event/ToggleEvent.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/event/ToggleListener.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/taglib/
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/taglib/SubTableHandler.java
Modified:
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UISubTable.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UIToggleControl.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/html/HtmlSubTable.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ToggleControlRendererBase.java
root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/resources/toggler.js
root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/tables.taglib.xml
Log:
add toggleEvent support, toggleListener attribute for th subTable
Added: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/Expandable.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/Expandable.java (rev 0)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/Expandable.java 2009-11-20 17:14:19 UTC (rev 15948)
@@ -0,0 +1,21 @@
+package org.richfaces.component;
+
+import javax.el.MethodExpression;
+
+import org.richfaces.event.ToggleListener;
+
+public interface Expandable {
+
+ public boolean isExpanded();
+
+ public void addToggleListener(ToggleListener listener);
+
+ public void removeToggleListener(ToggleListener listener);
+
+ public ToggleListener [] getToggleListeners();
+
+ public void setToggleListener(MethodExpression toggleExpression);
+
+ public MethodExpression getToggleListener();
+
+}
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UISubTable.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UISubTable.java 2009-11-20 17:02:34 UTC (rev 15947)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UISubTable.java 2009-11-20 17:14:19 UTC (rev 15948)
@@ -23,17 +23,23 @@
import java.util.Iterator;
+import javax.el.MethodExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.PhaseId;
import org.ajax4jsf.model.DataVisitor;
+import org.richfaces.event.ToggleEvent;
+import org.richfaces.event.ToggleListener;
/**
* JSF component class
*
*/
-public abstract class UISubTable extends UIDataTableBase implements Row, Column {
+public abstract class UISubTable extends UIDataTableBase implements Row, Column, Expandable{
public static final String COMPONENT_TYPE = "org.richfaces.SubTable";
@@ -47,7 +53,7 @@
enum PropertyKeys {
- switchType, expanded
+ switchType, expanded, toggleExpression
}
@Override
@@ -69,8 +75,7 @@
}
public void setSortExpression(String sortExpression) {
- // Do nothing - subtable is not sortable element;
- //TODO nick - throw exception
+ throw new IllegalArgumentException("subtable is not sortable element");
}
@Override
@@ -91,11 +96,53 @@
getStateHelper().put(PropertyKeys.expanded, expanded);
}
- public boolean getExpanded() {
+ public boolean isExpanded() {
return (Boolean) getStateHelper().eval(PropertyKeys.expanded, Boolean.TRUE);
}
+ public void setToggleListener(MethodExpression toggleExpression) {
+ getStateHelper().put(PropertyKeys.toggleExpression, toggleExpression);
+ }
+
+ public MethodExpression getToggleListener() {
+ return (MethodExpression) getStateHelper().eval(PropertyKeys.toggleExpression);
+ }
+
@Override
+ public void queueEvent(FacesEvent event) {
+ if(event instanceof ToggleEvent) {
+ event.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
+ }
+ super.queueEvent(event);
+ }
+
+ @Override
+ public void broadcast(FacesEvent event) throws AbortProcessingException {
+ super.broadcast(event);
+
+ if(event instanceof ToggleEvent) {
+ ToggleEvent toggleEvent = (ToggleEvent)event;
+
+ MethodExpression expression = getToggleListener();
+ if(expression != null) {
+ expression.invoke(getFacesContext().getELContext(), new Object[]{toggleEvent});
+ }
+ }
+ }
+
+ public void addToggleListener(ToggleListener listener) {
+ addFacesListener(listener);
+ }
+
+ public void removeToggleListener(ToggleListener listener) {
+ removeFacesListener(listener);
+ }
+
+ public ToggleListener [] getToggleListeners() {
+ return (ToggleListener[]) getFacesListeners(ToggleListener.class);
+ }
+
+ @Override
public boolean getRendersChildren() {
//TODO nick - why "false"?
return false;
@@ -157,5 +204,5 @@
public String getColumnFooterSkinClass() {
return "rich-subtable-subfooter-cell";
}
-
+
}
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UIToggleControl.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UIToggleControl.java 2009-11-20 17:02:34 UTC (rev 15947)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/UIToggleControl.java 2009-11-20 17:14:19 UTC (rev 15948)
@@ -1,8 +1,8 @@
package org.richfaces.component;
-import javax.faces.component.UICommand;
+import javax.faces.component.UIComponentBase;
-public abstract class UIToggleControl extends UICommand{
+public abstract class UIToggleControl extends UIComponentBase {
public static final String COMPONENT_TYPE = "org.richfaces.ToggleControl";
@@ -50,5 +50,4 @@
public void setEvent(String event) {
getStateHelper().put(PropertyKeys.event, event);
}
-
}
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/html/HtmlSubTable.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/html/HtmlSubTable.java 2009-11-20 17:02:34 UTC (rev 15947)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/html/HtmlSubTable.java 2009-11-20 17:14:19 UTC (rev 15948)
@@ -3,6 +3,7 @@
import javax.el.MethodExpression;
import org.richfaces.component.UISubTable;
+import org.richfaces.event.ToggleListener;
import org.richfaces.model.Ordering;
public class HtmlSubTable extends UISubTable{
Added: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/event/ToggleEvent.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/event/ToggleEvent.java (rev 0)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/event/ToggleEvent.java 2009-11-20 17:14:19 UTC (rev 15948)
@@ -0,0 +1,32 @@
+package org.richfaces.event;
+
+import javax.faces.component.UIComponent;
+import javax.faces.event.FacesEvent;
+import javax.faces.event.FacesListener;
+
+public class ToggleEvent extends FacesEvent {
+
+ private static final long serialVersionUID = 2916560585918250885L;
+
+ private String state;
+
+
+ public ToggleEvent(UIComponent target, String state) {
+ super(target);
+ this.state = state;
+ }
+
+ public String getState() {
+ return this.state;
+ }
+
+ @Override
+ public boolean isAppropriateListener(FacesListener listener) {
+ return (listener instanceof ToggleListener);
+ }
+
+ @Override
+ public void processListener(FacesListener listener) {
+ ((ToggleListener)listener).processToggle(this);
+ }
+}
Added: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/event/ToggleListener.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/event/ToggleListener.java (rev 0)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/event/ToggleListener.java 2009-11-20 17:14:19 UTC (rev 15948)
@@ -0,0 +1,9 @@
+package org.richfaces.event;
+
+import javax.faces.event.FacesListener;
+
+public interface ToggleListener extends FacesListener {
+
+ public void processToggle(ToggleEvent event);
+
+}
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java 2009-11-20 17:02:34 UTC (rev 15947)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java 2009-11-20 17:14:19 UTC (rev 15948)
@@ -17,7 +17,7 @@
import org.richfaces.component.UISubTable;
@ResourceDependencies( {
- @ResourceDependency(library = "javax.faces", name = "jsf.js"),
+ @ResourceDependency(library = "javax.faces", name = "jsf-uncompressed.js"),
@ResourceDependency(name = "jquery.js"),
@ResourceDependency(name = "richfaces.js"),
@ResourceDependency(name = "datatable.js"),
@@ -25,6 +25,10 @@
})
public class DataTableRenderer extends AbstractTableRenderer implements ElementEncodeListener{
+ @Override
+ protected void doDecode(FacesContext context, UIComponent component) {
+ System.out.println("DataTableRenderer.doDecode()");
+ }
protected void encodeTableStructure(ResponseWriter writer, FacesContext context, UIDataTableBase dataTable) throws IOException {
@@ -133,9 +137,10 @@
if(child instanceof UISubTable) {
UISubTable subTable = (UISubTable)child;
encodeFooter(writer, context, subTable);
-
+// encodeHiddenInput(context, writer, subTable);
+
encodeTableBodyEnd(writer, context, subTable);
-
+
bodyStart = false;
if(iterator.hasNext()) {
encodeTableBodyStart(writer, context, (UIDataTableBase)row);
@@ -182,6 +187,17 @@
encodeTableBodyEnd(writer, context, (UIDataTableBase) row);
}
}
+/*
+ public void encodeHiddenInput(FacesContext context, ResponseWriter writer, UIDataTableBase dataTable) throws IOException {
+
+ String hiddenId = dataTable.getClientId(context) + ":" + "hidden";
+
+ writer.startElement(HTML.INPUT_ELEM, dataTable);
+ writer.writeAttribute(HTML.ID_ATTRIBUTE, hiddenId, null);
+ writer.writeAttribute(HTML.TYPE_ATTR,"hidden", null);
+ writer.endElement(HTML.INPUT_ELEM);
+
+ } */
@Override
protected void doEncodeBegin(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ToggleControlRendererBase.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ToggleControlRendererBase.java 2009-11-20 17:02:34 UTC (rev 15947)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ToggleControlRendererBase.java 2009-11-20 17:14:19 UTC (rev 15948)
@@ -2,6 +2,7 @@
import java.io.IOException;
import java.text.MessageFormat;
+import java.util.Map;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
@@ -11,8 +12,10 @@
import org.ajax4jsf.renderkit.RendererBase;
import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.richfaces.component.Expandable;
import org.richfaces.component.UISubTable;
import org.richfaces.component.UIToggleControl;
+import org.richfaces.event.ToggleEvent;
@ResourceDependencies({
@ResourceDependency(name = "toggler.js")
@@ -33,30 +36,66 @@
private static final String COLLAPSE_STATE = "collapse";
+ private static final String HIDDEN = ":hidden";
+
+ @Override
+ protected void doDecode(FacesContext context, UIComponent component) {
+ if(!(component instanceof UIToggleControl)) {
+ return;
+ }
+
+ UIToggleControl toggle = (UIToggleControl)component;
+
+ Map<String, String> params = context.getExternalContext().getRequestParameterMap();
+
+ String hiddenId = toggle.getClientId() + HIDDEN;
+ String state = params.get(hiddenId);
+
+ if(state != null && state.trim().length()> 0) {
+ UIComponent processed = findComponent(context, toggle);
+ if(processed instanceof Expandable) {
+
+ String prevState = getState(((Expandable)processed).isExpanded());
+ if(!state.equals(prevState)) {
+ new ToggleEvent(processed, state).queue();
+ }
+
+ }
+
+ }
+ }
+
protected void encodeControl(FacesContext context, UIComponent component) throws IOException{
- UIToggleControl toggleControl = (UIToggleControl) component;
- UISubTable subTable = findComponent(context, toggleControl);
- if(subTable != null) {
- ResponseWriter writer = context.getResponseWriter();
-
- String toggleId = toggleControl.getClientId(context);
- String subTableId = subTable.getClientId(context);
- boolean expanded = subTable.getExpanded();
- String initialState = expanded ? EXPAND_STATE : COLLAPSE_STATE;
+
+ if(component instanceof UIToggleControl) {
+ UIToggleControl toggleControl = (UIToggleControl)component;
- String registerScript = MessageFormat.format(MANAGER_SCRIPT, toggleId, subTableId, initialState);
- writer.write(registerScript);
-
- String switchType = subTable.getSwichType();
- encodeControl(context, writer, toggleControl, switchType, expanded, false);
- encodeControl(context, writer, toggleControl, switchType, !expanded, true);
+ UISubTable subTable = findComponent(context, toggleControl);
+ if(subTable != null) {
+ ResponseWriter writer = context.getResponseWriter();
+
+ String toggleId = toggleControl.getClientId(context);
+ String subTableId = subTable.getClientId(context);
+ boolean expanded = subTable.isExpanded();
+ String initialState = getState(expanded);
+
+ String registerScript = MessageFormat.format(MANAGER_SCRIPT, toggleId, subTableId, initialState);
+ writer.write(registerScript);
+
+ String switchType = subTable.getSwichType();
+ encodeControl(context, writer, toggleControl, switchType, expanded, false);
+ encodeControl(context, writer, toggleControl, switchType, !expanded, true);
+ encodeHiddenInput(context, writer, toggleControl);
+
+ }
}
}
protected void encodeControl(FacesContext context, ResponseWriter writer, UIToggleControl control, String switchType, boolean expanded, boolean visible) throws IOException {
- String state = expanded ? EXPAND_STATE: COLLAPSE_STATE;
+ String state = getState(expanded);
+
String image = expanded ? control.getExpandControl() : control.getCollapseControl();
String script = getScript(control, switchType, state);
@@ -88,6 +127,18 @@
writer.endElement(HTML.SPAN_ELEM);
}
+ public void encodeHiddenInput(FacesContext context, ResponseWriter writer, UIComponent component) throws IOException {
+
+ String hiddenId = component.getClientId(context) +HIDDEN;
+
+ writer.startElement(HTML.INPUT_ELEM, component);
+ writer.writeAttribute(HTML.ID_ATTRIBUTE, hiddenId, null);
+ writer.writeAttribute(HTML.NAME_ATTRIBUTE, hiddenId, null);
+ writer.writeAttribute(HTML.TYPE_ATTR,"hidden", null);
+ writer.endElement(HTML.INPUT_ELEM);
+
+ }
+
public String getStyleClass(FacesContext context, UIToggleControl control) {
return null;
}
@@ -127,4 +178,8 @@
return script;
}
+ protected String getState(boolean expand) {
+ return expand ? EXPAND_STATE: COLLAPSE_STATE;
+ }
+
}
Added: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/taglib/SubTableHandler.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/taglib/SubTableHandler.java (rev 0)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/taglib/SubTableHandler.java 2009-11-20 17:14:19 UTC (rev 15948)
@@ -0,0 +1,58 @@
+package org.richfaces.taglib;
+
+import javax.el.MethodExpression;
+import javax.faces.view.facelets.ComponentConfig;
+import javax.faces.view.facelets.ComponentHandler;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.MetaRule;
+import javax.faces.view.facelets.MetaRuleset;
+import javax.faces.view.facelets.Metadata;
+import javax.faces.view.facelets.MetadataTarget;
+import javax.faces.view.facelets.TagAttribute;
+
+import org.richfaces.component.UISubTable;
+
+public class SubTableHandler extends ComponentHandler{
+
+ private static final SubTableHandlerMetaRule metaRule = new SubTableHandlerMetaRule();
+
+ public SubTableHandler(ComponentConfig config) {
+ super(config);
+ }
+
+ @Override
+ protected MetaRuleset createMetaRuleset(Class type) {
+ MetaRuleset m = super.createMetaRuleset(type);
+ m.addRule(metaRule);
+ return m;
+ }
+
+ static class SubTableHandlerMetaRule extends MetaRule {
+
+ @Override
+ public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta) {
+ if(meta.isTargetInstanceOf(UISubTable.class) && "toggleListener".equals(name)) {
+ return new SubTableMapper(attribute);
+ }
+ return null;
+ }
+
+ }
+
+ static class SubTableMapper extends Metadata {
+
+ private static final Class[] SIGNATURE = new Class[] { org.richfaces.event.ToggleEvent.class };
+
+ private final TagAttribute _attribute;
+
+ public SubTableMapper(TagAttribute attribute) {
+ this._attribute = attribute;
+ }
+
+ @Override
+ public void applyMetadata(FaceletContext ctx, Object instance) {
+ MethodExpression methodExpression = _attribute.getMethodExpression(ctx, null, SIGNATURE);
+ ((UISubTable)instance).setToggleListener(methodExpression);
+ }
+ }
+}
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/resources/toggler.js
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/resources/toggler.js 2009-11-20 17:02:34 UTC (rev 15947)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/resources/toggler.js 2009-11-20 17:14:19 UTC (rev 15948)
@@ -2,6 +2,7 @@
this.id = id;
this.forId = forId;
this.state = initialState;
+ this.hidden = id + ":hidden";
}
Toggle.prototype.convertId = function(id) {
@@ -28,9 +29,18 @@
this.command("show", elements);
}
this.state = toState;
+ this.saveState(this.state);
}
}
+Toggle.prototype.saveState= function(state) {
+ var id = this.hidden;
+ var element = this.getElement(id);
+ if(element) {
+ element[0].attr('value', state);
+ }
+}
+
Toggle.prototype.serverToggle = function(toState) {
}
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/tables.taglib.xml
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/tables.taglib.xml 2009-11-20 17:02:34 UTC (rev 15947)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/tables.taglib.xml 2009-11-20 17:14:19 UTC (rev 15948)
@@ -22,6 +22,7 @@
<component>
<component-type>org.richfaces.Column</component-type>
</component>
+
</tag>
<tag>
<tag-name>colGroup</tag-name>
@@ -34,7 +35,8 @@
<tag-name>subTable</tag-name>
<component>
<component-type>org.richfaces.SubTable</component-type>
- <!-- renderer-type>org.richfaces.renderkit.SubTableRenderer</renderer-type-->
+ <!-- renderer-type>org.richfaces.renderkit.SubTableRenderer</renderer-type-->
+ <!-- handler-class>org.richfaces.taglib.SubTableHandler</handler-class -->
</component>
</tag>
<tag>
15 years, 1 month
JBoss Rich Faces SVN: r15947 - in branches/sandbox/3.3.X_JSF2/samples: richfaces-demo and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: amarkhel
Date: 2009-11-20 12:02:34 -0500 (Fri, 20 Nov 2009)
New Revision: 15947
Modified:
branches/sandbox/3.3.X_JSF2/samples/pom.xml
branches/sandbox/3.3.X_JSF2/samples/richfaces-demo/pom.xml
branches/sandbox/3.3.X_JSF2/samples/themes/pom.xml
Log:
Fix build for richfaces-demo
Modified: branches/sandbox/3.3.X_JSF2/samples/pom.xml
===================================================================
--- branches/sandbox/3.3.X_JSF2/samples/pom.xml 2009-11-20 15:37:27 UTC (rev 15946)
+++ branches/sandbox/3.3.X_JSF2/samples/pom.xml 2009-11-20 17:02:34 UTC (rev 15947)
@@ -476,12 +476,12 @@
</profile>
</profiles>
<modules>
- <!--<module>skins</module>
+ <module>skins</module>
<module>laguna</module>
<module>glassX</module>
- <module>darkX</module>-->
+ <module>darkX</module>
<module>richfaces-demo</module>
- <!--<module>themes</module>-->
- <!--<module>violetRays</module>-->
+ <module>themes</module>
+ <module>violetRays</module>
</modules>
</project>
Modified: branches/sandbox/3.3.X_JSF2/samples/richfaces-demo/pom.xml
===================================================================
--- branches/sandbox/3.3.X_JSF2/samples/richfaces-demo/pom.xml 2009-11-20 15:37:27 UTC (rev 15946)
+++ branches/sandbox/3.3.X_JSF2/samples/richfaces-demo/pom.xml 2009-11-20 17:02:34 UTC (rev 15947)
@@ -1,10 +1,14 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>samples</artifactId>
+ <groupId>org.richfaces</groupId>
+ <version>3.3.3-jsf2-SNAPSHOT</version>
+ </parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.richfaces.samples</groupId>
<artifactId>richfaces-demo</artifactId>
- <version>3.3.3-jsf2-SNAPSHOT</version>
<packaging>war</packaging>
<name>richfaces-demo Maven Webapp</name>
@@ -177,23 +181,52 @@
<version>2.0</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>1.2_12</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ <version>1.2_12</version>
+ <scope>runtime</scope>
+ </dependency>
</dependencies>
</profile>
- </profiles>
- <dependencies>
- <dependency>
+ <profile>
+ <id>jsf2</id>
+ <dependencies>
+ <dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.0.1</version>
- </dependency><dependency>
+ <exclusions>
+ <exclusion>
+ <artifactId>javax.el</artifactId>
+ <groupId>el-api</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.0.1</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>javax.el</artifactId>
+ <groupId>el-api</groupId>
+ </exclusion>
+ </exclusions>
</dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+ <dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
- <version>3.1.0.CR1</version>
+ <version>3.1.0.GA</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@@ -201,6 +234,21 @@
<version>1.4.2</version>
</dependency>
<dependency>
+ <groupId>org.richfaces.samples</groupId>
+ <artifactId>laguna</artifactId>
+ <version>3.3.3-jsf2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.samples</groupId>
+ <artifactId>glassX</artifactId>
+ <version>3.3.3-jsf2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.samples</groupId>
+ <artifactId>darkX</artifactId>
+ <version>3.3.3-jsf2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-ui</artifactId>
<version>3.3.3-jsf2-SNAPSHOT</version>
@@ -237,6 +285,12 @@
<artifactId>nekohtml</artifactId>
<version>0.9.5</version>
<scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <artifactId>xerces</artifactId>
+ <groupId>xerces</groupId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
@@ -264,7 +318,7 @@
<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-seam</artifactId>
- <version>2.1.0.SP1</version>
+ <version>2.2.0.GA</version>
<exclusions>
<exclusion>
<groupId>org.richfaces.framework</groupId>
@@ -283,8 +337,18 @@
<groupId>javax.servlet</groupId>
</exclusion>
</exclusions>
- </dependency>
+ </dependency>
<dependency>
+ <groupId>org.richfaces.samples</groupId>
+ <artifactId>themes</artifactId>
+ <version>3.3.3-jsf2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.samples</groupId>
+ <artifactId>violetRays</artifactId>
+ <version>3.3.3-jsf2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
@@ -313,7 +377,7 @@
<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-seam-ui</artifactId>
- <version>2.1.0.SP1</version>
+ <version>2.2.0.GA</version>
<exclusions>
<exclusion>
<artifactId>jsf-api</artifactId>
@@ -328,7 +392,7 @@
<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-seam-debug</artifactId>
- <version>2.1.0.SP1</version>
+ <version>2.2.0.GA</version>
<exclusions>
<exclusion>
<artifactId>jsf-api</artifactId>
@@ -354,19 +418,12 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
- <version>3.3.0.ga</version>
+ <version>3.4.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
- <artifactId>hibernate</artifactId>
- <version>3.2.6.ga</version>
-
- <exclusions>
- <exclusion>
- <artifactId>commons-collections</artifactId>
- <groupId>commons-collections</groupId>
- </exclusion>
- </exclusions>
+ <artifactId>hibernate-core</artifactId>
+ <version>3.3.2.GA</version>
</dependency>
</dependencies>
</project>
Modified: branches/sandbox/3.3.X_JSF2/samples/themes/pom.xml
===================================================================
--- branches/sandbox/3.3.X_JSF2/samples/themes/pom.xml 2009-11-20 15:37:27 UTC (rev 15946)
+++ branches/sandbox/3.3.X_JSF2/samples/themes/pom.xml 2009-11-20 17:02:34 UTC (rev 15947)
@@ -25,7 +25,19 @@
</goals>
</execution>
</executions>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
</plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
</plugins>
</build>
<dependencies>
15 years, 1 month
JBoss Rich Faces SVN: r15946 - in root/ui-sandbox/trunk/components/tables/ui/src/main: java/org/richfaces/renderkit and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: konstantin.mishin
Date: 2009-11-20 10:37:27 -0500 (Fri, 20 Nov 2009)
New Revision: 15946
Added:
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/RowHolderBase.java
Modified:
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/html/HtmlExtendedDataTable.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/AbstractRowsRenderer.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ExtendedDataTableRenderer.java
root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/RowHolder.java
root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/resources/extendedDataTable.js
Log:
RF-7871
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/html/HtmlExtendedDataTable.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/html/HtmlExtendedDataTable.java 2009-11-20 15:37:21 UTC (rev 15945)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/component/html/HtmlExtendedDataTable.java 2009-11-20 15:37:27 UTC (rev 15946)
@@ -27,7 +27,7 @@
public static final String COMPONENT_TYPE = "org.richfaces.ExtendedDataTable";
- private static enum PropertyKeys {style, styleClass}
+ private static enum PropertyKeys {style, styleClass, frozenColumns}
public HtmlExtendedDataTable() {
setRendererType("org.richfaces.ExtendedDataTableRenderer");
@@ -49,14 +49,14 @@
getStateHelper().put(PropertyKeys.styleClass, styleClass);
}
-// public String getWidth() {
-// return (String) getStateHelper().eval(PropertyKeys.width, "");
-// }
+ public Integer getFrozenColumns() {
+ return (Integer) getStateHelper().eval(PropertyKeys.frozenColumns, 0);
+ }
+
+ public void setFrozenColumns(Integer frozenColumns) {
+ getStateHelper().put(PropertyKeys.frozenColumns, frozenColumns);
+ }
//
-// public void setWidth(String width) {
-// getStateHelper().put(PropertyKeys.width, width);
-// }
-//
// public String getHeight() {
// return (String) getStateHelper().eval(PropertyKeys.height, "");
// }
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/AbstractRowsRenderer.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/AbstractRowsRenderer.java 2009-11-20 15:37:21 UTC (rev 15945)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/AbstractRowsRenderer.java 2009-11-20 15:37:27 UTC (rev 15946)
@@ -29,7 +29,6 @@
import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.renderkit.RendererBase;
import org.richfaces.component.Row;
-import org.richfaces.component.UIDataTableBase;
/**
* @author shura
@@ -50,31 +49,24 @@
*/
- public abstract void encodeRow(FacesContext context, RowHolder rowHolder) throws IOException;
+ public abstract void encodeRow(RowHolderBase rowHolder) throws IOException;
public DataVisitResult process(FacesContext context, Object rowKey, Object argument) {
- RowHolder holder = (RowHolder) argument;
+ RowHolderBase holder = (RowHolderBase) argument;
Row row = holder.getRow();
row.setRowKey(context, rowKey);
try {
- encodeRow(context, holder);
+ encodeRow(holder);
} catch (IOException e) {
//TODO: seems we need add throws IOException ???
}
-
holder.nextRow();
return DataVisitResult.CONTINUE;
}
- //TODO remove
- public void encodeRows(FacesContext facesContext, UIDataTableBase table) throws IOException {
- RowHolder rowHolder = new RowHolder(table);
- encodeRows(facesContext, table, rowHolder);
+ protected void encodeRows(RowHolderBase rowHolder) throws IOException {
+ rowHolder.getRow().walk(rowHolder.getContext(), this, rowHolder);
}
-
- protected void encodeRows(FacesContext context, Row table, RowHolder rowHolder) throws IOException {
- table.walk(context, this, rowHolder);
- }
public boolean getRendersChildren() {
return true;
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java 2009-11-20 15:37:21 UTC (rev 15945)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/DataTableRenderer.java 2009-11-20 15:37:27 UTC (rev 15946)
@@ -64,18 +64,19 @@
public void encodeRows(FacesContext context, UIDataTableBase dataTable) throws IOException {
- RowHolder holder = new RowHolder(dataTable);
+ RowHolder holder = new RowHolder(context, dataTable);
holder.setCellClass(dataTable.getCellSkinClass());
holder.setRowClass(dataTable.getRowSkinClass());
holder.setFirstRowClass(dataTable.getFirstRowSkinClass());
holder.setHeaderRow(false);
holder.setCellElement(HTML.TD_ELEM);
- encodeRows(context, dataTable, holder);
+ encodeRows(holder);
}
//TODO: refactor
- public void encodeRow(FacesContext context, RowHolder rowHolder) throws IOException {
-
+ public void encodeRow(RowHolderBase holder) throws IOException {
+ FacesContext context = holder.getContext();
+ RowHolder rowHolder = (RowHolder) holder;
boolean rowStart = true;
boolean bodyStart = false;
@@ -99,7 +100,7 @@
if(child instanceof Row) {
Row childRow = (Row)child;
- RowHolder childRowHolder = new RowHolder(childRow);
+ RowHolder childRowHolder = new RowHolder(context, childRow);
childRowHolder.setCurrentRow(processRow);
childRowHolder.setCellElement(rowHolder.getCellElement());
@@ -127,7 +128,7 @@
encodeTableBodyStart(writer, context, subTable);
encodeHeader(writer, context, subTable);
}
- encodeRows(context, childRow, childRowHolder);
+ encodeRows(childRowHolder);
if(child instanceof UISubTable) {
UISubTable subTable = (UISubTable)child;
@@ -180,7 +181,6 @@
if(bodyStart && rowHolder.isDataTable()) {
encodeTableBodyEnd(writer, context, (UIDataTableBase) row);
}
-
}
@Override
@@ -427,7 +427,7 @@
if(footer instanceof Row) {
Row row = (Row)footer;
- RowHolder holder = new RowHolder(row);
+ RowHolder holder = new RowHolder(context, row);
holder.setCellElement(element);
holder.setFirstRowClass(skinFirstRowClass);
holder.setRowClass(skinRowClass);
@@ -435,7 +435,7 @@
//holder.resetCurrentRow();
holder.setHeaderRow(true);
- encodeRows(context, row, holder);
+ encodeRows(holder);
} else {
writer.startElement(HTML.TR_ELEMENT, footer);
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ExtendedDataTableRenderer.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ExtendedDataTableRenderer.java 2009-11-20 15:37:21 UTC (rev 15945)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/ExtendedDataTableRenderer.java 2009-11-20 15:37:27 UTC (rev 15946)
@@ -22,7 +22,9 @@
package org.richfaces.renderkit;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
@@ -43,6 +45,64 @@
})
public class ExtendedDataTableRenderer extends AbstractTableRenderer {
+ private class RendererState extends RowHolderBase{
+
+ private UIDataTableBase table;
+ private List<UIComponent> frozenColumns;
+ private List<UIComponent> columns;
+ private boolean frozen;
+
+ public RendererState(FacesContext context, UIDataTableBase table) {
+ super(context);
+ this.table = table;
+ int count = getFrozenColumnsCount();
+ frozenColumns = new ArrayList<UIComponent>();
+ columns = new ArrayList<UIComponent>();
+ Iterator<UIComponent> iterator = table.columns();
+ for (; iterator.hasNext() && count > 0; count--) {
+ UIComponent component = iterator.next();
+ if(component.isRendered()) {
+ frozenColumns.add(component);
+ }
+ }
+ for (; iterator.hasNext();) {
+ UIComponent component = iterator.next();
+ if(component.isRendered()) {
+ columns.add(component);
+ }
+ }
+ }
+
+ private int getFrozenColumnsCount() {
+ int count = ((Integer) table.getAttributes().get("frozenColumns")).intValue();
+ int columnsCount = getColumnsCount(table);
+ if (count > columnsCount) {
+ count = columnsCount;
+ }
+ return count;
+ }
+
+ public UIDataTableBase getRow() {
+ return table;
+ }
+
+ public List<UIComponent> getFrozenColumns() {
+ return frozenColumns;
+ }
+
+ public List<UIComponent> getColumns() {
+ return columns;
+ }
+
+ public void setFrozen(boolean frozen) {
+ this.frozen = frozen;
+ }
+
+ public boolean isFrozen() {
+ return frozen;
+ }
+ }
+
@Override
protected Class<? extends UIComponent> getComponentClass() {
return UIDataTableBase.class;
@@ -65,10 +125,12 @@
Object key = table.getRowKey();
table.captureOrigValue(context);
table.setRowKey(context, null);
- encodeStyle(writer, context, table);
- encodeHeaderOrFooter(writer, context, table, "header");
- encodeBody(writer, context, table);
- encodeHeaderOrFooter(writer, context, table, "footer");
+ RendererState state = new RendererState(context, table);
+ //TODO encodeCaption(context, table);
+ encodeStyle(state);
+ encodeHeaderOrFooter(state, "header");
+ encodeBody(state);
+ encodeHeaderOrFooter(state, "footer");
table.setRowKey(context,key);
table.restoreOrigValue(context);
}
@@ -83,27 +145,35 @@
writer.endElement(HTML.DIV_ELEM);
}
- private void encodeStyle(ResponseWriter writer, FacesContext context,
- UIDataTableBase table) throws IOException {
+ private void encodeStyle(RendererState state) throws IOException {
+ FacesContext context = state.getContext();
+ ResponseWriter writer = context.getResponseWriter();
+ UIDataTableBase table = state.getRow();
writer.startElement("style", table);
writer.writeAttribute(HTML.TYPE_ATTR, "text/css", null);
writer.writeText(".rich-extable-part-width{", null); //TODO getNormalizedId(context, state.getGrid())
writer.writeText("width: 100%;", "width");
writer.writeText("}", null);
- int columnIndex = 0;
Iterator<UIComponent> columns = table.columns();
while (columns.hasNext()) {
UIComponent column = (UIComponent) columns.next();
+ String id = column.getId();
+ if (id == null) {
+ column.getClientId(context); // hack initialize id
+ id = column.getId();
+ }
String width = getColumnWidth(column);
- writer.writeText(".rich-extable-cell-width-" + columnIndex++ + " {", "width"); //TODO getNormalizedId(context, state.getGrid())
+ writer.writeText(".rich-extable-cell-width-" + id + " {", "width"); //TODO getNormalizedId(context, state.getGrid())
writer.writeText("width: " + width + ";", "width");
writer.writeText("}", "width");
}
writer.endElement("style");
}
- private void encodeHeaderOrFooter(ResponseWriter writer, FacesContext context,
- UIDataTableBase table, String name) throws IOException {
+ private void encodeHeaderOrFooter(RendererState state, String name) throws IOException {
+ FacesContext context = state.getContext();
+ ResponseWriter writer = context.getResponseWriter();
+ UIDataTableBase table = state.getRow();
if (isColumnFacetPresent(table, name)) {
writer.startElement(HTML.DIV_ELEM, table);
writer.writeAttribute(HTML.CLASS_ATTRIBUTE, HtmlUtil.concatClasses("rich-extable-" + name, (String)table.getAttributes().get(name + "Class")), null);
@@ -112,61 +182,76 @@
writer.writeAttribute(HTML.CELLSPACING_ATTRIBUTE, "0", null);
writer.startElement(HTML.TBOBY_ELEMENT, table);
writer.startElement(HTML.TR_ELEMENT, table);
- int columnIndex = 0;
- Iterator<UIComponent> columns = table.columns();
- writer.startElement(HTML.TD_ELEM, table);
- writer.startElement(HTML.DIV_ELEM, table);
- writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) + ":n" + name.charAt(0) + "pe", null);
- writer.writeAttribute(HTML.CLASS_ATTRIBUTE, "rich-extable" + ("footer".equals(name) ? "-footer" : "") + "-part rich-extable-part-width", null);
- writer.startElement(HTML.TABLE_ELEMENT, table);
- writer.writeAttribute(HTML.CELLPADDING_ATTRIBUTE, "0", null);
- writer.writeAttribute(HTML.CELLSPACING_ATTRIBUTE, "0", null);
- writer.startElement(HTML.TBOBY_ELEMENT, table);
- writer.startElement(HTML.TR_ELEMENT, table);
- while (columns.hasNext()) {
- encodeHeaderOrFooterCell(context, writer, columns.next(), "rich-extable-" + name + "-cell", "rich-extable-cell-width-" + columnIndex++, name);
+ Iterator<UIComponent> columns = state.getFrozenColumns().iterator();
+ for (int i = 0; i < 2; i++) {
+ if (columns.hasNext()) {
+ writer.startElement(HTML.TD_ELEM, table);
+ writer.startElement(HTML.DIV_ELEM, table);
+ if (i == 0) {
+ if ("header".equals(name)) {
+ writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) + ":frozenHeader", null);
+ }
+ } else {
+ writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) + ":" + name, null);
+ writer.writeAttribute(HTML.CLASS_ATTRIBUTE, "rich-extable" + ("footer".equals(name) ? "-footer" : "") + "-part rich-extable-part-width", null);
+ }
+ writer.startElement(HTML.TABLE_ELEMENT, table);
+ writer.writeAttribute(HTML.CELLPADDING_ATTRIBUTE, "0", null);
+ writer.writeAttribute(HTML.CELLSPACING_ATTRIBUTE, "0", null);
+ writer.startElement(HTML.TBOBY_ELEMENT, table);
+ writer.startElement(HTML.TR_ELEMENT, table);
+ while (columns.hasNext()) {
+ encodeHeaderOrFooterCell(context, writer, columns.next(), name);
+ }
+ writer.endElement(HTML.TR_ELEMENT);
+ writer.endElement(HTML.TBOBY_ELEMENT);
+ writer.endElement(HTML.TABLE_ELEMENT);
+ writer.endElement(HTML.DIV_ELEM);
+ writer.endElement(HTML.TD_ELEM);
+ }
+ columns = state.getColumns().iterator();
}
writer.endElement(HTML.TR_ELEMENT);
writer.endElement(HTML.TBOBY_ELEMENT);
writer.endElement(HTML.TABLE_ELEMENT);
writer.endElement(HTML.DIV_ELEM);
- writer.endElement(HTML.TD_ELEM);
- writer.endElement(HTML.TR_ELEMENT);
- writer.endElement(HTML.TBOBY_ELEMENT);
- writer.endElement(HTML.TABLE_ELEMENT);
- writer.endElement(HTML.DIV_ELEM);
}
}
- private void encodeBody(ResponseWriter writer, FacesContext context,
- UIDataTableBase table) throws IOException {
+ private void encodeBody(RendererState state) throws IOException {
+ FacesContext context = state.getContext();
+ ResponseWriter writer = context.getResponseWriter();
+ UIDataTableBase table = state.getRow();
writer.startElement(HTML.DIV_ELEM, table);
writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) + ":b", null);
writer.writeAttribute(HTML.CLASS_ATTRIBUTE, "rich-extable-body", null);
writer.startElement(HTML.DIV_ELEM, table);
- writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) + ":c", null);
writer.startElement(HTML.DIV_ELEM, table);
writer.endElement(HTML.DIV_ELEM);
writer.startElement(HTML.TABLE_ELEMENT, table);
writer.writeAttribute(HTML.CELLPADDING_ATTRIBUTE, "0", null);
writer.writeAttribute(HTML.CELLSPACING_ATTRIBUTE, "0", null);
writer.startElement(HTML.TBOBY_ELEMENT, table);
- writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) + ":tb", null);
writer.startElement(HTML.TR_ELEMENT, table);
- writer.startElement(HTML.TD_ELEM, table);
- writer.startElement(HTML.DIV_ELEM, table);
- writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) + ":nbpe", null);
- writer.writeAttribute(HTML.CLASS_ATTRIBUTE, "rich-extable-part rich-extable-part-width", null);
- writer.startElement(HTML.TABLE_ELEMENT, table);
- writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) + ":nbte", null);
- writer.writeAttribute(HTML.CELLPADDING_ATTRIBUTE, "0", null);
- writer.writeAttribute(HTML.CELLSPACING_ATTRIBUTE, "0", null);
- writer.startElement(HTML.TBOBY_ELEMENT, table);
- encodeRows(context, table);
- writer.endElement(HTML.TBOBY_ELEMENT);
- writer.endElement(HTML.TABLE_ELEMENT);
- writer.endElement(HTML.DIV_ELEM);
- writer.endElement(HTML.TD_ELEM);
+ state.setFrozen(true);
+ for (int i = 0; i < 2; i++) { //TODO Empty frozen part shouldn't be rendered
+ writer.startElement(HTML.TD_ELEM, table);
+ writer.startElement(HTML.DIV_ELEM, table);
+ if (i == 1) {
+ writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context) + ":body", null);
+ writer.writeAttribute(HTML.CLASS_ATTRIBUTE, "rich-extable-part rich-extable-part-width", null);
+ }
+ writer.startElement(HTML.TABLE_ELEMENT, table);
+ writer.writeAttribute(HTML.CELLPADDING_ATTRIBUTE, "0", null);
+ writer.writeAttribute(HTML.CELLSPACING_ATTRIBUTE, "0", null);
+ writer.startElement(HTML.TBOBY_ELEMENT, table);
+ table.walk(context, this, state); //TODO encodeRows(context, table);
+ writer.endElement(HTML.TBOBY_ELEMENT);
+ writer.endElement(HTML.TABLE_ELEMENT);
+ writer.endElement(HTML.DIV_ELEM);
+ writer.endElement(HTML.TD_ELEM);
+ state.setFrozen(false);
+ }
writer.endElement(HTML.TR_ELEMENT);
writer.endElement(HTML.TBOBY_ELEMENT);
writer.endElement(HTML.TABLE_ELEMENT);
@@ -175,14 +260,13 @@
}
private void encodeHeaderOrFooterCell(FacesContext context, ResponseWriter writer,
- UIComponent column, String skinCellClass, String widthCellClass,
- String facetName) throws IOException {
+ UIComponent column, String facetName) throws IOException {
if (column.isRendered()) {
String classAttribute = facetName + "Class";
writer.startElement(HTML.TD_ELEM, column);
writer.startElement(HTML.DIV_ELEM, column);
- writer.writeAttribute(HTML.CLASS_ATTRIBUTE, HtmlUtil.concatClasses(skinCellClass, widthCellClass,
+ writer.writeAttribute(HTML.CLASS_ATTRIBUTE, HtmlUtil.concatClasses("rich-extable-" + facetName + "-cell", "rich-extable-cell-width-" + column.getId(),
(String) column.getAttributes().get(classAttribute)), null);
@@ -197,20 +281,25 @@
}
@Override
- public void encodeRow(FacesContext context, RowHolder rowHolder)
- throws IOException {
+ public void encodeRow(RowHolderBase rowHolder) throws IOException {
+ FacesContext context = rowHolder.getContext();
ResponseWriter writer = context.getResponseWriter();
- UIDataTableBase table = (UIDataTableBase) rowHolder.getRow(); //TODO Don't use cast this
+ RendererState state = (RendererState)rowHolder;
+ UIDataTableBase table = state.getRow();
writer.startElement(HTML.TR_ELEMENT, table);
writer.writeAttribute(HTML.ID_ATTRIBUTE, table.getClientId(context), null);
- Iterator<UIComponent> columns = table.columns();
- int columnIndex = 0;
+ Iterator<UIComponent> columns = null;
+ if (state.isFrozen()) {
+ columns = state.getFrozenColumns().iterator();
+ } else {
+ columns = state.getColumns().iterator();
+ }
while (columns.hasNext()) {
UIComponent column = (UIComponent) columns.next();
if (column.isRendered()) {
writer.startElement(HTML.TD_ELEM, table);
writer.startElement(HTML.DIV_ELEM, table);
- writer.writeAttribute(HTML.CLASS_ATTRIBUTE, "rich-extable-cell rich-extable-cell-width-" + columnIndex++, null);
+ writer.writeAttribute(HTML.CLASS_ATTRIBUTE, "rich-extable-cell rich-extable-cell-width-" + column.getId(), null);
renderChildren(context, column);
writer.endElement(HTML.DIV_ELEM);
writer.endElement(HTML.TD_ELEM);
@@ -226,5 +315,4 @@
}
return width;
}
-
}
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/RowHolder.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/RowHolder.java 2009-11-20 15:37:21 UTC (rev 15945)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/RowHolder.java 2009-11-20 15:37:27 UTC (rev 15946)
@@ -1,14 +1,14 @@
package org.richfaces.renderkit;
+import javax.faces.context.FacesContext;
+
import org.richfaces.component.Row;
import org.richfaces.component.UIColumnGroup;
import org.richfaces.component.UIDataTable;
import org.richfaces.component.UISubTable;
-public class RowHolder {
+public class RowHolder extends RowHolderBase{
- private int currentRow = 0;
-
private String cellElement;
private String cellClass;
@@ -30,26 +30,11 @@
private Row row;
- public RowHolder(Row row) {
+ public RowHolder(FacesContext context, Row row) {
+ super(context);
this.row = row;
}
- public int getCurrentRow() {
- return currentRow;
- }
-
- public int nextRow() {
- return ++currentRow;
- }
-
- public void setCurrentRow(int currentRow) {
- this.currentRow = currentRow;
- }
-
- public void resetCurrentRow() {
- this.currentRow = 0;
- }
-
public String getCellClass() {
return this.cellClass;
}
Added: root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/RowHolderBase.java
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/RowHolderBase.java (rev 0)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/java/org/richfaces/renderkit/RowHolderBase.java 2009-11-20 15:37:27 UTC (rev 15946)
@@ -0,0 +1,39 @@
+package org.richfaces.renderkit;
+
+import javax.faces.context.FacesContext;
+
+import org.richfaces.component.Row;
+
+public abstract class RowHolderBase {
+
+ private FacesContext context;
+
+ private int currentRow = 0;
+
+ public RowHolderBase(FacesContext context) {
+ this.context = context;
+ }
+
+ public FacesContext getContext() {
+ return context;
+ }
+
+ public abstract Row getRow();
+
+ public int getCurrentRow() {
+ return currentRow;
+ }
+
+ public int nextRow() {
+ return ++currentRow;
+ }
+
+ public void setCurrentRow(int currentRow) {
+ this.currentRow = currentRow;
+ }
+
+ public void resetCurrentRow() {
+ this.currentRow = 0;
+ }
+}
+
Modified: root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/resources/extendedDataTable.js
===================================================================
--- root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/resources/extendedDataTable.js 2009-11-20 15:37:21 UTC (rev 15945)
+++ root/ui-sandbox/trunk/components/tables/ui/src/main/resources/META-INF/resources/extendedDataTable.js 2009-11-20 15:37:27 UTC (rev 15946)
@@ -37,18 +37,18 @@
richfaces.ExtendedDataTable = function(id) {
var element = document.getElementById(id);
var bodyElement = document.getElementById(id + ":b");
- var contentElement = document.getElementById(id + ":c");
+ var contentElement = bodyElement.firstChild;//TODO Richfaces.firstDescendant;
var marginElement = contentElement.firstChild;//TODO this.marginElement = Richfaces.firstDescendant(this.contentElement);
var dataTableElement = contentElement.lastChild;//TODO this.dataTableElement = Richfaces.lastDescendant(this.contentElement);
- var frozenHeaderPartElement = document.getElementById(id + ":fhpe");
+ var frozenHeaderPartElement = document.getElementById(id + ":frozenHeader");
var normalPartStyle = richfaces.getCSSRule(".rich-extable-part-width").style;
- var idSuffixs = [":nhpe", ":nbpe", ":nfpe"];
+ var idSuffixs = [":header", ":body", ":footer"];
+ var rows = document.getElementById(id + idSuffixs[1]).firstChild.rows.length;//TODO Richfaces.firstDescendant;
+
var scrollElement = document.getElementById(id + idSuffixs[2]);
- var rows = document.getElementById(id + ":nbte").rows.length;
-
var updateLayout = function() {
var offsetWidth = frozenHeaderPartElement ? frozenHeaderPartElement.offsetWidth : 0;
normalPartStyle.width = element.clientWidth - offsetWidth + "px";
15 years, 1 month
JBoss Rich Faces SVN: r15945 - root/examples-sandbox/trunk/components/tables/src/main/webapp.
by richfaces-svn-commits@lists.jboss.org
Author: konstantin.mishin
Date: 2009-11-20 10:37:21 -0500 (Fri, 20 Nov 2009)
New Revision: 15945
Modified:
root/examples-sandbox/trunk/components/tables/src/main/webapp/extendedtable.xhtml
Log:
RF-7852 ExtendedDataTable sample
Modified: root/examples-sandbox/trunk/components/tables/src/main/webapp/extendedtable.xhtml
===================================================================
--- root/examples-sandbox/trunk/components/tables/src/main/webapp/extendedtable.xhtml 2009-11-20 15:16:08 UTC (rev 15944)
+++ root/examples-sandbox/trunk/components/tables/src/main/webapp/extendedtable.xhtml 2009-11-20 15:37:21 UTC (rev 15945)
@@ -36,13 +36,14 @@
@charset "utf-8";
.extendedDataTable{
width:500px;
+ height: 1000px;
}
</style>
</h:head>
<h:body>
<h:form id="form1">
- <rich:extendedDataTable var="record" value="#{dataBean.employeeList}" styleClass="extendedDataTable">
+ <rich:extendedDataTable frozenColumns="1" var="record" value="#{dataBean.employeeList}" styleClass="extendedDataTable">
<rich:column id="column_name">
<f:facet name="header">
<h:outputText id="columnHeader1" value="Column Header Facet"/>
15 years, 1 month