Author: nbelaevski
Date: 2009-03-13 11:04:32 -0400 (Fri, 13 Mar 2009)
New Revision: 12954
Added:
trunk/ui/columns/src/main/java/org/richfaces/taglib/RequestUniqueIdGenerator.java
Modified:
trunk/ui/columns/src/main/java/org/richfaces/taglib/ColumnsHandler.java
trunk/ui/columns/src/main/java/org/richfaces/taglib/ColumnsTag.java
Log:
https://jira.jboss.org/jira/browse/RF-6031
Modified: trunk/ui/columns/src/main/java/org/richfaces/taglib/ColumnsHandler.java
===================================================================
--- trunk/ui/columns/src/main/java/org/richfaces/taglib/ColumnsHandler.java 2009-03-13
14:15:02 UTC (rev 12953)
+++ trunk/ui/columns/src/main/java/org/richfaces/taglib/ColumnsHandler.java 2009-03-13
15:04:32 UTC (rev 12954)
@@ -28,7 +28,6 @@
package org.richfaces.taglib;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
@@ -40,20 +39,24 @@
import javax.el.VariableMapper;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
import javax.servlet.jsp.JspTagException;
-import org.richfaces.component.UIColumn;
import org.richfaces.el.ELBuilder;
import org.richfaces.iterator.ForEachIterator;
import org.richfaces.iterator.SimpleForEachIterator;
import com.sun.facelets.FaceletContext;
+import com.sun.facelets.FaceletHandler;
import com.sun.facelets.tag.MetaRule;
import com.sun.facelets.tag.MetaRuleset;
import com.sun.facelets.tag.MetaTagHandler;
import com.sun.facelets.tag.Metadata;
import com.sun.facelets.tag.MetadataTarget;
+import com.sun.facelets.tag.Tag;
import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.TagAttributes;
import com.sun.facelets.tag.jsf.ComponentConfig;
@@ -65,91 +68,154 @@
*
*/
public class ColumnsHandler extends MetaTagHandler {
-
- com.sun.facelets.tag.jsf.ComponentHandler handler;
-
- static final String DYNAMIC_COLUMN_MARKER = "_richfaces_columns";
-
- /** value attribute */
- private TagAttribute value;
- /** end attribute */
- private TagAttribute columns;
+ com.sun.facelets.tag.jsf.ComponentHandler handler;
- /** begin attribute */
- private TagAttribute begin;
+ private static final String ITERATION_INDEX_VARIABLE =
"__richfaces_iteration_index_variable";
+
+ private static final String ITERATION_INDEX_EXPRESSION = "#{" +
ITERATION_INDEX_VARIABLE + "}";
- /** var attribute */
- private TagAttribute var;
+ private static final String F_GENERATION_SERIES_ATTRIBUTE =
"org.richfaces.F_COLUMNS_GENERATION_SERIES";
- /** index attribute */
- private TagAttribute index;
+ /** value attribute */
+ private TagAttribute value;
- /** end attribute */
- private TagAttribute end;
-
- /** rendered attribute */
- private boolean rendered = true;
+ /** end attribute */
+ private TagAttribute columns;
- class IterationContext {
-
- /** Iterator for columns's tag value attribute */
- public ForEachIterator items; // our 'digested' items
-
- /** Value attribute value */
- public Object rawItems; // our 'raw' items
-
- /** Var attr - defines page variable for current item */
- public String _indexId;
-
- /** Integer value begin attr */
- public Integer _begin;
-
- /** Integer value end attr */
- public Integer _end;
-
- /** Integer value of end attr. */
- public Integer _columns;
-
- /** String value of var attr */
- public String _itemId = null;
-
- /** Current column counter */
- public Integer _index = 0;
-
- /** Expression for var item */
- public IteratedExpression iteratedExpression;
-
- public String valueExpr;
-
- public String getVarReplacement() {
- if (valueExpr == null) {
- return String.valueOf(index);
- }else if (items.getVarReplacement() != null) {
- return items.getVarReplacement();
- }
- return valueExpr + "[" + _index + "]";
- }
-
- public String getIndexReplacement() {
- return String.valueOf(_index);
- }
- };
-
- ThreadLocal<IterationContext> iterationContextLocal = new
ThreadLocal<IterationContext>();
-
- public IterationContext getIterationContext() {
- return iterationContextLocal.get();
- }
+ /** begin attribute */
+ private TagAttribute begin;
- /**
- * TODO Description goes here.
- *
- * @param config
- */
- public ColumnsHandler(ComponentConfig config) {
- super(config);
- handler = new ColumnTagHandler(config) {
+ /** var attribute */
+ private TagAttribute var;
+
+ /** index attribute */
+ private TagAttribute index;
+
+ /** end attribute */
+ private TagAttribute end;
+
+ /** rendered attribute */
+ private boolean rendered = true;
+
+ class IterationContext {
+
+ /** Iterator for columns's tag value attribute */
+ public ForEachIterator items; // our 'digested' items
+
+ /** Value attribute value */
+ public Object rawItems; // our 'raw' items
+
+ /** Var attr - defines page variable for current item */
+ public String _indexId;
+
+ /** Integer value begin attr */
+ public Integer _begin;
+
+ /** Integer value end attr */
+ public Integer _end;
+
+ /** Integer value of end attr. */
+ public Integer _columns;
+
+ /** String value of var attr */
+ public String _itemId = null;
+
+ /** Current column counter */
+ public Integer _index = 0;
+
+ /** Expression for var item */
+ public IteratedExpression iteratedExpression;
+
+ public String valueExpr;
+
+ public String getVarReplacement() {
+ if (valueExpr == null) {
+ return String.valueOf(index);
+ }else if (items.getVarReplacement() != null) {
+ return items.getVarReplacement();
+ }
+ return valueExpr + "[" + _index + "]";
+ }
+
+ public String getIndexReplacement() {
+ return String.valueOf(_index);
+ }
+ };
+
+ ThreadLocal<IterationContext> iterationContextLocal = new
ThreadLocal<IterationContext>();
+
+ public IterationContext getIterationContext() {
+ return iterationContextLocal.get();
+ }
+
+ /**
+ * TODO Description goes here.
+ *
+ * @param config
+ */
+ public ColumnsHandler(final ComponentConfig config) {
+ super(config);
+
+ final ComponentConfig columnConfig;
+
+ TagAttribute idAttribute = config.getTag().getAttributes().get("id");
+ if (idAttribute != null && idAttribute.isLiteral()) {
+ columnConfig = new ComponentConfig() {
+
+ private Tag tag;
+
+ {
+ Tag initialTag = config.getTag();
+ TagAttribute[] allInitialAttributes = initialTag.getAttributes().getAll();
+ TagAttribute[] attributes = new TagAttribute[allInitialAttributes.length];
+ for (int i = 0; i < allInitialAttributes.length; i++) {
+ TagAttribute initialAttribute = allInitialAttributes[i];
+ String localName = initialAttribute.getLocalName();
+ String attributeValue = initialAttribute.getValue();
+
+ if ("id".equals(localName)) {
+ attributeValue += ITERATION_INDEX_EXPRESSION;
+ }
+
+ attributes[i] = new TagAttribute(initialAttribute.getLocation(),
+ initialAttribute.getNamespace(),
+ localName,
+ initialAttribute.getQName(),
+ attributeValue);
+ }
+
+ TagAttributes tagAttributes = new TagAttributes(attributes);
+ this.tag = new Tag(initialTag, tagAttributes);
+ }
+
+ public String getComponentType() {
+ return config.getComponentType();
+ }
+
+ public String getRendererType() {
+ return config.getRendererType();
+ }
+
+ public FaceletHandler getNextHandler() {
+ return config.getNextHandler();
+ }
+
+ public Tag getTag() {
+ return tag;
+ }
+
+ public String getTagId() {
+ return config.getTagId();
+ }
+
+ };
+ } else {
+ columnConfig = config;
+ }
+
+ handler = new ColumnTagHandler(columnConfig) {
+
@Override
protected MetaRuleset createMetaRuleset(Class type) {
MetaRuleset ruleset = super.createMetaRuleset(type);
@@ -169,7 +235,7 @@
IterationContext itContext = iterationContextLocal.get();
ValueExpression ve = ELBuilder.createValueExpression(expr, Object.class,
ctx.getExpressionFactory(), ctx.getFacesContext().getELContext(),
- itContext._itemId, itContext._indexId,
+ itContext._itemId, itContext._indexId,
itContext.getVarReplacement(), itContext.getIndexReplacement());
((UIComponent)instance).setValueExpression(name, ve);
}else {
@@ -185,224 +251,224 @@
});
return ruleset;
}
-
+
@Override
protected void applyNextHandler(FaceletContext ctx, UIComponent c)
- throws IOException, FacesException, ELException {
- c.getAttributes().put(DYNAMIC_COLUMN_MARKER, Boolean.TRUE);
+ throws IOException, FacesException, ELException {
+ c.getAttributes().put(F_GENERATION_SERIES_ATTRIBUTE,
RequestUniqueIdGenerator.generateId(ctx.getFacesContext()));
super.applyNextHandler(ctx, c);
}
};
- }
-
-
- /**
- * Extracts tags attributes values
- */
- private void initVariables(FaceletContext ctx) {
- initColumnsCount(ctx);
- initIndex(ctx);
- initVar(ctx);
- initBegin(ctx);
- initEnd(ctx);
- }
+ }
- /**
- * Method prepares all we need for starting of tag rendering
- *
- * @throws JspTagException
- */
- private void prepare(FaceletContext ctx) {
- initVariables(ctx);
+ /**
+ * Extracts tags attributes values
+ */
+ private void initVariables(FaceletContext ctx) {
+ initColumnsCount(ctx);
+ initIndex(ctx);
+ initVar(ctx);
+ initBegin(ctx);
+ initEnd(ctx);
+ }
- IterationContext itContext = getIterationContext();
+ /**
+ * Method prepares all we need for starting of tag rendering
+ *
+ * @throws JspTagException
+ */
+ private void prepare(FaceletContext ctx) {
- try {
+ initVariables(ctx);
- this.value = getAttribute("value");
+ IterationContext itContext = getIterationContext();
- // produce the right sort of ForEachIterator
- if (this.value != null) {
- itContext.valueExpr = ELBuilder.getVarReplacement(this.value.getValue());
+ try {
- // If this is a deferred expression, make a note and get
- // the 'items' instance.
+ this.value = getAttribute("value");
- itContext.rawItems = this.value.getObject(ctx);
+ // produce the right sort of ForEachIterator
+ if (this.value != null) {
+ itContext.valueExpr = ELBuilder.getVarReplacement(this.value.getValue());
- // extract an iterator over the 'items' we've got
- itContext.items = SimpleForEachIterator
- .supportedTypeForEachIterator(itContext.rawItems);
- } else {
- // no 'items', so use 'begin' and 'end'
- itContext.items = SimpleForEachIterator.beginEndForEachIterator(itContext._columns
- 1);
- }
- } catch (Exception e) {
- // TODO: handle exception
- }
+ // If this is a deferred expression, make a note and get
+ // the 'items' instance.
- correctFirst(ctx);
- }
+ itContext.rawItems = this.value.getObject(ctx);
- /**
- * Inits first iteration item
- */
- private void correctFirst(FaceletContext ctx) {
- IterationContext itContext = getIterationContext();
- if (itContext.items != null) {
- if (itContext._begin > 0 && (itContext._index < itContext._begin)) {
- while ((itContext._index < itContext._begin && hasNext())) {
- next(ctx);
+ // extract an iterator over the 'items' we've got
+ itContext.items = SimpleForEachIterator
+ .supportedTypeForEachIterator(itContext.rawItems);
+ } else {
+ // no 'items', so use 'begin' and 'end'
+ itContext.items = SimpleForEachIterator.beginEndForEachIterator(itContext._columns -
1);
+ }
+ } catch (Exception e) {
+ // TODO: handle exception
}
- if (!hasNext()) {
- itContext._index = 0;
- }
- }
+
+ correctFirst(ctx);
}
- }
- /**
- * Return true if we didn't complete column's count
- *
- * @return
- * @throws JspTagException
- */
- private boolean hasNext() {
- IterationContext itContext = getIterationContext();
- try {
- if (itContext._end != 0) {
- return (itContext._index < itContext._end) ? itContext.items.hasNext() : false;
- } else {
- return itContext.items.hasNext();
- }
- } catch (Exception e) {
- return false;
+ /**
+ * Inits first iteration item
+ */
+ private void correctFirst(FaceletContext ctx) {
+ IterationContext itContext = getIterationContext();
+ if (itContext.items != null) {
+ if (itContext._begin > 0 && (itContext._index < itContext._begin)) {
+ while ((itContext._index < itContext._begin && hasNext())) {
+ next(ctx);
+ }
+ if (!hasNext()) {
+ itContext._index = 0;
+ }
+ }
+ }
}
- }
+ /**
+ * Return true if we didn't complete column's count
+ *
+ * @return
+ * @throws JspTagException
+ */
+ private boolean hasNext() {
+ IterationContext itContext = getIterationContext();
+ try {
+ if (itContext._end != 0) {
+ return (itContext._index < itContext._end) ? itContext.items.hasNext() : false;
+ } else {
+ return itContext.items.hasNext();
+ }
+ } catch (Exception e) {
+ return false;
+ }
- /**
- * Iterate to next column
- *
- * @return
- * @throws JspTagException
- */
- private Object next(FaceletContext ctx) {
- IterationContext itContext = getIterationContext();
- try {
- Object o = itContext.items.next();
- itContext._index++;
- return o;
- } catch (Exception e) {
- return null;
}
- }
- /**
- * Extracts integer value from end attr
- */
- private void initColumnsCount(FaceletContext ctx) {
- IterationContext itContext = getIterationContext();
- this.columns = getAttribute("columns");
- if (columns != null) {
- try {
- itContext._columns = Integer.parseInt((String) columns.getObject(ctx));
- if (itContext._columns < 0) {
- itContext._columns = 0; // If end is negative set up zero
+ /**
+ * Iterate to next column
+ *
+ * @return
+ * @throws JspTagException
+ */
+ private Object next(FaceletContext ctx) {
+ IterationContext itContext = getIterationContext();
+ try {
+ Object o = itContext.items.next();
+ itContext._index++;
+ return o;
+ } catch (Exception e) {
+ return null;
}
- } catch (Exception e) {
- itContext._columns = 0;
- }
- } else {
- itContext._columns = 0;
}
- }
- /**
- * Extracts integer value from begin attr
- */
- private void initBegin(FaceletContext ctx) {
- IterationContext itContext = getIterationContext();
- this.begin = getAttribute("begin");
- if (begin != null) {
- try {
- Object o = begin.getObject(ctx);
- if (o instanceof Number) {
- itContext._begin = ((Number)o).intValue();
- }else if (o instanceof String) {
- itContext._begin = Integer.parseInt((String) o);
- }
- itContext._begin--;
- if (itContext._begin < 0) {
- itContext._begin = 0; // If end is negative set up zero
+ /**
+ * Extracts integer value from end attr
+ */
+ private void initColumnsCount(FaceletContext ctx) {
+ IterationContext itContext = getIterationContext();
+ this.columns = getAttribute("columns");
+ if (columns != null) {
+ try {
+ itContext._columns = Integer.parseInt((String) columns.getObject(ctx));
+ if (itContext._columns < 0) {
+ itContext._columns = 0; // If end is negative set up zero
+ }
+ } catch (Exception e) {
+ itContext._columns = 0;
+ }
+ } else {
+ itContext._columns = 0;
}
- } catch (Exception e) {
- itContext._begin = 0;
- }
- } else {
- itContext._begin = 0;
}
- }
- /**
- * Extracts integer value from end attr
- */
- private void initEnd(FaceletContext ctx) {
- IterationContext itContext = getIterationContext();
- this.end = getAttribute("end");
- if (end != null) {
- try {
- Object o = end.getObject(ctx);
- if (o instanceof Number) {
- itContext._end = ((Number)o).intValue();
- }else if ( o instanceof String) {
- itContext._end = Integer.parseInt((String) o);
- }
- if (itContext._end < 0) {
- itContext._end = 0; // If end is negative set up zero
+ /**
+ * Extracts integer value from begin attr
+ */
+ private void initBegin(FaceletContext ctx) {
+ IterationContext itContext = getIterationContext();
+ this.begin = getAttribute("begin");
+ if (begin != null) {
+ try {
+ Object o = begin.getObject(ctx);
+ if (o instanceof Number) {
+ itContext._begin = ((Number)o).intValue();
+ }else if (o instanceof String) {
+ itContext._begin = Integer.parseInt((String) o);
+ }
+ itContext._begin--;
+ if (itContext._begin < 0) {
+ itContext._begin = 0; // If end is negative set up zero
+ }
+ } catch (Exception e) {
+ itContext._begin = 0;
+ }
+ } else {
+ itContext._begin = 0;
}
- } catch (Exception e) {
- itContext._end = 0;
- }
- } else {
- itContext._end = 0;
}
- }
- /**
- * Extracts string value from var attr
- */
- private void initVar(FaceletContext ctx) {
- IterationContext itContext = getIterationContext();
- this.var = getAttribute("var");
- if (var != null) {
- try {
- itContext._itemId = (String) var.getObject(ctx);
- } catch (ClassCastException e) {
- itContext._itemId = null;
- }
+ /**
+ * Extracts integer value from end attr
+ */
+ private void initEnd(FaceletContext ctx) {
+ IterationContext itContext = getIterationContext();
+ this.end = getAttribute("end");
+ if (end != null) {
+ try {
+ Object o = end.getObject(ctx);
+ if (o instanceof Number) {
+ itContext._end = ((Number)o).intValue();
+ }else if ( o instanceof String) {
+ itContext._end = Integer.parseInt((String) o);
+ }
+ if (itContext._end < 0) {
+ itContext._end = 0; // If end is negative set up zero
+ }
+ } catch (Exception e) {
+ itContext._end = 0;
+ }
+ } else {
+ itContext._end = 0;
+ }
+ }
+ /**
+ * Extracts string value from var attr
+ */
+ private void initVar(FaceletContext ctx) {
+ IterationContext itContext = getIterationContext();
+ this.var = getAttribute("var");
+ if (var != null) {
+ try {
+ itContext._itemId = (String) var.getObject(ctx);
+ } catch (ClassCastException e) {
+ itContext._itemId = null;
+ }
+
+ }
}
- }
- /**
- * Extracts string value from index attr
- */
- private void initIndex(FaceletContext ctx) {
- IterationContext itContext = getIterationContext();
- this.index = getAttribute("index");
- if (index != null) {
- try {
- itContext._indexId = (String) index.getObject(ctx);
- } catch (ClassCastException e) {
- itContext._indexId = null;
- }
+ /**
+ * Extracts string value from index attr
+ */
+ private void initIndex(FaceletContext ctx) {
+ IterationContext itContext = getIterationContext();
+ this.index = getAttribute("index");
+ if (index != null) {
+ try {
+ itContext._indexId = (String) index.getObject(ctx);
+ } catch (ClassCastException e) {
+ itContext._indexId = null;
+ }
+ }
}
- }
-
- private void initRendered(FaceletContext ctx) {
+
+ private void initRendered(FaceletContext ctx) {
TagAttribute renderedAttribute = getAttribute("rendered");
if (renderedAttribute != null) {
try {
@@ -412,152 +478,154 @@
}
}
}
-
- /*
+
+ /*
* (non-Javadoc)
*
* @see org.richfaces.taglib.ComponentHandler#apply(com.sun.facelets.FaceletContext,
* javax.faces.component.UIComponent)
*/
- //@Override
- public void apply(FaceletContext ctx, UIComponent parent)
- throws IOException, FacesException, ELException {
-
- initRendered(ctx);
- if(!rendered){
- return;
- }
-
- IterationContext iterationContext = new IterationContext();
- iterationContextLocal.set(iterationContext);
-
- clearOldColumns(parent);
- prepare(ctx); // prepare data
-
- try {
- while (hasNext()) { // for each
- exposeVariables(ctx);
- handler.apply(ctx, parent);
- next(ctx);
- }
- } catch (Exception e) {
- // TODO: handle exception
- } finally {
- release();
- unExposeVariables(ctx);
- }
-
- }
+ //@Override
+ public void apply(FaceletContext ctx, UIComponent parent)
+ throws IOException, FacesException, ELException {
-
- private void clearOldColumns (UIComponent parent) {
- if (parent.getChildren() != null) {
- Iterator<UIComponent> childrenIt = parent.getChildren().iterator();
- List<UIComponent> forDelete = new ArrayList<UIComponent>();
- while (childrenIt.hasNext()) {
- UIComponent c = childrenIt.next();
- if (c instanceof UIColumn && c.getAttributes().get(DYNAMIC_COLUMN_MARKER)
!= null
- && (Boolean)c.getAttributes().get(DYNAMIC_COLUMN_MARKER)) {
- forDelete.add(c);
- }
- }
- if (forDelete.size() > 0) {
- Iterator<UIComponent> it = forDelete.iterator();
- while (it.hasNext()) {
- parent.getChildren().remove(it.next());
- }
- }
- }
-
- }
-
- /**
- * Sets page request variables
- *
- * @throws JspTagException
- */
- private void exposeVariables(FaceletContext ctx) {
- IterationContext itContext = getIterationContext();
- VariableMapper vm = ctx.getVariableMapper();
- int k = itContext._index;
+ initRendered(ctx);
+ if(!rendered){
+ return;
+ }
- if (itContext._itemId != null) {
- if (vm != null) {
- if (value != null) {
- ValueExpression srcVE = value.getValueExpression(ctx,
- Object.class);
- ValueExpression ve = getVarExpression(ctx, srcVE);
- vm.setVariable(itContext._itemId, ve);
+ IterationContext iterationContext = new IterationContext();
+ iterationContextLocal.set(iterationContext);
+
+ clearOldColumns(ctx.getFacesContext(), parent);
+ prepare(ctx); // prepare data
+
+ try {
+ while (hasNext()) { // for each
+ exposeVariables(ctx);
+ handler.apply(ctx, parent);
+ next(ctx);
+ }
+ } catch (Exception e) {
+ // TODO: handle exception
+ } finally {
+ release();
+ unExposeVariables(ctx);
}
- }
}
- // Set up index variable
- if (itContext._indexId != null) {
- if (vm != null) {
- ValueExpression ve = new IteratedIndexExpression(k);
- vm.setVariable(itContext._indexId, ve);
- }
+ private void clearOldColumns(FacesContext context, UIComponent parent) {
+ if (parent.getChildCount() > 0) {
+ Integer generatedId = RequestUniqueIdGenerator.generateId(context);
+
+ Iterator<UIComponent> childrenIt = parent.getChildren().iterator();
+ while (childrenIt.hasNext()) {
+ UIComponent c = childrenIt.next();
+ Object generationSeries = c.getAttributes().get(F_GENERATION_SERIES_ATTRIBUTE);
+ if (generationSeries != null && !generationSeries.equals(generatedId)) {
+ childrenIt.remove();
+ }
+ }
+ }
}
- }
+ /**
+ * Sets page request variables
+ *
+ * @throws JspTagException
+ */
+ private void exposeVariables(FaceletContext ctx) {
+ IterationContext itContext = getIterationContext();
+ VariableMapper vm = ctx.getVariableMapper();
+ int k = itContext._index;
- /**
- * Removes page attributes that we have exposed and, if applicable, restores
- * them to their prior values (and scopes).
- */
- private void unExposeVariables(FaceletContext ctx) {
- IterationContext itContext = getIterationContext();
- VariableMapper vm = ctx.getVariableMapper();
- // "nested" variables are now simply removed
- if (itContext._itemId != null) {
- if (vm != null)
- vm.setVariable(itContext._itemId, null);
+ if (itContext._itemId != null) {
+ if (vm != null) {
+ if (value != null) {
+ ValueExpression srcVE = value.getValueExpression(ctx,
+ Object.class);
+ ValueExpression ve = getVarExpression(ctx, srcVE);
+ vm.setVariable(itContext._itemId, ve);
+ }
+ }
+
+ }
+
+ // Set up index variable
+
+ if (itContext._indexId != null) {
+ if (vm != null) {
+ ValueExpression ve = new IteratedIndexExpression(k);
+ vm.setVariable(itContext._indexId, ve);
+ }
+
+ }
+
+ int componentsCount = itContext._index - itContext._begin;
+ if (componentsCount != 0) {
+ ValueExpression ve =
ctx.getExpressionFactory().createValueExpression(UIViewRoot.UNIQUE_ID_PREFIX +
componentsCount, String.class);
+ vm.setVariable(ITERATION_INDEX_VARIABLE, ve);
+ }
}
- if (itContext._indexId != null) {
- if (vm != null)
- vm.setVariable(itContext._indexId, null);
- }
- }
- /**
- * Return expression for page variables
- *
- * @param expr
- * @return
- */
- private ValueExpression getVarExpression(FaceletContext ctx,
- ValueExpression expr/*, IterationContext itContext*/) {
- IterationContext itContext = getIterationContext();
- Object o = expr.getValue(ctx.getFacesContext().getELContext());
- int k = itContext._index;
- if (o.getClass().isArray() || o instanceof List) {
- return new IndexedValueExpression(expr, k);
+ /**
+ * Removes page attributes that we have exposed and, if applicable, restores
+ * them to their prior values (and scopes).
+ */
+ private void unExposeVariables(FaceletContext ctx) {
+ IterationContext itContext = getIterationContext();
+ VariableMapper vm = ctx.getVariableMapper();
+ // "nested" variables are now simply removed
+ if (itContext._itemId != null) {
+ if (vm != null)
+ vm.setVariable(itContext._itemId, null);
+ }
+ if (itContext._indexId != null) {
+ if (vm != null)
+ vm.setVariable(itContext._indexId, null);
+ }
+
+ vm.setVariable(ITERATION_INDEX_VARIABLE, null);
}
- if (o instanceof Collection || o instanceof Iterator
- || o instanceof Enumeration || o instanceof Map
- || o instanceof String) {
+ /**
+ * Return expression for page variables
+ *
+ * @param expr
+ * @return
+ */
+ private ValueExpression getVarExpression(FaceletContext ctx,
+ ValueExpression expr/*, IterationContext itContext*/) {
+ IterationContext itContext = getIterationContext();
+ Object o = expr.getValue(ctx.getFacesContext().getELContext());
+ int k = itContext._index;
+ if (o.getClass().isArray() || o instanceof List) {
+ return new IndexedValueExpression(expr, k);
+ }
- if (itContext.iteratedExpression == null) {
- itContext.iteratedExpression = new IteratedExpression(expr, ",");
- }
- return new IteratedValueExpression(itContext.iteratedExpression, k);
+ if (o instanceof Collection || o instanceof Iterator
+ || o instanceof Enumeration || o instanceof Map
+ || o instanceof String) {
+
+ if (itContext.iteratedExpression == null) {
+ itContext.iteratedExpression = new IteratedExpression(expr, ",");
+ }
+ return new IteratedValueExpression(itContext.iteratedExpression, k);
+ }
+
+ throw new ELException("FOREACH_BAD_ITEMS");
}
- throw new ELException("FOREACH_BAD_ITEMS");
- }
+ /**
+ * Release iteration variables
+ */
+ private void release() {
+ IterationContext itContext = getIterationContext();
+ itContext.items = null;
+ itContext._index = 0;
+ }
- /**
- * Release iteration variables
- */
- private void release() {
- IterationContext itContext = getIterationContext();
- itContext.items = null;
- itContext._index = 0;
- }
-
}
Modified: trunk/ui/columns/src/main/java/org/richfaces/taglib/ColumnsTag.java
===================================================================
--- trunk/ui/columns/src/main/java/org/richfaces/taglib/ColumnsTag.java 2009-03-13
14:15:02 UTC (rev 12953)
+++ trunk/ui/columns/src/main/java/org/richfaces/taglib/ColumnsTag.java 2009-03-13
15:04:32 UTC (rev 12954)
@@ -21,7 +21,6 @@
package org.richfaces.taglib;
import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
@@ -36,6 +35,7 @@
import javax.el.ValueExpression;
import javax.el.VariableMapper;
import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.webapp.UIComponentClassicTagBase;
import javax.servlet.jsp.JspException;
@@ -57,6 +57,8 @@
/** Data table */
private UIComponent dataTable;
+ private static final String J_GENERATION_SERIES_ATTRIBUTE =
"org.richfaces.J_COLUMNS_GENERATION_SERIES";
+
/** Prefix before id to be assigned for column */
private static final String COLUMN_ID_PREFIX = "rf";
@@ -107,7 +109,8 @@
private String jspId;
-
+ private String pageId;
+
/**
* style CSS style(s) is/are to be applied when this component is rendered
*/
@@ -285,6 +288,8 @@
*/
@Override
public int doStartTag() throws JspException {
+ pageId = getId();
+
initRendered();
if(!rendered){
return SKIP_BODY;
@@ -313,6 +318,9 @@
if (hasNext()) {
super.doAfterBody();
super.doEndTag();
+
+ setId(pageId);
+
next();
exposeVariables();
super.doStartTag();
@@ -359,9 +367,10 @@
throws JspException {
UIComponent c = getFacesContext().getApplication().createComponent(
getComponentType());
- c.setId(generateColumnId());
+ c.setId(newId);
c.setTransient(false);
setProperties(c);
+ c.getAttributes().put(J_GENERATION_SERIES_ATTRIBUTE,
RequestUniqueIdGenerator.generateId(context));
return c;
}
@@ -491,22 +500,17 @@
*/
private void deleteRichColumns() {
List<UIComponent> children = dataTable.getChildren();
+ Integer generatedId = RequestUniqueIdGenerator.generateId(getFacesContext());
+
Iterator<UIComponent> it = children.iterator();
- List<UIComponent> forDelete = new ArrayList<UIComponent>();
- Integer i = 0;
while (it.hasNext()) {
UIComponent child = it.next();
- String id = child.getId();
- if (id != null && id.startsWith(COLUMN_ID_PREFIX)) {
- forDelete.add(child);
+
+ Object generationSeries = child.getAttributes().get(J_GENERATION_SERIES_ATTRIBUTE);
+ if (generationSeries != null && !generationSeries.equals(generatedId)) {
+ it.remove();
}
- i++;
}
- it = forDelete.iterator();
- while (it.hasNext()) {
- UIComponent elem = it.next();
- children.remove(elem);
- }
}
/**
@@ -733,7 +737,12 @@
}
private String generateColumnId() {
- return COLUMN_ID_PREFIX + Integer.toString(index);
+ String id = getId();
+ if (id == null) {
+ id = getFacesJspId();
+ }
+
+ return id;
}
/**
Added: trunk/ui/columns/src/main/java/org/richfaces/taglib/RequestUniqueIdGenerator.java
===================================================================
--- trunk/ui/columns/src/main/java/org/richfaces/taglib/RequestUniqueIdGenerator.java
(rev 0)
+++
trunk/ui/columns/src/main/java/org/richfaces/taglib/RequestUniqueIdGenerator.java 2009-03-13
15:04:32 UTC (rev 12954)
@@ -0,0 +1,59 @@
+/**
+ * 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.richfaces.taglib;
+
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+/**
+ * @author Nick Belaevski
+ * @since 3.3.1
+ */
+final class RequestUniqueIdGenerator {
+
+ private static final String GENERATOR_ATTRIBUTE =
RequestUniqueIdGenerator.class.getName();
+
+ public static Integer generateId(FacesContext context) {
+ Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
+ Integer id = (Integer) requestMap.get(GENERATOR_ATTRIBUTE);
+
+ if (id == null) {
+ Map<String, Object> attributes = context.getViewRoot().getAttributes();
+ id = (Integer) attributes.get(GENERATOR_ATTRIBUTE);
+ if (id == null) {
+ //start from zero
+ id = Integer.valueOf(0);
+ } else {
+ //increase id used for last view creation
+ id = Integer.valueOf(id.intValue() + 1);
+ }
+
+ attributes.put(GENERATOR_ATTRIBUTE, id);
+ requestMap.put(GENERATOR_ATTRIBUTE, id);
+ } else {
+ //already generated id for this request, reuse
+ }
+
+ return id;
+ }
+}