From 0465829c25ef43ba9ba898dff01ebaa5106fd1f8 Mon Sep 17 00:00:00 2001 From: Eduardo Pedroni Date: Fri, 5 Jun 2015 15:37:51 +0200 Subject: It works! Reading in a file, writing to the same file or a different existing file, glancing, perusing, adding and removing cards by number --- src/eu/equalparts/cardbase/data/Card.java | 4 +- src/eu/equalparts/cardbase/data/CardBase.java | 18 +- .../equalparts/cardbase/data/CardBaseManager.java | 68 ++++++- src/eu/equalparts/cardbase/data/Deck.java | 10 ++ src/eu/equalparts/cardbase/data/MetaCardSet.java | 31 +--- src/eu/equalparts/cardbase/query/IO.java | 46 ++++- src/eu/equalparts/cardbase/query/Test.java | 1 - .../cardbase/standalone/CardBaseCLI.java | 198 ++++++++++++++++++--- 8 files changed, 312 insertions(+), 64 deletions(-) (limited to 'src/eu') diff --git a/src/eu/equalparts/cardbase/data/Card.java b/src/eu/equalparts/cardbase/data/Card.java index 8e25d56..1bf6a75 100644 --- a/src/eu/equalparts/cardbase/data/Card.java +++ b/src/eu/equalparts/cardbase/data/Card.java @@ -28,8 +28,8 @@ public class Card { public String border; public String watermark; - // Not part of JSON, will be set later + // Not part of upstream JSON public String setCode; - public String setName; + public Integer count; } \ No newline at end of file diff --git a/src/eu/equalparts/cardbase/data/CardBase.java b/src/eu/equalparts/cardbase/data/CardBase.java index 70ae0ea..abdd423 100644 --- a/src/eu/equalparts/cardbase/data/CardBase.java +++ b/src/eu/equalparts/cardbase/data/CardBase.java @@ -4,9 +4,21 @@ import java.util.ArrayList; public class CardBase { - private ArrayList cards; - private ArrayList decks; - + public ArrayList cards = new ArrayList<>(); + public ArrayList decks = new ArrayList<>(); + /** + * @param setCode + * @param number + * @return the card if found, else null. + */ + public Card getCardByNumber(String setCode, String number) { + for (Card card : cards) { + if (card.setCode.equals(setCode) && card.number.equals(number)) + return card; + } + + return null; + } } diff --git a/src/eu/equalparts/cardbase/data/CardBaseManager.java b/src/eu/equalparts/cardbase/data/CardBaseManager.java index acf5a3a..0baf9d7 100644 --- a/src/eu/equalparts/cardbase/data/CardBaseManager.java +++ b/src/eu/equalparts/cardbase/data/CardBaseManager.java @@ -2,6 +2,7 @@ package eu.equalparts.cardbase.data; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Iterator; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; @@ -11,19 +12,17 @@ import eu.equalparts.cardbase.query.IO; public class CardBaseManager { private ArrayList metaSets; + public CardBase cardBase; - public static void main(String... args) { - - } - /** * Parse a cardbase file and create an associated CardBase object. * @throws IOException * @throws JsonMappingException * @throws JsonParseException */ - public CardBaseManager(File cardbase) throws JsonParseException, JsonMappingException, IOException { + public CardBaseManager(File cardBaseFile) throws JsonParseException, JsonMappingException, IOException { metaSets = IO.getAllMetaSets(); + cardBase = IO.readCardBase(cardBaseFile); } /** @@ -34,10 +33,69 @@ public class CardBaseManager { */ public CardBaseManager() throws JsonParseException, JsonMappingException, IOException { metaSets = IO.getAllMetaSets(); + cardBase = new CardBase(); } public ArrayList getAllMetaSets() { return metaSets; } + /** + * Add a specific amount of a card to the cardbase. + * If the card is not already in the cardbase, it is added. + * If it is already present, the count is simply updated. + * + * + * @param newCard + * @param count + */ + public void addCard(Card newCard, Integer count) { + Card card = cardBase.getCardByNumber(newCard.setCode, newCard.number); + if (card != null) { + card.count += count; + } else { + newCard.count = count; + cardBase.cards.add(newCard); + } + } + + /** + * Remove a specific amount of a card from the cardbase. + * If the card is not present in the cardbase, nothing happens. + * If the card is present in the card, the specified amount is removed. + * If that amount is equal to or exceeds the count already in the cardbase, + * the card entry is removed altogether. + * + * @param remove + * @param count + */ + public void removeCard(Card remove, Integer count) { + Card card = cardBase.getCardByNumber(remove.setCode, remove.number); + if (card != null) { + if (card.count <= count) { + cardBase.cards.remove(card); + } else { + card.count -= count; + } + } + } + + /** + * @return an iterator to the cards in the cardbase. + */ + public Iterator cardIterator() { + return cardBase.cards.iterator(); + } + + /** + * Return a card from the cardBase by setCode and number. + * If no such card is in the cardbase, return null. + * + * @param code + * @param string + * @return + */ + public Card getCard(String code, String number) { + return cardBase.getCardByNumber(code, number); + } } diff --git a/src/eu/equalparts/cardbase/data/Deck.java b/src/eu/equalparts/cardbase/data/Deck.java index 50f1129..b5fe402 100644 --- a/src/eu/equalparts/cardbase/data/Deck.java +++ b/src/eu/equalparts/cardbase/data/Deck.java @@ -1,5 +1,15 @@ package eu.equalparts.cardbase.data; +import java.util.HashMap; + public class Deck { + /** + * Cards stored in key-value pairs of [multiverse ID, amount]. + */ + public HashMap cards; + + public Deck() { + + } } diff --git a/src/eu/equalparts/cardbase/data/MetaCardSet.java b/src/eu/equalparts/cardbase/data/MetaCardSet.java index 4ddf228..3b7d4fd 100644 --- a/src/eu/equalparts/cardbase/data/MetaCardSet.java +++ b/src/eu/equalparts/cardbase/data/MetaCardSet.java @@ -2,34 +2,9 @@ package eu.equalparts.cardbase.data; public class MetaCardSet { - private String name = ""; - private String code = ""; - private String releaseDate = ""; - - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getReleaseDate() { - return releaseDate; - } - - public void setReleaseDate(String releaseDate) { - this.releaseDate = releaseDate; - } + public String name = ""; + public String code = ""; + public String releaseDate = ""; @Override public String toString() { diff --git a/src/eu/equalparts/cardbase/query/IO.java b/src/eu/equalparts/cardbase/query/IO.java index 65a3a34..9b81b20 100644 --- a/src/eu/equalparts/cardbase/query/IO.java +++ b/src/eu/equalparts/cardbase/query/IO.java @@ -2,6 +2,7 @@ package eu.equalparts.cardbase.query; import java.io.File; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -21,21 +22,56 @@ public class IO { public static final String BASE_URL = "http://mtgjson.com/json/"; public static final String SETS_URL = BASE_URL + "SetList.json"; - private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = createMapper(); - public static CardSet getCardSet(String setId) { - return new CardSet(); + private static ObjectMapper createMapper() { + ObjectMapper om = new ObjectMapper(); + om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return om; } - public static ArrayList getAllMetaSets() throws JsonParseException, JsonMappingException, IOException { - //mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + /** + * @param code + * @return the actual cardset (containing cards). + * @throws IOException + * @throws MalformedURLException + * @throws JsonMappingException + * @throws JsonParseException + */ + public static CardSet getCardSet(String code) throws JsonParseException, JsonMappingException, MalformedURLException, IOException { + return mapper.readValue(new URL(BASE_URL + code + ".json"), CardSet.class); + } + + /** + * @return a list of metadata for every available set. + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + public static ArrayList getAllMetaSets() throws JsonParseException, JsonMappingException, IOException { return mapper.readValue(new URL(SETS_URL), new TypeReference>() {}); } + /** + * @param file + * @return a CardBase object equivalent to the given file. + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ public static CardBase readCardBase(File file) throws JsonParseException, JsonMappingException, IOException { return mapper.readValue(file, CardBase.class); } + /** + * Writes the provided CardBase to the provided file in JSON format. + * + * @param file + * @param cardBase + * @throws JsonGenerationException + * @throws JsonMappingException + * @throws IOException + */ public static void writeCardBase(File file, CardBase cardBase) throws JsonGenerationException, JsonMappingException, IOException { mapper.writeValue(file, cardBase); } diff --git a/src/eu/equalparts/cardbase/query/Test.java b/src/eu/equalparts/cardbase/query/Test.java index 2050c76..e466c55 100644 --- a/src/eu/equalparts/cardbase/query/Test.java +++ b/src/eu/equalparts/cardbase/query/Test.java @@ -59,7 +59,6 @@ public class Test { for (CardSet set : sets.values()) { for (Card card : set.cards) { card.setCode = set.code; - card.setName = set.name; // System.out.println(set.getName() + ": " + card.getName()); allCards.add(card); diff --git a/src/eu/equalparts/cardbase/standalone/CardBaseCLI.java b/src/eu/equalparts/cardbase/standalone/CardBaseCLI.java index 2806a9e..d0503ac 100644 --- a/src/eu/equalparts/cardbase/standalone/CardBaseCLI.java +++ b/src/eu/equalparts/cardbase/standalone/CardBaseCLI.java @@ -4,22 +4,32 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Scanner; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; +import eu.equalparts.cardbase.data.Card; import eu.equalparts.cardbase.data.CardBaseManager; +import eu.equalparts.cardbase.data.CardSet; import eu.equalparts.cardbase.data.MetaCardSet; +import eu.equalparts.cardbase.query.IO; /** * This provides a lightweight CLI for interacting with cardbase files. * */ public class CardBaseCLI { - - private static String selectedSet = ""; + + private static CardSet selectedSet = null; + private static HashMap setCache = new HashMap(); private static CardBaseManager cbm; private static boolean exit = false; + private static String help = "No help file was found"; + private static File cardBaseFile; /** * Execute the interface. @@ -33,18 +43,35 @@ public class CardBaseCLI { try { // construct the cardbase if (args.length > 0) { - System.out.println("Building cardbase from " + args[0]); - cbm = new CardBaseManager(new File(args[0])); + cardBaseFile = new File(args[0]); + if (cardBaseFile.exists() && cardBaseFile.isFile() && cardBaseFile.canRead()) { + System.out.println("Loading cardbase from " + args[0]); + cbm = new CardBaseManager(cardBaseFile); + } else { + System.out.println(args[0] + " appears to be invalid"); + System.exit(0); + } } else { - System.out.println("No cardbase file was provided, initialising a clean cardbase"); - cbm = new CardBaseManager(); + //System.out.println("No cardbase file was provided, initialising a clean cardbase"); + System.out.println("Loading testbase for debugging purposes"); + cardBaseFile = new File("testbase"); + cbm = new CardBaseManager(cardBaseFile); } // initialise necessary components System.out.println("Fetching card sets from upstream"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + System.out.println("Loading externals"); + File helpFile = new File("help"); + if (helpFile.exists() && helpFile.canRead()) { + help = new Scanner(helpFile).useDelimiter("\\Z").next(); + } else { + System.out.println("Help file is not available, I hope you know how to use the program!"); + } + while (!exit) { + System.out.print(selectedSet == null ? "> " : selectedSet.code + " > "); String rawInput = br.readLine().trim().toLowerCase(); String[] commands = rawInput.split("[ \t]+"); @@ -64,21 +91,51 @@ public class CardBaseCLI { } - private static void parse(String[] commands) { + private static void parse(String[] commands) throws JsonParseException, JsonMappingException, MalformedURLException, IOException { if (commands.length > 0) { switch (commands[0]) { /* - * Exit procedures + * Show help */ - case "exit": - exit = true; + case "help": + System.out.println(help); break; + /* - * Show help (externalised?) + * Write current CardBase to file */ - case "help": - System.out.println("google it"); + case "write": + if (commands.length > 1) { + File output = new File(commands[1]); + if (output.exists()) { + if(output.isFile()) { + if (output.canWrite()) { + IO.writeCardBase(output, cbm.cardBase); + cardBaseFile = output; + System.out.println("Cardbase saved to " + output.getAbsolutePath()); + } else { + System.out.println(commands[1] + " cannot be written to, nothing was written"); + } + } else { + System.out.println(commands[1] + " is not a file, nothing was written"); + } + } else { + System.out.println(commands[1] + " does not exist, nothing was written"); + } + } else if (cardBaseFile != null) { + System.out.println("Writing to " + cardBaseFile.getAbsolutePath()); + } else { + System.out.println("Please provide a file name"); + } break; + + /* + * Exit procedures + */ + case "exit": + exit = true; + break; + /* * Print a list of valid set codes */ @@ -87,31 +144,132 @@ public class CardBaseCLI { System.out.println(mcs); } break; + /* * Select a set, any card numbers provided will be fetched from that set */ case "set": for (MetaCardSet mcs : cbm.getAllMetaSets()) { - if (mcs.getCode().equalsIgnoreCase(commands[1])) { - System.out.println("Selected set: " + mcs.getName()); - selectedSet = mcs.getCode(); + if (mcs.code.equalsIgnoreCase(commands[1])) { + // if the set is cached, use that + if (setCache.containsKey(mcs.code)) { + selectedSet = setCache.get(mcs.code); + } else { + selectedSet = IO.getCardSet(mcs.code); + setCache.put(mcs.code, selectedSet); + } + System.out.println("Selected set: " + mcs.name); return; } } System.out.println(commands[1] + " does not correspond to any set (use \"sets\" to see all valid set codes)"); break; + /* - * Write current CardBase to file + * Print a brief list of the complete cardbase. */ - case "write": + case "glance": + for (Iterator i = cbm.cardIterator(); i.hasNext();) { + printGlance(i.next()); + } + break; + + /* + * Print a detailed information of a single card or the whole cardbase. + */ + case "peruse": + if (commands.length > 1) { + if (selectedSet != null) { + Card card = cbm.getCard(selectedSet.code, commands[1]); + if (card != null) { + printPerusal(card); + } else { + System.out.println("Card not in cardbase"); + } + } else { + System.out.println("Please select a set before perusing a specific card"); + } + } else { + for (Iterator i = cbm.cardIterator(); i.hasNext();) { + printPerusal(i.next()); + } + } + break; + + /* + * Remove one or more cards + */ + case "remove": + if (selectedSet != null) { + if (commands.length > 1) { + Card remove = selectedSet.getCardByNumber(commands[1]); + if (remove != null) { + Integer count = 1; + if (commands.length > 2 && commands[2].matches("[0-9]+")) { + count = Integer.valueOf(commands[2]); + if (count <= 0) { + System.out.println("Can't remove " + count + " cards"); + return; + } + } + cbm.removeCard(remove, count); + System.out.println("Removed " + count + "x " + remove.name); + } else { + System.out.println(commands[1] + " does not correspond to a card in " + selectedSet.name); + } + } else { + System.out.println("Please specify a card number to remove"); + } + } else { + System.out.println("Select a set before removing cards."); + } break; + /* - * Try to parse a card number and get it from the set + * Add one or more cards */ default: + if (selectedSet != null) { + Card newCard = selectedSet.getCardByNumber(commands[0]); + if (newCard != null) { + Integer count = 1; + if (commands.length > 1 && commands[1].matches("[0-9]+")) { + count = Integer.valueOf(commands[1]); + if (count <= 0) { + System.out.println("Can't add " + count + " cards"); + return; + } + } + newCard.setCode = selectedSet.code; + cbm.addCard(newCard, count); + System.out.println("Added " + count + "x " + newCard.name); + } else { + System.out.println(commands[0] + " does not correspond to a card in " + selectedSet.name); + } + } else { + System.out.println("Select a set before adding cards."); + } break; } } } - + + private static void printPerusal(Card card) { + printGlance(card); + if (card.type != null) System.out.println("\t" + card.type); + if (card.manaCost != null) System.out.println("\tCost: " + card.manaCost); + if (card.power != null && card.toughness != null) System.out.println("\t" + card.power + "/" + card.toughness); + if (card.loyalty != null) System.out.println("\tLoyalty: " + card.loyalty); + + if (card.text != null) System.out.println("\t" + card.text.replaceAll("\n", "\n\t")); + if (card.flavor != null) System.out.println("\t" + card.flavor.replaceAll("\n", "\n\t")); + + if (card.rarity != null) System.out.println("\t" + card.rarity); + if (card.multiverseid != null) System.out.println("\tMID: " + card.multiverseid); + if (card.artist != null) System.out.println("\tIllus. " + card.artist); + } + + private static void printGlance(Card card) { + System.out.println(String.format("%1$-4d %2$s (%3$s, %4$s)", card.count, card.name, card.setCode, card.number)); + } } -- cgit v1.2.3