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.responders;
004:
005: import fitnesse.wiki.*;
006: import fitnesse.html.*;
007: import fitnesse.http.*;
008: import fitnesse.authentication.*;
009: import java.net.*;
010: import java.io.*;
011: import java.util.*;
012:
013: public class WikiImportingResponder extends ChunkingResponder implements
014: SecureResponder, WikiImporterClient {
015: private int alternation = 0;
016: private boolean isUpdate;
017: private boolean isNonRoot;
018: public PageData data;
019:
020: private WikiImporter importer = new WikiImporter();
021:
022: public void setImporter(WikiImporter importer) {
023: this .importer = importer;
024: }
025:
026: protected void doSending() throws Exception {
027: data = page.getData();
028: HtmlPage html = makeHtml();
029: response.add(html.preDivision);
030:
031: try {
032: initializeImporter();
033: addHeadContent();
034: if (isNonRoot)
035: importer.importRemotePageContent(page);
036:
037: importer.importWiki(page);
038:
039: addTailContent();
040:
041: if (!isUpdate) {
042: WikiImportProperty importProperty = new WikiImportProperty(
043: importer.remoteUrl());
044: importProperty.setRoot(true);
045: importProperty.setAutoUpdate(importer
046: .getAutoUpdateSetting());
047: importProperty.addTo(data.getProperties());
048: page.commit(data);
049: }
050: } catch (MalformedURLException e) {
051: writeErrorMessage(e);
052: } catch (FileNotFoundException e) {
053: writeErrorMessage("The remote resource, "
054: + importer.remoteUrl() + ", was not found.");
055: } catch (WikiImporter.AuthenticationRequiredException e) {
056: writeAuthenticationForm(e.getMessage());
057: } catch (Exception e) {
058: writeErrorMessage(e);
059: }
060:
061: response.add(html.postDivision);
062: response.closeAll();
063: }
064:
065: public void initializeImporter() throws Exception {
066: String remoteWikiUrl = establishRemoteUrlAndUpdateStyle();
067: importer.setWikiImporterClient(this );
068: importer.setLocalPath(path);
069: importer.parseUrl(remoteWikiUrl);
070: setRemoteUserCredentialsOnImporter();
071: importer.setAutoUpdateSetting(request.hasInput("autoUpdate"));
072: }
073:
074: private void setRemoteUserCredentialsOnImporter() {
075: if (request.hasInput("remoteUsername"))
076: importer.setRemoteUsername((String) request
077: .getInput("remoteUsername"));
078: if (request.hasInput("remotePassword"))
079: importer.setRemotePassword((String) request
080: .getInput("remotePassword"));
081: }
082:
083: private String establishRemoteUrlAndUpdateStyle() throws Exception {
084: String remoteWikiUrl = (String) request.getInput("remoteUrl");
085:
086: WikiImportProperty importProperty = WikiImportProperty
087: .createFrom(data.getProperties());
088: if (importProperty != null) {
089: remoteWikiUrl = importProperty.getSourceUrl();
090: isUpdate = true;
091: isNonRoot = !importProperty.isRoot();
092: }
093: return remoteWikiUrl;
094: }
095:
096: private void writeErrorMessage(String message) throws Exception {
097: HtmlTag alert = HtmlUtil.makeDivTag("centered");
098: alert.add(new HtmlTag("h2", "Import Failure"));
099: alert.add(message);
100: response.add(alert.html());
101: }
102:
103: private void writeErrorMessage(Exception e) throws Exception {
104: writeErrorMessage(e.getMessage());
105: HtmlTag pre = new HtmlTag("pre");
106: ByteArrayOutputStream output = new ByteArrayOutputStream();
107: PrintStream printStream = new PrintStream(output);
108: e.printStackTrace(printStream);
109: printStream.flush();
110: pre.add(new String(output.toByteArray()));
111: response.add(pre.html());
112: }
113:
114: private void addHeadContent() throws Exception {
115: TagGroup head = new TagGroup();
116: if (isUpdate)
117: head.add("Updating imported wiki.");
118: else
119: head.add("Importing wiki.");
120: head.add(" This may take a few moments.");
121: head.add(HtmlUtil.BR);
122: head.add(HtmlUtil.BR);
123: head.add("Destination wiki: ");
124: String pageName = PathParser.render(path);
125: head.add(HtmlUtil.makeLink(pageName, pageName));
126:
127: head.add(HtmlUtil.BR);
128: head.add("Source wiki: ");
129: String remoteWikiUrl = importer.remoteUrl();
130: head.add(HtmlUtil.makeLink(remoteWikiUrl, remoteWikiUrl));
131:
132: head.add(HtmlUtil.BR);
133: head.add(HtmlUtil.BR);
134: head.add("Imported pages:");
135: head.add(HtmlUtil.HR);
136: response.add(head.html());
137: }
138:
139: private void addTailContent() throws Exception {
140: TagGroup tail = makeTailHtml(importer);
141: response.add(tail.html());
142: }
143:
144: public TagGroup makeTailHtml(WikiImporter importer)
145: throws Exception {
146: TagGroup tail = new TagGroup();
147: tail.add("<a name=\"end\"><hr></a>");
148: tail.add(HtmlUtil.makeBold("Import complete. "));
149:
150: addUnmodifiedCount(importer, tail);
151: tail.add(HtmlUtil.BR);
152: addImportedPageCount(importer, tail);
153: addOrphanedPageSection(importer, tail);
154: addAutoUpdateMessage(importer, tail);
155:
156: return tail;
157: }
158:
159: private void addAutoUpdateMessage(WikiImporter importer,
160: TagGroup tail) {
161: tail.add(HtmlUtil.BR);
162: String message = "Automatic Update turned "
163: + (importer.getAutoUpdateSetting() ? "ON" : "OFF");
164: tail.add(message);
165: }
166:
167: private void addUnmodifiedCount(WikiImporter importer, TagGroup tail) {
168: if (importer.getUnmodifiedCount() != 0) {
169: tail.add(HtmlUtil.BR);
170: if (importer.getUnmodifiedCount() == 1)
171: tail.add("1 page was unmodified.");
172: else
173: tail.add(importer.getUnmodifiedCount()
174: + " pages were unmodified.");
175: }
176: }
177:
178: private void addImportedPageCount(WikiImporter importer,
179: TagGroup tail) {
180: if (importer.getImportCount() == 1)
181: tail.add("1 page was imported.");
182: else
183: tail.add(importer.getImportCount()
184: + " pages were imported.");
185: }
186:
187: private void addOrphanedPageSection(WikiImporter importer,
188: TagGroup tail) {
189: List<WikiPagePath> orphans = importer.getOrphans();
190: if (orphans.size() > 0) {
191: tail.add(HtmlUtil.BR);
192: if (orphans.size() == 1)
193: tail
194: .add("1 orphaned page was found and has been removed.");
195: else
196: tail
197: .add(orphans.size()
198: + " orphaned pages were found and have been removed.");
199: tail
200: .add(" This may occur when a remote page is deleted, moved, or renamed.");
201: tail.add(HtmlUtil.BR);
202: tail.add(HtmlUtil.BR);
203: tail.add("Orphans:");
204: tail.add(HtmlUtil.HR);
205:
206: for (Iterator iterator = orphans.iterator(); iterator
207: .hasNext();) {
208: WikiPagePath path = (WikiPagePath) iterator.next();
209: HtmlTag row = alternatingRow();
210: row.add(PathParser.render(path));
211: tail.add(row);
212: }
213: tail.add(HtmlUtil.HR);
214: }
215: }
216:
217: private HtmlPage makeHtml() throws Exception {
218: HtmlPage html = context.htmlPageFactory.newPage();
219: html = context.htmlPageFactory.newPage();
220: String title = "Wiki Import";
221: if (isUpdate)
222: title += " Update";
223: String localPathName = PathParser.render(path);
224: html.title.use(title + ": " + localPathName);
225: html.header.use(HtmlUtil.makeBreadCrumbsWithPageType(
226: localPathName, title));
227: html.main.add(HtmlPage.BreakPoint);
228: html.divide();
229: return html;
230: }
231:
232: protected PageCrawler getPageCrawler() {
233: return root.getPageCrawler();
234: }
235:
236: private void addRowToResponse(String status) throws Exception {
237: HtmlTag tag = alternatingRow();
238: String relativePathName = PathParser.render(importer
239: .getRelativePath());
240: String localPathName = PathParser.render(importer
241: .getLocalPath());
242: tag.add(HtmlUtil.makeLink(localPathName, relativePathName));
243: tag.add(" " + status);
244: response.add(tag.html());
245: }
246:
247: private HtmlTag alternatingRow() {
248: return HtmlUtil.makeDivTag("alternating_row_" + alternate());
249: }
250:
251: private int alternate() {
252: alternation = alternation % 2 + 1;
253: return alternation;
254: }
255:
256: public void setResponse(ChunkedResponse response) {
257: this .response = response;
258: }
259:
260: public SecureOperation getSecureOperation() {
261: return new SecureWriteOperation();
262: }
263:
264: private void writeAuthenticationForm(String resource)
265: throws Exception {
266: HtmlTag html = HtmlUtil.makeDivTag("centered");
267: html.add(new HtmlTag("h3", "The wiki at " + resource
268: + " requires authentication."));
269: html.add(HtmlUtil.BR);
270:
271: HtmlTag form = new HtmlTag("form");
272: form.addAttribute("action", request.getResource());
273: form.addAttribute("method", "post");
274: form
275: .add(HtmlUtil.makeInputTag("hidden", "responder",
276: "import"));
277: if (request.hasInput("remoteUrl"))
278: form.add(HtmlUtil.makeInputTag("hidden", "remoteUrl",
279: (String) request.getInput("remoteUrl")));
280:
281: form.add("remote username: ");
282: form.add(HtmlUtil.makeInputTag("text", "remoteUsername"));
283: form.add(HtmlUtil.BR);
284: form.add("remote password: ");
285: form.add(HtmlUtil.makeInputTag("password", "remotePassword"));
286: form.add(HtmlUtil.BR);
287: form.add(HtmlUtil.makeInputTag("submit", "submit",
288: "Authenticate and Continue Import"));
289:
290: html.add(form);
291: response.add(html.html());
292: }
293:
294: public void pageImported(WikiPage localPage) throws Exception {
295: addRowToResponse("");
296: }
297:
298: public void pageImportError(WikiPage localPage, Exception e)
299: throws Exception {
300: addRowToResponse(e.toString());
301: }
302:
303: public WikiImporter getImporter() {
304: return importer;
305: }
306: }
|