0001: /**
0002: * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
0003: *
0004: * This program is free software; you can redistribute it and/or modify
0005: * it under the terms of the latest version of the GNU Lesser General
0006: * Public License as published by the Free Software Foundation;
0007: *
0008: * This program is distributed in the hope that it will be useful,
0009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0011: * GNU Lesser General Public License for more details.
0012: *
0013: * You should have received a copy of the GNU Lesser General Public License
0014: * along with this program (LICENSE.txt); if not, write to the Free Software
0015: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0016: */package org.jamwiki.db;
0017:
0018: import java.sql.Connection;
0019: import java.sql.Timestamp;
0020: import java.util.Collection;
0021: import java.util.Iterator;
0022: import java.util.LinkedHashMap;
0023: import java.util.List;
0024: import java.util.Locale;
0025: import java.util.Vector;
0026: import net.sf.ehcache.Element;
0027: import org.apache.commons.lang.StringUtils;
0028: import org.jamwiki.DataHandler;
0029: import org.jamwiki.WikiBase;
0030: import org.jamwiki.WikiException;
0031: import org.jamwiki.WikiMessage;
0032: import org.jamwiki.authentication.JAMWikiAnonymousProcessingFilter;
0033: import org.jamwiki.authentication.WikiUserAuth;
0034: import org.jamwiki.model.Category;
0035: import org.jamwiki.model.RecentChange;
0036: import org.jamwiki.model.Role;
0037: import org.jamwiki.model.RoleMap;
0038: import org.jamwiki.model.Topic;
0039: import org.jamwiki.model.TopicVersion;
0040: import org.jamwiki.model.VirtualWiki;
0041: import org.jamwiki.model.Watchlist;
0042: import org.jamwiki.model.WikiFile;
0043: import org.jamwiki.model.WikiFileVersion;
0044: import org.jamwiki.model.WikiGroup;
0045: import org.jamwiki.model.WikiUser;
0046: import org.jamwiki.model.WikiUserInfo;
0047: import org.jamwiki.parser.ParserOutput;
0048: import org.jamwiki.parser.ParserUtil;
0049: import org.jamwiki.utils.LinkUtil;
0050: import org.jamwiki.utils.NamespaceHandler;
0051: import org.jamwiki.utils.Pagination;
0052: import org.jamwiki.utils.WikiCache;
0053: import org.jamwiki.utils.WikiLink;
0054: import org.jamwiki.utils.WikiLogger;
0055: import org.jamwiki.utils.WikiUtil;
0056:
0057: /**
0058: * Default implementation of the {@link org.jamwiki.DataHandler} interface for
0059: * ANSI SQL compatible databases.
0060: */
0061: public class AnsiDataHandler implements DataHandler {
0062:
0063: private static final String CACHE_TOPICS = "org.jamwiki.db.AnsiDataHandler.CACHE_TOPICS";
0064: private static final String CACHE_VIRTUAL_WIKI = "org.jamwiki.db.AnsiDataHandler.CACHE_VIRTUAL_WIKI";
0065: private static final WikiLogger logger = WikiLogger
0066: .getLogger(AnsiDataHandler.class.getName());
0067:
0068: // some constants
0069: public static final String DATA_TOPIC_NAME = "topic_name";
0070: public static final String DATA_WIKI_USER_ID = "wiki_user_id";
0071: public static final String DATA_GROUP_ID = "group_id";
0072: public static final String DATA_CATEGORY_NAME = "category_name";
0073: public static final String DATA_TOPIC_ID = "topic_id";
0074:
0075: private final QueryHandler queryHandler = new AnsiQueryHandler();
0076:
0077: /**
0078: *
0079: */
0080: private void addCategory(Category category, Connection conn)
0081: throws Exception {
0082: int virtualWikiId = this .lookupVirtualWikiId(category
0083: .getVirtualWiki());
0084: this .queryHandler().insertCategory(category, virtualWikiId,
0085: conn);
0086: }
0087:
0088: /**
0089: *
0090: */
0091: private void addRecentChange(RecentChange change, Connection conn)
0092: throws Exception {
0093: int virtualWikiId = this .lookupVirtualWikiId(change
0094: .getVirtualWiki());
0095: this .queryHandler().insertRecentChange(change, virtualWikiId,
0096: conn);
0097: }
0098:
0099: /**
0100: *
0101: */
0102: private void addTopic(Topic topic, Connection conn)
0103: throws Exception {
0104: int virtualWikiId = this .lookupVirtualWikiId(topic
0105: .getVirtualWiki());
0106: if (topic.getTopicId() < 1) {
0107: int topicId = this .queryHandler().nextTopicId(conn);
0108: topic.setTopicId(topicId);
0109: }
0110: this .queryHandler().insertTopic(topic, virtualWikiId, conn);
0111: }
0112:
0113: /**
0114: *
0115: */
0116: private void addTopicVersion(TopicVersion topicVersion,
0117: Connection conn) throws Exception {
0118: if (topicVersion.getTopicVersionId() < 1) {
0119: int topicVersionId = this .queryHandler()
0120: .nextTopicVersionId(conn);
0121: topicVersion.setTopicVersionId(topicVersionId);
0122: }
0123: if (topicVersion.getEditDate() == null) {
0124: Timestamp editDate = new Timestamp(System
0125: .currentTimeMillis());
0126: topicVersion.setEditDate(editDate);
0127: }
0128: this .queryHandler().insertTopicVersion(topicVersion, conn);
0129: }
0130:
0131: /**
0132: *
0133: */
0134: private void addVirtualWiki(VirtualWiki virtualWiki, Connection conn)
0135: throws Exception {
0136: if (virtualWiki.getVirtualWikiId() < 1) {
0137: int virtualWikiId = this .queryHandler().nextVirtualWikiId(
0138: conn);
0139: virtualWiki.setVirtualWikiId(virtualWikiId);
0140: }
0141: this .queryHandler().insertVirtualWiki(virtualWiki, conn);
0142: }
0143:
0144: /**
0145: *
0146: */
0147: private void addWatchlistEntry(int virtualWikiId, String topicName,
0148: int userId, Connection conn) throws Exception {
0149: this .queryHandler().insertWatchlistEntry(virtualWikiId,
0150: topicName, userId, conn);
0151: }
0152:
0153: /**
0154: *
0155: */
0156: private void addWikiFile(WikiFile wikiFile, Connection conn)
0157: throws Exception {
0158: if (wikiFile.getFileId() < 1) {
0159: int fileId = this .queryHandler().nextWikiFileId(conn);
0160: wikiFile.setFileId(fileId);
0161: }
0162: int virtualWikiId = this .lookupVirtualWikiId(wikiFile
0163: .getVirtualWiki());
0164: this .queryHandler().insertWikiFile(wikiFile, virtualWikiId,
0165: conn);
0166: }
0167:
0168: /**
0169: *
0170: */
0171: private void addWikiFileVersion(WikiFileVersion wikiFileVersion,
0172: Connection conn) throws Exception {
0173: if (wikiFileVersion.getFileVersionId() < 1) {
0174: int fileVersionId = this .queryHandler()
0175: .nextWikiFileVersionId(conn);
0176: wikiFileVersion.setFileVersionId(fileVersionId);
0177: }
0178: if (wikiFileVersion.getUploadDate() == null) {
0179: Timestamp uploadDate = new Timestamp(System
0180: .currentTimeMillis());
0181: wikiFileVersion.setUploadDate(uploadDate);
0182: }
0183: this .queryHandler()
0184: .insertWikiFileVersion(wikiFileVersion, conn);
0185: }
0186:
0187: /**
0188: *
0189: */
0190: private void addWikiGroup(WikiGroup group, Connection conn)
0191: throws Exception {
0192: if (group.getGroupId() < 1) {
0193: int groupId = this .queryHandler().nextWikiGroupId(conn);
0194: group.setGroupId(groupId);
0195: }
0196: this .queryHandler().insertWikiGroup(group, conn);
0197: }
0198:
0199: /**
0200: *
0201: */
0202: protected void addWikiUser(WikiUser user, Connection conn)
0203: throws Exception {
0204: if (user.getUserId() < 1) {
0205: int nextUserId = this .queryHandler().nextWikiUserId(conn);
0206: user.setUserId(nextUserId);
0207: }
0208: this .queryHandler().insertWikiUser(user, conn);
0209: }
0210:
0211: /**
0212: *
0213: */
0214: public boolean canMoveTopic(Topic fromTopic, String destination)
0215: throws Exception {
0216: Topic toTopic = this .lookupTopic(fromTopic.getVirtualWiki(),
0217: destination, false, null);
0218: if (toTopic == null || toTopic.getDeleteDate() != null) {
0219: // destination doesn't exist or is deleted, so move is OK
0220: return true;
0221: }
0222: if (toTopic.getRedirectTo() != null
0223: && toTopic.getRedirectTo().equals(fromTopic.getName())) {
0224: // source redirects to destination, so move is OK
0225: return true;
0226: }
0227: return false;
0228: }
0229:
0230: /**
0231: *
0232: */
0233: private void deleteRecentChanges(Topic topic, Connection conn)
0234: throws Exception {
0235: this .queryHandler().deleteRecentChanges(topic.getTopicId(),
0236: conn);
0237: }
0238:
0239: /**
0240: *
0241: */
0242: public void deleteTopic(Topic topic, TopicVersion topicVersion,
0243: boolean userVisible, Object transactionObject)
0244: throws Exception {
0245: Connection conn = null;
0246: try {
0247: conn = WikiDatabase.getConnection(transactionObject);
0248: if (userVisible) {
0249: // delete old recent changes
0250: deleteRecentChanges(topic, conn);
0251: }
0252: // update topic to indicate deleted, add delete topic version. parser output
0253: // should be empty since nothing to add to search engine.
0254: ParserOutput parserOutput = new ParserOutput();
0255: topic.setDeleteDate(new Timestamp(System
0256: .currentTimeMillis()));
0257: this .writeTopic(topic, topicVersion, parserOutput
0258: .getCategories(), parserOutput.getLinks(),
0259: userVisible, conn);
0260: } catch (Exception e) {
0261: DatabaseConnection.handleErrors(conn);
0262: throw e;
0263: } finally {
0264: WikiDatabase.releaseConnection(conn, transactionObject);
0265: }
0266: }
0267:
0268: /**
0269: *
0270: */
0271: private void deleteTopicCategories(Topic topic, Connection conn)
0272: throws Exception {
0273: this .queryHandler().deleteTopicCategories(topic.getTopicId(),
0274: conn);
0275: }
0276:
0277: /**
0278: *
0279: */
0280: private void deleteWatchlistEntry(int virtualWikiId,
0281: String topicName, int userId, Connection conn)
0282: throws Exception {
0283: this .queryHandler().deleteWatchlistEntry(virtualWikiId,
0284: topicName, userId, conn);
0285: }
0286:
0287: /**
0288: *
0289: */
0290: public List getAllCategories(String virtualWiki,
0291: Pagination pagination) throws Exception {
0292: List results = new Vector();
0293: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
0294: WikiResultSet rs = this .queryHandler().getCategories(
0295: virtualWikiId, pagination);
0296: while (rs.next()) {
0297: Category category = new Category();
0298: category.setName(rs.getString(DATA_CATEGORY_NAME));
0299: // child topic name not initialized since it is not needed
0300: category.setVirtualWiki(virtualWiki);
0301: category.setSortKey(rs.getString("sort_key"));
0302: // topic type not initialized since it is not needed
0303: results.add(category);
0304: }
0305: return results;
0306: }
0307:
0308: /**
0309: *
0310: */
0311: public List getAllRoles() throws Exception {
0312: List results = new Vector();
0313: WikiResultSet rs = this .queryHandler().getRoles();
0314: while (rs.next()) {
0315: results.add(this .initRole(rs));
0316: }
0317: return results;
0318: }
0319:
0320: /**
0321: *
0322: */
0323: public List getAllTopicNames(String virtualWiki) throws Exception {
0324: Vector all = new Vector();
0325: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
0326: WikiResultSet rs = this .queryHandler().getAllTopicNames(
0327: virtualWikiId);
0328: while (rs.next()) {
0329: all.add(rs.getString(DATA_TOPIC_NAME));
0330: }
0331: return all;
0332: }
0333:
0334: /**
0335: *
0336: */
0337: public List getAllWikiFileVersions(String virtualWiki,
0338: String topicName, boolean descending) throws Exception {
0339: Vector all = new Vector();
0340: WikiFile wikiFile = lookupWikiFile(virtualWiki, topicName);
0341: if (wikiFile == null) {
0342: throw new Exception("No topic exists for " + virtualWiki
0343: + " / " + topicName);
0344: }
0345: WikiResultSet rs = this .queryHandler().getAllWikiFileVersions(
0346: wikiFile, descending);
0347: while (rs.next()) {
0348: all.add(initWikiFileVersion(rs));
0349: }
0350: return all;
0351: }
0352:
0353: /**
0354: *
0355: */
0356: public List getRecentChanges(String virtualWiki,
0357: Pagination pagination, boolean descending) throws Exception {
0358: Vector all = new Vector();
0359: WikiResultSet rs = this .queryHandler().getRecentChanges(
0360: virtualWiki, pagination, descending);
0361: while (rs.next()) {
0362: RecentChange change = initRecentChange(rs);
0363: all.add(change);
0364: }
0365: return all;
0366: }
0367:
0368: /**
0369: *
0370: */
0371: public List getRecentChanges(String virtualWiki, String topicName,
0372: Pagination pagination, boolean descending) throws Exception {
0373: Vector all = new Vector();
0374: Topic topic = this .lookupTopic(virtualWiki, topicName, true,
0375: null);
0376: if (topic == null) {
0377: return all;
0378: }
0379: WikiResultSet rs = this .queryHandler().getRecentChanges(
0380: topic.getTopicId(), pagination, descending);
0381: while (rs.next()) {
0382: RecentChange change = initRecentChange(rs);
0383: all.add(change);
0384: }
0385: return all;
0386: }
0387:
0388: /**
0389: *
0390: */
0391: public Collection getRoleMapByLogin(String loginFragment)
0392: throws Exception {
0393: LinkedHashMap roleMaps = new LinkedHashMap();
0394: WikiResultSet rs = this .queryHandler().getRoleMapByLogin(
0395: loginFragment);
0396: while (rs.next()) {
0397: Integer userId = new Integer(rs.getInt(DATA_WIKI_USER_ID));
0398: RoleMap roleMap = new RoleMap();
0399: if (roleMaps.containsKey(userId)) {
0400: roleMap = (RoleMap) roleMaps.get(userId);
0401: } else {
0402: roleMap.setUserId(userId);
0403: roleMap.setUserLogin(rs.getString("login"));
0404: }
0405: roleMap.addRole(rs.getString("role_name"));
0406: roleMaps.put(userId, roleMap);
0407: }
0408: return roleMaps.values();
0409: }
0410:
0411: /**
0412: *
0413: */
0414: public Collection getRoleMapByRole(String roleName)
0415: throws Exception {
0416: LinkedHashMap roleMaps = new LinkedHashMap();
0417: WikiResultSet rs = this .queryHandler().getRoleMapByRole(
0418: roleName);
0419: while (rs.next()) {
0420: int userId = rs.getInt(DATA_WIKI_USER_ID);
0421: int groupId = rs.getInt(DATA_GROUP_ID);
0422: RoleMap roleMap = new RoleMap();
0423: String key = userId + "|" + groupId;
0424: if (roleMaps.containsKey(key)) {
0425: roleMap = (RoleMap) roleMaps.get(key);
0426: } else {
0427: if (userId > 0) {
0428: roleMap.setUserId(new Integer(userId));
0429: roleMap.setUserLogin(rs.getString("login"));
0430: }
0431: if (groupId > 0) {
0432: roleMap.setGroupId(new Integer(groupId));
0433: roleMap.setGroupName(rs.getString("group_name"));
0434: }
0435: }
0436: roleMap.addRole(rs.getString("role_name"));
0437: roleMaps.put(key, roleMap);
0438: }
0439: return roleMaps.values();
0440: }
0441:
0442: /**
0443: *
0444: */
0445: public Role[] getRoleMapGroup(String groupName) throws Exception {
0446: List results = new Vector();
0447: WikiResultSet rs = this .queryHandler().getRoleMapGroup(
0448: groupName);
0449: while (rs.next()) {
0450: Role role = this .initRole(rs);
0451: results.add(role);
0452: }
0453: return (Role[]) results.toArray(new Role[0]);
0454: }
0455:
0456: /**
0457: *
0458: */
0459: public Collection getRoleMapGroups() throws Exception {
0460: LinkedHashMap roleMaps = new LinkedHashMap();
0461: WikiResultSet rs = this .queryHandler().getRoleMapGroups();
0462: while (rs.next()) {
0463: Integer groupId = new Integer(rs.getInt(DATA_GROUP_ID));
0464: RoleMap roleMap = new RoleMap();
0465: if (roleMaps.containsKey(groupId)) {
0466: roleMap = (RoleMap) roleMaps.get(groupId);
0467: } else {
0468: roleMap.setGroupId(groupId);
0469: roleMap.setGroupName(rs.getString("group_name"));
0470: }
0471: roleMap.addRole(rs.getString("role_name"));
0472: roleMaps.put(groupId, roleMap);
0473: }
0474: return roleMaps.values();
0475: }
0476:
0477: /**
0478: *
0479: */
0480: public Role[] getRoleMapUser(String login) throws Exception {
0481: List results = new Vector();
0482: WikiResultSet rs = this .queryHandler().getRoleMapUser(login);
0483: while (rs.next()) {
0484: Role role = this .initRole(rs);
0485: results.add(role);
0486: }
0487: return (Role[]) results.toArray(new Role[0]);
0488: }
0489:
0490: /**
0491: *
0492: */
0493: public List getTopicsAdmin(String virtualWiki, Pagination pagination)
0494: throws Exception {
0495: List all = new Vector();
0496: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
0497: WikiResultSet rs = this .queryHandler().getTopicsAdmin(
0498: virtualWikiId, pagination);
0499: while (rs.next()) {
0500: String topicName = rs.getString(DATA_TOPIC_NAME);
0501: all.add(topicName);
0502: }
0503: return all;
0504: }
0505:
0506: /**
0507: *
0508: */
0509: public List getUserContributions(String virtualWiki,
0510: String userString, Pagination pagination, boolean descending)
0511: throws Exception {
0512: List all = new Vector();
0513: WikiResultSet rs = this .queryHandler().getUserContributions(
0514: virtualWiki, userString, pagination, descending);
0515: while (rs.next()) {
0516: RecentChange change = initRecentChange(rs);
0517: all.add(change);
0518: }
0519: return all;
0520: }
0521:
0522: /**
0523: * Return a List of all VirtualWiki objects that exist for the Wiki.
0524: */
0525: public List getVirtualWikiList(Object transactionObject)
0526: throws Exception {
0527: Connection conn = null;
0528: Vector results = new Vector();
0529: try {
0530: conn = WikiDatabase.getConnection(transactionObject);
0531: WikiResultSet rs = this .queryHandler()
0532: .getVirtualWikis(conn);
0533: while (rs.next()) {
0534: VirtualWiki virtualWiki = initVirtualWiki(rs);
0535: results.add(virtualWiki);
0536: }
0537: } catch (Exception e) {
0538: DatabaseConnection.handleErrors(conn);
0539: throw e;
0540: } finally {
0541: WikiDatabase.releaseConnection(conn, transactionObject);
0542: }
0543: return results;
0544: }
0545:
0546: /**
0547: * Retrieve a watchlist containing a List of topic ids and topic
0548: * names that can be used to determine if a topic is in a user's current
0549: * watchlist.
0550: */
0551: public Watchlist getWatchlist(String virtualWiki, int userId)
0552: throws Exception {
0553: List all = new Vector();
0554: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
0555: WikiResultSet rs = this .queryHandler().getWatchlist(
0556: virtualWikiId, userId);
0557: while (rs.next()) {
0558: String topicName = rs.getString(DATA_TOPIC_NAME);
0559: all.add(topicName);
0560: }
0561: return new Watchlist(virtualWiki, all);
0562: }
0563:
0564: /**
0565: * Retrieve a watchlist containing a List of RecentChanges objects
0566: * that can be used for display on the Special:Watchlist page.
0567: */
0568: public List getWatchlist(String virtualWiki, int userId,
0569: Pagination pagination) throws Exception {
0570: List all = new Vector();
0571: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
0572: WikiResultSet rs = this .queryHandler().getWatchlist(
0573: virtualWikiId, userId, pagination);
0574: while (rs.next()) {
0575: RecentChange change = initRecentChange(rs);
0576: all.add(change);
0577: }
0578: return all;
0579: }
0580:
0581: /**
0582: *
0583: */
0584: private RecentChange initRecentChange(WikiResultSet rs) {
0585: try {
0586: RecentChange change = new RecentChange();
0587: change.setTopicVersionId(rs.getInt("topic_version_id"));
0588: int previousTopicVersionId = rs
0589: .getInt("previous_topic_version_id");
0590: if (previousTopicVersionId > 0) {
0591: change.setPreviousTopicVersionId(new Integer(
0592: previousTopicVersionId));
0593: }
0594: change.setTopicId(rs.getInt(DATA_TOPIC_ID));
0595: change.setTopicName(rs.getString(DATA_TOPIC_NAME));
0596: change.setEditDate(rs.getTimestamp("edit_date"));
0597: change.setEditComment(rs.getString("edit_comment"));
0598: int userId = rs.getInt(DATA_WIKI_USER_ID);
0599: if (userId > 0) {
0600: change.setAuthorId(new Integer(userId));
0601: }
0602: change.setAuthorName(rs.getString("display_name"));
0603: change.setEditType(rs.getInt("edit_type"));
0604: change.setVirtualWiki(rs.getString("virtual_wiki_name"));
0605: return change;
0606: } catch (Exception e) {
0607: logger
0608: .severe("Failure while initializing recent change",
0609: e);
0610: return null;
0611: }
0612: }
0613:
0614: /**
0615: *
0616: */
0617: private Role initRole(WikiResultSet rs) {
0618: try {
0619: Role role = new Role(rs.getString("role_name"));
0620: role.setDescription(rs.getString("role_description"));
0621: return role;
0622: } catch (Exception e) {
0623: logger.severe("Failure while initializing role", e);
0624: return null;
0625: }
0626: }
0627:
0628: /**
0629: *
0630: */
0631: private Topic initTopic(WikiResultSet rs) {
0632: try {
0633: // if a topic by this name has been deleted then there will be
0634: // multiple results. the first will be a non-deleted topic (if
0635: // one exists), otherwise the last is the most recently deleted
0636: // topic.
0637: if (rs.size() > 1 && rs.getTimestamp("delete_date") != null) {
0638: // go to the last result
0639: rs.last();
0640: }
0641: int virtualWikiId = rs.getInt("virtual_wiki_id");
0642: String virtualWiki = this
0643: .lookupVirtualWikiName(virtualWikiId);
0644: Topic topic = new Topic();
0645: topic.setAdminOnly(rs.getInt("topic_admin_only") != 0);
0646: topic.setName(rs.getString(DATA_TOPIC_NAME));
0647: topic.setVirtualWiki(virtualWiki);
0648: int currentVersionId = rs.getInt("current_version_id");
0649: if (currentVersionId > 0) {
0650: topic
0651: .setCurrentVersionId(new Integer(
0652: currentVersionId));
0653: }
0654: topic.setTopicContent(rs.getString("version_content"));
0655: // FIXME - Oracle cannot store an empty string - it converts them
0656: // to null - so add a hack to work around the problem.
0657: if (topic.getTopicContent() == null) {
0658: topic.setTopicContent("");
0659: }
0660: topic.setTopicId(rs.getInt(DATA_TOPIC_ID));
0661: topic.setReadOnly(rs.getInt("topic_read_only") != 0);
0662: topic.setDeleteDate(rs.getTimestamp("delete_date"));
0663: topic.setTopicType(rs.getInt("topic_type"));
0664: topic.setRedirectTo(rs.getString("redirect_to"));
0665: return topic;
0666: } catch (Exception e) {
0667: logger.severe("Failure while initializing topic", e);
0668: return null;
0669: }
0670: }
0671:
0672: /**
0673: *
0674: */
0675: private TopicVersion initTopicVersion(WikiResultSet rs) {
0676: try {
0677: TopicVersion topicVersion = new TopicVersion();
0678: topicVersion.setTopicVersionId(rs
0679: .getInt("topic_version_id"));
0680: topicVersion.setTopicId(rs.getInt(DATA_TOPIC_ID));
0681: topicVersion.setEditComment(rs.getString("edit_comment"));
0682: topicVersion.setVersionContent(rs
0683: .getString("version_content"));
0684: // FIXME - Oracle cannot store an empty string - it converts them
0685: // to null - so add a hack to work around the problem.
0686: if (topicVersion.getVersionContent() == null) {
0687: topicVersion.setVersionContent("");
0688: }
0689: int previousTopicVersionId = rs
0690: .getInt("previous_topic_version_id");
0691: if (previousTopicVersionId > 0) {
0692: topicVersion.setPreviousTopicVersionId(new Integer(
0693: previousTopicVersionId));
0694: }
0695: int userId = rs.getInt(DATA_WIKI_USER_ID);
0696: if (userId > 0) {
0697: topicVersion.setAuthorId(new Integer(userId));
0698: }
0699: topicVersion.setEditDate(rs.getTimestamp("edit_date"));
0700: topicVersion.setEditType(rs.getInt("edit_type"));
0701: topicVersion.setAuthorIpAddress(rs
0702: .getString("wiki_user_ip_address"));
0703: return topicVersion;
0704: } catch (Exception e) {
0705: logger
0706: .severe("Failure while initializing topic version",
0707: e);
0708: return null;
0709: }
0710: }
0711:
0712: /**
0713: *
0714: */
0715: private VirtualWiki initVirtualWiki(WikiResultSet rs) {
0716: try {
0717: VirtualWiki virtualWiki = new VirtualWiki();
0718: virtualWiki.setVirtualWikiId(rs.getInt("virtual_wiki_id"));
0719: virtualWiki.setName(rs.getString("virtual_wiki_name"));
0720: virtualWiki.setDefaultTopicName(rs
0721: .getString("default_topic_name"));
0722: return virtualWiki;
0723: } catch (Exception e) {
0724: logger.severe("Failure while initializing virtual wiki", e);
0725: return null;
0726: }
0727: }
0728:
0729: /**
0730: *
0731: */
0732: private WikiFile initWikiFile(WikiResultSet rs) {
0733: try {
0734: int virtualWikiId = rs.getInt("virtual_wiki_id");
0735: String virtualWiki = this
0736: .lookupVirtualWikiName(virtualWikiId);
0737: WikiFile wikiFile = new WikiFile();
0738: wikiFile.setFileId(rs.getInt("file_id"));
0739: wikiFile.setAdminOnly(rs.getInt("file_admin_only") != 0);
0740: wikiFile.setFileName(rs.getString("file_name"));
0741: wikiFile.setVirtualWiki(virtualWiki);
0742: wikiFile.setUrl(rs.getString("file_url"));
0743: wikiFile.setTopicId(rs.getInt(DATA_TOPIC_ID));
0744: wikiFile.setReadOnly(rs.getInt("file_read_only") != 0);
0745: wikiFile.setDeleteDate(rs.getTimestamp("delete_date"));
0746: wikiFile.setMimeType(rs.getString("mime_type"));
0747: wikiFile.setFileSize(rs.getInt("file_size"));
0748: return wikiFile;
0749: } catch (Exception e) {
0750: logger.severe("Failure while initializing file", e);
0751: return null;
0752: }
0753: }
0754:
0755: /**
0756: *
0757: */
0758: private WikiFileVersion initWikiFileVersion(WikiResultSet rs) {
0759: try {
0760: WikiFileVersion wikiFileVersion = new WikiFileVersion();
0761: wikiFileVersion.setFileVersionId(rs
0762: .getInt("file_version_id"));
0763: wikiFileVersion.setFileId(rs.getInt("file_id"));
0764: wikiFileVersion.setUploadComment(rs
0765: .getString("upload_comment"));
0766: wikiFileVersion.setUrl(rs.getString("file_url"));
0767: int userId = rs.getInt(DATA_WIKI_USER_ID);
0768: if (userId > 0) {
0769: wikiFileVersion.setAuthorId(new Integer(userId));
0770: }
0771: wikiFileVersion.setUploadDate(rs
0772: .getTimestamp("upload_date"));
0773: wikiFileVersion.setMimeType(rs.getString("mime_type"));
0774: wikiFileVersion.setAuthorIpAddress(rs
0775: .getString("wiki_user_ip_address"));
0776: wikiFileVersion.setFileSize(rs.getInt("file_size"));
0777: return wikiFileVersion;
0778: } catch (Exception e) {
0779: logger.severe(
0780: "Failure while initializing wiki file version", e);
0781: return null;
0782: }
0783: }
0784:
0785: /**
0786: *
0787: */
0788: private WikiUser initWikiUser(WikiResultSet rs) {
0789: try {
0790: String username = rs.getString("login");
0791: WikiUser user = new WikiUser(username);
0792: user.setUserId(rs.getInt(DATA_WIKI_USER_ID));
0793: user.setDisplayName(rs.getString("display_name"));
0794: user.setCreateDate(rs.getTimestamp("create_date"));
0795: user.setLastLoginDate(rs.getTimestamp("last_login_date"));
0796: user.setCreateIpAddress(rs.getString("create_ip_address"));
0797: user.setLastLoginIpAddress(rs
0798: .getString("last_login_ip_address"));
0799: user.setPassword(rs.getString("remember_key"));
0800: user.setDefaultLocale(rs.getString("default_locale"));
0801: return user;
0802: } catch (Exception e) {
0803: logger.severe("Failure while initializing user", e);
0804: return null;
0805: }
0806: }
0807:
0808: /**
0809: *
0810: */
0811: public List lookupCategoryTopics(String virtualWiki,
0812: String categoryName) throws Exception {
0813: Vector results = new Vector();
0814: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
0815: WikiResultSet rs = this .queryHandler().lookupCategoryTopics(
0816: virtualWikiId, categoryName);
0817: while (rs.next()) {
0818: Category category = new Category();
0819: category.setName(categoryName);
0820: category.setVirtualWiki(virtualWiki);
0821: category.setChildTopicName(rs.getString(DATA_TOPIC_NAME));
0822: category.setSortKey(rs.getString("sort_key"));
0823: category.setTopicType(rs.getInt("topic_type"));
0824: results.add(category);
0825: }
0826: return results;
0827: }
0828:
0829: /**
0830: *
0831: */
0832: public Topic lookupTopic(String virtualWiki, String topicName,
0833: boolean deleteOK, Object transactionObject)
0834: throws Exception {
0835: if (StringUtils.isBlank(virtualWiki)
0836: || StringUtils.isBlank(topicName)) {
0837: return null;
0838: }
0839: Connection conn = null;
0840: try {
0841: conn = WikiDatabase.getConnection(transactionObject);
0842: String key = WikiCache.key(virtualWiki, topicName);
0843: if (transactionObject == null) {
0844: // retrieve topic from the cache only if this call is not currently a part
0845: // of a transaction to avoid retrieving data that might have been updated
0846: // as part of this transaction and would thus now be out of date
0847: Element cacheElement = WikiCache.retrieveFromCache(
0848: CACHE_TOPICS, key);
0849: if (cacheElement != null) {
0850: Topic cacheTopic = (Topic) cacheElement
0851: .getObjectValue();
0852: return (cacheTopic == null || (!deleteOK && cacheTopic
0853: .getDeleteDate() != null)) ? null
0854: : new Topic(cacheTopic);
0855: }
0856: }
0857: WikiLink wikiLink = LinkUtil.parseWikiLink(topicName);
0858: String namespace = wikiLink.getNamespace();
0859: boolean caseSensitive = true;
0860: if (namespace != null) {
0861: if (namespace
0862: .equals(NamespaceHandler.NAMESPACE_SPECIAL)) {
0863: // invalid namespace
0864: return null;
0865: }
0866: if (namespace
0867: .equals(NamespaceHandler.NAMESPACE_TEMPLATE)
0868: || namespace
0869: .equals(NamespaceHandler.NAMESPACE_USER)
0870: || namespace
0871: .equals(NamespaceHandler.NAMESPACE_CATEGORY)) {
0872: // user/template/category namespaces are case-insensitive
0873: caseSensitive = false;
0874: }
0875: }
0876: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
0877: WikiResultSet rs = this .queryHandler().lookupTopic(
0878: virtualWikiId, topicName, caseSensitive, conn);
0879: Topic topic = null;
0880: if (rs.size() != 0) {
0881: topic = initTopic(rs);
0882: }
0883: if (transactionObject == null) {
0884: // add topic to the cache only if it is not currently a part of a transaction
0885: // to avoid caching something that might need to be rolled back
0886: Topic cacheTopic = (topic == null) ? null : new Topic(
0887: topic);
0888: WikiCache.addToCache(CACHE_TOPICS, key, cacheTopic);
0889: }
0890: return (topic == null || (!deleteOK && topic
0891: .getDeleteDate() != null)) ? null : topic;
0892: } catch (Exception e) {
0893: DatabaseConnection.handleErrors(conn);
0894: throw e;
0895: } finally {
0896: WikiDatabase.releaseConnection(conn, transactionObject);
0897: }
0898: }
0899:
0900: /**
0901: * Return a count of all topics, including redirects, comments pages and templates,
0902: * currently available on the Wiki. This method excludes deleted topics.
0903: *
0904: * @param virtualWiki The virtual wiki for which the total topic count is being returned
0905: * for.
0906: */
0907: public int lookupTopicCount(String virtualWiki) throws Exception {
0908: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
0909: WikiResultSet rs = this .queryHandler().lookupTopicCount(
0910: virtualWikiId);
0911: return rs.getInt("topic_count");
0912: }
0913:
0914: /**
0915: *
0916: */
0917: public List lookupTopicByType(String virtualWiki, int topicType,
0918: Pagination pagination) throws Exception {
0919: Vector results = new Vector();
0920: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
0921: WikiResultSet rs = this .queryHandler().lookupTopicByType(
0922: virtualWikiId, topicType, pagination);
0923: while (rs.next()) {
0924: results.add(rs.getString(DATA_TOPIC_NAME));
0925: }
0926: return results;
0927: }
0928:
0929: /**
0930: *
0931: */
0932: public TopicVersion lookupTopicVersion(int topicVersionId,
0933: Object transactionObject) throws Exception {
0934: Connection conn = null;
0935: try {
0936: conn = WikiDatabase.getConnection(transactionObject);
0937: WikiResultSet rs = this .queryHandler().lookupTopicVersion(
0938: topicVersionId, conn);
0939: return (rs.size() == 0) ? null : this .initTopicVersion(rs);
0940: } catch (Exception e) {
0941: DatabaseConnection.handleErrors(conn);
0942: throw e;
0943: } finally {
0944: WikiDatabase.releaseConnection(conn, transactionObject);
0945: }
0946: }
0947:
0948: /**
0949: *
0950: */
0951: public VirtualWiki lookupVirtualWiki(String virtualWikiName)
0952: throws Exception {
0953: Element cacheElement = WikiCache.retrieveFromCache(
0954: CACHE_VIRTUAL_WIKI, virtualWikiName);
0955: if (cacheElement != null) {
0956: return (VirtualWiki) cacheElement.getObjectValue();
0957: }
0958: List virtualWikis = this .getVirtualWikiList(null);
0959: for (Iterator iterator = virtualWikis.iterator(); iterator
0960: .hasNext();) {
0961: VirtualWiki virtualWiki = (VirtualWiki) iterator.next();
0962: if (virtualWiki.getName().equals(virtualWikiName)) {
0963: WikiCache.addToCache(CACHE_VIRTUAL_WIKI,
0964: virtualWikiName, virtualWiki);
0965: return virtualWiki;
0966: }
0967: }
0968: WikiCache.addToCache(CACHE_VIRTUAL_WIKI, virtualWikiName, null);
0969: return null;
0970: }
0971:
0972: /**
0973: *
0974: */
0975: private int lookupVirtualWikiId(String virtualWikiName)
0976: throws Exception {
0977: VirtualWiki virtualWiki = this
0978: .lookupVirtualWiki(virtualWikiName);
0979: WikiCache.addToCache(CACHE_VIRTUAL_WIKI, virtualWikiName,
0980: virtualWiki);
0981: return (virtualWiki == null) ? -1 : virtualWiki
0982: .getVirtualWikiId();
0983: }
0984:
0985: /**
0986: *
0987: */
0988: private String lookupVirtualWikiName(int virtualWikiId)
0989: throws Exception {
0990: VirtualWiki virtualWiki = null;
0991: Element cacheElement = WikiCache.retrieveFromCache(
0992: CACHE_VIRTUAL_WIKI, virtualWikiId);
0993: if (cacheElement != null) {
0994: virtualWiki = (VirtualWiki) cacheElement.getObjectValue();
0995: return (virtualWiki == null) ? null : virtualWiki.getName();
0996: }
0997: List virtualWikis = this .getVirtualWikiList(null);
0998: for (Iterator iterator = virtualWikis.iterator(); iterator
0999: .hasNext();) {
1000: virtualWiki = (VirtualWiki) iterator.next();
1001: if (virtualWiki.getVirtualWikiId() == virtualWikiId) {
1002: WikiCache.addToCache(CACHE_VIRTUAL_WIKI, virtualWikiId,
1003: virtualWiki);
1004: return virtualWiki.getName();
1005: }
1006: }
1007: WikiCache.addToCache(CACHE_VIRTUAL_WIKI, virtualWikiId, null);
1008: return null;
1009: }
1010:
1011: /**
1012: *
1013: */
1014: public WikiFile lookupWikiFile(String virtualWiki, String topicName)
1015: throws Exception {
1016: Topic topic = this .lookupTopic(virtualWiki, topicName, false,
1017: null);
1018: if (topic == null) {
1019: return null;
1020: }
1021: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
1022: WikiResultSet rs = this .queryHandler().lookupWikiFile(
1023: virtualWikiId, topic.getTopicId());
1024: return (rs.size() == 0) ? null : initWikiFile(rs);
1025: }
1026:
1027: /**
1028: * Return a count of all wiki files currently available on the Wiki. This
1029: * method excludes deleted files.
1030: *
1031: * @param virtualWiki The virtual wiki of the files being retrieved.
1032: */
1033: public int lookupWikiFileCount(String virtualWiki) throws Exception {
1034: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
1035: WikiResultSet rs = this .queryHandler().lookupWikiFileCount(
1036: virtualWikiId);
1037: return rs.getInt("file_count");
1038: }
1039:
1040: /**
1041: *
1042: */
1043: public WikiUser lookupWikiUser(int userId, Object transactionObject)
1044: throws Exception {
1045: Connection conn = null;
1046: try {
1047: conn = WikiDatabase.getConnection(transactionObject);
1048: WikiResultSet rs = this .queryHandler().lookupWikiUser(
1049: userId, conn);
1050: return (rs.size() == 0) ? null : initWikiUser(rs);
1051: } catch (Exception e) {
1052: DatabaseConnection.handleErrors(conn);
1053: throw e;
1054: } finally {
1055: WikiDatabase.releaseConnection(conn, transactionObject);
1056: }
1057: }
1058:
1059: /**
1060: *
1061: */
1062: public WikiUser lookupWikiUser(String username,
1063: Object transactionObject) throws Exception {
1064: Connection conn = null;
1065: try {
1066: conn = WikiDatabase.getConnection(transactionObject);
1067: WikiResultSet rs = this .queryHandler().lookupWikiUser(
1068: username, conn);
1069: if (rs.size() == 0) {
1070: return null;
1071: }
1072: int userId = rs.getInt(DATA_WIKI_USER_ID);
1073: return lookupWikiUser(userId, conn);
1074: } catch (Exception e) {
1075: DatabaseConnection.handleErrors(conn);
1076: throw e;
1077: } finally {
1078: WikiDatabase.releaseConnection(conn, transactionObject);
1079: }
1080: }
1081:
1082: /**
1083: * Return a count of all wiki users.
1084: */
1085: public int lookupWikiUserCount() throws Exception {
1086: // FIXME - handle LDAP
1087: WikiResultSet rs = this .queryHandler().lookupWikiUserCount();
1088: return rs.getInt("user_count");
1089: }
1090:
1091: /**
1092: *
1093: */
1094: public List lookupWikiUsers(Pagination pagination) throws Exception {
1095: Vector results = new Vector();
1096: WikiResultSet rs = this .queryHandler().lookupWikiUsers(
1097: pagination);
1098: while (rs.next()) {
1099: results.add(rs.getString("login"));
1100: }
1101: return results;
1102: }
1103:
1104: /**
1105: *
1106: */
1107: public void moveTopic(Topic fromTopic, TopicVersion fromVersion,
1108: String destination, Object transactionObject)
1109: throws Exception {
1110: Connection conn = null;
1111: try {
1112: conn = WikiDatabase.getConnection(transactionObject);
1113: if (!this .canMoveTopic(fromTopic, destination)) {
1114: throw new WikiException(
1115: new WikiMessage(
1116: "move.exception.destinationexists",
1117: destination));
1118: }
1119: Topic toTopic = this .lookupTopic(
1120: fromTopic.getVirtualWiki(), destination, false,
1121: conn);
1122: boolean detinationExistsFlag = (toTopic != null && toTopic
1123: .getDeleteDate() == null);
1124: if (detinationExistsFlag) {
1125: // if the target topic is a redirect to the source topic then the
1126: // target must first be deleted.
1127: this .deleteTopic(toTopic, null, false, conn);
1128: }
1129: // first rename the source topic with the new destination name
1130: String fromTopicName = fromTopic.getName();
1131: fromTopic.setName(destination);
1132: ParserOutput fromParserOutput = ParserUtil.parserOutput(
1133: fromTopic.getTopicContent(), fromTopic
1134: .getVirtualWiki(), fromTopic.getName());
1135: writeTopic(fromTopic, fromVersion, fromParserOutput
1136: .getCategories(), fromParserOutput.getLinks(),
1137: true, conn);
1138: // now either create a new topic that is a redirect with the
1139: // source topic's old name, or else undelete the new topic and
1140: // rename.
1141: if (detinationExistsFlag) {
1142: // target topic was deleted, so rename and undelete
1143: toTopic.setName(fromTopicName);
1144: writeTopic(toTopic, null, null, null, false, conn);
1145: this .undeleteTopic(toTopic, null, false, conn);
1146: } else {
1147: // create a new topic that redirects to the destination
1148: toTopic = fromTopic;
1149: toTopic.setTopicId(-1);
1150: toTopic.setName(fromTopicName);
1151: }
1152: String content = ParserUtil
1153: .parserRedirectContent(destination);
1154: toTopic.setRedirectTo(destination);
1155: toTopic.setTopicType(Topic.TYPE_REDIRECT);
1156: toTopic.setTopicContent(content);
1157: TopicVersion toVersion = fromVersion;
1158: toVersion.setTopicVersionId(-1);
1159: toVersion.setVersionContent(content);
1160: ParserOutput toParserOutput = ParserUtil.parserOutput(
1161: toTopic.getTopicContent(),
1162: toTopic.getVirtualWiki(), toTopic.getName());
1163: writeTopic(toTopic, toVersion, toParserOutput
1164: .getCategories(), toParserOutput.getLinks(), true,
1165: conn);
1166: } catch (Exception e) {
1167: DatabaseConnection.handleErrors(conn);
1168: throw e;
1169: } finally {
1170: WikiDatabase.releaseConnection(conn, transactionObject);
1171: }
1172: }
1173:
1174: /**
1175: *
1176: */
1177: protected QueryHandler queryHandler() {
1178: return this .queryHandler;
1179: }
1180:
1181: /**
1182: *
1183: */
1184: public void reloadRecentChanges(Object transactionObject)
1185: throws Exception {
1186: Connection conn = null;
1187: try {
1188: conn = WikiDatabase.getConnection(transactionObject);
1189: this .queryHandler().reloadRecentChanges(conn);
1190: } catch (Exception e) {
1191: DatabaseConnection.handleErrors(conn);
1192: throw e;
1193: } finally {
1194: WikiDatabase.releaseConnection(conn, transactionObject);
1195: }
1196: }
1197:
1198: /**
1199: *
1200: */
1201: public void setup(Locale locale, WikiUser user) throws Exception {
1202: WikiDatabase.initialize();
1203: // determine if database exists
1204: try {
1205: DatabaseConnection.executeQuery(WikiDatabase
1206: .getExistenceValidationQuery());
1207: return;
1208: } catch (Exception e) {
1209: // database not yet set up
1210: }
1211: WikiDatabase.setup(locale, user);
1212: }
1213:
1214: /**
1215: *
1216: */
1217: public void setupSpecialPages(Locale locale, WikiUser user,
1218: VirtualWiki virtualWiki, Object transactionObject)
1219: throws Exception {
1220: Connection conn = null;
1221: try {
1222: conn = WikiDatabase.getConnection(transactionObject);
1223: // create the default topics
1224: WikiDatabase.setupSpecialPage(locale,
1225: virtualWiki.getName(),
1226: WikiBase.SPECIAL_PAGE_STARTING_POINTS, user, false,
1227: conn);
1228: WikiDatabase.setupSpecialPage(locale,
1229: virtualWiki.getName(),
1230: WikiBase.SPECIAL_PAGE_LEFT_MENU, user, true, conn);
1231: WikiDatabase
1232: .setupSpecialPage(locale, virtualWiki.getName(),
1233: WikiBase.SPECIAL_PAGE_BOTTOM_AREA, user,
1234: true, conn);
1235: WikiDatabase.setupSpecialPage(locale,
1236: virtualWiki.getName(),
1237: WikiBase.SPECIAL_PAGE_STYLESHEET, user, true, conn);
1238: } catch (Exception e) {
1239: DatabaseConnection.handleErrors(conn);
1240: throw e;
1241: } finally {
1242: WikiDatabase.releaseConnection(conn, transactionObject);
1243: }
1244: }
1245:
1246: /**
1247: *
1248: */
1249: public void undeleteTopic(Topic topic, TopicVersion topicVersion,
1250: boolean userVisible, Object transactionObject)
1251: throws Exception {
1252: Connection conn = null;
1253: try {
1254: conn = WikiDatabase.getConnection(transactionObject);
1255: // update topic to indicate deleted, add delete topic version. if
1256: // topic has categories or other metadata then parser document is
1257: // also needed.
1258: ParserOutput parserOutput = ParserUtil.parserOutput(topic
1259: .getTopicContent(), topic.getVirtualWiki(), topic
1260: .getName());
1261: topic.setDeleteDate(null);
1262: this .writeTopic(topic, topicVersion, parserOutput
1263: .getCategories(), parserOutput.getLinks(),
1264: userVisible, conn);
1265: } catch (Exception e) {
1266: DatabaseConnection.handleErrors(conn);
1267: throw e;
1268: } finally {
1269: WikiDatabase.releaseConnection(conn, transactionObject);
1270: }
1271: }
1272:
1273: /**
1274: *
1275: */
1276: public void updateSpecialPage(Locale locale, String virtualWiki,
1277: String topicName, WikiUser user, String ipAddress,
1278: Object transactionObject) throws Exception {
1279: logger.info("Updating special page " + virtualWiki + " / "
1280: + topicName);
1281: Connection conn = null;
1282: try {
1283: conn = WikiDatabase.getConnection(transactionObject);
1284: String contents = WikiUtil.readSpecialPage(locale,
1285: topicName);
1286: Topic topic = this .lookupTopic(virtualWiki, topicName,
1287: false, conn);
1288: topic.setTopicContent(contents);
1289: // FIXME - hard coding
1290: TopicVersion topicVersion = new TopicVersion(user,
1291: ipAddress,
1292: "Automatically updated by system upgrade", contents);
1293: ParserOutput parserOutput = ParserUtil.parserOutput(topic
1294: .getTopicContent(), virtualWiki, topicName);
1295: writeTopic(topic, topicVersion, parserOutput
1296: .getCategories(), parserOutput.getLinks(), true,
1297: conn);
1298: } catch (Exception e) {
1299: DatabaseConnection.handleErrors(conn);
1300: throw e;
1301: } finally {
1302: WikiDatabase.releaseConnection(conn, transactionObject);
1303: }
1304: }
1305:
1306: /**
1307: *
1308: */
1309: private void updateTopic(Topic topic, Connection conn)
1310: throws Exception {
1311: int virtualWikiId = this .lookupVirtualWikiId(topic
1312: .getVirtualWiki());
1313: this .queryHandler().updateTopic(topic, virtualWikiId, conn);
1314: }
1315:
1316: /**
1317: *
1318: */
1319: private void updateVirtualWiki(VirtualWiki virtualWiki,
1320: Connection conn) throws Exception {
1321: this .queryHandler().updateVirtualWiki(virtualWiki, conn);
1322: }
1323:
1324: /**
1325: *
1326: */
1327: private void updateWikiFile(WikiFile wikiFile, Connection conn)
1328: throws Exception {
1329: int virtualWikiId = this .lookupVirtualWikiId(wikiFile
1330: .getVirtualWiki());
1331: this .queryHandler().updateWikiFile(wikiFile, virtualWikiId,
1332: conn);
1333: }
1334:
1335: /**
1336: *
1337: */
1338: private void updateWikiGroup(WikiGroup group, Connection conn)
1339: throws Exception {
1340: this .queryHandler().updateWikiGroup(group, conn);
1341: }
1342:
1343: /**
1344: *
1345: */
1346: private void updateWikiUser(WikiUser user, Connection conn)
1347: throws Exception {
1348: this .queryHandler().updateWikiUser(user, conn);
1349: }
1350:
1351: /**
1352: *
1353: */
1354: public void writeFile(WikiFile wikiFile,
1355: WikiFileVersion wikiFileVersion, Object transactionObject)
1356: throws Exception {
1357: Connection conn = null;
1358: try {
1359: conn = WikiDatabase.getConnection(transactionObject);
1360: WikiUtil.validateTopicName(wikiFile.getFileName());
1361: if (wikiFile.getFileId() <= 0) {
1362: addWikiFile(wikiFile, conn);
1363: } else {
1364: updateWikiFile(wikiFile, conn);
1365: }
1366: wikiFileVersion.setFileId(wikiFile.getFileId());
1367: // write version
1368: addWikiFileVersion(wikiFileVersion, conn);
1369: } catch (Exception e) {
1370: DatabaseConnection.handleErrors(conn);
1371: throw e;
1372: } finally {
1373: WikiDatabase.releaseConnection(conn, transactionObject);
1374: }
1375: }
1376:
1377: /**
1378: *
1379: */
1380: public void writeRole(Role role, Object transactionObject,
1381: boolean update) throws Exception {
1382: Connection conn = null;
1383: try {
1384: conn = WikiDatabase.getConnection(transactionObject);
1385: if (update) {
1386: this .queryHandler().updateRole(role, conn);
1387: } else {
1388: this .queryHandler().insertRole(role, conn);
1389: }
1390: // FIXME - add caching
1391: } catch (Exception e) {
1392: DatabaseConnection.handleErrors(conn);
1393: throw e;
1394: } finally {
1395: WikiDatabase.releaseConnection(conn, transactionObject);
1396: }
1397: }
1398:
1399: /**
1400: *
1401: */
1402: public void writeRoleMapGroup(int groupId, List roles,
1403: Object transactionObject) throws Exception {
1404: Connection conn = null;
1405: try {
1406: conn = WikiDatabase.getConnection(transactionObject);
1407: this .queryHandler().deleteRoleMapGroup(groupId, conn);
1408: Iterator roleIterator = roles.iterator();
1409: while (roleIterator.hasNext()) {
1410: String role = (String) roleIterator.next();
1411: this .queryHandler().insertRoleMap(-1, groupId, role,
1412: conn);
1413: }
1414: // refresh the current role requirements
1415: JAMWikiAnonymousProcessingFilter.reset();
1416: WikiUserAuth.resetDefaultGroupRoles();
1417: } catch (Exception e) {
1418: DatabaseConnection.handleErrors(conn);
1419: throw e;
1420: } finally {
1421: WikiDatabase.releaseConnection(conn, transactionObject);
1422: }
1423: }
1424:
1425: /**
1426: *
1427: */
1428: public void writeRoleMapUser(int userId, List roles,
1429: Object transactionObject) throws Exception {
1430: Connection conn = null;
1431: try {
1432: conn = WikiDatabase.getConnection(transactionObject);
1433: this .queryHandler().deleteRoleMapUser(userId, conn);
1434: Iterator roleIterator = roles.iterator();
1435: while (roleIterator.hasNext()) {
1436: String role = (String) roleIterator.next();
1437: this .queryHandler().insertRoleMap(userId, -1, role,
1438: conn);
1439: }
1440: } catch (Exception e) {
1441: DatabaseConnection.handleErrors(conn);
1442: throw e;
1443: } finally {
1444: WikiDatabase.releaseConnection(conn, transactionObject);
1445: }
1446: }
1447:
1448: /**
1449: * Commit changes to a topic (and its version) to the database or
1450: * filesystem.
1451: *
1452: * @param topic The topic object that is to be committed. If the topic
1453: * id is empty or less than zero then the topic is added, otherwise an
1454: * update is performed.
1455: * @param topicVersion The version associated with the topic that is
1456: * being added. This parameter should never be null UNLESS the change is
1457: * not user visible, such as when deleting a topic temporarily during
1458: * page moves.
1459: * @param categories A mapping of categories and their associated sort keys (if any)
1460: * for all categories that are associated with the current topic.
1461: * @param links A List of all topic names that are linked to from the
1462: * current topic. These will be passed to the search engine to create
1463: * searchable metadata.
1464: * @param transactionObject Database connection or other parameters
1465: * required for updates.
1466: * @param userVisible A flag indicating whether or not this change should
1467: * be visible to Wiki users. This flag should be true except in rare
1468: * cases, such as when temporarily deleting a topic during page moves.
1469: */
1470: public void writeTopic(Topic topic, TopicVersion topicVersion,
1471: LinkedHashMap categories, Vector links,
1472: boolean userVisible, Object transactionObject)
1473: throws Exception {
1474: Connection conn = null;
1475: try {
1476: String key = WikiCache.key(topic.getVirtualWiki(), topic
1477: .getName());
1478: WikiCache.removeFromCache(
1479: WikiBase.CACHE_PARSED_TOPIC_CONTENT, key);
1480: WikiCache.removeFromCache(CACHE_TOPICS, key);
1481: conn = WikiDatabase.getConnection(transactionObject);
1482: WikiUtil.validateTopicName(topic.getName());
1483: if (topic.getTopicId() <= 0) {
1484: addTopic(topic, conn);
1485: } else {
1486: updateTopic(topic, conn);
1487: }
1488: if (userVisible) {
1489: if (topicVersion.getPreviousTopicVersionId() == null
1490: && topic.getCurrentVersionId() != null) {
1491: topicVersion.setPreviousTopicVersionId(topic
1492: .getCurrentVersionId());
1493: }
1494: topicVersion.setTopicId(topic.getTopicId());
1495: // write version
1496: addTopicVersion(topicVersion, conn);
1497: String authorName = topicVersion.getAuthorIpAddress();
1498: Integer authorId = topicVersion.getAuthorId();
1499: if (authorId != null) {
1500: WikiUser user = this .lookupWikiUser(topicVersion
1501: .getAuthorId().intValue(), conn);
1502: authorName = user.getUsername();
1503: }
1504: RecentChange change = new RecentChange(topic,
1505: topicVersion, authorName);
1506: this .addRecentChange(change, conn);
1507: }
1508: if (categories != null) {
1509: // add / remove categories associated with the topic
1510: this .deleteTopicCategories(topic, conn);
1511: for (Iterator iterator = categories.keySet().iterator(); iterator
1512: .hasNext();) {
1513: String categoryName = (String) iterator.next();
1514: Category category = new Category();
1515: category.setName(categoryName);
1516: category.setSortKey((String) categories
1517: .get(categoryName));
1518: category.setVirtualWiki(topic.getVirtualWiki());
1519: category.setChildTopicName(topic.getName());
1520: this .addCategory(category, conn);
1521: }
1522: }
1523: if (links != null) {
1524: WikiBase.getSearchEngine().deleteFromIndex(topic);
1525: WikiBase.getSearchEngine().addToIndex(topic, links);
1526: }
1527: } catch (Exception e) {
1528: DatabaseConnection.handleErrors(conn);
1529: throw e;
1530: } finally {
1531: WikiDatabase.releaseConnection(conn, transactionObject);
1532: }
1533: }
1534:
1535: /**
1536: *
1537: */
1538: public void writeVirtualWiki(VirtualWiki virtualWiki,
1539: Object transactionObject) throws Exception {
1540: Connection conn = null;
1541: try {
1542: conn = WikiDatabase.getConnection(transactionObject);
1543: WikiUtil.validateTopicName(virtualWiki.getName());
1544: if (virtualWiki.getVirtualWikiId() <= 0) {
1545: this .addVirtualWiki(virtualWiki, conn);
1546: } else {
1547: this .updateVirtualWiki(virtualWiki, conn);
1548: }
1549: // update the cache AFTER the commit
1550: WikiCache.removeFromCache(CACHE_VIRTUAL_WIKI, virtualWiki
1551: .getName());
1552: WikiCache.removeFromCache(CACHE_VIRTUAL_WIKI, virtualWiki
1553: .getVirtualWikiId());
1554: WikiCache.addToCache(CACHE_VIRTUAL_WIKI, virtualWiki
1555: .getName(), virtualWiki);
1556: WikiCache.addToCache(CACHE_VIRTUAL_WIKI, virtualWiki
1557: .getVirtualWikiId(), virtualWiki);
1558: } catch (Exception e) {
1559: DatabaseConnection.handleErrors(conn);
1560: throw e;
1561: } finally {
1562: WikiDatabase.releaseConnection(conn, transactionObject);
1563: }
1564: }
1565:
1566: /**
1567: *
1568: */
1569: public void writeWatchlistEntry(Watchlist watchlist,
1570: String virtualWiki, String topicName, int userId,
1571: Object transactionObject) throws Exception {
1572: Connection conn = null;
1573: try {
1574: conn = WikiDatabase.getConnection(transactionObject);
1575: int virtualWikiId = this .lookupVirtualWikiId(virtualWiki);
1576: String article = WikiUtil.extractTopicLink(topicName);
1577: String comments = WikiUtil.extractCommentsLink(topicName);
1578: if (watchlist.containsTopic(topicName)) {
1579: // remove from watchlist
1580: this .deleteWatchlistEntry(virtualWikiId, article,
1581: userId, conn);
1582: this .deleteWatchlistEntry(virtualWikiId, comments,
1583: userId, conn);
1584: watchlist.remove(article);
1585: watchlist.remove(comments);
1586: } else {
1587: // add to watchlist
1588: this .addWatchlistEntry(virtualWikiId, article, userId,
1589: conn);
1590: this .addWatchlistEntry(virtualWikiId, comments, userId,
1591: conn);
1592: watchlist.add(article);
1593: watchlist.add(comments);
1594: }
1595: } catch (Exception e) {
1596: DatabaseConnection.handleErrors(conn);
1597: throw e;
1598: } finally {
1599: WikiDatabase.releaseConnection(conn, transactionObject);
1600: }
1601: }
1602:
1603: /**
1604: *
1605: */
1606: public void writeWikiGroup(WikiGroup group, Object transactionObject)
1607: throws Exception {
1608: Connection conn = null;
1609: try {
1610: conn = WikiDatabase.getConnection(transactionObject);
1611: if (group.getGroupId() <= 0) {
1612: this .addWikiGroup(group, conn);
1613: } else {
1614: this .updateWikiGroup(group, conn);
1615: }
1616: } catch (Exception e) {
1617: DatabaseConnection.handleErrors(conn);
1618: throw e;
1619: } finally {
1620: WikiDatabase.releaseConnection(conn, transactionObject);
1621: }
1622: }
1623:
1624: /**
1625: *
1626: */
1627: public void writeWikiUser(WikiUser user, WikiUserInfo userInfo,
1628: Object transactionObject) throws Exception {
1629: WikiUtil.validateUserName(user.getUsername());
1630: Connection conn = null;
1631: try {
1632: conn = WikiDatabase.getConnection(transactionObject);
1633: if (user.getUserId() <= 0) {
1634: this .addWikiUser(user, conn);
1635: if (WikiBase.getUserHandler().isWriteable()) {
1636: userInfo.setUserId(user.getUserId());
1637: WikiBase.getUserHandler().addWikiUserInfo(userInfo,
1638: conn);
1639: }
1640: } else {
1641: this .updateWikiUser(user, conn);
1642: if (WikiBase.getUserHandler().isWriteable()) {
1643: WikiBase.getUserHandler().updateWikiUserInfo(
1644: userInfo, conn);
1645: }
1646: }
1647: } catch (Exception e) {
1648: DatabaseConnection.handleErrors(conn);
1649: throw e;
1650: } finally {
1651: WikiDatabase.releaseConnection(conn, transactionObject);
1652: }
1653: }
1654: }
|