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.components.PageReferencer;
006: import fitnesse.wiki.*;
007: import java.util.*;
008: import java.util.regex.*;
009:
010: public class IncludeWidget extends ParentWidget implements
011: PageReferencer {
012: public static final String REGEXP = "^!include(?: +-setup| +-teardown| +-seamless| +-c)? "
013: + WikiWordWidget.REGEXP + LineBreakWidget.REGEXP + "?";
014: static final Pattern pattern = Pattern
015: .compile("^!include *(-setup|-teardown|-seamless|-c)? (.*)");
016:
017: public static final String COLLAPSE_SETUP = "COLLAPSE_SETUP";
018: public static final String COLLAPSE_TEARDOWN = "COLLAPSE_TEARDOWN";
019:
020: protected String pageName;
021: protected WikiPage includingPage;
022: protected WikiPage parentPage;
023:
024: private static Map optionPrefixMap = buildOptionPrefixMap();
025: private static Map optionCssMap = buildOptionsCssMap();
026:
027: public IncludeWidget(ParentWidget parent, String text)
028: throws Exception {
029: super (parent);
030: Matcher matcher = pattern.matcher(text);
031: if (matcher.find()) {
032: pageName = getPageName(matcher);
033: includingPage = parent.getWikiPage();
034: parentPage = includingPage.getParent();
035: buildWidget(getOption(matcher));
036: }
037: }
038:
039: protected String getIncludedPageContent() throws Exception {
040: PageCrawler crawler = parentPage.getPageCrawler();
041: crawler.setDeadEndStrategy(new VirtualEnabledPageCrawler());
042: WikiPagePath pagePath = PathParser.parse(pageName);
043: WikiPage includedPage = crawler.getSiblingPage(includingPage,
044: pagePath);
045: if (includedPage != null) {
046: return includedPage.getData().getContent();
047: } else if (includingPage instanceof ProxyPage) {
048: ProxyPage proxy = (ProxyPage) includingPage;
049: String host = proxy.getHost();
050: int port = proxy.getHostPort();
051: try {
052: ProxyPage remoteIncludedPage = new ProxyPage(
053: "RemoteIncludedPage", null, host, port,
054: pagePath);
055: return remoteIncludedPage.getData().getContent();
056: } catch (Exception e) {
057: return "!meta '''Remote page " + host + ":" + port
058: + "/" + pageName + " does not exist.'''";
059: }
060: } else {
061: return "!meta '''Page include failed because the page "
062: + pageName + " does not exist.'''";
063: }
064: }
065:
066: protected WikiPage getIncludedPage() throws Exception {
067: PageCrawler crawler = parentPage.getPageCrawler();
068: crawler.setDeadEndStrategy(new VirtualEnabledPageCrawler());
069: return crawler.getPage(parentPage, PathParser.parse(pageName));
070: }
071:
072: protected WikiPage getParentPage() throws Exception {
073: return parent.getWikiPage().getParent();
074: }
075:
076: private String getOption(Matcher match) {
077: return match.group(1);
078: }
079:
080: private String getPageName(Matcher match) {
081: return match.group(2);
082: }
083:
084: //TODO MDM I know this is bad... But it seems better then creatting two new widgets.
085: private void buildWidget(String option) throws Exception {
086: String widgetText = processLiterals(getIncludedPageContent());
087: if ("-seamless".equals(option)) {
088: addChildWidgets(widgetText + "\n");
089: } else {
090: new CollapsableWidget(this , getPrefix(option) + pageName,
091: widgetText, getCssClass(option),
092: isCollapsed(option));
093: }
094: }
095:
096: private String getCssClass(String option) {
097: return (String) optionCssMap.get(option);
098: }
099:
100: private String getPrefix(String option) {
101: return (String) optionPrefixMap.get(option);
102: }
103:
104: private boolean isCollapsed(String option) throws Exception {
105: if (isSetup(option) && isSetupCollapsed())
106: return true;
107: else if (isTeardown(option) && isTeardownCollapsed())
108: return true;
109: else if ("-c".equals(option))
110: return true;
111: return false;
112: }
113:
114: private static Map buildOptionsCssMap() {
115: Map optionCssMap = new HashMap();
116: optionCssMap.put("-setup", "setup");
117: optionCssMap.put("-teardown", "teardown");
118: optionCssMap.put("-c", "included");
119: optionCssMap.put(null, "included");
120: return optionCssMap;
121: }
122:
123: private static Map buildOptionPrefixMap() {
124: Map optionPrefixMap = new HashMap();
125: optionPrefixMap.put("-setup", "Set Up: ");
126: optionPrefixMap.put("-teardown", "Tear Down: ");
127: optionPrefixMap.put("-c", "Included page: ");
128: optionPrefixMap.put(null, "Included page: ");
129: return optionPrefixMap;
130: }
131:
132: private boolean isTeardownCollapsed() throws Exception {
133: return "true".equals(parent.getVariable(COLLAPSE_TEARDOWN));
134: }
135:
136: private boolean isTeardown(String option) {
137: return "-teardown".equals(option);
138: }
139:
140: private boolean isSetupCollapsed() throws Exception {
141: return "true".equals(parent.getVariable(COLLAPSE_SETUP));
142: }
143:
144: private boolean isSetup(String option) {
145: return "-setup".equals(option);
146: }
147:
148: public String render() throws Exception {
149: return childHtml();
150: }
151:
152: public WikiPage getReferencedPage() throws Exception {
153: return getParentPage().getPageCrawler().getPage(
154: getParentPage(), PathParser.parse(pageName));
155: }
156:
157: }
|