From 4efae83b1adbcf3cacd213810678b7838bf8fcd5 Mon Sep 17 00:00:00 2001 From: Bauke Scholtz Date: Sun, 23 Jul 2023 12:55:18 -0400 Subject: [PATCH 1/3] https://github.com/jakartaee/faces/issues/1713 Improved spec wrt ui:repeat attributes --- .../metadata/taglib/faces.facelets.taglib.xml | 84 ++++++++++--------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/impl/src/main/resources/com/sun/faces/metadata/taglib/faces.facelets.taglib.xml b/impl/src/main/resources/com/sun/faces/metadata/taglib/faces.facelets.taglib.xml index 5501fd677e..08e6309e86 100644 --- a/impl/src/main/resources/com/sun/faces/metadata/taglib/faces.facelets.taglib.xml +++ b/impl/src/main/resources/com/sun/faces/metadata/taglib/faces.facelets.taglib.xml @@ -837,11 +837,12 @@ attribute must be an absolute path starting with "/". +

- If value specified: Iteration begins at the item located at the specified index. - First item of the collection has index 0. - If value not specified: Iteration begins with index set at the specified value. + If the value attribute is not specified: iteration begins with the specified number (inclusive) as item. + If the value attribute is specified: a FacesException must be thrown. + If the corresponding end attribute is not specified: use 0 as default. + The corresponding end attribute may be less than the beginbegin attribute: iteration will take place in a reversed manner.

]]> @@ -853,10 +854,12 @@ attribute must be an absolute path starting with "/". +

- If value specified: Iteration ends at the item located at the specified index (inclusive). - If value not specified: Iteration ends when index reaches the specified value (inclusive). + If the value attribute is not specified: iteration ends with the specified number (inclusive) as item. + If the value attribute is specified: a FacesException must be thrown. + If the corresponding begin attribute is not specified: use 0 as default. + The corresponding begin attribute may be greater than the end attribute: iteration will take place in a reversed manner.

]]> @@ -866,52 +869,51 @@ attribute must be an absolute path starting with "/". int
- - -

Read-write property setting the offset from the - beginning of the - collection from which to start the iteration. If not set, this - offset - is not considered and iteration will start at the beginning of - the - collection.

- + + +

+ If the value attribute is specified: iteration begins with the specified number as index. + If the value attribute is not specified: a FacesException must be thrown. + If the offset attribute is not specified: use 0 as default. + If the offset attribute is less than 0 or is greater than the size of the actual collection behind the value attribute: a FacesException must be thrown. +

- - ]]>
+ ]]> +
offset false int
- - -

Read-write property setting the size of the collection - to iterate. - If this value is less than the actual size of the collection, a - FacesException must be thrown.

- + + +

+ If the value attribute is specified: iteration ends when the specified number of times has been iterated (inclusive). + If the value attribute is not specified: a FacesException must be thrown. + If the size attribute is not specified: use the size of the actual collection behind the value attribute as default. + If the sum of the size attribute and the offset attribute is less than 0 or is greater than the size of the actual collection behind the value attribute: a FacesException must be thrown. + If the step attribute is specified: each skipped item must also be counted for the size attribute. +

- - ]]>
+ ]]> +
size false int
-

Iteration - will only process every step items of the collection, - starting with the first one.

- - ]]>
+ + +

+ Iteration will only process every step items of the collection, starting with the first one. + If the step attribute is less than 1: a FacesException must be thrown. +

