/* * festivoice * * Copyright 2009 FURUHASHI Sadayuki, KASHIHARA Shuzo, SHIBATA Yasuharu * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.festivoice; import java.util.*; import java.lang.*; import java.io.*; import java.net.*; import java.sql.*; public class ServerLogger extends Thread { // singleton private static ServerLogger instance = new ServerLogger(); public static ServerLogger getInstance() { return instance; } private PrintStream textStream = System.out; private ServerLogger() { } public void setTextStream(PrintStream stream) { textStream = stream; } private Connection connection = null; private GregorianCalendar calendar; private PreparedStatement channelCreateStatement; private PreparedStatement channelJoinStatement; private PreparedStatement channelLeaveStatement; private PreparedStatement channelRemoveStatement; private PreparedStatement channelEventsStatement; public class ChannelEventType { public static final int CREATE = 1; public static final int JOIN = 2; public static final int LEAVE = 3; public static final int REMOVE = 4; } public void enableDatabase(String path) throws IOException { // JDBCを有効化する // デフォルトはテキストのみ File file = new File(path); boolean fileExist = file.exists(); try { Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); String url = "jdbc:derby:" + path; if(!fileExist) { url += ";create=true"; } else { url += ";create=false"; } connection = DriverManager.getConnection(url); if(!fileExist) { createTables(); } createStatements(); calendar = new GregorianCalendar(); } catch(Exception e) { e.printStackTrace(); throw new IOException("can't initialize database: " + e); } } private void createTables() throws SQLException { connection.createStatement().executeUpdate( "create table \"channelEvent\" (\"time\" TIMESTAMP, \"type\" INTEGER, \"channel\" VARCHAR(256), \"user\" VARCHAR(256), \"address\" VARCHAR(64), \"port\" INTEGER)"); } private void createStatements() throws SQLException { channelCreateStatement = connection.prepareStatement( "insert into \"channelEvent\" (\"time\", \"type\", \"channel\", \"user\", \"address\", \"port\") VALUES (?, "+ChannelEventType.CREATE+", ?, null, null, null)"); channelJoinStatement = connection.prepareStatement( "insert into \"channelEvent\" (\"time\", \"type\", \"channel\", \"user\", \"address\", \"port\") VALUES (?, "+ChannelEventType.JOIN+", ?, ?, ?, ?)"); channelLeaveStatement = connection.prepareStatement( "insert into \"channelEvent\" (\"time\", \"type\", \"channel\", \"user\", \"address\", \"port\") VALUES (?, "+ChannelEventType.LEAVE+", ?, ?, ?, ?)"); channelRemoveStatement = connection.prepareStatement( "insert into \"channelEvent\" (\"time\", \"type\", \"channel\", \"user\", \"address\", \"port\") VALUES (?, "+ChannelEventType.REMOVE+", ?, null, null, null)"); channelEventsStatement = connection.prepareStatement( "select \"time\", \"type\", \"channel\", \"user\", \"address\", \"port\" from \"channelEvent\" order by \"time\" desc"); } public static Timestamp getCurrentTime() { return new Timestamp(System.currentTimeMillis()); } public void channelCreated(String channelName) { textStream.println("create: '"+channelName+"'"); if(connection == null) { return; } try { channelCreateStatement.setTimestamp(1, getCurrentTime()); channelCreateStatement.setString(2, channelName); channelCreateStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public void channelJoined(String channelName, String userName, InetSocketAddress userAddress) { textStream.println("join: "+userAddress+" '"+channelName+"' <- '"+userName+"'"); if(connection == null) { return; } try { channelJoinStatement.setTimestamp(1, getCurrentTime()); channelJoinStatement.setString(2, channelName); channelJoinStatement.setString(3, userName); channelJoinStatement.setString(4, userAddress.getAddress().toString()); channelJoinStatement.setInt(5, userAddress.getPort()); channelJoinStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public void channelLeaved(String channelName, String userName, InetSocketAddress userAddress) { textStream.println("leave: "+userAddress+" '"+channelName+"' -> '"+userName+"'"); if(connection == null) { return; } try { channelLeaveStatement.setTimestamp(1, getCurrentTime()); channelLeaveStatement.setString(2, channelName); channelLeaveStatement.setString(3, userName); channelLeaveStatement.setString(4, userAddress.getAddress().toString()); channelLeaveStatement.setInt(5, userAddress.getPort()); channelLeaveStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public void channelRemoved(String channelName) { textStream.println("remove: '"+channelName+"'"); if(connection == null) { return; } try { channelRemoveStatement.setTimestamp(1, getCurrentTime()); channelRemoveStatement.setString(2, channelName); channelRemoveStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public class Event { private Timestamp time; private int type; private String channel; private String address; private int port; private String user; Event(Timestamp time, int type, String channel, String user, String address, int port) { this.time = time; this.type = type; this.channel = channel; this.address = address; this.port = port; this.user = user; } public Timestamp getTimestamp() { return time; } public int getType() { return type; } public String getChannelName() { return channel; } public String getAddress() { return address; } public int getPort() { return port; } public String getUserName() { return user; } } public Iterable<? extends Event> getEvent(int n) { ArrayList<Event> ret = new ArrayList<Event>(); if(connection == null) { return ret; } try { channelEventsStatement.setMaxRows(n); ResultSet result = channelEventsStatement.executeQuery(); while(result.next()) { ret.add( new Event( result.getTimestamp(1), result.getInt(2), result.getString(3), result.getString(4), result.getString(5), result.getInt(6) ) ); } } catch (SQLException e) { e.printStackTrace(); } return ret; } }