001: /**
002: * Copyright 2006 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.example.common.framework.container;
016:
017: import java.util.ArrayList;
018: import java.util.Collection;
019: import java.util.Iterator;
020: import java.util.LinkedList;
021: import java.util.List;
022: import org.apache.commons.logging.Log;
023: import org.apache.commons.logging.LogFactory;
024: import org.araneaframework.OutputData;
025: import org.araneaframework.Widget;
026: import org.araneaframework.core.AraneaRuntimeException;
027: import org.araneaframework.core.StandardScope;
028: import org.araneaframework.example.common.framework.context.WizardContext;
029: import org.araneaframework.uilib.core.BaseUIWidget;
030:
031: /**
032: * This widget may contain other widgets (called pages) as children.
033: * It routes init() and event() to all of its children
034: * and render() to only current active child.
035: *
036: * It recieves following events:
037: * 1. eventId: "goto", eventParam: pageIndex.
038: * 2. eventId: "submit".
039: * 3. eventId: "cancel".
040: *
041: * @author Rein Raudjärv <reinra@ut.ee>
042: */
043: public class StandardWizardWidget extends BaseUIWidget implements
044: WizardContext {
045: private static final Log log = LogFactory
046: .getLog(StandardWizardWidget.class);
047:
048: public static final String CURRENT_PAGE_KEY = "currentPage";
049:
050: // List of Widget objects
051: private List pages = new ArrayList();
052:
053: // Active page index in the list
054: private int currentPageIndex = 0;
055:
056: public int getCurrentPageIndex() {
057: return currentPageIndex;
058: }
059:
060: private void setCurrentPageIndex(int currentPageIndex) {
061: if (this .currentPageIndex != currentPageIndex) {
062: if (containsIndex(this .currentPageIndex)) {
063: _getChildren().remove(CURRENT_PAGE_KEY);
064: }
065: this .currentPageIndex = currentPageIndex;
066: _getChildren().put(CURRENT_PAGE_KEY,
067: getPage(currentPageIndex));
068: }
069: makeListenersHandleGoto(getCurrentPage());
070: log.debug("Current page index set to " + currentPageIndex);
071: }
072:
073: // goto page
074:
075: public void gotoNext() {
076: if (countPages() == 0) {
077: throw new AraneaRuntimeException("No pages found");
078: }
079: if (getCurrentPageIndex() == countPages() - 1) {
080: throw new AraneaRuntimeException("There are no more pages");
081: }
082: setCurrentPageIndex(getCurrentPageIndex() + 1);
083: }
084:
085: public void gotoPrevious() {
086: if (countPages() == 0) {
087: throw new AraneaRuntimeException("No pages found");
088: }
089: if (getCurrentPageIndex() == 0) {
090: throw new AraneaRuntimeException("There are no more pages");
091: }
092: setCurrentPageIndex(getCurrentPageIndex() - 1);
093: }
094:
095: public void gotoFirst() {
096: if (countPages() == 0) {
097: throw new AraneaRuntimeException("No pages found");
098: }
099: setCurrentPageIndex(0);
100: }
101:
102: public void gotoLast() {
103: if (countPages() == 0) {
104: throw new AraneaRuntimeException("No pages found");
105: }
106: setCurrentPageIndex(countPages() - 1);
107: }
108:
109: public void gotoPage(Widget page) {
110: if (!containsPage(page)) {
111: throw new AraneaRuntimeException("Page not found");
112: }
113: setCurrentPageIndex(getIndexOfPage(page));
114: }
115:
116: public void gotoPage(int index) {
117: if (!containsIndex(index)) {
118: throw new AraneaRuntimeException(
119: "Page index out of bounds, page index = " + index
120: + ", total pages = " + countPages());
121: }
122: setCurrentPageIndex(index);
123: }
124:
125: // add/remove pages
126:
127: public void addPage(int index, Widget page) throws Exception {
128: pages.add(index, page);
129: initPage(page);
130: log.debug("Page added, index = " + index);
131: }
132:
133: public void addPage(Widget page) throws Exception {
134: pages.add(page);
135: initPage(page);
136: log.debug("Page added, index = " + (countPages() - 1));
137: }
138:
139: public void removePage(Widget page) throws Exception {
140: int index = getIndexOfPage(page);
141: destroyPage(page);
142: pages.remove(page);
143: if (getCurrentPageIndex() >= countPages()) {
144: setCurrentPageIndex(countPages() > 0 ? countPages() - 1 : 0);
145: }
146: log.debug("Page removed, page index = " + index);
147: }
148:
149: public void removePage(int index) throws Exception {
150: removePage(getPage(index));
151: }
152:
153: public void clearPages() throws Exception {
154: for (Iterator i = pages.iterator(); i.hasNext();) {
155: destroyPage((Widget) i.next());
156: }
157: pages.clear();
158: currentPageIndex = 0;
159: log.debug("All pages removed");
160: }
161:
162: private void initPage(Widget page) throws Exception {
163: log.debug("Initializing page...");
164: page._getComponent().init(
165: new StandardScope(CURRENT_PAGE_KEY, getScope()),
166: getChildEnvironment());
167: if (getIndexOfPage(page) == getCurrentPageIndex()) {
168: _getChildren().put(CURRENT_PAGE_KEY, page);
169: }
170: }
171:
172: private void destroyPage(Widget page) throws Exception {
173: log.debug("Destroying page...");
174: if (getIndexOfPage(page) == getCurrentPageIndex()
175: && _getChildren().containsKey(CURRENT_PAGE_KEY)) {
176: _getChildren().remove(CURRENT_PAGE_KEY);
177: }
178: }
179:
180: // getters
181:
182: public Widget getPage(int index) {
183: try {
184: return (Widget) pages.get(index);
185: } catch (IndexOutOfBoundsException e) {
186: throw new AraneaRuntimeException(
187: "Page index out of bounds, page index = " + index
188: + ", total pages = " + countPages());
189: }
190: }
191:
192: public Widget[] getAllPages() {
193: return (Widget[]) pages.toArray(new Widget[pages.size()]);
194: }
195:
196: public int getIndexOfPage(Widget page) {
197: int index = pages.indexOf(page);
198: if (index == -1) {
199: throw new AraneaRuntimeException("Page not found");
200: }
201: return index;
202: }
203:
204: public int countPages() {
205: return pages.size();
206: }
207:
208: public Widget getCurrentPage() {
209: return getPage(getCurrentPageIndex());
210: }
211:
212: // contains
213:
214: public boolean containsPage(Widget page) {
215: return pages.contains(page);
216: }
217:
218: public boolean containsIndex(int index) {
219: return countPages() > 0 && index >= 0 && index < countPages();
220: }
221:
222: protected void render(OutputData output) throws Exception {
223: log.debug("StandardWizardWidget render called");
224: getCurrentPage()._getWidget().render(output);
225: }
226:
227: protected void destroy() throws Exception {
228: clearPages();
229: }
230:
231: /*
232: * Submit & cancel
233: */
234:
235: public void submit() {
236: makeListenersHandleSubmit();
237: }
238:
239: public void cancel() {
240: makeListenersHandleCancel();
241: }
242:
243: /*
244: * Event listeners
245: */
246:
247: private Collection eventListeners = new LinkedList();
248:
249: public void addEventListener(WizardContext.EventListener listener) {
250: eventListeners.add(listener);
251: }
252:
253: public void removeEventListener(WizardContext.EventListener listener) {
254: eventListeners.remove(listener);
255: }
256:
257: public void clearEventListeners() {
258: eventListeners.clear();
259: }
260:
261: private void makeListenersHandleGoto(Widget page) {
262: try {
263: for (Iterator i = eventListeners.iterator(); i.hasNext();) {
264: ((WizardContext.EventListener) i.next()).onGoto(page);
265: }
266: } catch (Exception e) {
267: throw new AraneaRuntimeException(e);
268: }
269: }
270:
271: private void makeListenersHandleSubmit() {
272: try {
273: for (Iterator i = eventListeners.iterator(); i.hasNext();) {
274: ((WizardContext.EventListener) i.next()).onSubmit();
275: }
276: } catch (Exception e) {
277: throw new AraneaRuntimeException(e);
278: }
279: }
280:
281: private void makeListenersHandleCancel() {
282: try {
283: for (Iterator i = eventListeners.iterator(); i.hasNext();) {
284: ((WizardContext.EventListener) i.next()).onCancel();
285: }
286: } catch (Exception e) {
287: throw new AraneaRuntimeException(e);
288: }
289: }
290:
291: /*
292: * Methods for HandleEventProxyEventListener
293: */
294:
295: public void handleEventGoto(String eventParameter) throws Exception {
296: gotoPage(Integer.parseInt(eventParameter));
297: }
298:
299: public void handleEventSubmit(String eventParameter)
300: throws Exception {
301: submit();
302: }
303:
304: public void handleEventCancel(String eventParameter)
305: throws Exception {
306: cancel();
307: }
308: }
|