package player.request.factory; import java.util.ArrayList; import java.util.List; import player.gamer.Gamer; import player.request.factory.exceptions.RequestFormatException; import player.request.grammar.AbortRequest; import player.request.grammar.PingRequest; import player.request.grammar.PlayRequest; import player.request.grammar.Request; import player.request.grammar.StartRequest; import player.request.grammar.StopRequest; import util.game.Game; import util.gdl.factory.GdlFactory; import util.gdl.factory.exceptions.GdlFormatException; import util.gdl.grammar.Gdl; import util.gdl.grammar.GdlProposition; import util.gdl.grammar.GdlSentence; import util.symbol.factory.SymbolFactory; import util.symbol.grammar.Symbol; import util.symbol.grammar.SymbolAtom; import util.symbol.grammar.SymbolList; public final class RequestFactory { public Request create(Gamer gamer, String source) throws RequestFormatException { source = source.toLowerCase(); try { SymbolList list = (SymbolList) SymbolFactory.create(source); SymbolAtom head = (SymbolAtom) list.get(0); String type = head.getValue().toLowerCase(); if (type.equals("play")) { return createPlay(gamer, list); } else if (type.equals("start")) { return createStart(gamer, list); } else if (type.equals("stop")) { return createStop(gamer, list); } else if (type.equals("abort")) { return createAbort(gamer, list); } else if (type.equals("ping")) { return createPing(gamer, list); } else { throw new IllegalArgumentException("Unrecognized request type!"); } } catch (Exception e) { throw new RequestFormatException(source, e); } } private PlayRequest createPlay(Gamer gamer, SymbolList list) throws GdlFormatException { if (list.size() != 3) { throw new IllegalArgumentException("Expected exactly 2 arguments!"); } SymbolAtom arg1 = (SymbolAtom) list.get(1); Symbol arg2 = list.get(2); String matchId = arg1.getValue(); List<GdlSentence> moves = parseMoves(arg2); return new PlayRequest(gamer, matchId, moves); } private StartRequest createStart(Gamer gamer, SymbolList list) throws GdlFormatException { if (list.size() < 6) { throw new IllegalArgumentException("Expected at least 5 arguments!"); } SymbolAtom arg1 = (SymbolAtom) list.get(1); SymbolAtom arg2 = (SymbolAtom) list.get(2); SymbolList arg3 = (SymbolList) list.get(3); SymbolAtom arg4 = (SymbolAtom) list.get(4); SymbolAtom arg5 = (SymbolAtom) list.get(5); String matchId = arg1.getValue(); GdlProposition roleName = (GdlProposition) GdlFactory.create(arg2); List<Gdl> theRules = parseDescription(arg3); int startClock = Integer.valueOf(arg4.getValue()); int playClock = Integer.valueOf(arg5.getValue()); // TODO: There may be more than five arguments. These may be worth // parsing, once we find a meaningful way to handle them. They aren't // yet standardized, but, for example, one might be the URL of an XSL // stylesheet for visualizing a state of the game, or the URL for the // game on a repository server. Game theReceivedGame = Game.createEphemeralGame(theRules); return new StartRequest(gamer, matchId, roleName, theReceivedGame, startClock, playClock); } private StopRequest createStop(Gamer gamer, SymbolList list) throws GdlFormatException { if (list.size() != 3) { throw new IllegalArgumentException("Expected exactly 2 arguments!"); } SymbolAtom arg1 = (SymbolAtom) list.get(1); String matchId = arg1.getValue(); return new StopRequest(gamer, matchId); } private AbortRequest createAbort(Gamer gamer, SymbolList list) throws GdlFormatException { if (list.size() != 2) { throw new IllegalArgumentException("Expected exactly 2 arguments!"); } SymbolAtom arg1 = (SymbolAtom) list.get(1); String matchId = arg1.getValue(); return new AbortRequest(gamer, matchId); } private PingRequest createPing(Gamer gamer, SymbolList list) throws GdlFormatException { if (list.size() != 1) { throw new IllegalArgumentException("Expected exactly 1 argument!"); } return new PingRequest(gamer); } public List<Gdl> parseDescription(SymbolList list) throws GdlFormatException { List<Gdl> description = new ArrayList<Gdl>(); for (int i = 0; i < list.size(); i++) { description.add(GdlFactory.create(list.get(i))); } return description; } private List<GdlSentence> parseMoves(Symbol symbol) throws GdlFormatException { if (symbol instanceof SymbolAtom) { return null; } else { List<GdlSentence> moves = new ArrayList<GdlSentence>(); SymbolList list = (SymbolList) symbol; for (int i = 0; i < list.size(); i++) { moves.add((GdlSentence) GdlFactory.create(list.get(i))); } return moves; } } }