aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEduardo Pedroni <e.pedroni91@gmail.com>2015-06-11 16:57:42 +0200
committerEduardo Pedroni <e.pedroni91@gmail.com>2015-06-11 16:57:42 +0200
commit27be2dd797fc7087c5e362c22c1f30fc377ea0e9 (patch)
tree93b0b5360788f1df3b257c294dbe08ffcf291dc2
parent56dc0db523156c6ff77d9212983c51b531250733 (diff)
Streamlined Card class, cards are now stored in a hashmap, had to write a method to parse full card set json
-rw-r--r--src/eu/equalparts/cardbase/Cardbase.java54
-rw-r--r--src/eu/equalparts/cardbase/data/Card.java18
-rw-r--r--src/eu/equalparts/cardbase/data/FullCardSet.java90
-rw-r--r--src/eu/equalparts/cardbase/standalone/CardbaseCLI.java11
-rw-r--r--src/eu/equalparts/cardbase/utils/MTGUniverse.java80
5 files changed, 190 insertions, 63 deletions
diff --git a/src/eu/equalparts/cardbase/Cardbase.java b/src/eu/equalparts/cardbase/Cardbase.java
index d842031..c5efc85 100644
--- a/src/eu/equalparts/cardbase/Cardbase.java
+++ b/src/eu/equalparts/cardbase/Cardbase.java
@@ -1,16 +1,16 @@
package eu.equalparts.cardbase;
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
-import eu.equalparts.cardbase.comparators.CardComparators;
import eu.equalparts.cardbase.data.Card;
import eu.equalparts.cardbase.utils.JSON;
@@ -22,9 +22,10 @@ import eu.equalparts.cardbase.utils.JSON;
public class Cardbase {
/**
- * The cards in the cardbase.
+ * The cards in the cardbase, set in key-value pairs where the key is the card hash,
+ * generated using {makeHash()}.
*/
- private List<Card> cards;
+ private Map<String, Card> cards;
/**
* Debug flag is raised when the DEBUG environment variable is set. This causes additional
* information to be printed to the console.
@@ -35,7 +36,7 @@ public class Cardbase {
* Creates an empty cardbase.
*/
public Cardbase() {
- cards = new ArrayList<Card>();
+ cards = new HashMap<String, Card>();
}
/**
@@ -48,7 +49,7 @@ public class Cardbase {
* @throws IOException if a low-level I/O problem (unexpected end-of-input, network error) occurs.
*/
public Cardbase(File cardbaseFile) throws JsonParseException, JsonMappingException, IOException {
- cards = JSON.mapper.readValue(cardbaseFile, new TypeReference<ArrayList<Card>>() {});
+ cards = JSON.mapper.readValue(cardbaseFile, new TypeReference<Map<String, Card>>() {});
}
/**
@@ -79,7 +80,7 @@ public class Cardbase {
card.count += count;
} else {
cardToAdd.count = count;
- cards.add(cardToAdd);
+ cards.put(makeHash(cardToAdd), cardToAdd);
}
}
@@ -104,13 +105,13 @@ public class Cardbase {
Integer removed = 0;
if (card != null) {
if (card.count <= count) {
- cards.remove(card);
+ cards.remove(makeHash(card));
removed = card.count;
} else {
card.count -= count;
removed = count;
}
- }
+ }
return removed;
}
@@ -122,32 +123,41 @@ public class Cardbase {
*
* @return an unmodifiable list of all the cards in the cardbase.
*/
- public List<Card> getCards() {
- return Collections.unmodifiableList(cards);
+ public Collection<Card> getCards() {
+ return Collections.unmodifiableCollection(cards.values());
}
- public void sortByName() {
- cards.sort(new CardComparators.NameComparator());
- }
-
/**
* Returns a card from the cardbase by set code and number.
* If no such card is in the cardbase, returns null.
*
* @param setCode the set to which the requested card belongs.
* @param number the requested card's set number.
+ *
* @return the requested {@code Card} or null if no card is found.
*/
public Card getCard(String setCode, String number) {
- for (Card card : cards) {
- if (card.setCode.equals(setCode) && card.number.equals(number))
- return card;
- }
-
- return null;
+ return cards.get(makeHash(setCode, number));
}
+ /**
+ * Generate the hash used as a key in the storage map.
+ *
+ * @param setCode the card's set code.
+ * @param number the card's set number.
+ * @return the generated hash.
+ */
private String makeHash(String setCode, String number) {
return setCode + number;
}
+
+ /**
+ * Generate the hash used as a key in the storage map.
+ *
+ * @param the {@code Card} whose hash is desired.
+ * @return the generated hash.
+ */
+ private String makeHash(Card card) {
+ return card.setCode + card.number;
+ }
}
diff --git a/src/eu/equalparts/cardbase/data/Card.java b/src/eu/equalparts/cardbase/data/Card.java
index 3820223..cca1747 100644
--- a/src/eu/equalparts/cardbase/data/Card.java
+++ b/src/eu/equalparts/cardbase/data/Card.java
@@ -1,19 +1,12 @@
package eu.equalparts.cardbase.data;
-import java.util.List;
-
public class Card {
- public String name = "";
- public String layout = "";
- public List<String> names;
- public String manaCost = "";
- public Integer cmc = 0;
- public List<String> colors;
+ public String name;
+ public String layout;
+ public String manaCost;
+ public Integer cmc;
public String type;
- public List<String> supertypes;
- public List<String> types;
- public List<String> subtypes;
public String rarity;
public String text;
public String flavor;
@@ -23,7 +16,6 @@ public class Card {
public String toughness;
public Integer loyalty;
public Integer multiverseid;
- public List<String> variations;
public String imageName;
public String border;
public String watermark;
@@ -31,5 +23,5 @@ public class Card {
// Not part of upstream JSON
public String setCode;
public Integer count;
-
+
} \ No newline at end of file
diff --git a/src/eu/equalparts/cardbase/data/FullCardSet.java b/src/eu/equalparts/cardbase/data/FullCardSet.java
index d469829..e831b74 100644
--- a/src/eu/equalparts/cardbase/data/FullCardSet.java
+++ b/src/eu/equalparts/cardbase/data/FullCardSet.java
@@ -1,17 +1,19 @@
package eu.equalparts.cardbase.data;
-import java.util.List;
+import java.util.Collections;
+import java.util.Map;
public class FullCardSet {
private String name;
private String code;
+ private String magicCardsInfoCode;
private String releaseDate;
private String border;
private String type;
private String block;
private String gathererCode;
- private List<Card> cards;
+ private Map<String, Card> cards;
/**
* @return the set's name.
@@ -63,12 +65,12 @@ public class FullCardSet {
}
/**
- * @return a full list of the set's cards.
+ * @return a full unmodifiable map of the set's cards.
*/
- public List<Card> getCards() {
- return cards;
+ public Map<String, Card> getCards() {
+ return Collections.unmodifiableMap(cards);
}
-
+
/**
* Searches for a card by number (the one shown on the card itself).
*
@@ -76,10 +78,76 @@ public class FullCardSet {
* @return the requested {@code Card}, or null if no card is found with that number.
*/
public Card getCardByNumber(String number) {
- for (Card card : cards) {
- if (card.number.equals(number))
- return card;
- }
- return null;
+ return cards.get(number);
+ }
+
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @param code the code to set
+ */
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ /**
+ * @param releaseDate the releaseDate to set
+ */
+ public void setReleaseDate(String releaseDate) {
+ this.releaseDate = releaseDate;
+ }
+
+ /**
+ * @param border the border to set
+ */
+ public void setBorder(String border) {
+ this.border = border;
+ }
+
+ /**
+ * @param type the type to set
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * @param block the block to set
+ */
+ public void setBlock(String block) {
+ this.block = block;
+ }
+
+ /**
+ * @param gathererCode the gathererCode to set
+ */
+ public void setGathererCode(String gathererCode) {
+ this.gathererCode = gathererCode;
+ }
+
+ /**
+ * @param cards the cards to set
+ */
+ public void setCards(Map<String, Card> cards) {
+ this.cards = cards;
+ }
+
+ /**
+ * @return the magicCardsInfoCode
+ */
+ public String getMagicCardsInfoCode() {
+ return magicCardsInfoCode;
+ }
+
+ /**
+ * @param magicCardsInfoCode the magicCardsInfoCode to set
+ */
+ public void setMagicCardsInfoCode(String magicCardsInfoCode) {
+ this.magicCardsInfoCode = magicCardsInfoCode;
}
} \ No newline at end of file
diff --git a/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java b/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java
index f491f6c..be3616a 100644
--- a/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java
+++ b/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java
@@ -177,8 +177,6 @@ public class CardbaseCLI {
} else if (command.equalsIgnoreCase("remove")
|| command.equalsIgnoreCase("rm")) {
remove(args);
- } else if (command.equalsIgnoreCase("sort")) {
- sort(args);
} else {
add(command, args);
}
@@ -411,15 +409,6 @@ public class CardbaseCLI {
}
/**
- * Sort the cardbase by a specified parameter.
- *
- * @param args the ordering to sort by.
- */
- public void sort(String[] args) {
- cardbase.sortByName();
- }
-
- /**
* Add the specified count of the specified card
* to the cardbase.
*
diff --git a/src/eu/equalparts/cardbase/utils/MTGUniverse.java b/src/eu/equalparts/cardbase/utils/MTGUniverse.java
index 0bcda5c..8c77032 100644
--- a/src/eu/equalparts/cardbase/utils/MTGUniverse.java
+++ b/src/eu/equalparts/cardbase/utils/MTGUniverse.java
@@ -4,10 +4,13 @@ import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
import eu.equalparts.cardbase.data.Card;
import eu.equalparts.cardbase.data.CardSetInformation;
@@ -97,11 +100,7 @@ public final class MTGUniverse {
}
// not cached; fetch, cache and return it
else {
- requestedSet = JSON.mapper.readValue(new URL(BASE_URL + validCode + ".json"), FullCardSet.class);
- // MTG JSON does not include set code in the card information, but it is useful for sorting
- for (Card card : requestedSet.getCards()) {
- card.setCode = validCode;
- }
+ requestedSet = parseFullSet(JSON.mapper.readValue(new URL(BASE_URL + validCode + ".json"), JsonNode.class));
cardSetCache.put(validCode, requestedSet);
}
}
@@ -152,4 +151,73 @@ public final class MTGUniverse {
}
return null;
}
-}
+
+ /**
+ * This method is necessary to adapt the list of cards in the json to
+ * the map format used in cardbase.
+ *
+ * @param jsonTree the tree-representation of the json to be parsed.
+ * @return the parsed full card set.
+ *
+ * @throws JsonMappingException if the upstream JSON does not map to {@code FullCardSet}.
+ * @throws IOException if a low-level I/O problem (unexpected end-of-input, network error) occurs.
+ */
+ private static FullCardSet parseFullSet(JsonNode jsonTree) throws JsonMappingException, IOException {
+
+ FullCardSet fcs = new FullCardSet();
+
+ /*
+ * These fields are critical, if any of them is not present an exception is thrown.
+ */
+ if (jsonTree.hasNonNull("name")) {
+ fcs.setName(jsonTree.get("name").asText());
+ } else {
+ throw new JsonMappingException("Field \"name\" not found.");
+ }
+
+ String setCode;
+ if (jsonTree.hasNonNull("code")) {
+ setCode = jsonTree.get("code").asText();
+ fcs.setCode(setCode);
+ } else {
+ throw new JsonMappingException("Field \"code\" not found.");
+ }
+
+ if (jsonTree.hasNonNull("releaseDate")) {
+ fcs.setReleaseDate(jsonTree.get("releaseDate").asText());
+ } else {
+ throw new JsonMappingException("Field \"releaseDate\" not found.");
+ }
+
+ /*
+ * These fields are optional and are set to null if not present.
+ */
+ fcs.setGathererCode(jsonTree.hasNonNull("gathererCode") ? jsonTree.get("gathererCode").asText() : null);
+ fcs.setBorder(jsonTree.hasNonNull("border") ? jsonTree.get("border").asText() : null);
+ fcs.setType(jsonTree.hasNonNull("type") ? jsonTree.get("type").asText() : null);
+ fcs.setMagicCardsInfoCode(jsonTree.hasNonNull("magicCardsInfoCode") ? jsonTree.get("magicCardsInfoCode").asText() : null);
+ fcs.setBlock(jsonTree.hasNonNull("block") ? jsonTree.get("block").asText() : null);
+
+ /*
+ * This is a critical field which must be present, if not an exception is thrown.
+ */
+ if (jsonTree.hasNonNull("cards")) {
+ // attempt to card list as POJO
+ List<Card> rawList = jsonTree.get("cards").traverse(JSON.mapper).readValueAs(new TypeReference<List<Card>>() {});
+
+ // generate the map
+ Map<String, Card> cardMap = new HashMap<String, Card>();
+ for (Card card : rawList) {
+ // add set code for convenience
+ card.setCode = setCode;
+ cardMap.put(card.number, card);
+ }
+ fcs.setCards(cardMap);
+ } else {
+ throw new JsonMappingException("Field \"cards\" not found.");
+ }
+
+ return fcs;
+
+ }
+} \ No newline at end of file