webidor/src/main/java/cz/xelfi/quoridor/webidor/resources/Games.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 29 Aug 2009 15:55:53 +0200
changeset 46 71e4cf307c93
parent 39 6b889f2717e9
child 48 69e897fe8140
permissions -rw-r--r--
Support for logging in
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * The contents of this file are subject to the terms of either the GNU
     5  * General Public License Version 2 only ("GPL") or the Common
     6  * Development and Distribution License("CDDL") (collectively, the
     7  * "License"). You may not use this file except in compliance with the
     8  * License. You can obtain a copy of the License at
     9  * http://www.netbeans.org/cddl-gplv2.html
    10  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    11  * specific language governing permissions and limitations under the
    12  * License.  When distributing the software, include this License Header
    13  * Notice in each file and include the License file at
    14  * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    15  * particular file as subject to the "Classpath" exception as provided
    16  * by Sun in the GPL Version 2 section of the License file that
    17  * accompanied this code. If applicable, add the following below the
    18  * License Header, with the fields enclosed by brackets [] replaced by
    19  * your own identifying information:
    20  * "Portions Copyrighted [year] [name of copyright owner]"
    21  *
    22  * Contributor(s):
    23  *
    24  * Portions Copyrighted 2009 Jaroslav Tulach
    25  */
    26 
    27 package cz.xelfi.quoridor.webidor.resources;
    28 
    29 import cz.xelfi.quoridor.IllegalPositionException;
    30 import cz.xelfi.quoridor.webidor.*;
    31 import cz.xelfi.quoridor.Move;
    32 import java.io.BufferedReader;
    33 import java.io.BufferedWriter;
    34 import java.io.File;
    35 import java.io.FileReader;
    36 import java.io.FileWriter;
    37 import java.io.IOException;
    38 import java.io.PrintWriter;
    39 import java.util.ArrayList;
    40 import java.util.Arrays;
    41 import java.util.HashMap;
    42 import java.util.List;
    43 import java.util.Map;
    44 import java.util.TreeMap;
    45 import java.util.logging.Level;
    46 import java.util.logging.Logger;
    47 import javax.ws.rs.GET;
    48 import javax.ws.rs.POST;
    49 import javax.ws.rs.PUT;
    50 import javax.ws.rs.Path;
    51 import javax.ws.rs.PathParam;
    52 import javax.ws.rs.Produces;
    53 import javax.ws.rs.QueryParam;
    54 import javax.ws.rs.core.MediaType;
    55 import org.codehaus.jettison.json.JSONObject;
    56 
    57 /**
    58  *
    59  * @author Jaroslav Tulach <jtulach@netbeans.org>
    60  */
    61 public final class Games {
    62     private List<Game> games = new ArrayList<Game>();
    63     private final File dir;
    64     private static final Logger LOG = Logger.getLogger(Games.class.getName());
    65 
    66     public Games(File dir) {
    67         this.dir = dir;
    68         File[] arr = dir.listFiles();
    69         if (arr != null) {
    70             for (File f : arr) {
    71                 try {
    72                     Game g = readGame(f);
    73                     games.add(g);
    74                 } catch (IOException ex) {
    75                     LOG.log(Level.WARNING, "Wrong game in " + f, ex);
    76                 }
    77             }
    78         }
    79     }
    80 
    81     @POST
    82     @Produces(MediaType.APPLICATION_JSON)
    83     public Game createGame(
    84         @QueryParam("white") String white,
    85         @QueryParam("black") String black
    86     ) {
    87         if (white == null) {
    88             throw new IllegalArgumentException("Must specify white");
    89         }
    90         if (black == null) {
    91             throw new IllegalArgumentException("Must specify black");
    92         }
    93         Game g = new Game(white, black);
    94         games.add(g);
    95         return g;
    96     }
    97 
    98     @GET
    99     @Path("{id}")
   100     @Produces(MediaType.TEXT_PLAIN)
   101     public String getBoard(@PathParam("id") String id) {
   102         Game g = findGame(id);
   103         if (g == null) {
   104             throw new IllegalArgumentException("Unknown game " + id);
   105         }
   106         return g.getBoard().toString();
   107     }
   108 
   109     @GET
   110     @Path("{id}")
   111     @Produces(MediaType.APPLICATION_JSON)
   112     public Object getBoardInfo(@PathParam("id") String id) {
   113         Game g = findGame(id);
   114         if (g == null) {
   115             throw new IllegalArgumentException("Unknown game " + id);
   116         }
   117         Map<String,Object> data = new HashMap<String, Object>();
   118         data.put("board", g.getBoard().toString());
   119         data.put("game", g);
   120         return data;
   121     }
   122 
   123     @PUT
   124     @Path("{id}")
   125     @Produces(MediaType.APPLICATION_JSON)
   126     public Game applyMove(
   127         @PathParam("id") String id,
   128         @QueryParam("player") String player,
   129         @QueryParam("move") String move
   130     ) throws IllegalPositionException {
   131         Game g = findGame(id);
   132         if (g == null) {
   133             throw new IllegalArgumentException("Unknown game " + id);
   134         }
   135         Move m = Move.valueOf(move);
   136         g.apply(player, m);
   137         try {
   138             storeGame(g);
   139         } catch (IOException ex) {
   140             LOG.log(Level.WARNING, "Cannot store game " + id, ex);
   141         }
   142         return g;
   143     }
   144 
   145     @GET
   146     @Produces(MediaType.APPLICATION_JSON)
   147     public List<Game> getGames() {
   148         return games;
   149     }
   150 
   151     private Game findGame(String id) {
   152         for (Game g : games) {
   153             if (g.getId().equals(id)) {
   154                 return g;
   155             }
   156         }
   157         return null;
   158     }
   159 
   160     private Game readGame(File f) throws IOException {
   161         BufferedReader r = new BufferedReader(new FileReader(f));
   162         String white = null;
   163         String black = null;
   164         Game g = null;
   165         for (;;) {
   166             String line = r.readLine();
   167             if (line == null) {
   168                 break;
   169             }
   170             line = line.trim();
   171             if (line.length() == 0) {
   172                 continue;
   173             }
   174             if (line.startsWith("# white: ")) {
   175                 white = line.substring(9);
   176                 continue;
   177             }
   178             if (line.startsWith("# black: ")) {
   179                 black = line.substring(9);
   180                 continue;
   181             }
   182             if (line.startsWith("#")) {
   183                 continue;
   184             }
   185             if (white == null || black == null) {
   186                 throw new IOException("Missing white and black identification in " + f);
   187             }
   188             if (g == null) {
   189                 g = new Game(f.getName(), white, black);
   190             }
   191             String[] moves = line.split(" ");
   192             if (moves.length == 0) {
   193                 continue;
   194             }
   195             if (moves.length > 2) {
   196                 throw new IOException("Too much moves on line: " + line);
   197             }
   198             try {
   199                 g.apply(white, Move.valueOf(moves[0]));
   200                 if (moves.length == 2) {
   201                     g.apply(black, Move.valueOf(moves[1]));
   202                 }
   203             } catch (IllegalPositionException ex) {
   204                 throw new IOException("Wrong move: " + ex.getMessage());
   205             }
   206         }
   207         if (g == null) {
   208             throw new IOException("No moves in " + f);
   209         }
   210         return g;
   211     }
   212 
   213     private void storeGame(Game g) throws IOException {
   214         dir.mkdirs();
   215         File f = new File(dir, g.getId());
   216         PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(f)));
   217         pw.println("# white: " + g.getWhite());
   218         pw.println("# black: " + g.getBlack());
   219         int cnt = 0;
   220         for (Move m : g.getMoves()) {
   221             pw.print(m.toString());
   222             if (++cnt % 2 == 0) {
   223                 pw.println();
   224             } else {
   225                 pw.print(' ');
   226             }
   227         }
   228         pw.println();
   229         pw.println();
   230         pw.flush();
   231         pw.close();
   232     }
   233 }