src/org/sonews/storage/impl/DrupalDatabase.java
changeset 72 aae4b4688700
parent 71 beb11d70f0eb
child 73 1feed5fbf147
     1.1 --- a/src/org/sonews/storage/impl/DrupalDatabase.java	Tue Oct 11 16:34:17 2011 +0200
     1.2 +++ b/src/org/sonews/storage/impl/DrupalDatabase.java	Wed Oct 12 00:11:25 2011 +0200
     1.3 @@ -17,29 +17,26 @@
     1.4   */
     1.5  package org.sonews.storage.impl;
     1.6  
     1.7 -import java.io.UnsupportedEncodingException;
     1.8  import java.sql.Connection;
     1.9  import java.sql.DriverManager;
    1.10  import java.sql.PreparedStatement;
    1.11  import java.sql.ResultSet;
    1.12 -import java.sql.SQLException;
    1.13  import java.sql.Statement;
    1.14  import java.text.SimpleDateFormat;
    1.15  import java.util.ArrayList;
    1.16  import java.util.Collections;
    1.17 -import java.util.Date;
    1.18  import java.util.List;
    1.19  import java.util.Locale;
    1.20  import java.util.logging.Level;
    1.21  import java.util.logging.Logger;
    1.22 -import javax.mail.internet.MailDateFormat;
    1.23 -import javax.mail.internet.MimeUtility;
    1.24 -import org.apache.commons.codec.net.BCodec;
    1.25 +import javax.mail.Message;
    1.26  import org.apache.commons.codec.net.QuotedPrintableCodec;
    1.27  import org.sonews.config.Config;
    1.28  import org.sonews.feed.Subscription;
    1.29  import org.sonews.storage.Article;
    1.30  import org.sonews.storage.ArticleHead;
    1.31 +import org.sonews.storage.DrupalArticle;
    1.32 +import org.sonews.storage.DrupalMessage;
    1.33  import org.sonews.storage.Group;
    1.34  import org.sonews.storage.Storage;
    1.35  import org.sonews.storage.StorageBackendException;
    1.36 @@ -54,14 +51,11 @@
    1.37  	private static final Logger log = Logger.getLogger(DrupalDatabase.class.getName());
    1.38  	public static final String CHARSET = "UTF-8";
    1.39  	public static final String CRLF = "\r\n";
    1.40 -	public static final int MAX_RESTARTS = 2;
    1.41 -	/** How many times the database connection was reinitialized */
    1.42 -	protected int restarts = 0;
    1.43  	protected Connection conn = null;
    1.44  	private QuotedPrintableCodec qpc = new QuotedPrintableCodec(CHARSET);
    1.45  	private SimpleDateFormat RFC822_DATE = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
    1.46  	// TODO: správná doména
    1.47 -	private String myDomain = "kinderporno.cz";
    1.48 +	private String myDomain = "nntp.i1984.cz";
    1.49  
    1.50  	public DrupalDatabase() throws StorageBackendException {
    1.51  		connectDatabase();
    1.52 @@ -137,73 +131,12 @@
    1.53  			return null;
    1.54  		} else {
    1.55  			return Long.parseLong(localPart[1]);
    1.56 +			// If needed:
    1.57 +			// parseGroupName() will be same as this method, just with:
    1.58 +			// return localPart[2];
    1.59  		}
    1.60  	}
    1.61  
    1.62 -	private static String parseGroupName(String messageID) {
    1.63 -		String[] localPart = parseMessageID(messageID);
    1.64 -		if (localPart == null) {
    1.65 -			return null;
    1.66 -		} else {
    1.67 -			return localPart[2];
    1.68 -		}
    1.69 -	}
    1.70 -
    1.71 -	private static String constructMessageId(int articleID, int groupID, String groupName, String domainName) {
    1.72 -		StringBuilder sb = new StringBuilder();
    1.73 -		sb.append("<");
    1.74 -		sb.append(articleID);
    1.75 -		sb.append("-");
    1.76 -		sb.append(groupID);
    1.77 -		sb.append("-");
    1.78 -		sb.append(groupName);
    1.79 -		sb.append("@");
    1.80 -		sb.append(domainName);
    1.81 -		sb.append(">");
    1.82 -		return sb.toString();
    1.83 -	}
    1.84 -
    1.85 -	/**
    1.86 -	 * 
    1.87 -	 * @param sb header list to be appended with new header. List must be terminated by line end.
    1.88 -	 * @param key header name (without : and space)
    1.89 -	 * @param value header value
    1.90 -	 * @param encode true if value should be encoded/escaped before appending
    1.91 -	 * @throws UnsupportedEncodingException 
    1.92 -	 */
    1.93 -	private static void addHeader(StringBuilder sb, String key, String value, boolean encode) throws UnsupportedEncodingException {
    1.94 -		sb.append(key);
    1.95 -		sb.append(": ");
    1.96 -		if (encode) {
    1.97 -			sb.append(MimeUtility.encodeWord(value));
    1.98 -		} else {
    1.99 -			sb.append(value);
   1.100 -		}
   1.101 -		sb.append(CRLF);
   1.102 -	}
   1.103 -
   1.104 -	private String constructHeaders(ResultSet rs) throws SQLException, UnsupportedEncodingException {
   1.105 -		StringBuilder sb = new StringBuilder();
   1.106 -
   1.107 -		addHeader(sb, "Message-id", constructMessageId(rs.getInt("id"), rs.getInt("group_id"), rs.getString("group_name"), myDomain), false);
   1.108 -		addHeader(sb, "From", MimeUtility.encodeWord(rs.getString("sender_name")) + " <>", false);
   1.109 -		addHeader(sb, "Subject", rs.getString("subject"), true);
   1.110 -		/** TODO: správný formát data: */
   1.111 -		addHeader(sb, "Date", RFC822_DATE.format(new Date(rs.getLong("created"))), false);
   1.112 -		addHeader(sb, "Content-Type", "text/html; charset=" + CHARSET, false);
   1.113 -		addHeader(sb, "Content-Transfer-Encoding", "quoted-printable", false);
   1.114 -		//addHeader(sb, "Content-Transfer-Encoding", "base64", false);
   1.115 -
   1.116 -		Integer parentID = rs.getInt("parent_id");
   1.117 -		if (parentID != null && parentID > 0) {
   1.118 -			String parentMessageID = constructMessageId(parentID, rs.getInt("group_id"), rs.getString("group_name"), myDomain);
   1.119 -			addHeader(sb, "In-Reply-To", parentMessageID, false);
   1.120 -			addHeader(sb, "References", parentMessageID, false);
   1.121 -		}
   1.122 -
   1.123 -		return sb.toString();
   1.124 -	}
   1.125 -
   1.126  	@Override
   1.127  	public List<Group> getGroups() throws StorageBackendException {
   1.128  		PreparedStatement ps = null;
   1.129 @@ -275,13 +208,8 @@
   1.130  			rs = ps.executeQuery();
   1.131  
   1.132  			if (rs.next()) {
   1.133 -				String headers = constructHeaders(rs);
   1.134 -				// TODO: fold?
   1.135 -				BCodec bc = new BCodec(CHARSET);
   1.136 -				byte[] body = qpc.encode(rs.getString("text")).getBytes();
   1.137 -				//byte[] body = bc.encode(rs.getString("text")).getBytes();
   1.138 -
   1.139 -				return new Article(headers, body);
   1.140 +				DrupalMessage m = new DrupalMessage(rs, myDomain, true);
   1.141 +				return new DrupalArticle(m);
   1.142  			} else {
   1.143  				return null;
   1.144  			}
   1.145 @@ -297,7 +225,6 @@
   1.146  		PreparedStatement ps = null;
   1.147  		ResultSet rs = null;
   1.148  		try {
   1.149 -			// TODO: je nutné řazení?
   1.150  			ps = conn.prepareStatement("SELECT * FROM nntp_article WHERE group_id = ? AND id >= ? AND id <= ? ORDER BY id");
   1.151  			ps.setLong(1, group.getInternalID());
   1.152  			ps.setLong(2, first);
   1.153 @@ -307,7 +234,8 @@
   1.154  			List<Pair<Long, ArticleHead>> heads = new ArrayList<Pair<Long, ArticleHead>>();
   1.155  
   1.156  			while (rs.next()) {
   1.157 -				String headers = constructHeaders(rs);
   1.158 +				DrupalMessage m = new DrupalMessage(rs, myDomain, false);
   1.159 +				String headers = m.getHeaders();
   1.160  				heads.add(new Pair<Long, ArticleHead>(rs.getLong("id"), new ArticleHead(headers)));
   1.161  			}
   1.162  
   1.163 @@ -320,13 +248,6 @@
   1.164  	}
   1.165  
   1.166  	@Override
   1.167 -	public List<Pair<Long, String>> getArticleHeaders(Group group, long start, long end, String header, String pattern) throws StorageBackendException {
   1.168 -		log.log(Level.SEVERE, "TODO: getArticleHeaders {0} / {1} / {2} / {3} / {4}", new Object[]{group, start, end, header, pattern});
   1.169 -		/** TODO: */
   1.170 -		return Collections.emptyList();
   1.171 -	}
   1.172 -
   1.173 -	@Override
   1.174  	public long getArticleIndex(Article article, Group group) throws StorageBackendException {
   1.175  		Long id = parseArticleID(article.getMessageID());
   1.176  		if (id == null) {
   1.177 @@ -416,24 +337,6 @@
   1.178  		}
   1.179  	}
   1.180  
   1.181 -	//
   1.182 -	// --- zatím neimplementovat ---
   1.183 -	//
   1.184 -	@Override
   1.185 -	public void addArticle(Article art) throws StorageBackendException {
   1.186 -		log.log(Level.SEVERE, "TODO: addArticle {0}", new Object[]{art});
   1.187 -	}
   1.188 -
   1.189 -	@Override
   1.190 -	public void addEvent(long timestamp, int type, long groupID) throws StorageBackendException {
   1.191 -		log.log(Level.SEVERE, "TODO: addEvent {0} / {1} / {2}", new Object[]{timestamp, type, groupID});
   1.192 -	}
   1.193 -
   1.194 -	@Override
   1.195 -	public void addGroup(String groupname, int flags) throws StorageBackendException {
   1.196 -		log.log(Level.SEVERE, "TODO: addGroup {0} / {1}", new Object[]{groupname, flags});
   1.197 -	}
   1.198 -
   1.199  	@Override
   1.200  	public int countArticles() throws StorageBackendException {
   1.201  		PreparedStatement ps = null;
   1.202 @@ -467,6 +370,45 @@
   1.203  	}
   1.204  
   1.205  	@Override
   1.206 +	public int getPostingsCount(String groupname) throws StorageBackendException {
   1.207 +		PreparedStatement ps = null;
   1.208 +		ResultSet rs = null;
   1.209 +		try {
   1.210 +			ps = conn.prepareStatement("SELECT count(*) FROM nntp_article WHERE group_name = ?");
   1.211 +			ps.setString(1, groupname);
   1.212 +			rs = ps.executeQuery();
   1.213 +			rs.next();
   1.214 +			return rs.getInt(1);
   1.215 +		} catch (Exception e) {
   1.216 +			throw new StorageBackendException(e);
   1.217 +		} finally {
   1.218 +			close(null, ps, rs);
   1.219 +		}
   1.220 +	}
   1.221 +
   1.222 +	@Override
   1.223 +	public List<Pair<Long, String>> getArticleHeaders(Group group, long start, long end, String header, String pattern) throws StorageBackendException {
   1.224 +		log.log(Level.SEVERE, "TODO: getArticleHeaders {0} / {1} / {2} / {3} / {4}", new Object[]{group, start, end, header, pattern});
   1.225 +		/** TODO: */
   1.226 +		return Collections.emptyList();
   1.227 +	}
   1.228 +
   1.229 +	@Override
   1.230 +	public void addArticle(Article art) throws StorageBackendException {
   1.231 +		log.log(Level.SEVERE, "TODO: addArticle {0}", new Object[]{art});
   1.232 +	}
   1.233 +
   1.234 +	@Override
   1.235 +	public void addEvent(long timestamp, int type, long groupID) throws StorageBackendException {
   1.236 +		log.log(Level.SEVERE, "TODO: addEvent {0} / {1} / {2}", new Object[]{timestamp, type, groupID});
   1.237 +	}
   1.238 +
   1.239 +	@Override
   1.240 +	public void addGroup(String groupname, int flags) throws StorageBackendException {
   1.241 +		log.log(Level.SEVERE, "TODO: addGroup {0} / {1}", new Object[]{groupname, flags});
   1.242 +	}
   1.243 +
   1.244 +	@Override
   1.245  	public void delete(String messageID) throws StorageBackendException {
   1.246  		log.log(Level.SEVERE, "TODO: delete {0}", new Object[]{messageID});
   1.247  	}
   1.248 @@ -478,6 +420,11 @@
   1.249  	}
   1.250  
   1.251  	@Override
   1.252 +	public void setConfigValue(String key, String value) throws StorageBackendException {
   1.253 +		log.log(Level.SEVERE, "TODO: setConfigValue {0} = {1}", new Object[]{key, value});
   1.254 +	}
   1.255 +
   1.256 +	@Override
   1.257  	public int getEventsCount(int eventType, long startTimestamp, long endTimestamp, Group group) throws StorageBackendException {
   1.258  		log.log(Level.SEVERE, "TODO: getEventsCount {0} / {1} / {2} / {3}", new Object[]{eventType, startTimestamp, endTimestamp, group});
   1.259  		return 0;
   1.260 @@ -508,23 +455,6 @@
   1.261  	}
   1.262  
   1.263  	@Override
   1.264 -	public int getPostingsCount(String groupname) throws StorageBackendException {
   1.265 -		PreparedStatement ps = null;
   1.266 -		ResultSet rs = null;
   1.267 -		try {
   1.268 -			ps = conn.prepareStatement("SELECT count(*) FROM nntp_article WHERE group_name = ?");
   1.269 -			ps.setString(1, groupname);
   1.270 -			rs = ps.executeQuery();
   1.271 -			rs.next();
   1.272 -			return rs.getInt(1);
   1.273 -		} catch (Exception e) {
   1.274 -			throw new StorageBackendException(e);
   1.275 -		} finally {
   1.276 -			close(null, ps, rs);
   1.277 -		}
   1.278 -	}
   1.279 -
   1.280 -	@Override
   1.281  	public List<Subscription> getSubscriptions(int type) throws StorageBackendException {
   1.282  		log.log(Level.SEVERE, "TODO: getSubscriptions {0}", new Object[]{type});
   1.283  		return Collections.emptyList();
   1.284 @@ -536,11 +466,6 @@
   1.285  	}
   1.286  
   1.287  	@Override
   1.288 -	public void setConfigValue(String key, String value) throws StorageBackendException {
   1.289 -		log.log(Level.SEVERE, "TODO: setConfigValue {0} = {1}", new Object[]{key, value});
   1.290 -	}
   1.291 -
   1.292 -	@Override
   1.293  	public boolean update(Article article) throws StorageBackendException {
   1.294  		log.log(Level.SEVERE, "TODO: update {0}", new Object[]{article});
   1.295  		throw new StorageBackendException("Not implemented yet.");