From 0ea73b19df2ea30a00d679a5aee5008141afac0d Mon Sep 17 00:00:00 2001 From: John Hitchings Date: Sun, 17 Mar 2019 14:28:14 -0700 Subject: [PATCH] Refactor Sets.saveDeck into a deck exporter series of classes. --- .../deck/generator/DeckGeneratorDialog.java | 5 +- .../client/deckeditor/DeckEditorPanel.java | 8 +- Mage/src/main/java/mage/cards/Sets.java | 74 --------------- .../java/mage/cards/decks/DeckFormats.java | 90 +++++++++++++++++++ .../cards/decks/exporter/DckExporter.java | 82 +++++++++++++++++ .../cards/decks/exporter/DeckExporter.java | 24 +++++ .../cards/decks/exporter/MtgoExporter.java | 43 +++++++++ .../cards/decks/exporter/DckExporterTest.java | 32 +++++++ .../decks/exporter/MtgoExporterTest.java | 32 +++++++ 9 files changed, 310 insertions(+), 80 deletions(-) create mode 100644 Mage/src/main/java/mage/cards/decks/DeckFormats.java create mode 100644 Mage/src/main/java/mage/cards/decks/exporter/DckExporter.java create mode 100644 Mage/src/main/java/mage/cards/decks/exporter/DeckExporter.java create mode 100644 Mage/src/main/java/mage/cards/decks/exporter/MtgoExporter.java create mode 100644 Mage/src/test/java/mage/cards/decks/exporter/DckExporterTest.java create mode 100644 Mage/src/test/java/mage/cards/decks/exporter/MtgoExporterTest.java diff --git a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorDialog.java b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorDialog.java index a16607fa29..1665bc2309 100644 --- a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorDialog.java +++ b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorDialog.java @@ -11,7 +11,6 @@ import javax.swing.*; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.EtchedBorder; -import mage.cards.Sets; import mage.cards.decks.Deck; import mage.client.MageFrame; import mage.client.dialog.PreferencesDialog; @@ -19,6 +18,8 @@ import mage.client.util.gui.ColorsChooser; import mage.client.util.gui.FastSearchUtil; import mage.client.util.sets.ConstructedFormats; +import static mage.cards.decks.DeckFormats.DCK; + /** * * @author Simown @@ -328,7 +329,7 @@ public class DeckGeneratorDialog { tmp.getParentFile().mkdirs(); tmp.createNewFile(); deck.setName(deckName); - Sets.saveDeck(tmp.getAbsolutePath(), deck.getDeckCardLists()); + DCK.getExporter().writeDeck(tmp.getAbsolutePath(), deck.getDeckCardLists()); cleanUp(); return tmp.getAbsolutePath(); } catch (Exception e) { diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index d0c6d7c6df..48175a54cb 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -1,7 +1,6 @@ package mage.client.deckeditor; import mage.cards.Card; -import mage.cards.Sets; import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; import mage.cards.decks.DnDDeckTargetListener; @@ -35,12 +34,13 @@ import java.awt.*; import java.awt.dnd.DropTarget; import java.awt.event.*; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.List; import java.util.*; import java.util.concurrent.*; +import static mage.cards.decks.DeckFormats.DCK; + /** * @author BetaSteward_at_googlemail.com */ @@ -965,8 +965,8 @@ public class DeckEditorPanel extends javax.swing.JPanel { DeckCardLists cardLists = deck.getDeckCardLists(); cardLists.setCardLayout(deckArea.getCardLayout()); cardLists.setSideboardLayout(deckArea.getSideboardLayout()); - Sets.saveDeck(fileName, cardLists); - } catch (FileNotFoundException ex) { + DCK.getExporter().writeDeck(fileName, cardLists); + } catch (IOException ex) { JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage() + "\nTry ensuring that the selected directory is writable.", "Error saving deck", JOptionPane.ERROR_MESSAGE); } finally { MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); diff --git a/Mage/src/main/java/mage/cards/Sets.java b/Mage/src/main/java/mage/cards/Sets.java index 741acfd59c..1c3bde2f14 100644 --- a/Mage/src/main/java/mage/cards/Sets.java +++ b/Mage/src/main/java/mage/cards/Sets.java @@ -1,9 +1,6 @@ package mage.cards; import mage.Mana; -import mage.cards.decks.DeckCardInfo; -import mage.cards.decks.DeckCardLayout; -import mage.cards.decks.DeckCardLists; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; @@ -16,8 +13,6 @@ import mage.util.RandomUtil; import org.apache.log4j.Logger; import org.junit.Assert; -import java.io.FileNotFoundException; -import java.io.PrintWriter; import java.util.*; /** @@ -205,73 +200,4 @@ public class Sets extends HashMap { return null; } - public static void saveDeck(String file, DeckCardLists deck) throws FileNotFoundException { - Map deckCards = new HashMap<>(); - Map sideboard = new HashMap<>(); - try (PrintWriter out = new PrintWriter(file)) { - if (deck.getName() != null && !deck.getName().isEmpty()) { - out.println("NAME:" + deck.getName()); - } - if (deck.getAuthor() != null && !deck.getAuthor().isEmpty()) { - out.println("AUTHOR:" + deck.getAuthor()); - } - for (DeckCardInfo deckCardInfo : deck.getCards()) { - if (deckCards.containsKey(deckCardInfo.getCardKey())) { - deckCards.put(deckCardInfo.getCardKey(), deckCards.get(deckCardInfo.getCardKey()).increaseQuantity()); - } else { - deckCards.put(deckCardInfo.getCardKey(), deckCardInfo); - } - } - - for (DeckCardInfo deckCardInfo : deck.getSideboard()) { - if (sideboard.containsKey(deckCardInfo.getCardKey())) { - sideboard.put(deckCardInfo.getCardKey(), sideboard.get(deckCardInfo.getCardKey()).increaseQuantity()); - } else { - sideboard.put(deckCardInfo.getCardKey(), deckCardInfo); - } - } - - // Write out all of the cards - for (Entry entry : deckCards.entrySet()) { - out.printf("%d [%s:%s] %s%n", entry.getValue().getQuantity(), entry.getValue().getSetCode(), entry.getValue().getCardNum(), entry.getValue().getCardName()); - } - for (Entry entry : sideboard.entrySet()) { - out.printf("SB: %d [%s:%s] %s%n", entry.getValue().getQuantity(), entry.getValue().getSetCode(), entry.getValue().getCardNum(), entry.getValue().getCardName()); - } - - // Write out the layout - out.print("LAYOUT MAIN:"); - writeCardLayout(out, deck.getCardLayout()); - out.print("\n"); - out.print("LAYOUT SIDEBOARD:"); - writeCardLayout(out, deck.getSideboardLayout()); - out.print("\n"); - } - } - - private static void writeCardLayout(PrintWriter out, DeckCardLayout layout) { - if (layout == null) { - return; - } - List>> cardGrid = layout.getCards(); - int height = cardGrid.size(); - int width = (height > 0) ? cardGrid.get(0).size() : 0; - out.print("(" + height + ',' + width + ')'); - out.print(layout.getSettings()); - out.print("|"); - for (List> row : cardGrid) { - for (List stack : row) { - out.print("("); - for (int i = 0; i < stack.size(); ++i) { - DeckCardInfo info = stack.get(i); - out.printf("[%s:%s]", info.getSetCode(), info.getCardNum()); - if (i != stack.size() - 1) { - out.print(","); - } - } - out.print(")"); - } - } - } - } diff --git a/Mage/src/main/java/mage/cards/decks/DeckFormats.java b/Mage/src/main/java/mage/cards/decks/DeckFormats.java new file mode 100644 index 0000000000..272baf4956 --- /dev/null +++ b/Mage/src/main/java/mage/cards/decks/DeckFormats.java @@ -0,0 +1,90 @@ +package mage.cards.decks; + +import mage.cards.decks.exporter.DckExporter; +import mage.cards.decks.exporter.DeckExporter; +import mage.cards.decks.exporter.MtgoExporter; + +import java.io.*; +import java.util.Optional; + +public enum DeckFormats { + + DCK(new DckExporter()), + MTGO(new MtgoExporter()); + + private final DeckExporter exporter; + + DeckFormats(DeckExporter exporter) { + this.exporter = exporter; + } + + public DeckExporter getExporter() { + return exporter; + } + + public static Optional getFormatForExtension(String filename) { + return getExtension(filename).map(c -> { + try { + return DeckFormats.valueOf(c); + } catch (IllegalArgumentException e) { + return null; + } + }); + } + + public static Optional getExtension(String filename) { + int i = filename.lastIndexOf('.'); + if (i > 0) { + return Optional.of(filename.substring(i+1).toUpperCase()); + } else { + return Optional.empty(); + } + } + + public static void writeDeck(String file, DeckCardLists deck) throws IOException { + writeDeck(new File(file), deck); + } + + public static void writeDeck(String file, DeckCardLists deck, DeckFormats format) throws IOException { + writeDeck(new File(file), deck, format); + } + + public static void writeDeck(String file, DeckCardLists deck, DeckExporter exporter) throws IOException { + writeDeck(new File(file), deck, exporter); + } + + public static void writeDeck(File file, DeckCardLists deck) throws IOException { + DeckFormats format = DeckFormats.getFormatForExtension(file.getName()).orElseGet(() -> { + throw new IllegalArgumentException("Could not determine deck export format."); + }); + writeDeck(file, deck, format); + } + + public static void writeDeck(File file, DeckCardLists deck, DeckFormats format) throws IOException { + writeDeck(file, deck, format.getExporter()); + } + + public static void writeDeck(File file, DeckCardLists deck, DeckExporter exporter) throws IOException { + try (FileOutputStream out = new FileOutputStream(file)){ + writeDeck(out, deck, exporter); + } + } + + public static void writeDeck(OutputStream out, DeckCardLists deck, DeckFormats format) { + writeDeck(new PrintWriter(out), deck, format); + } + + public static void writeDeck(OutputStream out, DeckCardLists deck, DeckExporter exporter) { + writeDeck(new PrintWriter(out), deck, exporter); + } + + public static void writeDeck(PrintWriter out, DeckCardLists deck, DeckFormats format) { + writeDeck(out, deck, format.getExporter()); + } + + public static void writeDeck(PrintWriter out, DeckCardLists deck, DeckExporter exporter) { + exporter.writeDeck(out, deck); + out.flush(); + } + +} diff --git a/Mage/src/main/java/mage/cards/decks/exporter/DckExporter.java b/Mage/src/main/java/mage/cards/decks/exporter/DckExporter.java new file mode 100644 index 0000000000..3d673e7eb8 --- /dev/null +++ b/Mage/src/main/java/mage/cards/decks/exporter/DckExporter.java @@ -0,0 +1,82 @@ +package mage.cards.decks.exporter; + +import mage.cards.decks.DeckCardInfo; +import mage.cards.decks.DeckCardLayout; +import mage.cards.decks.DeckCardLists; + +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DckExporter extends DeckExporter { + + public void writeDeck(PrintWriter out, DeckCardLists deck) { + Map deckCards = new HashMap<>(); + Map sideboard = new HashMap<>(); + + if (deck.getName() != null && !deck.getName().isEmpty()) { + out.println("NAME:" + deck.getName()); + } + if (deck.getAuthor() != null && !deck.getAuthor().isEmpty()) { + out.println("AUTHOR:" + deck.getAuthor()); + } + for (DeckCardInfo deckCardInfo : deck.getCards()) { + if (deckCards.containsKey(deckCardInfo.getCardKey())) { + deckCards.put(deckCardInfo.getCardKey(), deckCards.get(deckCardInfo.getCardKey()).increaseQuantity()); + } else { + deckCards.put(deckCardInfo.getCardKey(), deckCardInfo); + } + } + + for (DeckCardInfo deckCardInfo : deck.getSideboard()) { + if (sideboard.containsKey(deckCardInfo.getCardKey())) { + sideboard.put(deckCardInfo.getCardKey(), sideboard.get(deckCardInfo.getCardKey()).increaseQuantity()); + } else { + sideboard.put(deckCardInfo.getCardKey(), deckCardInfo); + } + } + + // Write out all of the cards + for (Map.Entry entry : deckCards.entrySet()) { + out.printf("%d [%s:%s] %s%n", entry.getValue().getQuantity(), entry.getValue().getSetCode(), entry.getValue().getCardNum(), entry.getValue().getCardName()); + } + for (Map.Entry entry : sideboard.entrySet()) { + out.printf("SB: %d [%s:%s] %s%n", entry.getValue().getQuantity(), entry.getValue().getSetCode(), entry.getValue().getCardNum(), entry.getValue().getCardName()); + } + + // Write out the layout + out.print("LAYOUT MAIN:"); + writeCardLayout(out, deck.getCardLayout()); + out.print("\n"); + out.print("LAYOUT SIDEBOARD:"); + writeCardLayout(out, deck.getSideboardLayout()); + out.print("\n"); + } + + private static void writeCardLayout(PrintWriter out, DeckCardLayout layout) { + if (layout == null) { + return; + } + List>> cardGrid = layout.getCards(); + int height = cardGrid.size(); + int width = (height > 0) ? cardGrid.get(0).size() : 0; + out.print("(" + height + ',' + width + ')'); + out.print(layout.getSettings()); + out.print("|"); + for (List> row : cardGrid) { + for (List stack : row) { + out.print("("); + for (int i = 0; i < stack.size(); ++i) { + DeckCardInfo info = stack.get(i); + out.printf("[%s:%s]", info.getSetCode(), info.getCardNum()); + if (i != stack.size() - 1) { + out.print(","); + } + } + out.print(")"); + } + } + } + +} diff --git a/Mage/src/main/java/mage/cards/decks/exporter/DeckExporter.java b/Mage/src/main/java/mage/cards/decks/exporter/DeckExporter.java new file mode 100644 index 0000000000..57960bef3a --- /dev/null +++ b/Mage/src/main/java/mage/cards/decks/exporter/DeckExporter.java @@ -0,0 +1,24 @@ +package mage.cards.decks.exporter; + +import mage.cards.decks.DeckCardLists; +import mage.cards.decks.DeckFormats; + +import java.io.*; + +public abstract class DeckExporter { + + public void writeDeck(String file, DeckCardLists deck) throws IOException { + DeckFormats.writeDeck(file, deck, this); + } + + public void writeDeck(File file, DeckCardLists deck) throws IOException { + DeckFormats.writeDeck(file, deck, this); + } + + public void writeDeck(OutputStream out, DeckCardLists deck) { + DeckFormats.writeDeck(out, deck, this); + } + + public abstract void writeDeck(PrintWriter out, DeckCardLists deck); + +} diff --git a/Mage/src/main/java/mage/cards/decks/exporter/MtgoExporter.java b/Mage/src/main/java/mage/cards/decks/exporter/MtgoExporter.java new file mode 100644 index 0000000000..41d3e39139 --- /dev/null +++ b/Mage/src/main/java/mage/cards/decks/exporter/MtgoExporter.java @@ -0,0 +1,43 @@ +package mage.cards.decks.exporter; + +import mage.cards.decks.DeckCardInfo; +import mage.cards.decks.DeckCardLists; + +import java.io.PrintWriter; +import java.util.List; +import java.util.TreeMap; + +public class MtgoExporter extends DeckExporter { + + @Override + public void writeDeck(PrintWriter out, DeckCardLists deck) { + TreeMap deckCards = toCardMap(deck.getCards()); + TreeMap sideboard = toCardMap(deck.getSideboard()); + deckCards.forEach((name, count) -> { + out.print(count); + out.print(' '); + out.println(name); + }); + + out.println(); + out.println(); + + sideboard.forEach((name, count) -> { + out.print(count); + out.print(' '); + out.println(name); + }); + + out.println(); + } + + private TreeMap toCardMap(List cards) { + TreeMap counts = new TreeMap<>(); + for (DeckCardInfo card : cards) { + int count = counts.getOrDefault(card.getCardName(), 0) + card.getQuantity(); + counts.put(card.getCardName(), count); + } + return counts; + } + +} diff --git a/Mage/src/test/java/mage/cards/decks/exporter/DckExporterTest.java b/Mage/src/test/java/mage/cards/decks/exporter/DckExporterTest.java new file mode 100644 index 0000000000..d1b843dbec --- /dev/null +++ b/Mage/src/test/java/mage/cards/decks/exporter/DckExporterTest.java @@ -0,0 +1,32 @@ +package mage.cards.decks.exporter; + +import mage.cards.decks.DeckCardInfo; +import mage.cards.decks.DeckCardLists; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class DckExporterTest { + + @Test + public void writeDeck() throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DeckCardLists deck = new DeckCardLists(); + deck.getCards().add(new DeckCardInfo("Forest", "RNA", "1", 2)); + deck.getCards().add(new DeckCardInfo("Plains", "RNA", "2", 3)); + deck.getSideboard().add(new DeckCardInfo("Island", "RNA", "3", 2)); + DckExporter exporter = new DckExporter(); + exporter.writeDeck(baos, deck); + assertEquals( + "2 [1:RNA] Forest\n" + + "3 [2:RNA] Plains\n" + + "SB: 2 [3:RNA] Island\n" + + "LAYOUT MAIN:\n" + + "LAYOUT SIDEBOARD:\n", + new String(baos.toByteArray())); + } + +} \ No newline at end of file diff --git a/Mage/src/test/java/mage/cards/decks/exporter/MtgoExporterTest.java b/Mage/src/test/java/mage/cards/decks/exporter/MtgoExporterTest.java new file mode 100644 index 0000000000..de3681c0bd --- /dev/null +++ b/Mage/src/test/java/mage/cards/decks/exporter/MtgoExporterTest.java @@ -0,0 +1,32 @@ +package mage.cards.decks.exporter; + +import mage.cards.decks.DeckCardInfo; +import mage.cards.decks.DeckCardLists; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class MtgoExporterTest { + + @Test + public void writeDeck() throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DeckCardLists deck = new DeckCardLists(); + deck.getCards().add(new DeckCardInfo("Forest", "RNA", "1", 2)); + deck.getCards().add(new DeckCardInfo("Plains", "RNA", "2", 3)); + deck.getSideboard().add(new DeckCardInfo("Island", "RNA", "3", 2)); + MtgoExporter exporter = new MtgoExporter(); + exporter.writeDeck(baos, deck); + assertEquals( + "2 Forest\n" + + "3 Plains\n" + + "\n" + + "\n" + + "2 Island\n" + + "\n", new String(baos.toByteArray())); + } + +} \ No newline at end of file