001: /*
002: Very Quick Wiki - WikiWikiWeb clone
003: Copyright (C) 2001-2002 Gareth Cronin
004:
005: This program is free software; you can redistribute it and/or modify
006: it under the terms of the latest version of the GNU Lesser General
007: Public License as published by the Free Software Foundation;
008:
009: This program is distributed in the hope that it will be useful,
010: but WITHOUT ANY WARRANTY; without even the implied warranty of
011: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: GNU Lesser General Public License for more details.
013:
014: You should have received a copy of the GNU Lesser General Public License
015: along with this program (gpl.txt); if not, write to the Free Software
016: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: */
018: package vqwiki.db;
019:
020: import org.apache.log4j.Logger;
021: import vqwiki.Change;
022: import vqwiki.ChangeLog;
023: import vqwiki.Notify;
024: import vqwiki.WikiBase;
025: import vqwiki.Environment;
026: import vqwiki.utils.JSPUtils;
027:
028: import javax.servlet.http.HttpServletRequest;
029: import java.sql.Connection;
030: import java.sql.PreparedStatement;
031: import java.sql.ResultSet;
032: import java.util.ArrayList;
033: import java.util.Collection;
034: import java.util.Date;
035: import java.util.Iterator;
036:
037: public class DatabaseChangeLog implements ChangeLog {
038:
039: private static final Logger logger = Logger
040: .getLogger(DatabaseChangeLog.class);
041: protected static DatabaseChangeLog instance;
042:
043: protected final static String STATEMENT_WRITE_CHANGE = "INSERT INTO TopicChange( topic, username, changeat, virtualwiki ) VALUES( ?, ?, ?, ? )";
044: protected final static String STATEMENT_READ_CHANGES = "SELECT * FROM TopicChange WHERE changeat >= ? and changeat <= ? and virtualwiki = ? ORDER BY changeat DESC";
045: protected final static String STATEMENT_CHANGE_EXISTS = "SELECT * FROM TopicChange WHERE topic = ? AND changeat >= ? and changeat <= ? and virtualwiki = ?";
046: protected final static String STATEMENT_UPDATE_CHANGE = "UPDATE TopicChange SET username = ?, changeat = ? WHERE topic = ? AND changeat = ? and virtualwiki = ?";
047: protected final static String STATEMENT_DELETE_CHANGE = "DELETE FROM TopicChange WHERE topic = ? AND virtualwiki = ?";
048:
049: /**
050: *
051: */
052: private DatabaseChangeLog() {
053: }
054:
055: /**
056: *
057: */
058: public static DatabaseChangeLog getInstance() {
059: if (instance == null)
060: instance = new DatabaseChangeLog();
061: return instance;
062: }
063:
064: /**
065: *
066: */
067: public void logChange(Change change, HttpServletRequest request)
068: throws Exception {
069: logger.debug("Logging change: " + change);
070: Connection conn = null;
071: String virtualWiki = null;
072: String topic = null;
073: boolean changedToday = false;
074: try {
075: conn = DatabaseConnection.getConnection();
076: PreparedStatement existChangeStatement = conn
077: .prepareStatement(STATEMENT_CHANGE_EXISTS);
078: topic = change.getTopic();
079: existChangeStatement.setString(1, topic);
080: existChangeStatement.setTimestamp(2, (new DBDate(change
081: .getTime())).startOfDayStamp());
082: existChangeStatement.setTimestamp(3, (new DBDate(change
083: .getTime())).endOfDayStamp());
084: virtualWiki = change.getVirtualWiki();
085: existChangeStatement.setString(4, virtualWiki);
086: ResultSet rs = existChangeStatement.executeQuery();
087: if (rs.next()) {
088: changedToday = true;
089: logger.debug("Updating as existing change for "
090: + change.getUser());
091: DBDate changeDate = new DBDate(rs
092: .getTimestamp("changeat"));
093: rs.close();
094: PreparedStatement updateChangeStatement = conn
095: .prepareStatement(STATEMENT_UPDATE_CHANGE);
096: updateChangeStatement.setString(1, change.getUser());
097: updateChangeStatement.setTimestamp(2, (new DBDate())
098: .asTimestamp());
099: updateChangeStatement.setString(3, topic);
100: updateChangeStatement.setTimestamp(4, changeDate
101: .asTimestamp());
102: updateChangeStatement.setString(5, virtualWiki);
103: updateChangeStatement.execute();
104: updateChangeStatement.close();
105: } else {
106: logger.debug("New change for " + change.getUser());
107: rs.close();
108: PreparedStatement writeChangeStatement = conn
109: .prepareStatement(STATEMENT_WRITE_CHANGE);
110: writeChangeStatement.setString(1, topic);
111: writeChangeStatement.setString(2, change.getUser());
112: writeChangeStatement.setTimestamp(3, (new DBDate())
113: .asTimestamp());
114: writeChangeStatement.setString(4, virtualWiki);
115: writeChangeStatement.execute();
116: writeChangeStatement.close();
117: }
118: rs.close();
119: existChangeStatement.close();
120: } finally {
121: DatabaseConnection.closeConnection(conn);
122: }
123: boolean suppressNotifyInSameDay = Environment
124: .getInstance()
125: .getBooleanSetting(
126: Environment.PROPERTY_SUPPRESS_NOTIFY_WITHIN_SAME_DAY);
127: if (!changedToday && suppressNotifyInSameDay
128: || !suppressNotifyInSameDay) {
129: try {
130: Notify notifier = WikiBase.getInstance()
131: .getNotifyInstance(virtualWiki, topic);
132: String wikiServerHostname = Environment
133: .getInstance()
134: .getStringSetting(
135: Environment.PROPERTY_WIKI_SERVER_HOSTNAME);
136: notifier.sendNotifications(JSPUtils.createRootPath(
137: request, virtualWiki, wikiServerHostname),
138: request.getLocale());
139: } catch (Exception e) {
140: logger.warn(e);
141: e.printStackTrace();
142: }
143: } else {
144: logger
145: .debug("not sending notification because change has already been made today");
146: }
147: }
148:
149: /**
150: *
151: */
152: public Collection getChanges(String virtualWiki, Date d)
153: throws Exception {
154: logger.debug("Getting changes for virtualWiki " + virtualWiki);
155: Collection all = new ArrayList();
156: Connection conn = null;
157: try {
158: conn = DatabaseConnection.getConnection();
159: PreparedStatement readChangesStatement = conn
160: .prepareStatement(STATEMENT_READ_CHANGES);
161: readChangesStatement.setTimestamp(1, (new DBDate(d))
162: .startOfDayStamp());
163: readChangesStatement.setTimestamp(2, (new DBDate(d))
164: .endOfDayStamp());
165: readChangesStatement.setString(3, virtualWiki);
166: ResultSet rs = readChangesStatement.executeQuery();
167: while (rs.next()) {
168: Change change = new Change();
169: change.setUser(rs.getString("username"));
170: change.setTopic(rs.getString("topic"));
171: change.setTime(new DBDate(rs.getTimestamp("changeat")));
172: change.setVirtualWiki(virtualWiki);
173: all.add(change);
174: }
175: rs.close();
176: readChangesStatement.close();
177: } finally {
178: DatabaseConnection.closeConnection(conn);
179: }
180: return all;
181: }
182:
183: /**
184: *
185: */
186: public void removeChanges(String virtualwiki, Collection cl)
187: throws Exception {
188: logger
189: .debug("purging topics from the recent topics list for virtualWiki "
190: + virtualwiki);
191: Connection conn = null;
192: try {
193: conn = DatabaseConnection.getConnection();
194: PreparedStatement deleteChangesStatement = conn
195: .prepareStatement(STATEMENT_DELETE_CHANGE);
196: for (Iterator iter = cl.iterator(); iter.hasNext();) {
197: String topic = (String) iter.next();
198: logger.debug("add topic to delete " + topic);
199: deleteChangesStatement.setString(1, topic);
200: deleteChangesStatement.setString(2, virtualwiki);
201: deleteChangesStatement.execute();
202: }
203: deleteChangesStatement.close();
204: } finally {
205: DatabaseConnection.closeConnection(conn);
206: }
207: }
208: }
|