jaroslav@266: /** jaroslav@264: * Quoridor server and related libraries jaroslav@266: * Copyright (C) 2009-2010 Martin Rexa jaroslav@178: * jaroslav@264: * This program is free software: you can redistribute it and/or modify jaroslav@264: * it under the terms of the GNU General Public License as published by jaroslav@264: * the Free Software Foundation, either version 3 of the License. jaroslav@178: * jaroslav@264: * This program is distributed in the hope that it will be useful, jaroslav@264: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@264: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@264: * GNU General Public License for more details. jaroslav@178: * jaroslav@264: * You should have received a copy of the GNU General Public License jaroslav@264: * along with this program. Look for COPYING file in the top folder. jaroslav@264: * If not, see http://www.gnu.org/licenses/. jaroslav@178: */ jaroslav@266: jaroslav@178: package cz.xelfi.quoridor.statistics.resources; jaroslav@178: jaroslav@178: import com.sun.jersey.api.container.httpserver.HttpServerFactory; jaroslav@178: import com.sun.jersey.api.core.PackagesResourceConfig; jaroslav@178: import com.sun.jersey.api.core.ResourceConfig; jaroslav@178: import com.sun.jersey.spi.resource.Singleton; jaroslav@178: import com.sun.net.httpserver.HttpServer; jaroslav@178: import java.io.File; jaroslav@178: import java.io.IOException; jaroslav@178: import java.util.Comparator; jaroslav@178: import java.util.List; jaroslav@178: import java.util.Collections; jaroslav@178: import java.net.ServerSocket; jaroslav@178: import javax.ws.rs.Path; jaroslav@178: import cz.xelfi.quoridor.webidor.resources.Games; jaroslav@178: import cz.xelfi.quoridor.webidor.Game; jaroslav@178: jaroslav@178: /** jaroslav@178: * jaroslav@178: * @author Martin Rexa jaroslav@178: */ jaroslav@178: @Path("/") jaroslav@178: @Singleton jaroslav@178: public class Statistics { jaroslav@178: static final Comparator OLDEST_FIRST = new OldestFirst(); jaroslav@178: static Elo elo; jaroslav@178: static Openings openings; jaroslav@178: jaroslav@178: @Path("elo") jaroslav@178: public Elo getElo() { jaroslav@178: return elo; jaroslav@178: } jaroslav@178: jaroslav@178: @Path("openings") jaroslav@178: public Openings getOpenings() { jaroslav@178: return openings; jaroslav@178: } jaroslav@178: jaroslav@178: public static void main( String[] args ) throws IOException, InterruptedException jaroslav@178: { jaroslav@178: int port = 9444; jaroslav@178: // timeout between reprocessing games in miliseconds martin@187: long timeout = 1000 * 60 * 60 * 24; martin@187: // long timeout = 1000 * 10; jaroslav@178: jaroslav@178: try { jaroslav@178: port = Integer.parseInt(args[0]); jaroslav@178: } catch (Exception ex) { jaroslav@178: // OK jaroslav@178: } jaroslav@178: jaroslav@178: if (System.getProperty("quoridor.dir") == null) { jaroslav@178: File home = new File(System.getProperty("user.home")); jaroslav@178: File quoridor = new File(home, ".quoridor"); jaroslav@178: System.setProperty("quoridor.dir", quoridor.getPath()); jaroslav@178: } jaroslav@178: martin@215: long lastExec = System.currentTimeMillis(); jaroslav@178: processGames(); jaroslav@178: HttpServer s = start(port); jaroslav@178: System.out.println("Statistics started at port " + port); jaroslav@178: Object monitor = new Object(); martin@283: /* martin@283: * Disabled until OutOfMemory is solved martin@215: // Wait until begining of next period. If timeout is one day, then next martin@215: // processing will be done after midnight martin@215: synchronized (monitor) { martin@215: monitor.wait(timeout - (lastExec % timeout)); martin@215: } jaroslav@178: for(;;){ martin@223: processGames(); jaroslav@178: synchronized (monitor) { jaroslav@178: monitor.wait(timeout); jaroslav@178: } jaroslav@178: } martin@283: * martin@283: */ martin@283: synchronized (monitor) { martin@283: monitor.wait(timeout); martin@283: } jaroslav@178: } jaroslav@178: jaroslav@178: public static HttpServer start(int port) throws IOException { jaroslav@178: if (port == -1) { jaroslav@178: ServerSocket ss = new ServerSocket(0); jaroslav@178: port =ss.getLocalPort(); jaroslav@178: ss.close(); jaroslav@178: } jaroslav@178: final String baseUri = "http://localhost:" + port + "/"; jaroslav@178: jaroslav@178: if (System.getProperty("quoridor.dir") == null) { jaroslav@178: File home = new File(System.getProperty("user.home")); jaroslav@178: File quoridor = new File(home, ".quoridor"); jaroslav@178: System.setProperty("quoridor.dir", quoridor.getPath()); jaroslav@178: } jaroslav@178: jaroslav@178: ResourceConfig rc = new PackagesResourceConfig("cz.xelfi.quoridor.statistics"); jaroslav@178: HttpServer server = HttpServerFactory.create(baseUri, rc); jaroslav@178: server.start(); jaroslav@178: return server; jaroslav@178: } jaroslav@178: jaroslav@178: public static void processGames(){ jaroslav@178: Elo eloTmp = new Elo(); jaroslav@178: Openings openingsTmp = new Openings(); jaroslav@178: jaroslav@178: final String prop = System.getProperty("quoridor.dir"); // NOI18N jaroslav@178: if (prop == null) { jaroslav@178: throw new IllegalStateException("quoridor.dir property must be specified"); // NOI18N jaroslav@178: } jaroslav@178: File path = new File(prop); jaroslav@178: path.mkdirs(); jaroslav@178: File fGames = new File(path, "games"); jaroslav@178: //fGames.mkdirs(); jaroslav@178: Games games = new Games(fGames, null); jaroslav@178: List lGames = games.getGames(); jaroslav@178: Collections.sort(lGames, OLDEST_FIRST); jaroslav@178: jaroslav@178: // process games jaroslav@178: for(Game g: lGames){ jaroslav@178: if(g.getId().isFinished()){ martin@200: eloTmp.processGame(g.getId()); jaroslav@178: openingsTmp.processGame(g); jaroslav@178: } jaroslav@178: } jaroslav@178: jaroslav@178: elo = eloTmp; jaroslav@178: openings = openingsTmp; jaroslav@178: } jaroslav@178: jaroslav@178: private static final class OldestFirst implements Comparator { jaroslav@178: public int compare(Game g1, Game g2) { jaroslav@178: if(g1.getId() == g2.getId()) jaroslav@178: return 0; jaroslav@178: long diff = g2.getId().getModified() - g1.getId().getModified(); jaroslav@178: if (diff != 0) { martin@200: return diff < 0 ? 1 : -1; jaroslav@178: } jaroslav@178: return g1.getId().getId().compareTo(g2.getId().getId()); jaroslav@178: } jaroslav@178: } jaroslav@178: jaroslav@178: }