001: // Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
002: // Released under the terms of the GNU General Public License version 2 or later.
003: package fitnesse.wikitext.widgets;
004:
005: import fitnesse.wikitext.*;
006:
007: import java.util.*;
008: import java.util.regex.Matcher;
009:
010: public abstract class ParentWidget extends WikiWidget {
011: protected LinkedList children = new LinkedList();
012:
013: private int currentChild = 0;
014:
015: public ParentWidget(ParentWidget parent) {
016: super (parent);
017: }
018:
019: public void reset() {
020: children.clear();
021: currentChild = 0;
022: }
023:
024: public void addChild(WikiWidget widget) {
025: children.add(widget);
026: }
027:
028: public int numberOfChildren() {
029: return children.size();
030: }
031:
032: public List getChildren() {
033: return children;
034: }
035:
036: public WikiWidget nextChild() {
037: if (hasNextChild())
038: return (WikiWidget) children.get(currentChild++);
039: else
040: throw new ArrayIndexOutOfBoundsException(
041: "No next child exists");
042: }
043:
044: public boolean hasNextChild() {
045: return (currentChild < numberOfChildren());
046: }
047:
048: public String childHtml() throws Exception {
049: currentChild = 0;
050: StringBuffer html = new StringBuffer();
051: while (hasNextChild()) {
052: WikiWidget child = nextChild();
053: html.append(child.render());
054: }
055:
056: return html.toString();
057: }
058:
059: public String childWikiText() throws Exception {
060: currentChild = 0;
061: StringBuffer wikiText = new StringBuffer();
062: while (hasNextChild()) {
063: WikiWidget child = nextChild();
064: wikiText.append(child.asWikiText());
065: }
066:
067: return wikiText.toString();
068:
069: }
070:
071: public int defineLiteral(String literal) {
072: return parent.defineLiteral(literal);
073: }
074:
075: public String getLiteral(int literalNumber) {
076: return parent.getLiteral(literalNumber);
077: }
078:
079: public void addVariable(String key, String value) {
080: parent.addVariable(key, value);
081: }
082:
083: public String getVariable(String key) throws Exception {
084: return parent.getVariable(key);
085: }
086:
087: public void addChildWidgets(String value) throws Exception {
088: Matcher matcher = getBuilder().getWidgetPattern()
089: .matcher(value);
090:
091: if (matcher.find()) {
092: String preString = value.substring(0, matcher.start());
093: if (!"".equals(preString))
094: new TextWidget(this , preString);
095: getBuilder().makeWidget(this , matcher);
096: String postString = value.substring(matcher.end());
097: if (!postString.equals(""))
098: addChildWidgets(postString);
099: } else
100: new TextWidget(this , value);
101: }
102:
103: public WidgetBuilder getBuilder() {
104: return parent.getBuilder();
105: }
106:
107: public boolean doEscaping() {
108: return parent.doEscaping();
109: }
110:
111: public boolean preProcessingComplete() {
112: return (children.size() == 1 && (children.get(0) instanceof TextWidget));
113: }
114:
115: public void acceptVisitor(WidgetVisitor visitor) throws Exception {
116: visitor.visit(this );
117: currentChild = 0;
118: while (hasNextChild()) {
119: WikiWidget child = nextChild();
120: child.acceptVisitor(visitor);
121: }
122: }
123:
124: public String processLiterals(String value) throws Exception {
125: return new LiteralProcessingWidgetRoot(this , value).childHtml();
126: }
127:
128: public static WidgetBuilder preprocessingLiteralWidgetBuilder = new WidgetBuilder(
129: new Class[] { PreProcessorLiteralWidget.class });
130:
131: public static class LiteralProcessingWidgetRoot extends
132: ParentWidget {
133: public LiteralProcessingWidgetRoot(ParentWidget parent,
134: String content) throws Exception {
135: super (parent);
136: if (content != null)
137: addChildWidgets(content);
138: }
139:
140: public WidgetBuilder getBuilder() {
141: return preprocessingLiteralWidgetBuilder;
142: }
143:
144: public boolean doEscaping() {
145: return false;
146: }
147:
148: public String render() throws Exception {
149: return "";
150: }
151:
152: protected void addToParent() {
153: }
154: }
155: }
|