mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Custom printsheets implemented
CardPool deserialization moved to cardpool as factory method.
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -15,6 +15,7 @@ res/blockdata/blocks.txt svneol=native#text/plain
|
|||||||
res/blockdata/fantasyblocks.txt -text
|
res/blockdata/fantasyblocks.txt -text
|
||||||
res/blockdata/fatpacks.txt -text
|
res/blockdata/fatpacks.txt -text
|
||||||
res/blockdata/formats.txt -text
|
res/blockdata/formats.txt -text
|
||||||
|
res/blockdata/printsheets.txt -text
|
||||||
res/blockdata/setdata.txt svneol=native#text/plain
|
res/blockdata/setdata.txt svneol=native#text/plain
|
||||||
res/blockdata/starters.txt -text
|
res/blockdata/starters.txt -text
|
||||||
res/cardsfolder/a/a_display_of_my_dark_power.txt -text
|
res/cardsfolder/a/a_display_of_my_dark_power.txt -text
|
||||||
@@ -14418,6 +14419,7 @@ src/main/java/forge/util/storage/IStorage.java -text
|
|||||||
src/main/java/forge/util/storage/IStorageView.java -text
|
src/main/java/forge/util/storage/IStorageView.java -text
|
||||||
src/main/java/forge/util/storage/StorageImmediatelySerialized.java svneol=native#text/plain
|
src/main/java/forge/util/storage/StorageImmediatelySerialized.java svneol=native#text/plain
|
||||||
src/main/java/forge/util/storage/StorageReaderFile.java -text
|
src/main/java/forge/util/storage/StorageReaderFile.java -text
|
||||||
|
src/main/java/forge/util/storage/StorageReaderFileSections.java -text
|
||||||
src/main/java/forge/util/storage/StorageReaderFolder.java -text
|
src/main/java/forge/util/storage/StorageReaderFolder.java -text
|
||||||
src/main/java/forge/util/storage/StorageView.java -text
|
src/main/java/forge/util/storage/StorageView.java -text
|
||||||
src/main/java/forge/util/storage/package-info.java -text
|
src/main/java/forge/util/storage/package-info.java -text
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ CFX: 3 covers, 10 Common, 3 Uncommon, 1 Rare, 1 BasicLand ALA
|
|||||||
CHK: 5 covers, 11 Common, 3 Uncommon, 1 Rare
|
CHK: 5 covers, 11 Common, 3 Uncommon, 1 Rare
|
||||||
CHR: 1 covers, 9 Common, 3 UncommonRare
|
CHR: 1 covers, 9 Common, 3 UncommonRare
|
||||||
CSP: 3 covers, 11 Common, 3 Uncommon, 1 Rare
|
CSP: 3 covers, 11 Common, 3 Uncommon, 1 Rare
|
||||||
DGM: 3 covers, 10 Common, 3 Uncommon, 1 Rare:!name("Maze's End"), 1 MazeLand
|
DGM: 3 covers, 10 Common, 3 Uncommon, 1 Rare:!name("Maze's End"), 1 Custom("Dragon's Maze Lands")
|
||||||
DIS: 3 covers, 11 Common, 3 Uncommon, 1 Rare
|
DIS: 3 covers, 11 Common, 3 Uncommon, 1 Rare
|
||||||
DKA: 3 covers, 9 Common:!dfc, 3 Uncommon:!dfc, 1 Rare:!dfc, 1 Any:dfc, 1 BasicLand ISD
|
DKA: 3 covers, 9 Common:!dfc, 3 Uncommon:!dfc, 1 Rare:!dfc, 1 Any:dfc, 1 BasicLand ISD
|
||||||
DRK: 1 covers, 6 Common, 2 UncommonRare
|
DRK: 1 covers, 6 Common, 2 UncommonRare
|
||||||
|
|||||||
23
res/blockdata/printsheets.txt
Normal file
23
res/blockdata/printsheets.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
[Dragon's Maze Lands]
|
||||||
|
# Uncomment all after DGM set is added to setdata.txt
|
||||||
|
#10 Azorius Guildgate|DGM
|
||||||
|
#10 Boros Guildgate|DGM
|
||||||
|
#10 Dimir Guildgate|DGM
|
||||||
|
#10 Golgari Guildgate|DGM
|
||||||
|
#10 Gruul Guildgate|DGM
|
||||||
|
#10 Izzet Guildgate|DGM
|
||||||
|
#10 Orzhov Guildgate|DGM
|
||||||
|
#10 Rakdos Guildgate|DGM
|
||||||
|
#10 Selesnya Guildgate|DGM
|
||||||
|
#10 Simic Guildgate|DGM
|
||||||
|
2 Blood Crypt|RTR
|
||||||
|
2 Hallowed Fountain|RTR
|
||||||
|
2 Overgrown Tomb|RTR
|
||||||
|
2 Steam Vents|RTR
|
||||||
|
2 Temple Garden|RTR
|
||||||
|
2 Breeding Pool|GTC
|
||||||
|
2 Godless Shrine|GTC
|
||||||
|
2 Sacred Foundry|GTC
|
||||||
|
2 Stomping Ground|GTC
|
||||||
|
2 Watery Grave|GTC
|
||||||
|
#1 Maze's End|DGM
|
||||||
@@ -31,10 +31,12 @@ import com.google.common.base.Predicates;
|
|||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import forge.Singletons;
|
||||||
import forge.item.CardDb;
|
import forge.item.CardDb;
|
||||||
import forge.item.CardPrinted;
|
import forge.item.CardPrinted;
|
||||||
import forge.item.IPaperCard;
|
import forge.item.IPaperCard;
|
||||||
import forge.item.PrintSheet;
|
import forge.item.PrintSheet;
|
||||||
|
import forge.model.FModel;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,7 +88,7 @@ public class BoosterGenerator {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static final PrintSheet makeSheet(String sheetKey, Iterable<CardPrinted> src) {
|
private static final PrintSheet makeSheet(String sheetKey, Iterable<CardPrinted> src) {
|
||||||
PrintSheet ps = new PrintSheet();
|
PrintSheet ps = new PrintSheet(sheetKey);
|
||||||
String[] sKey = TextUtil.splitWithParenthesis(sheetKey, ' ', '(', ')', 2);
|
String[] sKey = TextUtil.splitWithParenthesis(sheetKey, ' ', '(', ')', 2);
|
||||||
|
|
||||||
String[] operators = TextUtil.splitWithParenthesis(sKey[0], ':', '(', ')');
|
String[] operators = TextUtil.splitWithParenthesis(sKey[0], ':', '(', ')');
|
||||||
@@ -148,8 +150,9 @@ public class BoosterGenerator {
|
|||||||
Predicate<CardPrinted> predicate = Predicates.and( setPred, IPaperCard.Predicates.Presets.IS_SPECIAL, extraPred );
|
Predicate<CardPrinted> predicate = Predicates.and( setPred, IPaperCard.Predicates.Presets.IS_SPECIAL, extraPred );
|
||||||
ps.addAll(Iterables.filter(src, predicate));
|
ps.addAll(Iterables.filter(src, predicate));
|
||||||
|
|
||||||
} else if ( mainCode.equalsIgnoreCase("mazeland") ) {
|
} else if ( mainCode.equalsIgnoreCase("custom(") ) {
|
||||||
|
String sheetName = StringUtils.strip(mainCode.substring(6), "()\" ");
|
||||||
|
return Singletons.getModel().getPrintSheets().get(sheetName);
|
||||||
}
|
}
|
||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,15 @@
|
|||||||
*/
|
*/
|
||||||
package forge.deck;
|
package forge.deck;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.item.CardDb;
|
import forge.item.CardDb;
|
||||||
import forge.item.CardPrinted;
|
import forge.item.CardPrinted;
|
||||||
@@ -49,19 +54,6 @@ public class CardPool extends ItemPool<CardPrinted> {
|
|||||||
this.addAll(cards);
|
this.addAll(cards);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the.
|
|
||||||
*
|
|
||||||
* @param cardNames
|
|
||||||
* the card names
|
|
||||||
*/
|
|
||||||
public void set(final Iterable<String> cardNames) {
|
|
||||||
this.clear();
|
|
||||||
for (final String name : cardNames) {
|
|
||||||
this.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the.
|
* Adds the.
|
||||||
*
|
*
|
||||||
@@ -131,13 +123,13 @@ public class CardPool extends ItemPool<CardPrinted> {
|
|||||||
*
|
*
|
||||||
* @param cardName the card name
|
* @param cardName the card name
|
||||||
*/
|
*/
|
||||||
public void add(final String cardName) {
|
public void add(final String cardName, int cnt) {
|
||||||
CardPrinted cp = CardDb.instance().tryGetCard(cardName);
|
CardPrinted cp = CardDb.instance().tryGetCard(cardName);
|
||||||
if ( cp == null )
|
if ( cp == null )
|
||||||
cp = CardDb.variants().tryGetCard(cardName);
|
cp = CardDb.variants().tryGetCard(cardName);
|
||||||
|
|
||||||
if ( cp != null)
|
if ( cp != null)
|
||||||
this.add(cp);
|
this.add(cp, cnt);
|
||||||
else
|
else
|
||||||
throw new NoSuchElementException(String.format("Card %s is not supported by Forge, as it's neither a known common card nor one of casual variants' card.", cardName));
|
throw new NoSuchElementException(String.format("Card %s is not supported by Forge, as it's neither a known common card nor one of casual variants' card.", cardName));
|
||||||
}
|
}
|
||||||
@@ -171,4 +163,32 @@ public class CardPool extends ItemPool<CardPrinted> {
|
|||||||
}
|
}
|
||||||
return sb.append(']').toString();
|
return sb.append(']').toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static CardPool fromCardList(final Iterable<String> lines) {
|
||||||
|
CardPool pool = new CardPool();
|
||||||
|
final Pattern p = Pattern.compile("((\\d+)\\s+)?(.*?)");
|
||||||
|
|
||||||
|
if (lines == null) {
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Iterator<String> lineIterator = lines.iterator();
|
||||||
|
while (lineIterator.hasNext()) {
|
||||||
|
final String line = lineIterator.next();
|
||||||
|
if (line.startsWith(";") || line.startsWith("#")) { continue; } // that is a comment or not-yet-supported card
|
||||||
|
|
||||||
|
final Matcher m = p.matcher(line.trim());
|
||||||
|
m.matches();
|
||||||
|
final String sCnt = m.group(2);
|
||||||
|
final String cardName = m.group(3);
|
||||||
|
if (StringUtils.isBlank(cardName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int count = sCnt == null ? 1 : Integer.parseInt(sCnt);
|
||||||
|
pool.add(cardName, count);
|
||||||
|
}
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,6 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
@@ -185,9 +182,7 @@ public class Deck extends DeckBase implements Iterable<Entry<DeckSection, CardPo
|
|||||||
if ( null == sec )
|
if ( null == sec )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CardPool pool = new CardPool();
|
CardPool pool = CardPool.fromCardList(s.getValue());
|
||||||
pool.set(Deck.readCardList(s.getValue()));
|
|
||||||
|
|
||||||
// I used to store planes and schemes under sideboard header, so this will assign them to a correct section
|
// I used to store planes and schemes under sideboard header, so this will assign them to a correct section
|
||||||
IPaperCard sample = pool.get(0);
|
IPaperCard sample = pool.get(0);
|
||||||
if ( sample != null && ( sample.getRules().getType().isPlane() || sample.getRules().getType().isPhenomenon() ) )
|
if ( sample != null && ( sample.getRules().getType().isPlane() || sample.getRules().getType().isPhenomenon() ) )
|
||||||
@@ -200,34 +195,7 @@ public class Deck extends DeckBase implements Iterable<Entry<DeckSection, CardPo
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> readCardList(final List<String> lines) {
|
|
||||||
final List<String> result = new ArrayList<String>();
|
|
||||||
final Pattern p = Pattern.compile("((\\d+)\\s+)?(.*?)");
|
|
||||||
|
|
||||||
if (lines == null) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Iterator<String> lineIterator = lines.iterator();
|
|
||||||
while (lineIterator.hasNext()) {
|
|
||||||
final String line = lineIterator.next();
|
|
||||||
if (line.startsWith(";") || line.startsWith("#")) { continue; } // that is a comment or not-yet-supported card
|
|
||||||
|
|
||||||
final Matcher m = p.matcher(line.trim());
|
|
||||||
m.matches();
|
|
||||||
final String sCnt = m.group(2);
|
|
||||||
final String cardName = m.group(3);
|
|
||||||
if (StringUtils.isBlank(cardName)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int count = sCnt == null ? 1 : Integer.parseInt(sCnt);
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
result.add(cardName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<String> writeCardPool(final ItemPoolView<CardPrinted> pool) {
|
private static List<String> writeCardPool(final ItemPoolView<CardPrinted> pool) {
|
||||||
final List<Entry<CardPrinted, Integer>> main2sort = pool.getOrderedList();
|
final List<Entry<CardPrinted, Integer>> main2sort = pool.getOrderedList();
|
||||||
|
|||||||
@@ -84,12 +84,12 @@ public enum CDeckgen implements ICDoc {
|
|||||||
Iterable<CardPrinted> source = Iterables.filter(CardDb.instance().getUniqueCards(), notBasicLand);
|
Iterable<CardPrinted> source = Iterables.filter(CardDb.instance().getUniqueCards(), notBasicLand);
|
||||||
randomDeck.getMain().addAllFlat(Aggregates.random(source, 15 * 5));
|
randomDeck.getMain().addAllFlat(Aggregates.random(source, 15 * 5));
|
||||||
|
|
||||||
randomDeck.getMain().add("Plains");
|
randomDeck.getMain().add("Plains", 1);
|
||||||
randomDeck.getMain().add("Island");
|
randomDeck.getMain().add("Island", 1);
|
||||||
randomDeck.getMain().add("Swamp");
|
randomDeck.getMain().add("Swamp", 1);
|
||||||
randomDeck.getMain().add("Mountain");
|
randomDeck.getMain().add("Mountain", 1);
|
||||||
randomDeck.getMain().add("Forest");
|
randomDeck.getMain().add("Forest", 1);
|
||||||
randomDeck.getMain().add("Terramorphic Expanse");
|
randomDeck.getMain().add("Terramorphic Expanse", 1);
|
||||||
|
|
||||||
final ACEditorBase<TItem, TModel> ed = (ACEditorBase<TItem, TModel>)
|
final ACEditorBase<TItem, TModel> ed = (ACEditorBase<TItem, TModel>)
|
||||||
CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController();
|
CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController();
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
package forge.item;
|
package forge.item;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
import forge.deck.CardPool;
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
|
import forge.util.storage.StorageReaderFileSections;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,9 +18,24 @@ import forge.util.MyRandom;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class PrintSheet {
|
public class PrintSheet {
|
||||||
private final ItemPool<CardPrinted> cardsWithWeights = new ItemPool<CardPrinted>(CardPrinted.class);
|
public static final Function<PrintSheet, String> FN_GET_KEY = new Function<PrintSheet, String>() {
|
||||||
|
@Override public final String apply(PrintSheet sheet) { return sheet.name; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private final ItemPool<CardPrinted> cardsWithWeights;
|
||||||
|
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
public PrintSheet(String name0) {
|
||||||
|
this(name0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PrintSheet(String name0, ItemPool<CardPrinted> pool) {
|
||||||
|
name = name0;
|
||||||
|
cardsWithWeights = pool != null ? pool : new ItemPool<CardPrinted>(CardPrinted.class);
|
||||||
|
}
|
||||||
|
|
||||||
public void add(CardPrinted card) {
|
public void add(CardPrinted card) {
|
||||||
add(card,1);
|
add(card,1);
|
||||||
}
|
}
|
||||||
@@ -67,5 +88,16 @@ public class PrintSheet {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Reader extends StorageReaderFileSections<PrintSheet> {
|
||||||
|
public Reader(String fileName) {
|
||||||
|
super(fileName, PrintSheet.FN_GET_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PrintSheet read(String title, Iterable<String> body, int idx) {
|
||||||
|
return new PrintSheet(title, CardPool.fromCardList(body));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import forge.game.MatchController;
|
|||||||
import forge.game.limited.GauntletMini;
|
import forge.game.limited.GauntletMini;
|
||||||
import forge.gauntlet.GauntletData;
|
import forge.gauntlet.GauntletData;
|
||||||
import forge.item.CardDb;
|
import forge.item.CardDb;
|
||||||
|
import forge.item.PrintSheet;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
import forge.properties.NewConstants;
|
import forge.properties.NewConstants;
|
||||||
@@ -89,6 +90,7 @@ public enum FModel {
|
|||||||
private final IStorageView<CardBlock> blocks;
|
private final IStorageView<CardBlock> blocks;
|
||||||
private final IStorageView<CardBlock> fantasyBlocks;
|
private final IStorageView<CardBlock> fantasyBlocks;
|
||||||
private final IStorageView<QuestWorld> worlds;
|
private final IStorageView<QuestWorld> worlds;
|
||||||
|
private final IStorageView<PrintSheet> printSheets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@@ -170,6 +172,8 @@ public enum FModel {
|
|||||||
|
|
||||||
this.decks = new CardCollections();
|
this.decks = new CardCollections();
|
||||||
this.quest = new QuestController();
|
this.quest = new QuestController();
|
||||||
|
|
||||||
|
this.printSheets = new StorageView<PrintSheet>(new PrintSheet.Reader("res/blockdata/printsheets.txt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final QuestController getQuest() {
|
public final QuestController getQuest() {
|
||||||
@@ -373,6 +377,10 @@ public enum FModel {
|
|||||||
return boosters;
|
return boosters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IStorageView<PrintSheet> getPrintSheets() {
|
||||||
|
return printSheets;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this method.
|
* TODO: Write javadoc for this method.
|
||||||
* @param data0 {@link forge.gauntlet.GauntletData}
|
* @param data0 {@link forge.gauntlet.GauntletData}
|
||||||
@@ -392,4 +400,6 @@ public enum FModel {
|
|||||||
}
|
}
|
||||||
return gauntlet;
|
return gauntlet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
136
src/main/java/forge/util/storage/StorageReaderFileSections.java
Normal file
136
src/main/java/forge/util/storage/StorageReaderFileSections.java
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Nate
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.util.storage;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
import forge.util.FileUtil;
|
||||||
|
import forge.util.IItemReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class treats every line of a given file as a source for a named object.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* the generic type
|
||||||
|
*/
|
||||||
|
public abstract class StorageReaderFileSections<T> implements IItemReader<T> {
|
||||||
|
|
||||||
|
private final File file;
|
||||||
|
private final Function<? super T, String> keySelector;
|
||||||
|
|
||||||
|
public StorageReaderFileSections(final String pathname, final Function<? super T, String> keySelector0) {
|
||||||
|
this(new File(pathname), keySelector0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StorageReaderFileSections(final File file0, final Function<? super T, String> keySelector0) {
|
||||||
|
this.file = file0;
|
||||||
|
this.keySelector = keySelector0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.util.IItemReader#readAll()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, T> readAll() {
|
||||||
|
final Map<String, T> result = new TreeMap<String, T>();
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
Iterable<String> file = FileUtil.readFile(this.file);
|
||||||
|
|
||||||
|
List<String> accumulator = new ArrayList<String>();
|
||||||
|
String header = null;
|
||||||
|
|
||||||
|
for (final String s : file) {
|
||||||
|
if (!this.lineContainsObject(s)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(s.charAt(0) == '[') {
|
||||||
|
if( header != null ) {
|
||||||
|
// read previously collected item
|
||||||
|
T item = readItem(header, accumulator, idx);
|
||||||
|
if( item != null ) {
|
||||||
|
result.put(this.keySelector.apply(item), item);
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header = StringUtils.strip(s, "[] ");
|
||||||
|
accumulator.clear();
|
||||||
|
} else
|
||||||
|
accumulator.add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the last item
|
||||||
|
if ( !accumulator.isEmpty() ) {
|
||||||
|
T item = readItem(header, accumulator, idx);
|
||||||
|
if( item != null ) {
|
||||||
|
result.put(this.keySelector.apply(item), item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final T readItem(String header, Iterable<String> accumulator, int idx) {
|
||||||
|
final T item = this.read(header, accumulator, idx);
|
||||||
|
if (null != item) return item;
|
||||||
|
|
||||||
|
final String msg = "An object stored in " + this.file.getPath() + " failed to load.\nPlease submit this as a bug with the mentioned file attached.";
|
||||||
|
JOptionPane.showMessageDialog(null, msg);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
*
|
||||||
|
* @param line
|
||||||
|
* the line
|
||||||
|
* @return the t
|
||||||
|
*/
|
||||||
|
protected abstract T read(String title, Iterable<String> body, int idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Line contains object.
|
||||||
|
*
|
||||||
|
* @param line
|
||||||
|
* the line
|
||||||
|
* @return true, if successful
|
||||||
|
*/
|
||||||
|
protected boolean lineContainsObject(final String line) {
|
||||||
|
return !StringUtils.isBlank(line) && !line.trim().startsWith("#");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.util.IItemReader#getItemKey(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getItemKey(final T item) {
|
||||||
|
return this.keySelector.apply(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user