001: /*
002: * $Id: Loop.java 459916 2006-03-21 00:46:45Z jonl $ $Revision: 459916 $
003: * $Date: 2006-03-21 01:46:45 +0100 (Tue, 21 Mar 2006) $
004: *
005: * ==============================================================================
006: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007: * use this file except in compliance with the License. You may obtain a copy of
008: * the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations under
016: * the License.
017: */
018: package wicket.markup.html.list;
019:
020: import wicket.WicketRuntimeException;
021: import wicket.markup.MarkupStream;
022: import wicket.markup.html.WebMarkupContainer;
023: import wicket.model.IModel;
024: import wicket.model.Model;
025:
026: /**
027: * A very simple loop component whose model is an Integer defining the number of
028: * iterations the loop should render. During rendering, Loop iterates from 0 to
029: * getIterations() - 1, creating a new MarkupContainer for each iteration. The
030: * MarkupContainer is populated by the Loop subclass by implementing the
031: * abstract method populate(LoopItem). The populate() method is called just
032: * before the LoopItem container is rendered.
033: *
034: * @author Juergen Donnerstag
035: * @author Eelco Hillenius
036: * @author Jonathan Locke
037: */
038: public abstract class Loop extends WebMarkupContainer {
039: /**
040: * Item container for a Loop iteration.
041: *
042: * @author Jonathan Locke
043: */
044: public static final class LoopItem extends WebMarkupContainer {
045: private static final long serialVersionUID = 1L;
046:
047: /** The iteration number */
048: private final int iteration;
049:
050: /**
051: * Constructor
052: *
053: * @param iteration
054: * The iteration of the loop
055: */
056: private LoopItem(final int iteration) {
057: super (Integer.toString(iteration));
058: this .iteration = iteration;
059: }
060:
061: /**
062: * @return Returns the iteration.
063: */
064: public int getIteration() {
065: return iteration;
066: }
067: }
068:
069: /**
070: * Construct.
071: *
072: * @param id
073: * See Component
074: * @param iterations
075: * max index of the loop
076: * @see wicket.Component#Component(String, IModel)
077: */
078: public Loop(final String id, final int iterations) {
079: super (id, new Model(new Integer(iterations)));
080: }
081:
082: /**
083: * Construct.
084: *
085: * @param id
086: * See Component
087: * @param model
088: * Must contain a Integer model object
089: * @see wicket.Component#Component(String, IModel)
090: */
091: public Loop(final String id, final IModel model) {
092: super (id, model);
093: }
094:
095: /**
096: * @return The number of loop iterations
097: */
098: public final int getIterations() {
099: return ((Integer) getModelObject()).intValue();
100: }
101:
102: /**
103: * @see wicket.Component#internalOnAttach()
104: */
105: protected void internalOnAttach() {
106: // Remove any previous loop contents
107: removeAll();
108:
109: // Get number of iterations
110: final int iterations = getIterations();
111: if (iterations > 0) {
112: // Create LoopItems for each iteration
113: for (int iteration = 0; iteration < iterations; iteration++) {
114: // Create item for loop iteration
115: LoopItem item = newItem(iteration);
116:
117: // Add and populate item
118: add(item);
119: populateItem(item);
120: }
121: }
122: }
123:
124: /**
125: * Create a new LoopItem for loop at iteration.
126: *
127: * @param iteration
128: * iteration in the loop
129: * @return LoopItem
130: */
131: protected LoopItem newItem(int iteration) {
132: return new LoopItem(iteration);
133: }
134:
135: /**
136: *
137: * @see wicket.Component#onRender(wicket.markup.MarkupStream)
138: */
139: protected final void onRender(final MarkupStream markupStream) {
140: // Save position in markup stream
141: final int markupStart = markupStream.getCurrentIndex();
142:
143: // Get number of iterations
144: final int iterations = getIterations();
145: if (iterations > 0) {
146: // Loop through the markup in this container for each item
147: for (int iteration = 0; iteration < iterations; iteration++) {
148: // Get item for iteration
149: final LoopItem item = (LoopItem) get(Integer
150: .toString(iteration));
151:
152: // Item should have been constructed in internalOnBeginRequest
153: if (item == null) {
154: throw new WicketRuntimeException(
155: "Loop item is null. Probably the number of loop iterations were changed between onBeginRequest and render time.");
156: }
157:
158: // Rewind to start of markup for kids
159: markupStream.setCurrentIndex(markupStart);
160:
161: // Render iteration
162: renderItem(item);
163: }
164: } else {
165: markupStream.skipComponent();
166: }
167: }
168:
169: /**
170: * Populates this loop item.
171: *
172: * @param item
173: * The iteration of the loop
174: */
175: protected abstract void populateItem(LoopItem item);
176:
177: /**
178: * Renders this loop iteration.
179: *
180: * @param item
181: * The loop iteration
182: */
183: protected void renderItem(final LoopItem item) {
184: item.render(getMarkupStream());
185: }
186: }
|