Fix for #14
authorcli
Sun, 11 Sep 2011 17:01:19 +0200
changeset 498df94bfd3e2f
parent 48 b78e77619152
child 50 0bf10add82d9
Fix for #14
src/org/sonews/Main.java
src/org/sonews/ShutdownHook.java
src/org/sonews/acl/AccessControl.java
src/org/sonews/acl/AuthInfoCommand.java
src/org/sonews/config/AbstractConfig.java
src/org/sonews/config/BackendConfig.java
src/org/sonews/config/CommandLineConfig.java
src/org/sonews/config/Config.java
src/org/sonews/daemon/NNTPConnection.java
src/org/sonews/daemon/command/ListCommand.java
src/org/sonews/util/Stats.java
     1.1 --- a/src/org/sonews/Main.java	Sun Sep 11 15:05:04 2011 +0200
     1.2 +++ b/src/org/sonews/Main.java	Sun Sep 11 17:01:19 2011 +0200
     1.3 @@ -45,6 +45,8 @@
     1.4  
     1.5  	/** Version information of the sonews daemon */
     1.6  	public static final String VERSION = "sonews/1.1.0";
     1.7 +
     1.8 +	/** The server's startup date */
     1.9  	public static final Date STARTDATE = new Date();
    1.10  
    1.11  	/**
    1.12 @@ -81,13 +83,16 @@
    1.13  				mlgw = true;
    1.14  			} else if (args[n].equals("-p")) {
    1.15  				port = Integer.parseInt(args[++n]);
    1.16 -			} else if (args[n].equals("-plugin")) {
    1.17 +			} else if (args[n].equals("-plugin-storage")) {
    1.18  				System.out.println("Warning: -plugin-storage is not implemented!");
    1.19  			} else if (args[n].equals("-plugin-command")) {
    1.20  				try {
    1.21  					CommandSelector.addCommandHandler(args[++n]);
    1.22  				} catch (Exception ex) {
    1.23 -					Log.get().warning("Could not load command plugin: " + args[n]);
    1.24 +					StringBuilder strBuf = new StringBuilder();
    1.25 +					strBuf.append("Could not load command plugin: ");
    1.26 +					strBuf.append(args[n]);
    1.27 +					Log.get().warning(strBuf.toString());
    1.28  					Log.get().log(Level.INFO, "Main.java", ex);
    1.29  				}
    1.30  			} else if (args[n].equals("-plugin-storage")) {
    1.31 @@ -113,10 +118,10 @@
    1.32  				Log.get().info("Group 'control' created.");
    1.33  			}
    1.34  		} catch (StorageBackendException ex) {
    1.35 -			ex.printStackTrace();
    1.36 +			Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
    1.37  			System.err.println("Database initialization failed with " + ex.toString());
    1.38  			System.err.println("Make sure you have specified the correct database"
    1.39 -					+ " settings in sonews.conf!");
    1.40 +							+ " settings in sonews.conf!");
    1.41  			return;
    1.42  		}
    1.43  
     2.1 --- a/src/org/sonews/ShutdownHook.java	Sun Sep 11 15:05:04 2011 +0200
     2.2 +++ b/src/org/sonews/ShutdownHook.java	Sun Sep 11 17:01:19 2011 +0200
     2.3 @@ -15,7 +15,6 @@
     2.4   *   You should have received a copy of the GNU General Public License
     2.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     2.6   */
     2.7 -
     2.8  package org.sonews;
     2.9  
    2.10  import java.sql.SQLException;
    2.11 @@ -27,15 +26,13 @@
    2.12   * @author Christian Lins
    2.13   * @since sonews/0.5.0
    2.14   */
    2.15 -class ShutdownHook extends Thread
    2.16 -{
    2.17 +class ShutdownHook extends Thread {
    2.18  
    2.19  	/**
    2.20  	 * Called when the JVM exits.
    2.21  	 */
    2.22  	@Override
    2.23 -	public void run()
    2.24 -	{
    2.25 +	public void run() {
    2.26  		System.out.println("sonews: Trying to shutdown all threads...");
    2.27  
    2.28  		Map<Thread, StackTraceElement[]> threadsMap = Thread.getAllStackTraces();
     3.1 --- a/src/org/sonews/acl/AccessControl.java	Sun Sep 11 15:05:04 2011 +0200
     3.2 +++ b/src/org/sonews/acl/AccessControl.java	Sun Sep 11 17:01:19 2011 +0200
     3.3 @@ -15,7 +15,6 @@
     3.4   *   You should have received a copy of the GNU General Public License
     3.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     3.6   */
     3.7 -
     3.8  package org.sonews.acl;
     3.9  
    3.10  /**
    3.11 @@ -23,8 +22,7 @@
    3.12   * @author Christian Lins
    3.13   * @since sonews/1.1
    3.14   */
    3.15 -public interface AccessControl
    3.16 -{
    3.17 +public interface AccessControl {
    3.18  
    3.19  	boolean hasPermission(String user, char[] secret, String permission);
    3.20  }
     4.1 --- a/src/org/sonews/acl/AuthInfoCommand.java	Sun Sep 11 15:05:04 2011 +0200
     4.2 +++ b/src/org/sonews/acl/AuthInfoCommand.java	Sun Sep 11 17:01:19 2011 +0200
     4.3 @@ -15,7 +15,6 @@
     4.4   *   You should have received a copy of the GNU General Public License
     4.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     4.6   */
     4.7 -
     4.8  package org.sonews.acl;
     4.9  
    4.10  import java.io.IOException;
    4.11 @@ -28,37 +27,31 @@
    4.12   * @author Christian Lins
    4.13   * @since sonews/1.1
    4.14   */
    4.15 -public class AuthInfoCommand implements Command
    4.16 -{
    4.17 +public class AuthInfoCommand implements Command {
    4.18  
    4.19  	@Override
    4.20 -	public String[] getSupportedCommandStrings()
    4.21 -	{
    4.22 +	public String[] getSupportedCommandStrings() {
    4.23  		throw new UnsupportedOperationException("Not supported yet.");
    4.24  	}
    4.25  
    4.26  	@Override
    4.27 -	public boolean hasFinished()
    4.28 -	{
    4.29 +	public boolean hasFinished() {
    4.30  		throw new UnsupportedOperationException("Not supported yet.");
    4.31  	}
    4.32  
    4.33  	@Override
    4.34 -	public String impliedCapability()
    4.35 -	{
    4.36 +	public String impliedCapability() {
    4.37  		throw new UnsupportedOperationException("Not supported yet.");
    4.38  	}
    4.39  
    4.40  	@Override
    4.41 -	public boolean isStateful()
    4.42 -	{
    4.43 +	public boolean isStateful() {
    4.44  		throw new UnsupportedOperationException("Not supported yet.");
    4.45  	}
    4.46  
    4.47  	@Override
    4.48  	public void processLine(NNTPConnection conn, String line, byte[] rawLine)
    4.49 -		throws IOException, StorageBackendException
    4.50 -	{
    4.51 +			throws IOException, StorageBackendException {
    4.52  		throw new UnsupportedOperationException("Not supported yet.");
    4.53  	}
    4.54  }
     5.1 --- a/src/org/sonews/config/AbstractConfig.java	Sun Sep 11 15:05:04 2011 +0200
     5.2 +++ b/src/org/sonews/config/AbstractConfig.java	Sun Sep 11 17:01:19 2011 +0200
     5.3 @@ -15,7 +15,6 @@
     5.4   *   You should have received a copy of the GNU General Public License
     5.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     5.6   */
     5.7 -
     5.8  package org.sonews.config;
     5.9  
    5.10  /**
    5.11 @@ -23,19 +22,16 @@
    5.12   * @author Christian Lins
    5.13   * @since sonews/0.5.0
    5.14   */
    5.15 -public abstract class AbstractConfig
    5.16 -{
    5.17 +public abstract class AbstractConfig {
    5.18  
    5.19  	public abstract String get(String key, String defVal);
    5.20  
    5.21 -	public int get(final String key, final int defVal)
    5.22 -	{
    5.23 +	public int get(final String key, final int defVal) {
    5.24  		return Integer.parseInt(
    5.25 -			get(key, Integer.toString(defVal)));
    5.26 +				get(key, Integer.toString(defVal)));
    5.27  	}
    5.28  
    5.29 -	public boolean get(String key, boolean defVal)
    5.30 -	{
    5.31 +	public boolean get(String key, boolean defVal) {
    5.32  		String val = get(key, Boolean.toString(defVal));
    5.33  		return Boolean.parseBoolean(val);
    5.34  	}
    5.35 @@ -46,8 +42,7 @@
    5.36  	 * @param defVal
    5.37  	 * @return
    5.38  	 */
    5.39 -	public long get(String key, long defVal)
    5.40 -	{
    5.41 +	public long get(String key, long defVal) {
    5.42  		String val = get(key, Long.toString(defVal));
    5.43  		return Long.parseLong(val);
    5.44  	}
     6.1 --- a/src/org/sonews/config/BackendConfig.java	Sun Sep 11 15:05:04 2011 +0200
     6.2 +++ b/src/org/sonews/config/BackendConfig.java	Sun Sep 11 17:01:19 2011 +0200
     6.3 @@ -15,7 +15,6 @@
     6.4   *   You should have received a copy of the GNU General Public License
     6.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     6.6   */
     6.7 -
     6.8  package org.sonews.config;
     6.9  
    6.10  import java.util.logging.Level;
    6.11 @@ -30,19 +29,16 @@
    6.12   * @author Christian Lins
    6.13   * @since sonews/0.5.0
    6.14   */
    6.15 -class BackendConfig extends AbstractConfig
    6.16 -{
    6.17 +class BackendConfig extends AbstractConfig {
    6.18  
    6.19  	private static BackendConfig instance = new BackendConfig();
    6.20  
    6.21 -	public static BackendConfig getInstance()
    6.22 -	{
    6.23 +	public static BackendConfig getInstance() {
    6.24  		return instance;
    6.25  	}
    6.26  	private final TimeoutMap<String, String> values = new TimeoutMap<String, String>();
    6.27  
    6.28 -	private BackendConfig()
    6.29 -	{
    6.30 +	private BackendConfig() {
    6.31  		super();
    6.32  	}
    6.33  
    6.34 @@ -54,8 +50,7 @@
    6.35  	 * @return
    6.36  	 */
    6.37  	@Override
    6.38 -	public String get(String key, String defaultValue)
    6.39 -	{
    6.40 +	public String get(String key, String defaultValue) {
    6.41  		try {
    6.42  			String configValue = values.get(key);
    6.43  			if (configValue == null) {
    6.44 @@ -85,8 +80,7 @@
    6.45  	 * @param key
    6.46  	 * @param value
    6.47  	 */
    6.48 -	public void set(String key, String value)
    6.49 -	{
    6.50 +	public void set(String key, String value) {
    6.51  		values.put(key, value);
    6.52  
    6.53  		try {
     7.1 --- a/src/org/sonews/config/CommandLineConfig.java	Sun Sep 11 15:05:04 2011 +0200
     7.2 +++ b/src/org/sonews/config/CommandLineConfig.java	Sun Sep 11 17:01:19 2011 +0200
     7.3 @@ -15,7 +15,6 @@
     7.4   *   You should have received a copy of the GNU General Public License
     7.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     7.6   */
     7.7 -
     7.8  package org.sonews.config;
     7.9  
    7.10  import java.util.Map;
    7.11 @@ -25,24 +24,20 @@
    7.12   *
    7.13   * @author Christian Lins
    7.14   */
    7.15 -class CommandLineConfig extends AbstractConfig
    7.16 -{
    7.17 +class CommandLineConfig extends AbstractConfig {
    7.18  
    7.19  	private static final CommandLineConfig instance = new CommandLineConfig();
    7.20  
    7.21 -	public static CommandLineConfig getInstance()
    7.22 -	{
    7.23 +	public static CommandLineConfig getInstance() {
    7.24  		return instance;
    7.25  	}
    7.26  	private final Map<String, String> values = new HashMap<String, String>();
    7.27  
    7.28 -	private CommandLineConfig()
    7.29 -	{
    7.30 +	private CommandLineConfig() {
    7.31  	}
    7.32  
    7.33  	@Override
    7.34 -	public String get(String key, String def)
    7.35 -	{
    7.36 +	public String get(String key, String def) {
    7.37  		synchronized (this.values) {
    7.38  			if (this.values.containsKey(key)) {
    7.39  				def = this.values.get(key);
    7.40 @@ -52,8 +47,7 @@
    7.41  	}
    7.42  
    7.43  	@Override
    7.44 -	public void set(String key, String val)
    7.45 -	{
    7.46 +	public void set(String key, String val) {
    7.47  		synchronized (this.values) {
    7.48  			this.values.put(key, val);
    7.49  		}
     8.1 --- a/src/org/sonews/config/Config.java	Sun Sep 11 15:05:04 2011 +0200
     8.2 +++ b/src/org/sonews/config/Config.java	Sun Sep 11 17:01:19 2011 +0200
     8.3 @@ -15,7 +15,6 @@
     8.4   *   You should have received a copy of the GNU General Public License
     8.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     8.6   */
     8.7 -
     8.8  package org.sonews.config;
     8.9  
    8.10  /**
    8.11 @@ -23,8 +22,7 @@
    8.12   * @author Christian Lins
    8.13   * @since sonews/1.0
    8.14   */
    8.15 -public class Config extends AbstractConfig
    8.16 -{
    8.17 +public class Config extends AbstractConfig {
    8.18  
    8.19  	public static final int LEVEL_CLI = 1;
    8.20  	public static final int LEVEL_FILE = 2;
    8.21 @@ -91,18 +89,15 @@
    8.22  	};
    8.23  	private static Config instance = new Config();
    8.24  
    8.25 -	public static Config inst()
    8.26 -	{
    8.27 +	public static Config inst() {
    8.28  		return instance;
    8.29  	}
    8.30  
    8.31 -	private Config()
    8.32 -	{
    8.33 +	private Config() {
    8.34  	}
    8.35  
    8.36  	@Override
    8.37 -	public String get(String key, String def)
    8.38 -	{
    8.39 +	public String get(String key, String def) {
    8.40  		String val = CommandLineConfig.getInstance().get(key, null);
    8.41  
    8.42  		if (val == null) {
    8.43 @@ -116,8 +111,7 @@
    8.44  		return val;
    8.45  	}
    8.46  
    8.47 -	public String get(int maxLevel, String key, String def)
    8.48 -	{
    8.49 +	public String get(int maxLevel, String key, String def) {
    8.50  		String val = CommandLineConfig.getInstance().get(key, null);
    8.51  
    8.52  		if (val == null && maxLevel >= LEVEL_FILE) {
    8.53 @@ -131,13 +125,11 @@
    8.54  	}
    8.55  
    8.56  	@Override
    8.57 -	public void set(String key, String val)
    8.58 -	{
    8.59 +	public void set(String key, String val) {
    8.60  		set(LEVEL_BACKEND, key, val);
    8.61  	}
    8.62  
    8.63 -	public void set(int level, String key, String val)
    8.64 -	{
    8.65 +	public void set(int level, String key, String val) {
    8.66  		switch (level) {
    8.67  			case LEVEL_CLI: {
    8.68  				CommandLineConfig.getInstance().set(key, val);
     9.1 --- a/src/org/sonews/daemon/NNTPConnection.java	Sun Sep 11 15:05:04 2011 +0200
     9.2 +++ b/src/org/sonews/daemon/NNTPConnection.java	Sun Sep 11 17:01:19 2011 +0200
     9.3 @@ -15,7 +15,6 @@
     9.4   *   You should have received a copy of the GNU General Public License
     9.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     9.6   */
     9.7 -
     9.8  package org.sonews.daemon;
     9.9  
    9.10  import java.io.IOException;
    9.11 @@ -30,6 +29,7 @@
    9.12  import java.util.Arrays;
    9.13  import java.util.Timer;
    9.14  import java.util.TimerTask;
    9.15 +import java.util.logging.Level;
    9.16  import org.sonews.daemon.command.Command;
    9.17  import org.sonews.storage.Article;
    9.18  import org.sonews.storage.Group;
    9.19 @@ -43,8 +43,7 @@
    9.20   * @author Christian Lins
    9.21   * @since sonews/0.5.0
    9.22   */
    9.23 -public final class NNTPConnection
    9.24 -{
    9.25 +public final class NNTPConnection {
    9.26  
    9.27  	public static final String NEWLINE = "\r\n";    // RFC defines this as newline
    9.28  	public static final String MESSAGE_ID_PATTERN = "<[^>]+>";
    9.29 @@ -62,8 +61,7 @@
    9.30  	private SelectionKey writeSelKey = null;
    9.31  
    9.32  	public NNTPConnection(final SocketChannel channel)
    9.33 -		throws IOException
    9.34 -	{
    9.35 +			throws IOException {
    9.36  		if (channel == null) {
    9.37  			throw new IllegalArgumentException("channel is null");
    9.38  		}
    9.39 @@ -77,8 +75,7 @@
    9.40  	 * safe and returns true of the read lock was successfully set. If the lock
    9.41  	 * is still hold by another Thread the method returns false.
    9.42  	 */
    9.43 -	boolean tryReadLock()
    9.44 -	{
    9.45 +	boolean tryReadLock() {
    9.46  		// As synchronizing simple types may cause deadlocks,
    9.47  		// we use a gate object.
    9.48  		synchronized (readLockGate) {
    9.49 @@ -96,8 +93,7 @@
    9.50  	 * @throws IllegalMonitorStateException if a Thread not holding the lock
    9.51  	 * tries to release it.
    9.52  	 */
    9.53 -	void unlockReadLock()
    9.54 -	{
    9.55 +	void unlockReadLock() {
    9.56  		synchronized (readLockGate) {
    9.57  			if (readLock == Thread.currentThread().hashCode()) {
    9.58  				readLock = 0;
    9.59 @@ -110,8 +106,7 @@
    9.60  	/**
    9.61  	 * @return Current input buffer of this NNTPConnection instance.
    9.62  	 */
    9.63 -	public ByteBuffer getInputBuffer()
    9.64 -	{
    9.65 +	public ByteBuffer getInputBuffer() {
    9.66  		return this.lineBuffers.getInputBuffer();
    9.67  	}
    9.68  
    9.69 @@ -119,34 +114,29 @@
    9.70  	 * @return Output buffer of this NNTPConnection which has at least one byte
    9.71  	 * free storage.
    9.72  	 */
    9.73 -	public ByteBuffer getOutputBuffer()
    9.74 -	{
    9.75 +	public ByteBuffer getOutputBuffer() {
    9.76  		return this.lineBuffers.getOutputBuffer();
    9.77  	}
    9.78  
    9.79  	/**
    9.80  	 * @return ChannelLineBuffers instance associated with this NNTPConnection.
    9.81  	 */
    9.82 -	public ChannelLineBuffers getBuffers()
    9.83 -	{
    9.84 +	public ChannelLineBuffers getBuffers() {
    9.85  		return this.lineBuffers;
    9.86  	}
    9.87  
    9.88  	/**
    9.89  	 * @return true if this connection comes from a local remote address.
    9.90  	 */
    9.91 -	public boolean isLocalConnection()
    9.92 -	{
    9.93 +	public boolean isLocalConnection() {
    9.94  		return ((InetSocketAddress) this.channel.socket().getRemoteSocketAddress()).getHostName().equalsIgnoreCase("localhost");
    9.95  	}
    9.96  
    9.97 -	void setWriteSelectionKey(SelectionKey selKey)
    9.98 -	{
    9.99 +	void setWriteSelectionKey(SelectionKey selKey) {
   9.100  		this.writeSelKey = selKey;
   9.101  	}
   9.102  
   9.103 -	public void shutdownInput()
   9.104 -	{
   9.105 +	public void shutdownInput() {
   9.106  		try {
   9.107  			// Closes the input line of the channel's socket, so no new data
   9.108  			// will be received and a timeout can be triggered.
   9.109 @@ -156,14 +146,10 @@
   9.110  		}
   9.111  	}
   9.112  
   9.113 -	public void shutdownOutput()
   9.114 -	{
   9.115 -		cancelTimer.schedule(new TimerTask()
   9.116 -		{
   9.117 -
   9.118 +	public void shutdownOutput() {
   9.119 +		cancelTimer.schedule(new TimerTask() {
   9.120  			@Override
   9.121 -			public void run()
   9.122 -			{
   9.123 +			public void run() {
   9.124  				try {
   9.125  					// Closes the output line of the channel's socket.
   9.126  					channel.socket().shutdownOutput();
   9.127 @@ -178,41 +164,34 @@
   9.128  		}, 3000);
   9.129  	}
   9.130  
   9.131 -	public SocketChannel getSocketChannel()
   9.132 -	{
   9.133 +	public SocketChannel getSocketChannel() {
   9.134  		return this.channel;
   9.135  	}
   9.136  
   9.137 -	public Article getCurrentArticle()
   9.138 -	{
   9.139 +	public Article getCurrentArticle() {
   9.140  		return this.currentArticle;
   9.141  	}
   9.142  
   9.143 -	public Charset getCurrentCharset()
   9.144 -	{
   9.145 +	public Charset getCurrentCharset() {
   9.146  		return this.charset;
   9.147  	}
   9.148  
   9.149  	/**
   9.150  	 * @return The currently selected communication channel (not SocketChannel)
   9.151  	 */
   9.152 -	public Group getCurrentChannel()
   9.153 -	{
   9.154 +	public Group getCurrentChannel() {
   9.155  		return this.currentGroup;
   9.156  	}
   9.157  
   9.158 -	public void setCurrentArticle(final Article article)
   9.159 -	{
   9.160 +	public void setCurrentArticle(final Article article) {
   9.161  		this.currentArticle = article;
   9.162  	}
   9.163  
   9.164 -	public void setCurrentGroup(final Group group)
   9.165 -	{
   9.166 +	public void setCurrentGroup(final Group group) {
   9.167  		this.currentGroup = group;
   9.168  	}
   9.169  
   9.170 -	public long getLastActivity()
   9.171 -	{
   9.172 +	public long getLastActivity() {
   9.173  		return this.lastActivity;
   9.174  	}
   9.175  
   9.176 @@ -222,8 +201,7 @@
   9.177  	 * @throws IllegalArgumentException if raw is null.
   9.178  	 * @throws IllegalStateException if calling thread does not own the readLock.
   9.179  	 */
   9.180 -	void lineReceived(byte[] raw)
   9.181 -	{
   9.182 +	void lineReceived(byte[] raw) {
   9.183  		if (raw == null) {
   9.184  			throw new IllegalArgumentException("raw is null");
   9.185  		}
   9.186 @@ -262,17 +240,25 @@
   9.187  			}
   9.188  		} catch (ClosedChannelException ex0) {
   9.189  			try {
   9.190 -				Log.get().info("Connection to " + channel.socket().getRemoteSocketAddress()
   9.191 -					+ " closed: " + ex0);
   9.192 +				StringBuilder strBuf = new StringBuilder();
   9.193 +				strBuf.append("Connection to ");
   9.194 +				strBuf.append(channel.socket().getRemoteSocketAddress());
   9.195 +				strBuf.append(" closed: ");
   9.196 +				strBuf.append(ex0);
   9.197 +				Log.get().info(strBuf.toString());
   9.198  			} catch (Exception ex0a) {
   9.199  				ex0a.printStackTrace();
   9.200  			}
   9.201 -		} catch (Exception ex1) // This will catch a second StorageBackendException
   9.202 -		{
   9.203 +		} catch (Exception ex1) { // This will catch a second StorageBackendException
   9.204  			try {
   9.205  				command = null;
   9.206 -				ex1.printStackTrace();
   9.207 -				println("500 Internal server error");
   9.208 +				Log.get().log(Level.WARNING, ex1.getLocalizedMessage(), ex1);
   9.209 +				println("403 Internal server error");
   9.210 +
   9.211 +				// Should we end the connection here?
   9.212 +				// RFC says we MUST return 400 before closing the connection
   9.213 +				shutdownInput();
   9.214 +				shutdownOutput();
   9.215  			} catch (Exception ex2) {
   9.216  				ex2.printStackTrace();
   9.217  			}
   9.218 @@ -289,8 +275,7 @@
   9.219  	 * @param line
   9.220  	 * @return
   9.221  	 */
   9.222 -	private Command parseCommandLine(String line)
   9.223 -	{
   9.224 +	private Command parseCommandLine(String line) {
   9.225  		String cmdStr = line.split(" ")[0];
   9.226  		return CommandSelector.getInstance().get(cmdStr);
   9.227  	}
   9.228 @@ -303,8 +288,7 @@
   9.229  	 * @param line
   9.230  	 */
   9.231  	public void println(final CharSequence line, final Charset charset)
   9.232 -		throws IOException
   9.233 -	{
   9.234 +			throws IOException {
   9.235  		writeToChannel(CharBuffer.wrap(line), charset, line);
   9.236  		writeToChannel(CharBuffer.wrap(NEWLINE), charset, null);
   9.237  	}
   9.238 @@ -315,8 +299,7 @@
   9.239  	 * @param rawLines
   9.240  	 */
   9.241  	public void println(final byte[] rawLines)
   9.242 -		throws IOException
   9.243 -	{
   9.244 +			throws IOException {
   9.245  		this.lineBuffers.addOutputBuffer(ByteBuffer.wrap(rawLines));
   9.246  		writeToChannel(CharBuffer.wrap(NEWLINE), charset, null);
   9.247  	}
   9.248 @@ -328,9 +311,8 @@
   9.249  	 * @throws java.io.IOException
   9.250  	 */
   9.251  	private void writeToChannel(CharBuffer characters, final Charset charset,
   9.252 -		CharSequence debugLine)
   9.253 -		throws IOException
   9.254 -	{
   9.255 +			CharSequence debugLine)
   9.256 +			throws IOException {
   9.257  		if (!charset.canEncode()) {
   9.258  			Log.get().severe("FATAL: Charset " + charset + " cannot encode!");
   9.259  			return;
   9.260 @@ -343,8 +325,7 @@
   9.261  		enableWriteEvents(debugLine);
   9.262  	}
   9.263  
   9.264 -	private void enableWriteEvents(CharSequence debugLine)
   9.265 -	{
   9.266 +	private void enableWriteEvents(CharSequence debugLine) {
   9.267  		// Enable OP_WRITE events so that the buffers are processed
   9.268  		try {
   9.269  			this.writeSelKey.interestOps(SelectionKey.OP_WRITE);
   9.270 @@ -363,24 +344,20 @@
   9.271  	}
   9.272  
   9.273  	public void println(final CharSequence line)
   9.274 -		throws IOException
   9.275 -	{
   9.276 +			throws IOException {
   9.277  		println(line, charset);
   9.278  	}
   9.279  
   9.280  	public void print(final String line)
   9.281 -		throws IOException
   9.282 -	{
   9.283 +			throws IOException {
   9.284  		writeToChannel(CharBuffer.wrap(line), charset, line);
   9.285  	}
   9.286  
   9.287 -	public void setCurrentCharset(final Charset charset)
   9.288 -	{
   9.289 +	public void setCurrentCharset(final Charset charset) {
   9.290  		this.charset = charset;
   9.291  	}
   9.292  
   9.293 -	void setLastActivity(long timestamp)
   9.294 -	{
   9.295 +	void setLastActivity(long timestamp) {
   9.296  		this.lastActivity = timestamp;
   9.297  	}
   9.298  }
    10.1 --- a/src/org/sonews/daemon/command/ListCommand.java	Sun Sep 11 15:05:04 2011 +0200
    10.2 +++ b/src/org/sonews/daemon/command/ListCommand.java	Sun Sep 11 17:01:19 2011 +0200
    10.3 @@ -15,7 +15,6 @@
    10.4   *   You should have received a copy of the GNU General Public License
    10.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    10.6   */
    10.7 -
    10.8  package org.sonews.daemon.command;
    10.9  
   10.10  import java.io.IOException;
   10.11 @@ -34,37 +33,31 @@
   10.12   * @author Dennis Schwerdel
   10.13   * @since n3tpd/0.1
   10.14   */
   10.15 -public class ListCommand implements Command
   10.16 -{
   10.17 +public class ListCommand implements Command {
   10.18  
   10.19  	@Override
   10.20 -	public String[] getSupportedCommandStrings()
   10.21 -	{
   10.22 -		return new String[] {"LIST"};
   10.23 +	public String[] getSupportedCommandStrings() {
   10.24 +		return new String[]{"LIST"};
   10.25  	}
   10.26  
   10.27  	@Override
   10.28 -	public boolean hasFinished()
   10.29 -	{
   10.30 +	public boolean hasFinished() {
   10.31  		return true;
   10.32  	}
   10.33  
   10.34  	@Override
   10.35 -	public String impliedCapability()
   10.36 -	{
   10.37 +	public String impliedCapability() {
   10.38  		return null;
   10.39  	}
   10.40  
   10.41  	@Override
   10.42 -	public boolean isStateful()
   10.43 -	{
   10.44 +	public boolean isStateful() {
   10.45  		return false;
   10.46  	}
   10.47  
   10.48  	@Override
   10.49  	public void processLine(NNTPConnection conn, final String line, byte[] raw)
   10.50 -		throws IOException, StorageBackendException
   10.51 -	{
   10.52 +			throws IOException, StorageBackendException {
   10.53  		final String[] command = line.split(" ");
   10.54  
   10.55  		if (command.length >= 2) {
   10.56 @@ -90,7 +83,7 @@
   10.57  				conn.println(".");
   10.58  			} else if (command[1].equalsIgnoreCase("ACTIVE")) {
   10.59  				String pattern = command.length == 2
   10.60 -					? null : command[2].replace("*", "\\w*");
   10.61 +						? null : command[2].replace("*", "\\w*");
   10.62  				printGroupInfo(conn, pattern);
   10.63  			} else {
   10.64  				conn.println("500 unknown argument to LIST command");
   10.65 @@ -101,21 +94,20 @@
   10.66  	}
   10.67  
   10.68  	private void printGroupInfo(NNTPConnection conn, String pattern)
   10.69 -		throws IOException, StorageBackendException
   10.70 -	{
   10.71 +			throws IOException, StorageBackendException {
   10.72  		final List<Group> groups = Group.getAll();
   10.73  		if (groups != null) {
   10.74  			conn.println("215 list of newsgroups follows");
   10.75  			for (Group g : groups) {
   10.76  				try {
   10.77  					Matcher matcher = pattern == null
   10.78 -						? null : Pattern.compile(pattern).matcher(g.getName());
   10.79 +							? null : Pattern.compile(pattern).matcher(g.getName());
   10.80  					if (!g.isDeleted()
   10.81 -						&& (matcher == null || matcher.find())) {
   10.82 +							&& (matcher == null || matcher.find())) {
   10.83  						String writeable = g.isWriteable() ? " y" : " n";
   10.84  						// Indeed first the higher article number then the lower
   10.85  						conn.println(g.getName() + " " + g.getLastArticleNumber() + " "
   10.86 -							+ g.getFirstArticleNumber() + writeable);
   10.87 +								+ g.getFirstArticleNumber() + writeable);
   10.88  					}
   10.89  				} catch (PatternSyntaxException ex) {
   10.90  					Log.get().info(ex.toString());
    11.1 --- a/src/org/sonews/util/Stats.java	Sun Sep 11 15:05:04 2011 +0200
    11.2 +++ b/src/org/sonews/util/Stats.java	Sun Sep 11 17:01:19 2011 +0200
    11.3 @@ -18,6 +18,7 @@
    11.4  package org.sonews.util;
    11.5  
    11.6  import java.util.Calendar;
    11.7 +import java.util.logging.Level;
    11.8  import org.sonews.config.Config;
    11.9  import org.sonews.storage.Group;
   11.10  import org.sonews.storage.StorageBackendException;
   11.11 @@ -63,10 +64,14 @@
   11.12  							System.currentTimeMillis(), type, group.getInternalID());
   11.13  				}
   11.14  			} else {
   11.15 -				Log.get().info("Group " + groupname + " does not exist.");
   11.16 +				StringBuilder strBuf = new StringBuilder();
   11.17 +				strBuf.append("Group ");
   11.18 +				strBuf.append(groupname);
   11.19 +				strBuf.append(" does not exist.");
   11.20 +				Log.get().info(strBuf.toString());
   11.21  			}
   11.22  		} catch (StorageBackendException ex) {
   11.23 -			ex.printStackTrace();
   11.24 +			Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
   11.25  		}
   11.26  	}
   11.27  
   11.28 @@ -86,7 +91,7 @@
   11.29  		try {
   11.30  			return StorageManager.current().countGroups();
   11.31  		} catch (StorageBackendException ex) {
   11.32 -			ex.printStackTrace();
   11.33 +			Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
   11.34  			return -1;
   11.35  		}
   11.36  	}
   11.37 @@ -95,7 +100,7 @@
   11.38  		try {
   11.39  			return StorageManager.current().countArticles();
   11.40  		} catch (StorageBackendException ex) {
   11.41 -			ex.printStackTrace();
   11.42 +			Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
   11.43  			return -1;
   11.44  		}
   11.45  	}
   11.46 @@ -117,7 +122,7 @@
   11.47  		try {
   11.48  			return StorageManager.current().getEventsCount(eventType, startTimestamp, endTimestamp, group);
   11.49  		} catch (StorageBackendException ex) {
   11.50 -			ex.printStackTrace();
   11.51 +			Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
   11.52  			return -1;
   11.53  		}
   11.54  	}
   11.55 @@ -146,7 +151,7 @@
   11.56  		try {
   11.57  			return StorageManager.current().getEventsPerHour(key, gid);
   11.58  		} catch (StorageBackendException ex) {
   11.59 -			ex.printStackTrace();
   11.60 +			Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
   11.61  			return -1;
   11.62  		}
   11.63  	}