package zeta.tool;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.ServletException;
import zeta.ZetaServlet;
import zeta.handler.statistic.AbstractHandler;
import zeta.util.DatabaseUtils;
import zeta.util.Properties;
import zeta.util.StreamUtils;
import zeta.util.ThrowableHandler;
public class CreateStatistics extends Thread {
public static void main(String[] args) {
if (args.length == 1) {
if (args[0].equals("?")) {
System.out.println("USAGE: [<classname> [<imagename>]]");
return;
}
CreateStatistics csi = new CreateStatistics();
csi.getPage(args[0]);
return;
} else if (args.length == 2) {
CreateStatistics csi = new CreateStatistics();
csi.getImage(args[0], args[1]);
return;
} else {
CreateStatistics csi = new CreateStatistics();
csi.start();
}
}
public void run() {
int error = 0;
int wait = 0;
do {
error = 0;
try {
wait = generatePagesImages();
} catch (SQLException se) {
++error;
try {
sleep(30000);
} catch (InterruptedException ie) {
}
} catch (ServletException se) {
++error;
try {
sleep(30000);
} catch (InterruptedException ie) {
}
}
} while (error > 0 && error < 10);
while (true) {
try {
sleep(wait);
} catch (InterruptedException ie) {
}
error = 0;
do {
try {
updatePages();
} catch (SQLException se) {
++error;
try {
sleep(30000);
} catch (InterruptedException ie) {
}
} catch (ServletException se) {
++error;
try {
sleep(30000);
} catch (InterruptedException ie) {
}
}
} while (error == 1);
error = 0;
do {
try {
updateImages();
} catch (SQLException se) {
++error;
try {
sleep(30000);
} catch (InterruptedException ie) {
}
} catch (ServletException se) {
++error;
try {
sleep(30000);
} catch (InterruptedException ie) {
}
}
} while (error == 1);
}
}
public int generatePagesImages() throws SQLException, ServletException {
Statement stmt = null;
PreparedStatement pStmt = null;
int wait = 0;
try {
Properties properties = new Properties();
ZetaServlet servlet = new ZetaServlet();
servlet.getInitParameter("server_id"); servlet.addStatisticHandler("handler.get.producers 0 Top producers", "zeta.handler.statistic.TopProducersHandler", null);
servlet.addStatisticHandler("handler.get.teammembers 1 Team members", "zeta.handler.statistic.TeamMembersHandler", null);
servlet.setServerId(properties.get("server_id", 1));
connection = GetData.getConnection();
stmt = connection.createStatement();
AbstractHandler previousStatistic = null;
ResultSet rs = stmt.executeQuery("SELECT classname,imagename FROM zeta.image");
while (rs.next()) {
String classname = rs.getString(1);
String imagename = rs.getString(2);
Class statisticClass = Class.forName(classname);
Constructor[] statisticConstructor = statisticClass.getConstructors();
AbstractHandler statistic = servlet.getStatisticHandler(statisticClass);
if (statistic == null) {
statistic = (AbstractHandler)statisticConstructor[0].newInstance(new Object[] { servlet });
}
if (wait == 0) {
wait = statistic.getInnerPageExpiredDiffTime();
} else {
wait = gcd(wait, statistic.getInnerPageExpiredDiffTime());
}
byte[] buffer = null;
long startTime = System.currentTimeMillis();
try {
buffer = generateImage(statistic, imagename);
} catch (Exception e) {
ThrowableHandler.handle(e);
}
long stopTime = System.currentTimeMillis();
Timestamp lastUpdate = new Timestamp(startTime);
if (buffer != null) {
pStmt = connection.prepareStatement("UPDATE zeta.image SET (last_update,image)=('" + lastUpdate.toString()
+ "',?) WHERE classname='" + classname + "' AND imagename='" + imagename + '\'');
pStmt.setBytes(1, buffer);
pStmt.execute();
DatabaseUtils.close(pStmt);
pStmt = null;
images.add(classname);
images.add(imagename);
images.add(statistic);
String path = properties.get("ftp.statistic.path");
if (path != null && path.length() > 0) {
InputStream in = null;
FTP ftp = null;
try {
ftp = new FTP();
ftp.connect(properties.get("ftp.host", ""));
ftp.login(properties.get("ftp.user", ""), properties.get("ftp.password", ""));
ftp.cd(path);
in = new ByteArrayInputStream(buffer);
ftp.put(in, classname + '_' + imagename + ".png", FTP.MODE_BINARY);
} catch (Exception e) {
ThrowableHandler.handle(e);
} finally {
StreamUtils.close(in);
in = null;
if (ftp != null) {
ftp.disconnect();
}
}
}
System.out.println(lastUpdate.toString() + ':' + classname + ' ' + imagename + " (" + ((stopTime-startTime)/1000) + "s)");
} else {
System.out.println(lastUpdate.toString() + ':' + classname + ' ' + imagename + " is EMPTY! (" + ((stopTime-startTime)/1000) + "s)");
}
statistic.imageUpdateCompleted(imagename);
}
rs = stmt.executeQuery("SELECT classname FROM zeta.page ORDER BY classname DESC");
while (rs.next()) {
String classname = rs.getString(1);
Class statisticClass = Class.forName(classname);
Constructor[] statisticConstructor = statisticClass.getConstructors();
int idx = indexOf(statisticClass);
AbstractHandler statistic = (idx >= 0)? (AbstractHandler)images.get(idx) : servlet.getStatisticHandler(statisticClass);
if (statistic == null) {
statistic = (AbstractHandler)statisticConstructor[0].newInstance(new Object[] { servlet });
}
long startTime = System.currentTimeMillis();
String page = statistic.createPage(connection);
long stopTime = System.currentTimeMillis();
Timestamp lastUpdate = new Timestamp(startTime);
ZipOutputStream zip = null;
ByteArrayOutputStream out = null;
InputStream in = null;
try {
in = new ByteArrayInputStream(page.getBytes());
out = new ByteArrayOutputStream();
zip = new ZipOutputStream(out);
zip.setLevel(Deflater.BEST_COMPRESSION);
zip.putNextEntry(new ZipEntry(classname + ".html"));
StreamUtils.writeData(in, zip, true, true);
byte[] buffer = out.toByteArray();
in = null;
zip = null;
pStmt = connection.prepareStatement("UPDATE zeta.page SET (last_update,page)=('" + lastUpdate.toString()
+ "',?) WHERE classname='" + classname + '\'');
pStmt.setBytes(1, buffer);
pStmt.execute();
DatabaseUtils.close(pStmt);
pStmt = null;
if (idx == -1) {
images.add(classname);
images.add(null);
images.add(statistic);
}
String path = properties.get("ftp.statistic.path", "");
if (path != null && path.length() > 0) {
FTP ftp = null;
try {
ftp = new FTP();
ftp.connect(properties.get("ftp.host", ""));
ftp.login(properties.get("ftp.user", ""), properties.get("ftp.password", ""));
ftp.cd(path);
in = new ByteArrayInputStream(buffer);
ftp.put(in, classname + ".zip", FTP.MODE_BINARY);
} catch (Exception e) {
ThrowableHandler.handle(e);
} finally {
StreamUtils.close(in);
in = null;
if (ftp != null) {
ftp.disconnect();
}
}
}
System.out.println(lastUpdate.toString() + ':' + classname + " (" + ((stopTime-startTime)/1000) + "s)");
statistic.pageUpdateCompleted();
} catch (IOException ioe) {
ThrowableHandler.handle(ioe);
} finally {
StreamUtils.close(in);
StreamUtils.close(zip);
}
}
} catch (SQLException se) {
System.out.println(se.getMessage());
throw se;
} catch (ServletException se) {
System.out.println(se.getMessage());
throw se;
} catch (Exception e) {
ThrowableHandler.handle(e);
} finally {
DatabaseUtils.close(stmt);
DatabaseUtils.close(pStmt);
DatabaseUtils.close(connection);
connection = null;
}
return (wait < 60000)? 60000 : wait;
}
public int indexOf(Class cl) {
final int l = images.size();
for (int i = 2; i < l; i += 3) {
if (cl == images.get(i).getClass()) {
return i;
}
}
return -1;
}
public void updatePages() throws SQLException, ServletException {
PreparedStatement pStmt = null;
try {
Properties properties = new Properties();
connection = GetData.getConnection();
final int l = images.size();
Set statisticUpdated = new HashSet(l);
for (int i = 2; i < l; i += 3) {
AbstractHandler statistic = (AbstractHandler)images.get(i);
if (!statisticUpdated.contains(statistic.getClass()) && statistic.isInnerPageExpired()) {
statisticUpdated.add(statistic.getClass());
ZipOutputStream zip = null;
ByteArrayOutputStream out = null;
InputStream in = null;
try {
String page = null;
long startTime = System.currentTimeMillis();
try {
page = statistic.createPage(connection);
} catch (NullPointerException npe) {
throw new SQLException("Reset connection");
}
long stopTime = System.currentTimeMillis();
Timestamp lastUpdate = new Timestamp(startTime);
in = new ByteArrayInputStream(page.getBytes());
out = new ByteArrayOutputStream();
zip = new ZipOutputStream(out);
zip.setLevel(Deflater.BEST_COMPRESSION);
String classname = (String)images.get(i-2);
zip.putNextEntry(new ZipEntry(classname + ".html"));
StreamUtils.writeData(in, zip, true, true);
byte[] buffer = out.toByteArray();
in = null;
zip = null;
pStmt = connection.prepareStatement("UPDATE zeta.page SET (last_update,page)=('" + lastUpdate.toString() + "',?) WHERE classname='" + classname + '\'');
pStmt.setBytes(1, buffer);
pStmt.execute();
DatabaseUtils.close(pStmt);
pStmt = null;
String path = properties.get("ftp.statistic.path");
if (path != null && path.length() > 0) {
FTP ftp = null;
try {
ftp = new FTP();
ftp.connect(properties.get("ftp.host", ""));
ftp.login(properties.get("ftp.user", ""), properties.get("ftp.password", ""));
ftp.cd(path);
in = new ByteArrayInputStream(buffer);
ftp.put(in, classname + ".zip", FTP.MODE_BINARY);
} catch (Exception e) {
ThrowableHandler.handle(e);
continue;
} finally {
StreamUtils.close(in);
in = null;
if (ftp != null) {
ftp.disconnect();
}
}
}
System.out.println(lastUpdate.toString() + ':' + classname + " (" + ((stopTime-startTime)/1000) + "s)");
statistic.pageUpdateCompleted();
} catch (IOException ioe) {
ThrowableHandler.handle(ioe);
} finally {
StreamUtils.close(in);
StreamUtils.close(zip);
}
}
}
} catch (SQLException se) {
System.out.println(se.getMessage());
throw se;
} catch (ServletException se) {
System.out.println(se.getMessage());
throw se;
} catch (Exception e) {
ThrowableHandler.handle(e);
} finally {
DatabaseUtils.close(pStmt);
DatabaseUtils.close(connection);
connection = null;
}
}
public void updateImages() throws SQLException, ServletException {
PreparedStatement pStmt = null;
try {
Properties properties = new Properties();
connection = GetData.getConnection();
final int l = images.size();
for (int i = 2; i < l; i += 3) {
AbstractHandler statistic = (AbstractHandler)images.get(i);
String imagename = (String)images.get(i-1);
if (imagename != null && statistic.isImageExpired(imagename)) {
String classname = (String)images.get(i-2);
long startTime = System.currentTimeMillis();
byte[] buffer = generateImage(statistic, imagename);
long stopTime = System.currentTimeMillis();
Timestamp lastUpdate = new Timestamp(startTime);
pStmt = connection.prepareStatement("UPDATE zeta.image SET (last_update,image)=('" + lastUpdate.toString()
+ "',?) WHERE classname='" + classname + "' AND imagename='" + imagename + '\'');
pStmt.setBytes(1, buffer);
pStmt.execute();
DatabaseUtils.close(pStmt);
pStmt = null;
String path = properties.get("ftp.statistic.path", "");
if (path != null && path.length() > 0) {
InputStream in = null;
FTP ftp = null;
try {
ftp = new FTP();
ftp.connect(properties.get("ftp.host", ""));
ftp.login(properties.get("ftp.user", ""), properties.get("ftp.password", ""));
ftp.cd(path);
in = new ByteArrayInputStream(buffer);
ftp.put(in, classname + '_' + imagename + ".png", FTP.MODE_BINARY);
} catch (Exception e) {
ThrowableHandler.handle(e);
continue;
} finally {
StreamUtils.close(in);
in = null;
if (ftp != null) {
ftp.disconnect();
}
}
}
System.out.println(lastUpdate.toString() + ':' + classname + ' ' + imagename + " (" + ((stopTime-startTime)/1000) + "s)");
statistic.imageUpdateCompleted(imagename);
}
}
} catch (SQLException se) {
System.out.println(se.getMessage());
throw se;
} catch (ServletException se) {
System.out.println(se.getMessage());
throw se;
} catch (Exception e) {
ThrowableHandler.handle(e);
} finally {
DatabaseUtils.close(pStmt);
DatabaseUtils.close(connection);
connection = null;
}
}
public byte[] generateImage(AbstractHandler statistic, String imageName) throws IOException, SQLException, ServletException, com.sun.jimi.core.JimiException {
BufferedImage image = null;
try {
image = statistic.createImage(connection, imageName);
} catch (NullPointerException npe) {
ThrowableHandler.handle(npe);
throw new SQLException("Reset connection");
}
if (image == null) {
return null;
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();
com.sun.jimi.core.encoder.png.PNGEncoder encoder = new com.sun.jimi.core.encoder.png.PNGEncoder();
encoder.encodeImage(com.sun.jimi.core.Jimi.createRasterImage(image.getSource()), stream);
stream.close();
return stream.toByteArray();
}
public void getImage(String classname, String imageName) {
Statement stmt = null;
try {
connection = GetData.getConnection();
stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT image FROM zeta.image WHERE classname='" + classname + "' AND imagename='" + imageName + '\'');
if (rs.next()) {
StreamUtils.writeData(rs.getBinaryStream(1), new FileOutputStream(imageName + ".png"), false, true);
} else {
System.err.println("classname='" + classname + "' AND imagename='" + imageName + "' not found!");
}
rs.close();
} catch (Exception e) {
ThrowableHandler.handle(e);
} finally {
DatabaseUtils.close(connection);
connection = null;
}
}
public void getPage(String classname) {
Statement stmt = null;
try {
connection = GetData.getConnection();
stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT page FROM zeta.page WHERE classname='" + classname + '\'');
if (rs.next()) {
StreamUtils.writeData(rs.getBinaryStream(1), new FileOutputStream(classname + ".zip"), false, true);
} else {
System.err.println("classname='" + classname + "' not found!");
}
rs.close();
} catch (Exception e) {
ThrowableHandler.handle(e);
} finally {
DatabaseUtils.close(connection);
connection = null;
}
}
public static int gcd(int a, int b) {
if (a == 0) return b;
if (a < 0) a = -a;
if (b == 0) return a;
if (b < 0) b = -b;
int i,j;
for (i = 0; (a&1) == 0; ++i) a >>= 1;
for (j = 0; (b&1) == 0; ++j) b >>= 1;
while (a != b)
if (a > b) {
a -= b;
do a >>= 1; while ((a&1) == 0);
} else {
b -= a;
do b >>= 1; while ((b&1) == 0);
}
return a << ((i > j)? j : i);
}
private Connection connection = null;
private List images = new ArrayList(300);
}