webidor/src/main/java/cz/xelfi/quoridor/webidor/resources/Quoridor.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 14 Sep 2010 08:56:13 +0200
changeset 264 d60370059c3c
parent 239 a47345ebbdd7
child 282 40fc213a7f43
permissions -rw-r--r--
Changing headers to GPLv3
     1 /*
     2  * Quoridor server and related libraries
     3  * Copyright (C) 2009-2010 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, either version 3 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://www.gnu.org/licenses/.
    17  */
    18 
    19 package cz.xelfi.quoridor.webidor.resources;
    20 
    21 import com.sun.jersey.api.container.httpserver.HttpServerFactory;
    22 import com.sun.jersey.api.core.PackagesResourceConfig;
    23 import com.sun.jersey.api.core.ResourceConfig;
    24 import com.sun.jersey.api.json.JSONWithPadding;
    25 import com.sun.jersey.spi.resource.Singleton;
    26 import com.sun.net.httpserver.HttpServer;
    27 import cz.xelfi.quoridor.webidor.User;
    28 import java.io.File;
    29 import java.io.FileInputStream;
    30 import java.io.IOException;
    31 import java.net.ServerSocket;
    32 import java.util.HashMap;
    33 import java.util.Map;
    34 import java.util.Properties;
    35 import java.util.UUID;
    36 import javax.ws.rs.GET;
    37 import javax.ws.rs.PUT;
    38 import javax.ws.rs.Path;
    39 import javax.ws.rs.Produces;
    40 import javax.ws.rs.QueryParam;
    41 import javax.ws.rs.WebApplicationException;
    42 import javax.ws.rs.core.MediaType;
    43 import javax.ws.rs.core.Response.Status;
    44 
    45 /**
    46  *
    47  * @author Jaroslav Tulach <jtulach@netbeans.org>
    48  */
    49 @Path("/")
    50 @Singleton
    51 public final class Quoridor {
    52     private final File path;
    53     private Games games;
    54     private Users users;
    55     private final Map<UUID,String> loggedIn;
    56 
    57     public Quoridor() {
    58         final String prop = System.getProperty("quoridor.dir"); // NOI18N
    59         if (prop == null) {
    60             throw new IllegalStateException("quoridor.dir property must be specified"); // NOI18N
    61         }
    62         path = new File(prop);
    63         path.mkdirs();
    64         loggedIn = new HashMap<UUID, String>();
    65         games = new Games(new File(path, "games"), this); // NOI18N
    66         users = new Users(new File(path, "users"), this); // NOI18N
    67     }
    68 
    69     @Path("games")
    70     public Games getGames() {
    71         return games;
    72     }
    73 
    74     @Path("users")
    75     public Users getUsers() {
    76         return users;
    77     }
    78 
    79     @Path("login")
    80     @PUT
    81     @Produces({ MediaType.TEXT_PLAIN })
    82     public String login(
    83         @QueryParam("name") String name,
    84         @QueryParam("password") String password
    85     ) throws IOException {
    86         File f = new File(path, "passwd"); // NOI18Nt
    87         Properties p = new Properties();
    88         try {
    89             p.load(new FileInputStream(f));
    90         } catch (IOException ex) {
    91             ex.printStackTrace();
    92         }
    93         boolean loggedInOK = false;
    94         if (name != null && password.equals(p.getProperty(name))) {
    95             loggedInOK = true;
    96         } else {
    97             loggedInOK = getUsers().verifyPassword(name, password);
    98         }
    99 
   100         if (loggedInOK) {
   101             UUID uuid = UUID.randomUUID();
   102             loggedIn.put(uuid, name);
   103             return uuid.toString();
   104         } else {
   105             return null;
   106         }
   107         
   108     }
   109 
   110     @Path("login")
   111     @GET
   112     @Produces({ MediaType.TEXT_PLAIN })
   113     public String isLoggedIn(
   114         @QueryParam("id") String id
   115     ) {
   116         String ret = null;
   117         try {
   118             if (id != null) {
   119                 ret = loggedIn.get(UUID.fromString(id));
   120             }
   121         } catch (IllegalArgumentException ex) {
   122             // OK, happens for invalid ids
   123         }
   124         return ret == null ? "" : ret;
   125     }
   126 
   127     @Path("login")
   128     @GET
   129     @Produces({ "application/x-javascript", MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
   130     public JSONWithPadding loggedInInfo(
   131         @QueryParam("callback") String callback,
   132         @QueryParam("id") String id
   133     ) throws IOException {
   134         String ret = null;
   135         try {
   136             if (id != null) {
   137                 ret = loggedIn.get(UUID.fromString(id));
   138             }
   139         } catch (IllegalArgumentException ex) {
   140             // OK, happens for invalid ids
   141         }
   142         if (ret == null) {
   143             throw new WebApplicationException(Status.UNAUTHORIZED);
   144         } else {
   145             return getUsers().getUserInfo(callback, id, ret);
   146         }
   147     }
   148 
   149     //
   150     // start the server
   151     //
   152 
   153     public static void main(String[] args) throws IOException, InterruptedException {
   154         int port = 9222;
   155         try {
   156             port = Integer.parseInt(args[0]);
   157         } catch (Exception ex) {
   158             // OK
   159         }
   160         HttpServer s = start(port);
   161         System.out.println(
   162             "Quoridor started at port " + port + "\n" + "Hit enter to stop it..."
   163         );
   164         if (args.length < 2 || !args[args.length - 1].equals("--kill")) {
   165             System.out.println("Hit enter to stop it...");
   166             System.in.read();
   167         } else {
   168             synchronized (Quoridor.class) {
   169                 Quoridor.class.wait();
   170             }
   171         }
   172         System.in.read();
   173         s.stop(0);
   174         System.exit(0);
   175     }
   176 
   177     public static HttpServer start(int port) throws IOException {
   178         if (port == -1) {
   179             ServerSocket ss = new ServerSocket(0);
   180             port =ss.getLocalPort();
   181             ss.close();
   182         }
   183         final String baseUri = "http://localhost:" + port + "/";
   184 
   185         if (System.getProperty("quoridor.dir") == null) {
   186             File home = new File(System.getProperty("user.home"));
   187             File quoridor = new File(home, ".quoridor");
   188             System.setProperty("quoridor.dir", quoridor.getPath());
   189         }
   190 
   191         ResourceConfig rc = new PackagesResourceConfig("cz.xelfi.quoridor.webidor");
   192         HttpServer server = HttpServerFactory.create(baseUri, rc);
   193         server.start();
   194         return server;
   195     }
   196 
   197 }