Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ui:repeat clarification on attributes, such as offset and size #5289

Merged
merged 4 commits into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 35 additions & 15 deletions impl/src/main/java/com/sun/faces/facelets/component/UIRepeat.java
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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("UIRepeat: when 'value' attribute is set, you need 'offset' attribute instead of 'begin' attribute");
}
if (getEnd() != null) {
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("UIRepeat: 'offset' attribute may not be less than 0");
}
if (getStep() != null && getStep() < 1) {
throw new FacesException("UIRepeat: 'step' attribute may not be less than 1");
}
}

if (val == null) {
if (getOffset() != null) {
throw new FacesException("UIRepeat: when 'value' attribute is not set, you need 'begin' attribute instead of 'offset' attribute");
}
if (getSize() != null) {
throw new FacesException("UIRepeat: when 'value' attribute is not set, you need 'end' attribute instead of 'size' attribute");
}

if (originalBegin == null) {
originalBegin = getBegin();
}
Expand All @@ -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];
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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("UIRepeat: '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("UIRepeat: '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("UIRepeat: " + (getOffset() != null ? "'offset' plus " : "") + "'size' attribute may not be greater than the number of available rows");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -837,11 +837,12 @@ attribute must be an absolute path starting with "/".</span>
<attribute>
<description>
<![CDATA[
<div class="changed_modified_2_3">
<div class="changed_modified_4_1">
<p>
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 <code>value</code> attribute is <em>not</em> specified: iteration begins with the specified number (inclusive) as item.
If the <code>value</code> attribute is specified: a <code>FacesException</code> must be thrown.
If the corresponding <code>end</code> attribute is <em>not</em> specified: use <code>0</code> as default.
The corresponding <code>end</code> attribute may be less than the begin<code>begin</code> attribute: iteration will take place in a reversed manner.
</p>
</div>
]]>
Expand All @@ -853,10 +854,12 @@ attribute must be an absolute path starting with "/".</span>
<attribute>
<description>
<![CDATA[
<div class="changed_modified_2_3">
<div class="changed_modified_4_1">
<p>
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 <code>value</code> attribute is <em>not</em> specified: iteration ends with the specified number (inclusive) as item.
If the <code>value</code> attribute is specified: a <code>FacesException</code> must be thrown.
If the corresponding <code>begin</code> attribute is <em>not</em> specified: use <code>0</code> as default.
The corresponding <code>begin</code> attribute may be greater than the <code>end</code> attribute: iteration will take place in a reversed manner.
</p>
</div>
]]>
Expand All @@ -866,52 +869,51 @@ attribute must be an absolute path starting with "/".</span>
<type>int</type>
</attribute>
<attribute>
<description><![CDATA[


<div class="changed_added_2_0">

<p>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.</p>

<description>
<![CDATA[
<div class="changed_modified_4_1">
<p>
If the <code>value</code> attribute is specified: iteration begins with the specified number as index.
If the <code>value</code> attribute is <em>not</em> specified: a <code>FacesException</code> must be thrown.
If the <code>offset</code> attribute is <em>not</em> specified: use <code>0</code> as default.
If the <code>offset</code> attribute is less than <code>0</code> or is greater than the size of the actual collection behind the <code>value</code> attribute: a <code>FacesException</code> must be thrown.
</p>
</div>

]]></description>
]]>
</description>
<name>offset</name>
<required>false</required>
<type>int</type>
</attribute>
<attribute>
<description><![CDATA[


<div class="changed_added_2_0">

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

<description>
<![CDATA[
<div class="changed_modified_4_1">
<p>
If the <code>value</code> attribute is specified: iteration ends when the specified number of times has been iterated (inclusive).
If the <code>value</code> attribute is <em>not</em> specified: a <code>FacesException</code> must be thrown.
If the <code>size</code> attribute is <em>not</em> specified: use the size of the actual collection behind the value attribute as default.
If the sum of the <code>size</code> attribute and the <code>offset</code> attribute is less than <code>0</code> or is greater than the size of the actual collection behind the value attribute: a <code>FacesException</code> must be thrown.
If the <code>step</code> attribute is specified: each skipped item must also be counted for the <code>size</code> attribute.
</p>
</div>

]]></description>
]]>
</description>
<name>size</name>
<required>false</required>
<type>int</type>
</attribute>
<attribute>
<description><![CDATA[

<div class="changed_added_2_0"><p>Iteration
will only process every step items of the collection,
starting with the first one.</p></div>

]]></description>
<description>
<![CDATA[
<div class="changed_modified_4_1">
<p>
Iteration will only process every step items of the collection, starting with the first one.
If the <code>step</code> attribute is less than <code>1</code>: a <code>FacesException</code> must be thrown.
</p>
</div>
]]>
</description>
<name>step</name>
<required>false</required>
<type>int</type>
Expand Down
Loading