diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DeckDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DeckDAO.java index 179444a9a..51299eea0 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DeckDAO.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DeckDAO.java @@ -7,9 +7,7 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class DeckDAO { @@ -21,24 +19,16 @@ public class DeckDAO { _dbAccess = dbAccess; } - public synchronized LotroDeck getDeckForPlayer(Player player, String name) { + public LotroDeck getDeckForPlayer(Player player, String name) { Map lotroDeckMap = getPlayerDecks(player); - LotroDeck deck = lotroDeckMap.get(name); - if (deck != null) - return deck; - - deck = getDeckFromDB(player.getId(), name); - if (deck != null) { - lotroDeckMap.put(name, deck); - return deck; - } - return null; + return lotroDeckMap.get(name); } public synchronized void saveDeckForPlayer(Player player, String name, LotroDeck deck) { - storeDeckToDB(player, name, deck); - Map decksByName = getPlayerDecks(player); - decksByName.put(name, deck); + final Map playerDecks = getPlayerDecks(player); + boolean newDeck = !playerDecks.containsKey(name); + storeDeckToDB(player.getId(), name, deck, newDeck); + playerDecks.put(name, deck); } public synchronized void deleteDeckForPlayer(Player player, String name) { @@ -47,7 +37,7 @@ public class DeckDAO { Map map = getPlayerDecks(player); map.remove(name); } catch (SQLException exp) { - throw new RuntimeException("Unable to store player deck to DB", exp); + throw new RuntimeException("Unable to delete player deck from DB", exp); } } @@ -61,16 +51,54 @@ public class DeckDAO { return deck; } + public Set getPlayerDeckNames(Player player) { + return Collections.unmodifiableSet(getPlayerDecks(player).keySet()); + } + private Map getPlayerDecks(Player player) { Map decksByName = _decks.get(player.getId()); - if (decksByName == null) { - decksByName = new ConcurrentHashMap(); - _decks.put(player.getId(), decksByName); - } + if (decksByName == null) + decksByName = loadPlayerDecks(player); return decksByName; } - private void storeDeckToDB(Player player, String name, LotroDeck deck) { + private Map loadPlayerDecks(Player player) { + try { + return loadPlayerDecksFromDB(player.getId()); + } catch (SQLException exp) { + throw new RuntimeException("Unable to load player decks from DB", exp); + } + } + + private Map loadPlayerDecksFromDB(int playerId) throws SQLException { + Connection connection = _dbAccess.getDataSource().getConnection(); + try { + PreparedStatement statement = connection.prepareStatement("select name, contents from deck where player_id=?"); + try { + statement.setInt(1, playerId); + ResultSet rs = statement.executeQuery(); + try { + Map result = new HashMap(); + while (rs.next()) { + String name = rs.getString(1); + String contents = rs.getString(2); + + result.put(name, buildDeckFromContents(contents)); + } + return result; + } finally { + rs.close(); + } + } finally { + statement.close(); + } + } finally { + connection.close(); + } + + } + + private void storeDeckToDB(int playerId, String name, LotroDeck deck, boolean newDeck) { StringBuilder sb = new StringBuilder(); sb.append(deck.getRingBearer()); sb.append(",").append(deck.getRing()); @@ -79,11 +107,10 @@ public class DeckDAO { String contents = sb.toString(); try { - LotroDeck oldDeck = getDeckForPlayer(player, name); - if (oldDeck != null) - updateDeckInDB(player.getId(), name, contents); + if (newDeck) + storeDeckInDB(playerId, name, contents); else - storeDeckInDB(player.getId(), name, contents); + updateDeckInDB(playerId, name, contents); } catch (SQLException exp) { throw new RuntimeException("Unable to store player deck to DB", exp); } diff --git a/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java b/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java index f8bd5ca3d..59c3f7238 100644 --- a/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java +++ b/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java @@ -34,9 +34,7 @@ import javax.ws.rs.core.Response; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; @Singleton @Path("/") @@ -224,6 +222,38 @@ public class ServerResource { return doc; } + @Path("/deck/list") + @GET + @Produces(MediaType.APPLICATION_XML) + public Document listDecks( + @QueryParam("participantId") String participantId, + @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); + + PlayerDAO playerDao = _lotroServer.getPlayerDao(); + DeckDAO deckDao = _lotroServer.getDeckDao(); + + Player player = playerDao.getPlayer(participantId); + if (player == null) + sendError(Response.Status.UNAUTHORIZED); + + List names = new ArrayList(deckDao.getPlayerDeckNames(player)); + Collections.sort(names); + + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document doc = documentBuilder.newDocument(); + Element decksElem = doc.createElement("decks"); + for (String name : names) { + Element deckElem = doc.createElement("deck"); + deckElem.appendChild(doc.createTextNode(name)); + decksElem.appendChild(deckElem); + } + doc.appendChild(decksElem); + return doc; + } + @Path("/deck") @GET @Produces(MediaType.APPLICATION_XML)