001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2004-2005 Xan Gregg (xan.gregg@forthgo.com)
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (at your option) any later version.
010:
011: This program is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.forthgo.jspwiki.jdbcprovider;
021:
022: import com.ecyrd.jspwiki.*;
023: import com.ecyrd.jspwiki.providers.ProviderException;
024: import com.ecyrd.jspwiki.providers.WikiPageProvider;
025: import com.ecyrd.jspwiki.util.ClassUtil;
026: import org.apache.log4j.Category;
027:
028: import java.io.FileInputStream;
029: import java.io.IOException;
030: import java.sql.*;
031: import java.util.*;
032: import java.util.Date;
033:
034: /*
035: * History:
036: * 2005-09-28 XG Use jspwiki-s as property prefix for security.
037: * 2005-09-07 XG Always use java.util.Date for LastModifield field to friendlier comparisons.
038: * 2005-08-31 XG Remove legacy comment.
039: * 2005-08-30 XG Added changes suggested by Gregor Hagedorn:
040: * - removed dependence on auto-incrementing ID fields
041: * - added "continuation edit" time-out
042: * - added notes for SQL Server DB creation
043: * 2005-08-24 XG Fixed possible resource leak with conditionally closed statements
044: */
045:
046: /**
047: * Provides a database-based repository for Wiki pages.
048: * MySQL commands to create the tables are provided in the code comments.
049: * <p/>
050: * Based on Thierry Lach's DatabaseProvider, which supported Wiki pages
051: * but not attachments.
052: *
053: * @author Thierry Lach
054: * @author Xan Gregg
055: */
056: public class JDBCPageProvider extends JDBCBaseProvider implements
057: WikiPageProvider {
058:
059: /* MySQL table creation commands:
060:
061: CREATE TABLE WIKI_PAGE
062: (
063: PAGE_NAME VARCHAR (100) NOT NULL,
064: PAGE_VERSION INTEGER NOT NULL,
065: PAGE_MODIFIED DATETIME,
066: PAGE_MODIFIED_BY VARCHAR (50),
067: PAGE_TEXT MEDIUMTEXT,
068: PRIMARY KEY (PAGE_NAME),
069: UNIQUE (PAGE_NAME),
070: INDEX PAGE_MODIFIED_IX (PAGE_MODIFIED)
071: );
072: CREATE TABLE WIKI_PAGE_VERSIONS
073: (
074: VERSION_NAME VARCHAR (100) NOT NULL,
075: VERSION_NUM INTEGER NOT NULL,
076: VERSION_MODIFIED DATETIME,
077: VERSION_MODIFIED_BY VARCHAR (50),
078: VERSION_TEXT MEDIUMTEXT,
079: PRIMARY KEY (VERSION_NAME, VERSION_NUM),
080: UNIQUE (VERSION_NAME, VERSION_NUM)
081: );
082:
083: --Script written for MS SQL Server 2000 (from Gregor Hagedorn).
084: -- - NVARCHAR, NTEXT support unicode, VARCHAR, TEXT do not
085: -- - The INDEX syntax used for MySQL does not work here, separate statement added
086: -- - A foreign key relation to versions has been added
087:
088: CREATE DATABASE YourChoiceOfName
089: GO
090: Use YourChoiceOfName
091:
092: CREATE TABLE WIKI_PAGE (
093: PAGE_NAME NVARCHAR(100) NOT NULL ,
094: PAGE_VERSION INTEGER NOT NULL DEFAULT 0,
095: PAGE_MODIFIED DATETIME NULL ,
096: PAGE_MODIFIED_BY NVARCHAR(50) NULL ,
097: PAGE_TEXT NTEXT NULL ,
098: CONSTRAINT PK_WIKI_PAGE PRIMARY KEY CLUSTERED (PAGE_NAME)
099: )
100: CREATE INDEX IX_PAGE_MODIFIED ON WIKI_PAGE (PAGE_MODIFIED)
101:
102: CREATE TABLE WIKI_PAGE_VERSIONS (
103: VERSION_NAME NVARCHAR(100) NOT NULL ,
104: VERSION_NUM INTEGER NOT NULL DEFAULT 0,
105: VERSION_MODIFIED DATETIME NULL ,
106: VERSION_MODIFIED_BY NVARCHAR(50) NULL ,
107: VERSION_TEXT NTEXT NULL ,
108: CONSTRAINT PK_WIKI_PAGE_VERSIONS PRIMARY KEY CLUSTERED (VERSION_NAME, VERSION_NUM) ,
109: CONSTRAINT FK_WIKI_PAGE_VERSIONS_WIKI_PAGE FOREIGN KEY(VERSION_NAME) REFERENCES WIKI_PAGE(PAGE_NAME)
110: )
111: GO
112:
113: */
114:
115: protected static final Category log = Category
116: .getInstance(JDBCPageProvider.class);
117: protected static final int ONE_MINUTE = 60 * 1000; // in milliseconds
118: protected int m_continuationEditTimeout = 60 * ONE_MINUTE; // one hour in milliseconds
119:
120: private static final String PAGE_TABLE_NAME = "WIKI_PAGE";
121: private static final String PAGE_VERSIONS_TABLE_NAME = "WIKI_PAGE_VERSIONS";
122:
123: public void initialize(WikiEngine engine, Properties properties)
124: throws NoRequiredPropertyException, IOException {
125: debug("Initializing JDBCPageProvider");
126: super .initialize(engine, properties);
127: try {
128: checkTable(JDBCPageProvider.PAGE_TABLE_NAME);
129: checkTable(JDBCPageProvider.PAGE_VERSIONS_TABLE_NAME);
130: } catch (SQLException e) {
131: throw new IOException("SQL Exception: " + e.getMessage());
132: }
133: m_continuationEditTimeout = TextUtil.getIntegerProperty(
134: properties, getPropertyBase()
135: + "continuationEditMinutes", 0);
136: m_continuationEditTimeout *= ONE_MINUTE;
137: int n = getPageCount();
138: String migrationPath = properties.getProperty(getPropertyBase()
139: + "migrateFrom");
140: if (n == 0 && migrationPath != null)
141: migratePages(engine, migrationPath);
142: }
143:
144: protected String getPropertyBase() {
145: return "jspwiki-s.JDBCPageProvider."; // -s prevents display as a wikii variable for security
146: }
147:
148: public Category getLog() {
149: return log;
150: }
151:
152: public String getCheckAliveTableName() {
153: return PAGE_TABLE_NAME;
154: }
155:
156: public boolean pageExists(String page) {
157: boolean found = false;
158: Connection connection = null;
159: try {
160: connection = getConnection();
161: String sql = "SELECT PAGE_VERSION FROM " + PAGE_TABLE_NAME
162: + " " + " WHERE PAGE_NAME = ?";
163: PreparedStatement ps = connection.prepareStatement(sql);
164: ps.setString(1, page);
165: ResultSet rs = ps.executeQuery();
166: if (rs.next()) {
167: found = true;
168: }
169: rs.close();
170: ps.close();
171: } catch (SQLException se) {
172: error("unable to check existence for " + page, se);
173: } finally {
174: releaseConnection(connection);
175: }
176: return found;
177: }
178:
179: /**
180: * Read the text directly from the correct file.
181: */
182: private String getCurrentPageText(String page) {
183: String pageText = null;
184: Connection connection = null;
185: try {
186: connection = getConnection();
187: String sql = "SELECT PAGE_TEXT FROM " + PAGE_TABLE_NAME
188: + " WHERE PAGE_NAME = ?";
189: PreparedStatement ps = connection.prepareStatement(sql);
190: ps.setString(1, page);
191: ResultSet rs = ps.executeQuery();
192:
193: if (rs.next()) {
194: pageText = rs.getString("PAGE_TEXT");
195: } else {
196: // This is okay.
197: info("New page '" + page + "'");
198: }
199: rs.close();
200: ps.close();
201:
202: } catch (SQLException se) {
203: error("unable to get current page text for " + page, se);
204: } finally {
205: releaseConnection(connection);
206: }
207:
208: return pageText;
209: }
210:
211: public String getPageText(String page, int version)
212: throws ProviderException {
213: if (version == WikiPageProvider.LATEST_VERSION) {
214: return getCurrentPageText(page);
215: }
216:
217: String pageText = null;
218: Connection connection = null;
219: try {
220: connection = getConnection();
221: String sql = "SELECT VERSION_TEXT FROM "
222: + PAGE_VERSIONS_TABLE_NAME
223: + " WHERE VERSION_NAME = ?"
224: + " AND VERSION_NUM = ?";
225: PreparedStatement ps = connection.prepareStatement(sql);
226: ps.setString(1, page);
227: ps.setInt(2, version);
228: ResultSet rs = ps.executeQuery();
229:
230: if (rs.next()) {
231: pageText = rs.getString("VERSION_TEXT");
232: } else {
233: // This is okay.
234: info("New page '" + page + "'");
235: }
236: rs.close();
237: ps.close();
238:
239: } catch (SQLException se) {
240: error(
241: "unable to get page text for " + page + ":"
242: + version, se);
243: } finally {
244: releaseConnection(connection);
245: }
246: return pageText;
247: }
248:
249: private void insertPageText(WikiPage page, String text) {
250: Connection connection = null;
251: try {
252: connection = getConnection();
253: String sql = "INSERT INTO " + PAGE_TABLE_NAME
254: + " (PAGE_NAME, PAGE_VERSION,"
255: + " PAGE_MODIFIED, PAGE_MODIFIED_BY,"
256: + " PAGE_TEXT)" + " VALUES (?, ?, ?, ?, ?)";
257: PreparedStatement psPage = connection.prepareStatement(sql);
258: psPage.setString(1, page.getName());
259: psPage.setInt(2, 1);
260: Timestamp d = new Timestamp(System.currentTimeMillis());
261: psPage.setTimestamp(3, d);
262: psPage.setString(4, page.getAuthor());
263: psPage.setString(5, text);
264: psPage.execute();
265: psPage.close();
266:
267: sql = "INSERT INTO " + PAGE_VERSIONS_TABLE_NAME
268: + " (VERSION_NAME, VERSION_NUM,"
269: + " VERSION_MODIFIED, VERSION_MODIFIED_BY,"
270: + " VERSION_TEXT)" + " VALUES (?, ?, ?, ?, ?)";
271: PreparedStatement psVer = connection.prepareStatement(sql);
272: psVer.setString(1, page.getName());
273: psVer.setInt(2, 1);
274: psVer.setTimestamp(3, d);
275: psVer.setString(4, page.getAuthor());
276: psVer.setString(5, text);
277: psVer.execute();
278: psVer.close();
279: } catch (SQLException se) {
280: error("Saving failed", se);
281: } finally {
282: releaseConnection(connection);
283: }
284: }
285:
286: private void updatePageText(WikiPage page, String text) {
287: Connection connection = null;
288: try {
289: connection = getConnection();
290: String sql = "SELECT PAGE_VERSION, PAGE_MODIFIED, PAGE_MODIFIED_BY FROM "
291: + PAGE_TABLE_NAME + " WHERE PAGE_NAME = ?";
292: PreparedStatement psQuery = connection
293: .prepareStatement(sql);
294: psQuery.setString(1, page.getName());
295: ResultSet rs = psQuery.executeQuery();
296: rs.next();
297: int version = rs.getInt(1);
298: Timestamp previousModified = rs.getTimestamp(2);
299: String previousAuthor = rs.getString(3);
300: rs.close();
301: psQuery.close();
302:
303: /* If same author and saved again within m_continuationEditTimeout, save by directly overwriting,
304: i.e. keep version number and do not create a backup */
305: boolean isDifferentAuthor = page.getAuthor() == null
306: || page.getAuthor().equals("")
307: || !page.getAuthor().equals(previousAuthor);
308: boolean isContinuationEditTimeExpired = System
309: .currentTimeMillis() > m_continuationEditTimeout
310: + previousModified.getTime();
311: boolean createVersion = isDifferentAuthor
312: || isContinuationEditTimeExpired;
313:
314: if (createVersion)
315: version += 1;
316:
317: sql = "UPDATE " + PAGE_TABLE_NAME
318: + " SET PAGE_MODIFIED = ?,"
319: + " PAGE_MODIFIED_BY = ?,"
320: + " PAGE_VERSION = ?," + " PAGE_TEXT = ?"
321: + " WHERE PAGE_NAME = ?";
322: PreparedStatement psPage = connection.prepareStatement(sql);
323: Timestamp d = new Timestamp(System.currentTimeMillis());
324: psPage.setTimestamp(1, d);
325: psPage.setString(2, page.getAuthor());
326: psPage.setInt(3, version);
327: psPage.setString(4, text);
328: psPage.setString(5, page.getName());
329: psPage.execute();
330: psPage.close();
331:
332: if (createVersion) {
333: sql = "INSERT INTO " + PAGE_VERSIONS_TABLE_NAME
334: + " (VERSION_NAME, VERSION_NUM,"
335: + " VERSION_MODIFIED, VERSION_MODIFIED_BY,"
336: + " VERSION_TEXT)" + " VALUES (?, ?, ?, ?, ?)";
337: PreparedStatement psVer = connection
338: .prepareStatement(sql);
339: psVer.setString(1, page.getName());
340: psVer.setInt(2, version);
341: psVer.setTimestamp(3, d);
342: psVer.setString(4, page.getAuthor());
343: psVer.setString(5, text);
344: psVer.execute();
345: psVer.close();
346: }
347: } catch (SQLException se) {
348: error("Saving failed", se);
349: } finally {
350: releaseConnection(connection);
351: }
352: }
353:
354: public void putPageText(WikiPage page, String text)
355: throws ProviderException {
356: if (pageExists(page.getName())) {
357: updatePageText(page, text);
358: } else {
359: insertPageText(page, text);
360: }
361: }
362:
363: public Collection getAllPages() throws ProviderException {
364: Collection set = new ArrayList();
365:
366: Connection connection = null;
367: try {
368: connection = getConnection();
369: String sql = "SELECT PAGE_NAME, PAGE_VERSION,"
370: + " PAGE_MODIFIED, PAGE_MODIFIED_BY" + " FROM "
371: + PAGE_TABLE_NAME;
372: PreparedStatement ps = connection.prepareStatement(sql);
373: ResultSet rs = ps.executeQuery();
374: while (rs.next()) {
375: WikiPage page = new WikiPage(rs.getString("PAGE_NAME"));
376: page.setVersion(rs.getInt("PAGE_VERSION"));
377: // use Java Date for friendlier comparisons with other dates
378: page.setLastModified(new java.util.Date(rs
379: .getTimestamp("PAGE_MODIFIED").getTime()));
380: page.setAuthor(rs.getString("PAGE_MODIFIED_BY"));
381: set.add(page);
382: }
383: rs.close();
384: ps.close();
385: } catch (SQLException se) {
386: error("unable to get all pages", se);
387: } finally {
388: releaseConnection(connection);
389: }
390:
391: return set;
392: }
393:
394: public Collection getAllChangedSince(Date date) {
395: Collection set = new ArrayList();
396:
397: Connection connection = null;
398: try {
399: connection = getConnection();
400: String sql = "SELECT PAGE_NAME, PAGE_VERSION,"
401: + " PAGE_MODIFIED, PAGE_MODIFIED_BY" + " FROM "
402: + PAGE_TABLE_NAME + " WHERE PAGE_MODIFIED > ?";
403: PreparedStatement ps = connection.prepareStatement(sql);
404: ps.setTimestamp(1, new Timestamp(date.getTime()));
405: ResultSet rs = ps.executeQuery();
406: while (rs.next()) {
407: WikiPage page = new WikiPage(rs.getString("PAGE_NAME"));
408: page.setVersion(rs.getInt("PAGE_VERSION"));
409: // use Java Date for friendlier comparisons with other dates
410: page.setLastModified(new java.util.Date(rs
411: .getTimestamp("PAGE_MODIFIED").getTime()));
412: page.setAuthor(rs.getString("PAGE_MODIFIED_BY"));
413: set.add(page);
414: }
415: rs.close();
416: ps.close();
417: } catch (SQLException se) {
418: error("unable to get all pages since " + date, se);
419: } finally {
420: releaseConnection(connection);
421: }
422:
423: return set;
424: }
425:
426: public int getPageCount() {
427: int count = 0;
428: // Check if the page table exists
429: Connection connection = null;
430: try {
431: connection = getConnection();
432: String sql = "SELECT COUNT(*) FROM " + PAGE_TABLE_NAME;
433: Statement stmt = connection.createStatement();
434: ResultSet rs = stmt.executeQuery(sql);
435: rs.next();
436: count = rs.getInt(1);
437: rs.close();
438: stmt.close();
439: } catch (SQLException se) {
440: error("unable to get page count ", se);
441: } finally {
442: releaseConnection(connection);
443: }
444: return count;
445:
446: }
447:
448: public Collection findPages(QueryItem[] query) {
449: Collection res = new TreeSet(new SearchResultComparator());
450: SearchMatcher matcher = new SearchMatcher(query);
451:
452: Collection wikipages = null;
453: try {
454: wikipages = getAllPages();
455: } catch (ProviderException e) {
456: }
457:
458: nextfile: for (Iterator i = wikipages.iterator(); i.hasNext();) {
459: // debug("Searching page "+wikipages[i].getPath() );
460: WikiPage page = (WikiPage) i.next();
461: try {
462: String pagetext = getCurrentPageText(page.getName());
463: SearchResult comparison = matcher.matchPageContent(page
464: .getName(), pagetext);
465: if (comparison != null) {
466: res.add(comparison);
467: }
468:
469: } catch (IOException se) {
470: error("Failed to read", se);
471: }
472: }
473:
474: return res;
475: }
476:
477: /**
478: * Always returns the latest version here.
479: */
480: private WikiPage getCurrentPageInfo(String page) {
481: WikiPage p = null;
482: Connection connection = null;
483: try {
484: connection = getConnection();
485: String sql = "SELECT PAGE_VERSION," + " PAGE_MODIFIED,"
486: + " PAGE_MODIFIED_BY" + " FROM " + PAGE_TABLE_NAME
487: + " WHERE PAGE_NAME = ?";
488: PreparedStatement ps = connection.prepareStatement(sql);
489: ps.setString(1, page);
490: ResultSet rs = ps.executeQuery();
491:
492: if (rs.next()) {
493: p = new WikiPage(page);
494: p.setVersion(rs.getInt("PAGE_VERSION"));
495: // use Java Date for friendlier comparisons with other dates
496: p.setLastModified(new java.util.Date(rs.getTimestamp(
497: "PAGE_MODIFIED").getTime()));
498: p.setAuthor(rs.getString("PAGE_MODIFIED_BY"));
499: }
500: rs.close();
501: ps.close();
502: } catch (SQLException se) {
503: error("unable to get current page info for " + page, se);
504: } finally {
505: releaseConnection(connection);
506: }
507: return p;
508: }
509:
510: /**
511: * Return the correct version of the page.
512: */
513: public WikiPage getPageInfo(String page, int version)
514: throws ProviderException {
515: WikiPage p = null;
516: if (version == WikiPageProvider.LATEST_VERSION) {
517: p = getCurrentPageInfo(page);
518: } else {
519: Connection connection = null;
520: try {
521: connection = getConnection();
522: String sql = "SELECT VERSION_NUM,"
523: + " VERSION_MODIFIED," + " VERSION_MODIFIED_BY"
524: + " FROM " + PAGE_VERSIONS_TABLE_NAME
525: + " WHERE VERSION_NAME = ?"
526: + " AND VERSION_NUM = ?";
527: PreparedStatement ps = connection.prepareStatement(sql);
528: ps.setString(1, page);
529: ps.setInt(2, version);
530: ResultSet rs = ps.executeQuery();
531:
532: if (rs.next()) {
533: p = new WikiPage(page);
534: p.setVersion(rs.getInt("VERSION_NUM"));
535: // use Java Date for friendlier comparisons with other dates
536: p
537: .setLastModified(new java.util.Date(rs
538: .getTimestamp("VERSION_MODIFIED")
539: .getTime()));
540: p.setAuthor(rs.getString("VERSION_MODIFIED_BY"));
541: }
542: rs.close();
543: ps.close();
544:
545: } catch (SQLException se) {
546: error("unable to get page info for " + page + ":"
547: + version, se);
548: } finally {
549: releaseConnection(connection);
550: }
551: }
552: return p;
553: }
554:
555: /**
556: * Provide the list of versions.
557: */
558: public List getVersionHistory(String page) throws ProviderException {
559: List list = new ArrayList();
560:
561: Connection connection = null;
562: try {
563: connection = getConnection();
564: String sql = "SELECT VERSION_NUM,"
565: + " VERSION_MODIFIED,"
566: + " VERSION_MODIFIED_BY"
567: + " FROM "
568: + PAGE_VERSIONS_TABLE_NAME
569: + " WHERE VERSION_NAME = ? ORDER BY VERSION_NUM DESC";
570: PreparedStatement ps = connection.prepareStatement(sql);
571: ps.setString(1, page);
572: ResultSet rs = ps.executeQuery();
573:
574: while (rs.next()) {
575: WikiPage p = new WikiPage(page);
576: p.setVersion(rs.getInt("VERSION_NUM"));
577: // use Java Date for friendlier comparisons with other dates
578: p.setLastModified(new java.util.Date(rs.getTimestamp(
579: "VERSION_MODIFIED").getTime()));
580: p.setAuthor(rs.getString("VERSION_MODIFIED_BY"));
581: list.add(p);
582: }
583: rs.close();
584: ps.close();
585: } catch (SQLException se) {
586: error("unable to get version history for " + page, se);
587: } finally {
588: releaseConnection(connection);
589: }
590: return list;
591: }
592:
593: public String getProviderInfo() {
594: return "JDBC/MySQL page provider";
595: }
596:
597: public void deleteVersion(String pageName, int version)
598: throws ProviderException {
599: // TODO: If they delete the current version,
600: // replace the current version with the previous version.
601: Connection connection = null;
602: try {
603: connection = getConnection();
604: String sql = "DELETE FROM " + PAGE_VERSIONS_TABLE_NAME
605: + " WHERE VERSION_NAME = ?"
606: + " AND VERSION_NUM = ?";
607: PreparedStatement psVer = connection.prepareStatement(sql);
608: psVer.setString(1, pageName);
609: psVer.setInt(2, version);
610: psVer.execute();
611: psVer.close();
612:
613: } catch (SQLException se) {
614: error("Delete version failed " + pageName + ":" + version,
615: se);
616: } finally {
617: releaseConnection(connection);
618: }
619: }
620:
621: public void deletePage(String pageName) throws ProviderException {
622: Connection connection = null;
623: try {
624: connection = getConnection();
625: String sql = "DELETE FROM " + PAGE_VERSIONS_TABLE_NAME
626: + " WHERE VERSION_NAME = ?";
627: PreparedStatement psVer = connection.prepareStatement(sql);
628: psVer.setString(1, pageName);
629: psVer.execute();
630: psVer.close();
631:
632: sql = "DELETE FROM " + PAGE_TABLE_NAME
633: + " WHERE PAGE_NAME = ?";
634: PreparedStatement psPage = connection.prepareStatement(sql);
635: psPage.setString(1, pageName);
636: psPage.execute();
637: psPage.close();
638:
639: } catch (SQLException se) {
640: error("Delete failed " + pageName, se);
641: } finally {
642: releaseConnection(connection);
643: }
644: }
645:
646: /**
647: * Copies pages from one provider to this provider. The source,
648: * "import" provider is specified by the properties file at
649: * the given path.
650: */
651: private void migratePages(WikiEngine engine, String path)
652: throws IOException {
653: Properties importProps = new Properties();
654: importProps.load(new FileInputStream(path));
655: String classname = importProps
656: .getProperty(PageManager.PROP_PAGEPROVIDER);
657:
658: WikiPageProvider importProvider = null;
659: try {
660: Class providerclass = ClassUtil.findClass(
661: "com.ecyrd.jspwiki.providers", classname);
662: importProvider = (WikiPageProvider) providerclass
663: .newInstance();
664: } catch (Exception e) {
665: log.error(
666: "Unable to locate/instantiate import provider class "
667: + classname, e);
668: return;
669: }
670: try {
671: importProvider.initialize(engine, importProps);
672:
673: Collection pages = importProvider.getAllPages();
674: for (Iterator i = pages.iterator(); i.hasNext();) {
675: WikiPage latest = (WikiPage) i.next();
676:
677: int version = 1;
678: boolean done = false;
679: while (!done) {
680: WikiPage page = importProvider.getPageInfo(latest
681: .getName(), version);
682: if (page == null)
683: done = true;
684: else {
685: //debug( "importing page " + page );
686: String text = importProvider.getPageText(page
687: .getName(), version);
688: WikiPage newpage = (WikiPage) page.clone();
689: newpage.setName(WikiEngine
690: .makeAbsolutePageName(page.getName()));
691: putPageText(newpage, text);
692: if (page.getVersion() >= latest.getVersion())
693: done = true;
694: version += 1;
695: }
696: }
697: }
698: } catch (ProviderException e) {
699: throw new IOException(e.getMessage());
700: } catch (NoRequiredPropertyException e) {
701: throw new IOException(e.getMessage());
702: }
703: }
704:
705: }
|