Download | Plain Text | No Line Numbers
- /*
- * Copyright (c) 2010, Manuel Mausz. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- import java.text.SimpleDateFormat;
- import java.text.ParseException;
-
- import java.rmi.registry.*;
- import java.rmi.server.*;
- import java.rmi.*;
-
- import java.util.concurrent.ScheduledExecutorService;
- import java.util.concurrent.ScheduledFuture;
- import java.util.concurrent.Executors;
- import java.util.concurrent.TimeUnit;
- import java.util.Collections;
- import java.util.Properties;
- import java.util.HashSet;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.Map;
-
- import java.io.*;
-
- /*
- * Client implementation for Lab#2 of DSLab WS10
- * See angabe.pdf for details
- *
- * This code is not documented at all. This is volitional
- *
- * @author Manuel Mausz (0728348)
- */
- public class Client
- {
- public class WaitForServer
- implements Runnable
- {
- public void shutdown()
- {
- scheduler.shutdown();
- synchronized(mainLock)
- {
- mainLock.notify();
- }
- }
-
- public void run()
- {
- synchronized(registry)
- {
- try
- {
- int i;
- {
- if (c2siface != null)
- shutdown();
- }
- }
- {
- err.println("Error: " + e.getMessage()); /* this shouldn't happen */
- shutdown();
- }
- {
- err.println("Unable to lookup servers: " + e.getMessage());
- shutdown();
- }
- }
- }
- }
-
- /*==========================================================================*/
-
- public class Interactive
- extends CommandInteractive
- implements Runnable
- {
- private boolean loggedin = false;
-
- {
- this.sin = sin;
- this.mainLock = mainLock;
-
- cmdHandler.register("!register", this, "cmdRegister");
- cmdHandler.register("!login", this, "cmdLogin");
- cmdHandler.register("!create", this, "cmdCreate");
- cmdHandler.register("!addDate", this, "cmdAddDate");
- cmdHandler.register("!invite", this, "cmdInvite");
- cmdHandler.register("!get", this, "cmdGet");
- cmdHandler.register("!vote", this, "cmdVote");
- cmdHandler.register("!finalize", this, "cmdFinalize");
- cmdHandler.register("!logout", this, "cmdLogout");
- cmdHandler.register("!exit", this, "cmdExit");
- cmdHandler.register("!help", this, "cmdHelp");
- cmdHandler.register("unknown", this, "cmdUnknown");
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (args.length != 2)
- {
- err.println("Invalid Syntax: " + cmd + " <username> <password>");
- return;
- }
-
- try
- {
- if (c2siface.register(args[0], args[1]))
- out.println("Successfully registered.");
- else
- err.println("Username already registered.");
- }
- {
- err.println("Error: " + e.getCause().getMessage());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (args.length != 2)
- {
- err.println("Invalid Syntax: " + cmd + " <username> <password>");
- return;
- }
-
- try
- {
- if (c2siface.login(args[0], args[1], s2ciface))
- {
- out.println("Successfully logged in.");
- loggedin = true;
- }
- else
- err.println("Wrong username or password.");
- }
- {
- err.println("Error: " + e.getCause().getMessage());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (args.length != 3)
- {
- err.println("Invalid Syntax: " + cmd + " <name> <location> <duration in minutes>");
- return;
- }
-
- int duration = 0;
- try
- {
- if (duration <= 0)
- {
- err.println("Error: Invalid argument: Duration must be a positive number.");
- return;
- }
- }
- {
- err.println("Error: Invalid argument: Duration must be numeric.");
- return;
- }
-
- try
- {
- if (c2siface.create(args[0], args[1], duration))
- out.println("Event created successfully.");
- else
- err.println("Unable to create Event. Event already exists.");
- }
- {
- err.println("Error: " + e.getCause().getMessage());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (args.length != 2)
- {
- err.println("Invalid Syntax: " + cmd + " <name of event> <date: " + datefmt.toPattern() + ">");
- return;
- }
-
- try
- {
- date = datefmt.parse(args[1]);
- }
- {}
- if (date == null)
- {
- err.println("Error: Invalid date argument. Syntax: <" + datefmt.toPattern() + ">.");
- return;
- }
-
- try
- {
- c2siface.addDate(args[0], date);
- out.println("Date option added.");
- }
- {
- err.println("Error: Unable to add date: " + e.getCause().getMessage());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (args.length != 2)
- {
- err.println("Invalid Syntax: " + cmd + " <name of event> <username>");
- return;
- }
-
- try
- {
- c2siface.invite(args[0], args[1]);
- out.println("User invited.");
- }
- {
- err.println("Error: Unable to invite user: " + e.getCause().getMessage());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (args.length != 1)
- {
- err.println("Invalid Syntax: " + cmd + " <name of event>");
- return;
- }
-
- try
- {
- out.print(c2siface.event2String(args[0]));
- out.flush();
- }
- {
- err.println("Error: Unable to fetch event: " + e.getCause().getMessage());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (args.length < 2)
- {
- err.println("Invalid Syntax: " + cmd + " <name of event> <date: " + datefmt.toPattern() + "> ...");
- return;
- }
-
- int i = 1;
- HashSet<Date> dates = new HashSet<Date>();
-
- try
- {
- for(i = 1; i < args.length; ++i)
- dates.add(datefmt.parse(args[i]));
- }
- {
- err.println("Error: Invalid date \"" + args[i] + "\". Syntax: <" + datefmt.toPattern() + ">.");
- return;
- }
-
- try
- {
- out.println("Vote registered.");
- }
- {
- err.println("Error: Unable to vote: " + e.getCause().getMessage());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (args.length != 1)
- {
- err.println("Invalid Syntax: " + cmd + " <name of event>");
- return;
- }
-
- try
- {
- c2siface.finalize(args[0]);
- }
- {
- err.println("Error: Unable to finalize: " + e.getCause().getMessage());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (args.length != 0)
- {
- err.println("Invalid Syntax: " + cmd);
- return;
- }
-
- try
- {
- c2siface.logout();
- loggedin = false;
- out.println("You have been logged out.");
- }
- {
- err.println("Error: " + e.getCause().getMessage());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- {
- if (loggedin)
- stop();
- }
-
- /*------------------------------------------------------------------------*/
-
- throws IOException
- {
- {
- if (entry.getKey().equals("unknown") || entry.getKey().equals("!help"))
- continue;
- out.println(entry.getKey());
- }
- }
-
- /*------------------------------------------------------------------------*/
-
- throws IOException
- {
- out.println("Try !help for a list of commands");
- }
-
- /*------------------------------------------------------------------------*/
-
- public void printPrompt()
- {
- out.print(">: ");
- out.flush();
- }
-
- /*------------------------------------------------------------------------*/
-
- public void shutdown()
- {}
-
- /*------------------------------------------------------------------------*/
-
- public void run()
- {
- try
- {
- run(sin);
- }
- {
- err.println("Remote Error: " + e.getMessage());
- }
- {
- err.println("Internal Error: " + e.getMessage());
- }
- {
- /* ignore that exception
- * thread will shutdown and unlock the main thread
- * which will shutdown the application
- */
- }
-
- shutdown();
- synchronized(mainLock)
- {
- mainLock.notify();
- }
- }
- }
-
- /*==========================================================================*/
-
- private ScheduledExecutorService scheduler = null;
- private C2SInterface c2siface = null;
- private S2CInterfaceImpl s2ciface = null;
-
- /*--------------------------------------------------------------------------*/
-
- public static void usage()
- throws Utils.Shutdown
- {
- out.println("Usage: Server serverName\n");
- out.println("serverName\t...the name of the remote reference in the RMI registry");
- out.println("\t\t of the server that shall be responsible for this client.");
-
- // Java is some piece of crap which doesn't allow me to set exitcode w/o
- // using System.exit. Maybe someday Java will be a fully functional
- // programming language, but I wouldn't bet my money
- //System.exit(1);
- throw new Utils.Shutdown("FUCK YOU JAVA");
- }
-
- /*--------------------------------------------------------------------------*/
-
- throws Utils.Shutdown
- {
- if (error != null)
- err.println("Error: " + error);
- shutdown();
-
- // Java is some piece of crap which doesn't allow me to set exitcode w/o
- // using System.exit. Maybe someday Java will be a fully functional
- // programming language, but I wouldn't bet my money
- //System.exit(2);
- throw new Utils.Shutdown("FUCK YOU JAVA");
- }
-
- /*--------------------------------------------------------------------------*/
-
- {
- if (args.length != 1)
- usage();
-
- serverName = args[0];
- if (serverName.length() == 0)
- bailout("serverName is empty");
- }
-
- /*--------------------------------------------------------------------------*/
-
- public void createInterface()
- {
- int regPort = 0;
-
- try
- {
- if (in == null)
- bailout("Properties file doesn't exist or isn't readable");
- props.load(in);
- {
- if (prop.equals("registry.host"))
- regHost = props.getProperty(prop);
- else if (prop.equals("registry.port"))
- {
- try
- {
- if (regPort <= 0 || regPort > 65536)
- {
- err.println("Property " + prop + " must be a valid port number (1 - 65535). Skipping...");
- regPort = 0;
- }
- }
- {
- err.println("Property " + prop + " must be numeric. Skipping...");
- }
- }
- else
- err.println("Property " + prop + " is unknown. Skipping...");
- }
- in.close();
- }
- {
- bailout("Unable to read from properties file: " + e.getMessage());
- }
-
- if (regHost == null || regHost.length() <= 0)
- bailout("Registry host is not set");
- if (regPort == 0)
- bailout("Registry port is not set");
-
- try
- {
- }
- {
- bailout("Unable to get registry: " + e.getMessage());
- }
- }
-
- /*--------------------------------------------------------------------------*/
-
- public void remoteLogout()
- {
- if (tInteractive != null)
- tInteractive.interrupt();
- }
-
- /*--------------------------------------------------------------------------*/
-
- public void shutdown()
- {
- try
- {
- if (scheduler != null)
- {
- scheduler.shutdownNow();
- }
- }
- {}
-
- try
- {
- if (s2ciface != null)
- s2ciface.unexport();
- }
- {}
-
- try
- {
- if (tInteractive != null)
- {
- tInteractive.interrupt();
- tInteractive.join();
- }
- }
- {}
-
- try
- {
- if (stdin != null)
- stdin.close();
- }
- {}
- }
-
- /*--------------------------------------------------------------------------*/
-
- {
- parseArgs(args);
-
- synchronized(mainLock)
- {
- createInterface();
-
- try
- {
- out.println("Waiting for the server to come online...");
- scheduler = Executors.newScheduledThreadPool(1);
- ScheduledFuture<?> waitServerTimer = scheduler.scheduleAtFixedRate(
- new WaitForServer(), 0, 500, TimeUnit.MILLISECONDS);
- mainLock.wait();
- if (!scheduler.isShutdown() || c2siface == null)
- bailout(null);
- }
- {
- /* if we get interrupted -> ignore */
- }
-
- try
- {
- s2ciface = new S2CInterfaceImpl(this);
- }
- {
- bailout("Unable to export client callback");
- }
-
- try
- {
- tInteractive.start();
- }
- {
- bailout("Unable to setup interactive command handler");
- }
- {
- bailout("Unable to create object output stream: " + e.getMessage());
- }
-
- out.println("Client startup successful!");
- try
- {
- mainLock.wait();
- }
- {
- /* if we get interrupted -> ignore */
- }
- }
-
- shutdown();
- }
-
- /*--------------------------------------------------------------------------*/
-
- {
- try
- {
- Client cli = new Client();
- cli.run(args);
- }
- catch(Utils.Shutdown e)
- {}
- }
- }
-