+ + ]]> +
step false int From 50036e743cfecaf36be2ffcaaa57e4d0eea4f95a Mon Sep 17 00:00:00 2001 From: Bauke Scholtz Date: Sun, 23 Jul 2023 12:58:14 -0400 Subject: [PATCH 2/3] https://github.com/jakartaee/faces/issues/1713 Fixed impl as per improved spec on ui:repeat attributes --- .../faces/facelets/component/UIRepeat.java | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/impl/src/main/java/com/sun/faces/facelets/component/UIRepeat.java b/impl/src/main/java/com/sun/faces/facelets/component/UIRepeat.java index 217d790f7a..a962edd30e 100644 --- a/impl/src/main/java/com/sun/faces/facelets/component/UIRepeat.java +++ b/impl/src/main/java/com/sun/faces/facelets/component/UIRepeat.java @@ -85,6 +85,7 @@ public class UIRepeat extends UINamingContainer { private Integer begin; private Integer end; private Integer step; + private Integer offset; private Integer size; public UIRepeat() { @@ -131,13 +132,13 @@ public Integer getSize() { } public void setOffset(Integer offset) { - begin = offset; + this.offset = offset; } public Integer getOffset() { - if (begin != null) { - return begin; + if (offset != null) { + return offset; } ValueExpression ve = getValueExpression("offset"); if (ve != null) { @@ -211,7 +212,30 @@ private void setDataModel(DataModel model) { private DataModel getDataModel() { if (model == null) { Object val = getValue(); + + if (val != null) { + if (getBegin() != null) { + throw new FacesException(": when 'value' attribute is set, you need 'offset' attribute instead of 'begin' attribute"); + } + if (getEnd() != null) { + throw new FacesException(": when 'value' attribute is set, you need 'size' attribute instead of 'end' attribute"); + } + if (getOffset() != null && getOffset() < 0) { + throw new FacesException(": 'offset' attribute may not be less than 0"); + } + if (getStep() != null && getStep() < 1) { + throw new FacesException(": 'step' attribute may not be less than 1"); + } + } + if (val == null) { + if (getOffset() != null) { + throw new FacesException(": when 'value' attribute is not set, you need 'begin' attribute instead of 'offset' attribute"); + } + if (getSize() != null) { + throw new FacesException(": when 'value' attribute is not set, you need 'end' attribute instead of 'size' attribute"); + } + if (originalBegin == null) { originalBegin = getBegin(); } @@ -222,15 +246,11 @@ private DataModel getDataModel() { Integer begin = originalBegin; Integer end = originalEnd; - if (end == null) { - if (begin == null) { - model = EMPTY_MODEL; - } else { - throw new IllegalArgumentException("end"); - } + if (begin == null && end == null) { + model = EMPTY_MODEL; } else { int b = begin == null ? 0 : begin; - int e = end; + int e = end == null ? 0 : end; int d = b < e ? 1 : b > e ? -1 : 0; int s = Math.abs(e - b) + 1; Integer[] array = new Integer[s]; @@ -524,7 +544,7 @@ public void process(FacesContext faces, PhaseId phase) { Integer size = getSize(); if (null != size) { - end = size; + end = (begin != null ? begin : 0) + size; } // grab renderer @@ -540,7 +560,7 @@ public void process(FacesContext faces, PhaseId phase) { int s = step != null ? step : 1; validateIterationControlValues(rowCount, i, e); if (null != size && size > 0) { - e = size - 1; + e = e - 1; } setIndex(faces, i); @@ -736,13 +756,13 @@ private void validateIterationControlValues(int rowCount, int begin, int end) { } // PENDING i18n if (begin > rowCount) { - throw new FacesException("Iteration start index is greater than the number of available rows."); + throw new FacesException(": 'offset' attribute may not be greater than the number of available rows"); } if (begin > end) { - throw new FacesException("Iteration start index is greater than the end index."); + throw new FacesException(": 'size' attribute may not be less than 0"); } if (end > rowCount) { - throw new FacesException("Iteration end index is greater than the number of available rows."); + throw new FacesException(": " + (getOffset() != null ? "'offset' plus " : "") + "'size' attribute may not be greater than the number of available rows"); } } From 0a88f9155d796c701139d3bf0b2660e068ba7e09 Mon Sep 17 00:00:00 2001 From: Bauke Scholtz Date: Sun, 8 Oct 2023 12:29:00 -0400 Subject: [PATCH 3/3] Neutralize xml namespace in exception message as this isn't per definition always ui --- .../sun/faces/facelets/component/UIRepeat.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/impl/src/main/java/com/sun/faces/facelets/component/UIRepeat.java b/impl/src/main/java/com/sun/faces/facelets/component/UIRepeat.java index a962edd30e..c89c8cc4fb 100644 --- a/impl/src/main/java/com/sun/faces/facelets/component/UIRepeat.java +++ b/impl/src/main/java/com/sun/faces/facelets/component/UIRepeat.java @@ -215,25 +215,25 @@ private DataModel getDataModel() { if (val != null) { if (getBegin() != null) { - throw new FacesException(": when 'value' attribute is set, you need 'offset' attribute instead of 'begin' attribute"); + throw new FacesException("UIRepeat: when 'value' attribute is set, you need 'offset' attribute instead of 'begin' attribute"); } if (getEnd() != null) { - throw new FacesException(": when 'value' attribute is set, you need 'size' attribute instead of 'end' attribute"); + throw new FacesException("UIRepeat: when 'value' attribute is set, you need 'size' attribute instead of 'end' attribute"); } if (getOffset() != null && getOffset() < 0) { - throw new FacesException(": 'offset' attribute may not be less than 0"); + throw new FacesException("UIRepeat: 'offset' attribute may not be less than 0"); } if (getStep() != null && getStep() < 1) { - throw new FacesException(": 'step' attribute may not be less than 1"); + throw new FacesException("UIRepeat: 'step' attribute may not be less than 1"); } } if (val == null) { if (getOffset() != null) { - throw new FacesException(": when 'value' attribute is not set, you need 'begin' attribute instead of 'offset' attribute"); + throw new FacesException("UIRepeat: when 'value' attribute is not set, you need 'begin' attribute instead of 'offset' attribute"); } if (getSize() != null) { - throw new FacesException(": when 'value' attribute is not set, you need 'end' attribute instead of 'size' attribute"); + throw new FacesException("UIRepeat: when 'value' attribute is not set, you need 'end' attribute instead of 'size' attribute"); } if (originalBegin == null) { @@ -756,13 +756,13 @@ private void validateIterationControlValues(int rowCount, int begin, int end) { } // PENDING i18n if (begin > rowCount) { - throw new FacesException(": 'offset' attribute may not be greater than the number of available rows"); + throw new FacesException("UIRepeat: 'offset' attribute may not be greater than the number of available rows"); } if (begin > end) { - throw new FacesException(": 'size' attribute may not be less than 0"); + throw new FacesException("UIRepeat: 'size' attribute may not be less than 0"); } if (end > rowCount) { - throw new FacesException(": " + (getOffset() != null ? "'offset' plus " : "") + "'size' attribute may not be greater than the number of available rows"); + throw new FacesException("UIRepeat: " + (getOffset() != null ? "'offset' plus " : "") + "'size' attribute may not be greater than the number of available rows"); } }