001: /* ====================================================================
002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
003: *
004: * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by Jcorporate Ltd.
021: * (http://www.jcorporate.com/)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. "Jcorporate" and product names such as "Expresso" must
026: * not be used to endorse or promote products derived from this
027: * software without prior written permission. For written permission,
028: * please contact info@jcorporate.com.
029: *
030: * 5. Products derived from this software may not be called "Expresso",
031: * or other Jcorporate product names; nor may "Expresso" or other
032: * Jcorporate product names appear in their name, without prior
033: * written permission of Jcorporate Ltd.
034: *
035: * 6. No product derived from this software may compete in the same
036: * market space, i.e. framework, without prior written permission
037: * of Jcorporate Ltd. For written permission, please contact
038: * partners@jcorporate.com.
039: *
040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
051: * SUCH DAMAGE.
052: * ====================================================================
053: *
054: * This software consists of voluntary contributions made by many
055: * individuals on behalf of the Jcorporate Ltd. Contributions back
056: * to the project(s) are encouraged when you make modifications.
057: * Please send them to support@jcorporate.com. For more information
058: * on Jcorporate Ltd. and its products, please see
059: * <http://www.jcorporate.com/>.
060: *
061: * Portions of this software are based upon other open source
062: * products and are subject to their respective licenses.
063: */
064:
065: package com.jcorporate.expresso.core.servlet.viewhandler;
066:
067: import com.jcorporate.expresso.core.controller.Block;
068: import com.jcorporate.expresso.core.controller.ControllerElement;
069: import com.jcorporate.expresso.core.controller.ControllerException;
070: import com.jcorporate.expresso.core.controller.ControllerResponse;
071: import com.jcorporate.expresso.core.controller.ErrorCollection;
072: import com.jcorporate.expresso.core.controller.Input;
073: import com.jcorporate.expresso.core.controller.Output;
074: import com.jcorporate.expresso.core.controller.State;
075: import com.jcorporate.expresso.core.controller.Transition;
076: import com.jcorporate.expresso.core.db.DBException;
077: import com.jcorporate.expresso.core.dbobj.ValidValue;
078: import com.jcorporate.expresso.core.jsdkapi.GenericSession;
079: import com.jcorporate.expresso.core.misc.ConfigManager;
080: import com.jcorporate.expresso.core.misc.ConfigurationException;
081: import com.jcorporate.expresso.core.misc.StringUtil;
082: import com.jcorporate.expresso.services.dbobj.Setup;
083: import com.jcorporate.expresso.services.html.Break;
084: import com.jcorporate.expresso.services.html.Button;
085: import com.jcorporate.expresso.services.html.Cell;
086: import com.jcorporate.expresso.services.html.CheckBox;
087: import com.jcorporate.expresso.services.html.DropDown;
088: import com.jcorporate.expresso.services.html.FileInput;
089: import com.jcorporate.expresso.services.html.Form;
090: import com.jcorporate.expresso.services.html.Heading;
091: import com.jcorporate.expresso.services.html.HiddenField;
092: import com.jcorporate.expresso.services.html.HtmlElement;
093: import com.jcorporate.expresso.services.html.HtmlException;
094: import com.jcorporate.expresso.services.html.Page;
095: import com.jcorporate.expresso.services.html.Paragraph;
096: import com.jcorporate.expresso.services.html.Radio;
097: import com.jcorporate.expresso.services.html.Row;
098: import com.jcorporate.expresso.services.html.Table;
099: import com.jcorporate.expresso.services.html.Text;
100: import com.jcorporate.expresso.services.html.TextArea;
101: import com.jcorporate.expresso.services.html.TextField;
102: import org.apache.log4j.Logger;
103: import org.apache.struts.action.ActionMessage;
104:
105: import javax.servlet.ServletException;
106: import javax.servlet.http.HttpServletRequest;
107: import javax.servlet.http.HttpServletResponse;
108: import java.io.IOException;
109: import java.util.Enumeration;
110: import java.util.Hashtable;
111: import java.util.Iterator;
112: import java.util.Vector;
113:
114: /**
115: * ViewHandler designed to generate a default view in HTML when no other view is specified
116: *
117: * @author Michael Nash
118: */
119: public class DefaultViewHandler extends ViewHandler {
120: private static Logger log = Logger
121: .getLogger(DefaultViewHandler.class);
122:
123: /* No-args constructor for dynamic instantiation */
124: public DefaultViewHandler() {
125: }
126:
127: /**
128: * Display the response from a controller with a "default" view generated in HTML
129: *
130: * @param con The ControllerResponse object to render
131: * @param req the Servlet Request.
132: * @param res the Servlet response
133: * @throws ServletException upon HTML rendering error
134: * @throws ControllerException upon error querying controller response object
135: * @throws IOException upon i/o error
136: */
137: public void handleView(ControllerResponse con,
138: HttpServletRequest req, HttpServletResponse res)
139: throws ServletException, IOException, ControllerException {
140: try {
141: if (log.isDebugEnabled()) {
142: log.debug("Begin processing default view");
143: }
144:
145: Page myPage = new Page(con.getTitle());
146: Paragraph p1 = new Paragraph(new Text(con.getTitle()));
147: p1.setCSSClass("jc-pageheader");
148: myPage.add(p1);
149:
150: State currState = con.getCurrentState();
151: myPage.add(new Heading(currState.getDescription(), 4));
152:
153: Vector blocks = con.getBlocks();
154: Vector inputs = con.getInputs();
155: Vector outputs = con.getOutputs();
156: Vector transitions = con.getTransitions();
157: ErrorCollection ee = con.getErrors();
158:
159: if (ee != null) {
160: if (!ee.isEmpty()) {
161: displayErrors(myPage, ee);
162: }
163: }
164: if ((blocks == null) && (inputs == null)
165: && (outputs == null) && (transitions == null)) {
166: if (log.isDebugEnabled()) {
167: log.debug("No results to display");
168: }
169: throw new ServletException(
170: "No input, output or transitions "
171: + "defined for this Controller");
172: }
173: if (outputs != null) {
174: Table outputTable = new Table("Output Table");
175: outputTable.setAlignment("center");
176:
177: // outputTable.setWidth("95%");
178: outputTable.setBorder(0);
179: add(con, outputs, outputTable);
180:
181: if (outputTable.getContentCount() > 0) {
182: myPage.add(outputTable);
183: }
184: } /* if outputs not null */
185:
186: Form f = new Form("Input and transitions");
187: f.setCSSClass("jc-default");
188: String encoding = null;
189: f.setAction(Setup.getValueRequired(con.getDBName(),
190: "ContextPath")
191: + con.getRequestPath());
192:
193: /* If the controller has an attribute that specifies a particular */
194:
195: /* form encoding - use it */
196: encoding = StringUtil.notNull(con
197: .getAttribute("formEncoding"));
198:
199: if (!encoding.equals("")) {
200: f.setEncoding(encoding);
201: }
202: if (blocks != null) {
203: for (Enumeration eb = blocks.elements(); eb
204: .hasMoreElements();) {
205: addBlock(con, f, (Block) eb.nextElement());
206: }
207: } /* if inputs not null */
208:
209: if (inputs != null) {
210:
211: /* Check to see if we have any "file" type inputs */
212:
213: /* if so, and we have not had an explicit coding set for the form */
214:
215: /* use multipart/form-data encoding */
216: Input oneInput = null;
217:
218: for (Enumeration ei = inputs.elements(); ei
219: .hasMoreElements();) {
220: oneInput = (Input) ei.nextElement();
221:
222: String s = oneInput.getType();
223:
224: if (s != null && s.equals("file")) {
225: if (encoding.equals("")) {
226: f.setEncoding("multipart/form-data");
227: }
228: }
229: }
230:
231: Table inputTable = new Table("Input Table");
232: add(con, inputs, inputTable);
233:
234: if (inputTable.getContentCount() > 0) {
235: f.add(inputTable);
236: }
237: } /* if inputs not null */
238:
239: if (transitions != null) {
240: Table transitionTable = new Table("Transitions Table");
241: Row transitionRow = new Row();
242: transitionTable.add(transitionRow);
243: addTransitions(transitions, transitionRow, f, con);
244:
245: if (transitionRow.getContentCount() > 0) {
246: f.add(transitionTable);
247: }
248: } /* if transitions not null */
249:
250: if (f.getContentCount() > 0) {
251: myPage.add(f);
252: }
253:
254: Object o = GenericSession.getAttribute(req,
255: com.jcorporate.expresso.ext.taglib.Back.BACK_KEY
256: + ".URL");
257: Object ot = GenericSession.getAttribute(req,
258: com.jcorporate.expresso.ext.taglib.Back.BACK_KEY
259: + ".TITLE");
260:
261: if (o != null) {
262: String backUrl = (String) o;
263: String title = (String) ot;
264: String backImage = ConfigManager.getContext("default")
265: .getImages()
266: + "/FingerLeft.gif";
267:
268: if (!backUrl.equals("NONE")) {
269: myPage.add(new Text(
270: "<p align=\"center\"><a href=\"" + backUrl
271: + "\" title=\"" + title
272: + "\"><img src=\"" + backImage
273: + "\" border=\"0\"></a></p>"));
274: }
275: }
276:
277: printDisplay(con, req, res, myPage);
278: if (log.isDebugEnabled()) {
279: log.debug("Finished displaying default view");
280: }
281: } catch (NullPointerException npe) {
282: npe.printStackTrace();
283: log.warn("NullPointerException:", npe);
284: throw npe;
285: } catch (HtmlException he) {
286: log.warn("HtmlException:", he);
287: throw new ControllerException(he);
288: } catch (DBException de) {
289: log.warn("DBException:", de);
290: throw new ControllerException(de);
291: } catch (ConfigurationException ce) {
292: throw new ControllerException(ce);
293: }
294: } /* doController(HttpServletRequest, HttpServletResponse, Hashtable) */
295:
296: /**
297: * Separate to allow overriding for different types of rendering.
298: *
299: * @param con The ControllerResponse object to render
300: * @param request the Servlet Request.
301: * @param response the Servlet response
302: * @param p the Page to display
303: * @throws HtmlException upon rendering error
304: * @throws ControllerException upon i18n error
305: */
306: protected void printDisplay(ControllerResponse con,
307: HttpServletRequest request, HttpServletResponse response,
308: Page p) throws HtmlException, ControllerException {
309: p.display(request, response, con.getString("charset"));
310: }
311:
312: /**
313: * Displays the errors
314: *
315: * @param myPage page to add the errors for
316: * @param errs the error collection to add to the page
317: * @throws HtmlException upon rendering error
318: */
319: private void displayErrors(Page myPage, ErrorCollection errs)
320: throws HtmlException {
321: Heading errorHeading = new Heading("Errors", 3);
322: errorHeading.setFontColor("red");
323: myPage.add(errorHeading);
324:
325: Table errorTable = new Table("errors");
326: errorTable.setBorder(1);
327:
328: Row oneRow = null;
329:
330: for (Iterator i = errs.get(); i.hasNext();) {
331: ActionMessage oneError = (ActionMessage) i.next();
332: oneRow = new Row("one error");
333:
334: Text t = new Text(oneError.getKey());
335: t.setFontColor("red");
336: oneRow.add(new Cell(t));
337: errorTable.add(oneRow);
338: }
339:
340: myPage.add(errorTable);
341: myPage.add(new Break());
342: }
343:
344: /**
345: * Add a Vector of Transition objects to the specified HtmlElement object.
346: * We are also passed the Form object in order to add the necessary hidden fields
347: * for parameters for each transition.
348: *
349: * @param h the list of transitions
350: * @param res the ControllerREsponse object
351: * @param r the table row to add to
352: * @param f the html element to add to
353: * @throws HtmlException upon rendering error
354: */
355: private void addTransitions(Vector h, Row r, HtmlElement f,
356: ControllerResponse res) throws HtmlException {
357: Transition a = null;
358: Cell oneCell = null;
359: Button oneButton = null;
360: String paramString = null;
361: Hashtable params = null;
362: HiddenField hidden = null;
363:
364: /* Add the parameters by creating a hidden "xxx_params" field for each transition */
365: for (Enumeration e = h.elements(); e.hasMoreElements();) {
366: a = (Transition) e.nextElement();
367:
368: if (a != null) {
369: params = a.getParams();
370:
371: if (params != null) {
372: paramString = a.getParamString();
373: hidden = new HiddenField(a.getName() + "_params",
374: paramString);
375: }
376: if (f != null) {
377: f.add(hidden);
378: } else {
379: r.add(hidden);
380: }
381: }
382: }
383: /* Add an actual button for each of the specified transitions to the row we were given */
384: for (Enumeration e = h.elements(); e.hasMoreElements();) {
385: a = (Transition) e.nextElement();
386:
387: if (a != null) {
388: oneCell = new Cell();
389: oneCell.setAlignment("center");
390: oneCell.setVerticalAlignment("center");
391:
392: String labelString = null;
393:
394: try {
395: labelString = res.getString(a.getLabel());
396: } catch (Exception ee) {
397: labelString = a.getLabel();
398: }
399:
400: oneButton = new Button("button_" + a.getName(),
401: labelString);
402: oneCell.add(oneButton);
403: r.add(oneCell);
404: }
405: }
406: } /* addTransitions(Vector, Row) */
407:
408: /**
409: * Add an Input item to the specified row in a table
410: *
411: * @param i the input to render
412: * @param oneRow the row to render to
413: * @param con the controller response where we got the input
414: * @throws HtmlException upon rendering error
415: * @throws ConfigurationException upon error getting data contexts and setup values
416: * @throws ControllerException upon other exception
417: */
418: private void addInput(Input i, Row oneRow, ControllerResponse con)
419: throws HtmlException, ConfigurationException,
420: ControllerException {
421: String l = i.getLabel();
422: Cell oneCell;
423:
424: if (l != null && l.length() != 0) {
425: oneCell = new Cell();
426: oneCell.add(new Text(l + ":"));
427: oneCell.setCSSClass("jc-label");
428: oneRow.add(oneCell);
429: }
430:
431: oneCell = new Cell();
432: oneCell.setCSSClass("jc-formfield");
433: oneRow.add(oneCell);
434:
435: if (StringUtil.notNull(i.getAttribute("readOnly"))
436: .equalsIgnoreCase("Y")) {
437: oneCell.add(new Text(i.getDefaultValue()));
438:
439: return;
440: }
441:
442: String defaultValue = i.getDefaultValue();
443:
444: if (defaultValue == null) {
445: defaultValue = ("");
446: }
447:
448: /* if the input is multi-valued, use a drop-down list */
449: Vector validValues = i.getValidValues();
450: ValidValue oneValue = null;
451:
452: if (validValues != null && !validValues.isEmpty()) {
453: if (i.getAttributes().containsKey("radio")
454: || i.getAttributes().containsKey("radio-vertical")) {
455: Radio radio = new Radio(i.getName(), defaultValue);
456:
457: for (Enumeration vv = validValues.elements(); vv
458: .hasMoreElements();) {
459: ValidValue v = (ValidValue) vv.nextElement();
460: radio.addOption(v.getValue(), v.getDescription());
461: }
462: if (i.getAttributes().containsKey("radio-vertical")) {
463: radio.setVertical(true);
464: }
465:
466: oneCell.add(radio);
467: } else if (i.getAttributes().containsKey("checkbox")
468: || i.getAttributes().containsKey(
469: "checkbox-vertical")) {
470: CheckBox check = new CheckBox(i.getName(), defaultValue);
471:
472: for (Enumeration vv = validValues.elements(); vv
473: .hasMoreElements();) {
474: ValidValue v = (ValidValue) vv.nextElement();
475: check.addOption(v.getValue(), v.getDescription());
476: }
477:
478: oneCell.add(check);
479:
480: if (i.getAttributes().containsKey("checkbox-vertical")) {
481: check.setVertical(true);
482: }
483: } else {
484: DropDown d = new DropDown(i.getName());
485:
486: for (Enumeration vv = validValues.elements(); vv
487: .hasMoreElements();) {
488: oneValue = (ValidValue) vv.nextElement();
489: d.addOption(oneValue.getValue(), oneValue
490: .getDescription());
491: }
492:
493: d.setCurrentValue(defaultValue);
494: oneCell.add(d);
495: }
496: } else if (i.getAttributes().containsKey("checkbox")) {
497:
498: /* if it's boolean, use a checkbox */
499: if (defaultValue.equalsIgnoreCase("Y")) {
500: oneCell.add(new CheckBox(i.getName(), "Y", true));
501: } else {
502: oneCell.add(new CheckBox(i.getName(), "Y", false));
503: }
504:
505: oneCell.setAlignment("center");
506: } else if (i.getAttributes().containsKey("textarea")) {
507: oneCell.add(new TextArea(i.getName(), StringUtil.notNull(
508: defaultValue).trim(), i.getLines(), i
509: .getDisplayLength()));
510: } else if (i.getAttributes().containsKey("password")) {
511: oneCell.add(new TextField(i.getName(), defaultValue, i
512: .getMaxLength(), i.getDisplayLength()));
513: } else if (i.getAttributes().containsKey("submit")) {
514: oneCell.add(new Button(i.getName(), i.getName()));
515: } else if (i.getAttributes().containsKey("reset")) {
516: } else if (i.getAttributes().containsKey("file")) {
517: oneCell.add(new FileInput(i.getName(), defaultValue));
518: } else if (i.getAttributes().containsKey("hidden")) {
519: oneCell.add(new HiddenField(i.getName(), defaultValue));
520: } else {
521:
522: /* else use a text field */
523: if (i.getLines() > 1) {
524:
525: /* use a text area */
526: oneCell.add(new TextArea(i.getName(), defaultValue, i
527: .getLines(), i.getDisplayLength()));
528: } else {
529: oneCell.add(new TextField(i.getName(), defaultValue, i
530: .getMaxLength(), i.getDisplayLength()));
531: }
532: }
533: if (i.getNested() != null) {
534: Vector v = i.getNested();
535: ControllerElement oneElement = null;
536:
537: for (Enumeration ve = v.elements(); ve.hasMoreElements();) {
538: oneElement = (ControllerElement) ve.nextElement();
539:
540: if (oneElement instanceof Input) {
541: addInput((Input) oneElement, oneRow, con);
542: } else if (oneElement instanceof Output) {
543: addOutput((Output) oneElement, oneRow, con);
544: } else if (oneElement instanceof Transition) {
545: Transition nestedTransition = (Transition) oneElement;
546: String newText = "<a href=\""
547: + ConfigManager.getContextPath()
548: + con.getRequestPath()
549: + "?"
550: + nestedTransition.getParamString()
551: + "\" target=\"_new\"><img src=\""
552: + ConfigManager.getContext(con.getDBName())
553: .getImages()
554: + "/search.png\" border=\"0\"></a>";
555: Cell lookupCell = new Cell(new Text(newText));
556: oneRow.add(lookupCell);
557: }
558: } /* for each nested element */
559:
560: } /* if any nested elements */
561:
562: // if (!lookupAdded) {
563: // oneRow.add(new Cell(new Text(" ")));
564: // }
565: }
566:
567: private void addInput(Input i, Table t, ControllerResponse con)
568: throws HtmlException, ConfigurationException,
569: ControllerException {
570: Row oneRow = new Row();
571: t.add(oneRow);
572: addInput(i, oneRow, con);
573: } /* addInput(Input, Table) */
574:
575: private void addOutput(Output o, Row oneRow, ControllerResponse con)
576: throws HtmlException {
577: Cell oneCell = null;
578: String l = o.getLabel();
579:
580: if (l != null && l.length() > 0) {
581: oneCell = new Cell();
582: oneCell.setCSSClass("jc-label");
583:
584: if (o.getStyle() != null) {
585: oneCell.add(new Text(l, o.getStyle()));
586: } else {
587: oneCell.add(new Text(l));
588: }
589: if (oneRow.isCaptionRow()) {
590: oneCell.setCSSClass("jc-tabletitle");
591: oneCell.setHeaderCell(true);
592: } else {
593: oneCell.setNoWrap(false);
594: }
595:
596: oneRow.add(oneCell);
597: }
598:
599: boolean anyNested = false;
600: Vector v = o.getNested();
601:
602: if (v != null) {
603: if (v.size() > 0) {
604: anyNested = true;
605: }
606: }
607:
608: Transition nestedTransition = null;
609: ControllerElement ce = null;
610:
611: if (anyNested) {
612: for (Enumeration tn = v.elements(); tn.hasMoreElements();) {
613: ce = (ControllerElement) tn.nextElement();
614:
615: if (ce instanceof Transition) {
616: nestedTransition = (Transition) ce;
617: }
618: }
619: }
620:
621: String c = o.getContent();
622:
623: if (c != null) {
624: oneCell = new Cell();
625:
626: if (oneRow.isCaptionRow()) {
627: oneCell.setCSSClass("jc-tabletitle");
628: oneCell.setHeaderCell(true);
629: } else {
630: oneCell.setCSSClass("jc-default");
631: }
632: if (nestedTransition == null) {
633: oneCell.add(new Text(c));
634: } else {
635: String newText = "<a href=\""
636: + ConfigManager.getContextPath()
637: + con.getRequestPath() + "?"
638: + nestedTransition.getParamString() + "\">" + c
639: + "</a>";
640: oneCell.add(new Text(newText));
641: }
642:
643: oneRow.add(oneCell);
644: }
645: if (anyNested) {
646: Cell c2 = new Cell();
647: c2.setNoWrap(false);
648: oneRow.add(c2);
649:
650: Table t2 = new Table("Nested Output");
651: t2.setBorder(1);
652: c2.add(t2);
653:
654: for (Enumeration ve = v.elements(); ve.hasMoreElements();) {
655: ce = (ControllerElement) ve.nextElement();
656:
657: if (ce instanceof Output) {
658: addOutput((Output) ce, t2, con);
659: } else if (ce instanceof Transition) {
660: nestedTransition = (Transition) ce;
661: }
662: }
663: } /* if any nested elements */
664:
665: }
666:
667: /**
668: * Add the designated output to the given table
669: *
670: * @param o The Output object to be added to this table
671: * @param t The Table object that the output should be added to
672: * @param con the ControllerResponse object
673: * @throws HtmlException upon rendering error
674: */
675: private void addOutput(Output o, Table t, ControllerResponse con)
676: throws HtmlException {
677: Row oneRow = new Row();
678: t.add(oneRow);
679: addOutput(o, oneRow, con);
680: } /* addOutput(Output, Table) */
681:
682: /**
683: * Type generic method to addOutput/addInput/addTransition
684: *
685: * @param con The controller response
686: * @param v the list of controller elements
687: * @param t the table to add to
688: */
689: private void add(ControllerResponse con, Vector v, Table t)
690: throws HtmlException, ConfigurationException,
691: ControllerException {
692: for (Enumeration e = v.elements(); e.hasMoreElements();) {
693: ControllerElement o = (ControllerElement) e.nextElement();
694:
695: if (o instanceof Output) {
696: addOutput((Output) o, t, con);
697: } else if (o instanceof Input) {
698: addInput((Input) o, t, con);
699:
700: //} else if (o instanceof Block) {
701: // addBlock(con, (Block) o, t);
702: }
703: } /* for each element in the vector */
704:
705: } /* add(Vector, Table) */
706:
707: private void addBlockAsTable(Block b, HtmlElement myPage,
708: ControllerResponse con) throws HtmlException,
709: ConfigurationException, ControllerException {
710: Table blockTable = new Table();
711: blockTable.setBorder(1);
712: myPage.add(blockTable);
713:
714: if (b.getAttributes().containsKey("header-row")) {
715: Row oneRow = new Row();
716: oneRow.setTitle(b.getAttribute("header-row"));
717: blockTable.add(oneRow);
718: }
719:
720: Block oneBlockRow = null;
721: ControllerElement ce = null;
722:
723: for (Enumeration erows = b.getNested().elements(); erows
724: .hasMoreElements();) {
725: ce = (ControllerElement) erows.nextElement();
726:
727: if (ce instanceof Block) {
728: oneBlockRow = (Block) ce;
729: } else {
730: throw new HtmlException(
731: "Block '"
732: + b.getName()
733: + "' is specified as a table, but tables must "
734: + "contain only blocks (one per row) - this block contained a '"
735: + ce.getClass().getName() + "'");
736: }
737: if ("Y".equals(oneBlockRow.getAttribute("row"))) {
738: ControllerElement oneCell = null;
739: Row oneRow = new Row();
740: blockTable.add(oneRow);
741:
742: for (Enumeration rowContents = oneBlockRow.getNested()
743: .elements(); rowContents.hasMoreElements();) {
744: oneCell = (ControllerElement) rowContents
745: .nextElement();
746:
747: if (oneCell instanceof Output) {
748: addOutput((Output) oneCell, oneRow, con);
749: } else if (oneCell instanceof Input) {
750: addInput((Input) oneCell, oneRow, con);
751: }
752: }
753: } else {
754: throw new HtmlException(
755: "Block '"
756: + b.getName()
757: + "' is specified as a table, but tables must "
758: + "contain only blocks designed as rows. This block contained a row '"
759: + oneBlockRow.getName()
760: + "' that was not specified as a row.");
761: }
762: }
763: } /* addBlockAsTable */
764:
765: /**
766: * Add a single "block" object to the page. This is done by creating a table to hold the contents of the block,
767: * then adding all of the contents to that table.
768: *
769: * @param con the controller response object
770: * @param container the container element
771: * @param thisBlock the block to render
772: */
773: private void addBlock(ControllerResponse con,
774: HtmlElement container, Block this Block)
775: throws HtmlException, ConfigurationException,
776: ControllerException {
777: if ("Y".equals(this Block.getAttribute("table"))) {
778: addBlockAsTable(this Block, container, con);
779: } else {
780: if (this Block.getNested() != null) {
781: Vector transitions = new Vector();
782: Vector v = this Block.getNested();
783:
784: if (v.size() > 0) {
785: Table myBlockTable = new Table("Table for Block "
786: + this Block.getName());
787: container.add(myBlockTable);
788:
789: for (Enumeration ve = v.elements(); ve
790: .hasMoreElements();) {
791: ControllerElement ce = (ControllerElement) ve
792: .nextElement();
793:
794: if (ce instanceof Output) {
795: addOutput((Output) ce, myBlockTable, con);
796: } else if (ce instanceof Input) {
797: addInput((Input) ce, myBlockTable, con);
798: } else if (ce instanceof Transition) {
799: transitions.addElement(ce);
800: } else if (ce instanceof Block) {
801: addBlock(con, container, (Block) ce);
802: }
803: }
804: if (transitions.size() > 0) {
805: Row r = new Row("transitions for block");
806: myBlockTable.add(r);
807: addTransitions(transitions, r, null, con);
808: }
809: } /* if nested vector has contents */
810:
811: } /* if any nested elements */
812:
813: } /* if the block is marked as a table itself */
814:
815: } /* addBlock(ControllerResponse, myPage, thisBlock) */
816:
817: }
|