Support setting directory for newly created decks by adding fullPath to StorageBase

This commit is contained in:
drdev
2015-10-04 21:59:20 +00:00
parent c6d81ed4cd
commit 8c49a7d264
15 changed files with 125 additions and 107 deletions

View File

@@ -397,7 +397,6 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
public IItemReader<SealedProduct.Template> getBoosterGenerator() { public IItemReader<SealedProduct.Template> getBoosterGenerator() {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return new StorageReaderBase<SealedProduct.Template>(null) { return new StorageReaderBase<SealedProduct.Template>(null) {
@Override @Override
public Map<String, SealedProduct.Template> readAll() { public Map<String, SealedProduct.Template> readAll() {
Map<String, SealedProduct.Template> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); Map<String, SealedProduct.Template> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
@@ -411,6 +410,11 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
public String getItemKey(SealedProduct.Template item) { public String getItemKey(SealedProduct.Template item) {
return item.getEdition(); return item.getEdition();
} }
@Override
public String getFullPath() {
return null;
}
}; };
} }

View File

@@ -18,6 +18,7 @@
package forge.item; package forge.item;
import com.google.common.base.Function; import com.google.common.base.Function;
import forge.StaticData; import forge.StaticData;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.io.DeckSerializer; import forge.deck.io.DeckSerializer;

View File

@@ -26,21 +26,10 @@ import java.util.Map;
* @param <T> the generic type * @param <T> the generic type
*/ */
public interface IItemReader<T> { public interface IItemReader<T> {
String getFullPath();
/**
* Read all.
*
* @return the map
*/
Map<String, T> readAll(); Map<String, T> readAll();
// T read(File file);
/**
* Gets the item key.
*
* @param item the item
* @return the item key
*/
String getItemKey(T item); String getItemKey(T item);
Iterable<File> getSubFolders(); Iterable<File> getSubFolders();

View File

@@ -24,6 +24,7 @@ import com.google.common.base.Predicate;
import forge.util.IHasName; import forge.util.IHasName;
public interface IStorage<T> extends Iterable<T>, IHasName { public interface IStorage<T> extends Iterable<T>, IHasName {
String getFullPath();
T get(String name); T get(String name);
T find(Predicate<T> condition); T find(Predicate<T> condition);
Collection<String> getItemNames(); Collection<String> getItemNames();

View File

@@ -35,42 +35,42 @@ import java.util.*;
public class StorageBase<T> implements IStorage<T> { public class StorageBase<T> implements IStorage<T> {
protected final Map<String, T> map; protected final Map<String, T> map;
public final static StorageBase<?> emptyMap = new StorageBase<Object>("Empty", new HashMap<String, Object>()); public final static StorageBase<?> emptyMap = new StorageBase<Object>("Empty", null, new HashMap<String, Object>());
public final String name; public final String name, fullPath;
public StorageBase(final String name, final IItemReader<T> io) { public StorageBase(final String name0, final IItemReader<T> io) {
this.name = name; this(name0, io.getFullPath(), io.readAll());
this.map = io.readAll();
} }
public StorageBase(final String name, final Map<String, T> inMap) { public StorageBase(final String name0, final String fullPath0, final Map<String, T> map0) {
this.name = name; name = name0;
this.map = inMap; fullPath = fullPath0;
map = map0;
} }
@Override @Override
public T get(final String name) { public T get(final String name) {
return this.map.get(name); return map.get(name);
} }
@Override @Override
public final Collection<String> getItemNames() { public final Collection<String> getItemNames() {
return new ArrayList<String>(this.map.keySet()); return new ArrayList<String>(map.keySet());
} }
@Override @Override
public Iterator<T> iterator() { public Iterator<T> iterator() {
return this.map.values().iterator(); return map.values().iterator();
} }
@Override @Override
public boolean contains(String name) { public boolean contains(String name) {
return name == null ? false : this.map.containsKey(name); return name == null ? false : map.containsKey(name);
} }
@Override @Override
public int size() { public int size() {
return this.map.size(); return map.size();
} }
@Override @Override
@@ -95,15 +95,19 @@ public class StorageBase<T> implements IStorage<T> {
return (IStorage<IStorage<T>>) emptyMap; return (IStorage<IStorage<T>>) emptyMap;
} }
/* (non-Javadoc)
* @see forge.util.IHasName#getName()
*/
@Override @Override
public String getName() { public final String getName() {
// TODO Auto-generated method stub
return name; return name;
} }
@Override
public final String getFullPath() {
if (fullPath == null) {
return name;
}
return fullPath;
}
@Override @Override
public IStorage<T> tryGetFolder(String path) { public IStorage<T> tryGetFolder(String path) {
throw new UnsupportedOperationException("This storage does not support subfolders"); throw new UnsupportedOperationException("This storage does not support subfolders");

View File

@@ -9,7 +9,7 @@ public class StorageNestedFolders<T> extends StorageBase<IStorage<T>> {
private final File thisFolder; private final File thisFolder;
public StorageNestedFolders(File thisFolder, Iterable<File> subfolders, Function<File, IStorage<T>> factory) { public StorageNestedFolders(File thisFolder, Iterable<File> subfolders, Function<File, IStorage<T>> factory) {
super("<Subfolders>", new HashMap<String, IStorage<T>>()); super("<Subfolders>", thisFolder.getPath(), new HashMap<String, IStorage<T>>());
this.thisFolder = thisFolder; this.thisFolder = thisFolder;
for (File sf : subfolders) { for (File sf : subfolders) {
IStorage<T> newUnit = factory.apply(sf); IStorage<T> newUnit = factory.apply(sf);

View File

@@ -18,7 +18,9 @@
package forge.util.storage; package forge.util.storage;
import com.google.common.base.Function; import com.google.common.base.Function;
import forge.util.FileUtil; import forge.util.FileUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.io.File; import java.io.File;
@@ -52,7 +54,12 @@ public abstract class StorageReaderFile<T> extends StorageReaderBase<T> {
*/ */
public StorageReaderFile(final File file0, final Function<? super T, String> keySelector0) { public StorageReaderFile(final File file0, final Function<? super T, String> keySelector0) {
super(keySelector0); super(keySelector0);
this.file = file0; file = file0;
}
@Override
public String getFullPath() {
return file.getPath();
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -63,14 +70,14 @@ public abstract class StorageReaderFile<T> extends StorageReaderBase<T> {
final Map<String, T> result = new TreeMap<String, T>(); final Map<String, T> result = new TreeMap<String, T>();
int idx = 0; int idx = 0;
for (final String s : FileUtil.readFile(this.file)) { for (final String s : FileUtil.readFile(file)) {
if (!this.lineContainsObject(s)) { if (!lineContainsObject(s)) {
continue; continue;
} }
final T item = this.read(s, idx); final T item = read(s, idx);
if (null == item) { if (null == 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."; final String msg = "An object stored in " + file.getPath() + " failed to load.\nPlease submit this as a bug with the mentioned file attached.";
throw new RuntimeException(msg); throw new RuntimeException(msg);
} }
@@ -110,6 +117,6 @@ public abstract class StorageReaderFile<T> extends StorageReaderBase<T> {
*/ */
@Override @Override
public String getItemKey(final T item) { public String getItemKey(final T item) {
return this.keySelector.apply(item); return keySelector.apply(item);
} }
} }

View File

@@ -18,7 +18,9 @@
package forge.util.storage; package forge.util.storage;
import com.google.common.base.Function; import com.google.common.base.Function;
import forge.util.FileUtil; import forge.util.FileUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.io.File; import java.io.File;
@@ -42,7 +44,12 @@ public abstract class StorageReaderFileSections<T> extends StorageReaderBase<T>
public StorageReaderFileSections(final File file0, final Function<? super T, String> keySelector0) { public StorageReaderFileSections(final File file0, final Function<? super T, String> keySelector0) {
super(keySelector0); super(keySelector0);
this.file = file0; file = file0;
}
@Override
public String getFullPath() {
return file.getPath();
} }
protected Map<String, T> createMap() { protected Map<String, T> createMap() {
@@ -57,34 +64,36 @@ public abstract class StorageReaderFileSections<T> extends StorageReaderBase<T>
final Map<String, T> result = createMap(); final Map<String, T> result = createMap();
int idx = 0; int idx = 0;
Iterable<String> file = FileUtil.readFile(this.file); Iterable<String> contents = FileUtil.readFile(file);
List<String> accumulator = new ArrayList<String>(); List<String> accumulator = new ArrayList<String>();
String header = null; String header = null;
for (final String s : file) { for (final String s : contents) {
if (!this.lineContainsObject(s)) { if (!lineContainsObject(s)) {
continue; continue;
} }
if(s.charAt(0) == '[') { if (s.charAt(0) == '[') {
if( header != null ) { if( header != null ) {
// read previously collected item // read previously collected item
T item = readItem(header, accumulator, idx); T item = readItem(header, accumulator, idx);
if( item != null ) { if( item != null ) {
result.put(this.keySelector.apply(item), item); result.put(keySelector.apply(item), item);
idx++; idx++;
} }
} }
header = StringUtils.strip(s, "[] "); header = StringUtils.strip(s, "[] ");
accumulator.clear(); accumulator.clear();
} else }
else {
accumulator.add(s); accumulator.add(s);
}
} }
// store the last item // store the last item
if ( !accumulator.isEmpty() ) { if (!accumulator.isEmpty()) {
T item = readItem(header, accumulator, idx); T item = readItem(header, accumulator, idx);
if( item != null ) { if( item != null ) {
String newKey = keySelector.apply(item); String newKey = keySelector.apply(item);
@@ -98,10 +107,10 @@ public abstract class StorageReaderFileSections<T> extends StorageReaderBase<T>
} }
private final T readItem(String header, Iterable<String> accumulator, int idx) { private final T readItem(String header, Iterable<String> accumulator, int idx) {
final T item = this.read(header, accumulator, idx); final T item = read(header, accumulator, idx);
if (null != item) return item; 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."; final String msg = "An object stored in " + file.getPath() + " failed to load.\nPlease submit this as a bug with the mentioned file attached.";
throw new RuntimeException(msg); throw new RuntimeException(msg);
} }
@@ -130,6 +139,6 @@ public abstract class StorageReaderFileSections<T> extends StorageReaderBase<T>
*/ */
@Override @Override
public String getItemKey(final T item) { public String getItemKey(final T item) {
return this.keySelector.apply(item); return keySelector.apply(item);
} }
} }

View File

@@ -40,6 +40,11 @@ public abstract class StorageReaderFolder<T> extends StorageReaderBase<T> {
return directory; return directory;
} }
@Override
public String getFullPath() {
return directory.getPath();
}
protected final File directory; protected final File directory;
/** /**

View File

@@ -22,6 +22,7 @@ import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import forge.deck.DeckBase; import forge.deck.DeckBase;
import forge.properties.ForgeConstants;
import forge.screens.deckeditor.menus.DeckFileMenu; import forge.screens.deckeditor.menus.DeckFileMenu;
import forge.screens.deckeditor.views.VCurrentDeck; import forge.screens.deckeditor.views.VCurrentDeck;
import forge.screens.home.sanctioned.VSubmenuConstructed; import forge.screens.home.sanctioned.VSubmenuConstructed;
@@ -45,14 +46,14 @@ public class DeckController<T extends DeckBase> {
* @param newModelCreator0 the new model creator0 * @param newModelCreator0 the new model creator0
*/ */
public DeckController(final IStorage<T> folder0, final ACEditorBase<?, T> view0, final Supplier<T> newModelCreator0) { public DeckController(final IStorage<T> folder0, final ACEditorBase<?, T> view0, final Supplier<T> newModelCreator0) {
this.rootFolder = folder0; rootFolder = folder0;
this.currentFolder = rootFolder; currentFolder = rootFolder;
this.view = view0; view = view0;
this.model = null; model = null;
this.saved = true; saved = true;
this.modelInStorage = false; modelInStorage = false;
this.modelPath = ""; modelPath = "";
this.newModelCreator = newModelCreator0; newModelCreator = newModelCreator0;
} }
/** /**
@@ -61,11 +62,11 @@ public class DeckController<T extends DeckBase> {
* @return the document * @return the document
*/ */
public T getModel() { public T getModel() {
return this.model; return model;
} }
public String getModelPath() { public String getModelPath() {
return this.modelPath; return modelPath;
} }
public boolean isEmpty() { public boolean isEmpty() {
@@ -77,27 +78,27 @@ public class DeckController<T extends DeckBase> {
* *
*/ */
public void setModel(final T document) { public void setModel(final T document) {
this.setModel(document, false); setModel(document, false);
} }
public void setModel(final T document, final boolean isStored) { public void setModel(final T document, final boolean isStored) {
this.modelInStorage = isStored; modelInStorage = isStored;
this.model = document; model = document;
this.view.resetTables(); view.resetTables();
CStatistics.SINGLETON_INSTANCE.update(); CStatistics.SINGLETON_INSTANCE.update();
CProbabilities.SINGLETON_INSTANCE.update(); CProbabilities.SINGLETON_INSTANCE.update();
if (isStored) { if (isStored) {
if (this.isModelInSyncWithFolder()) { if (isModelInSyncWithFolder()) {
this.setSaved(true); setSaved(true);
} }
else { else {
this.notifyModelChanged(); notifyModelChanged();
} }
} else { //TODO: Make this smarter } else { //TODO: Make this smarter
this.currentFolder = this.rootFolder; currentFolder = rootFolder;
this.modelPath = ""; modelPath = "";
this.setSaved(true); setSaved(true);
} }
} }
@@ -106,16 +107,16 @@ public class DeckController<T extends DeckBase> {
return true; return true;
} }
final T modelStored = this.currentFolder.get(this.model.getName()); final T modelStored = currentFolder.get(model.getName());
// checks presence in dictionary only. // checks presence in dictionary only.
if (modelStored == this.model) { if (modelStored == model) {
return true; return true;
} }
if (modelStored == null) { if (modelStored == null) {
return false; return false;
} }
return modelStored.equals(this.model); return modelStored.equals(model);
} }
/** /**
@@ -124,7 +125,7 @@ public class DeckController<T extends DeckBase> {
* @return the view * @return the view
*/ */
public ACEditorBase<?, T> getView() { public ACEditorBase<?, T> getView() {
return this.view; return view;
} }
/** /**
@@ -132,7 +133,7 @@ public class DeckController<T extends DeckBase> {
*/ */
public void notifyModelChanged() { public void notifyModelChanged() {
if (saved) { if (saved) {
this.setSaved(false); setSaved(false);
} }
} }
@@ -145,7 +146,7 @@ public class DeckController<T extends DeckBase> {
* Reload current model * Reload current model
*/ */
public void reload() { public void reload() {
final String name = this.getModelName(); final String name = getModelName();
if (name.isEmpty()) { if (name.isEmpty()) {
newModel(); newModel();
} }
@@ -172,12 +173,12 @@ public class DeckController<T extends DeckBase> {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void load(final String name) { private void load(final String name) {
final T newModel = this.currentFolder.get(name); final T newModel = currentFolder.get(name);
if (newModel != null) { if (newModel != null) {
this.setModel((T) newModel.copyTo(name), true); setModel((T) newModel.copyTo(name), true);
} }
else { else {
this.setSaved(true); setSaved(true);
} }
} }
@@ -191,9 +192,10 @@ public class DeckController<T extends DeckBase> {
} }
// copy to new instance before adding to current folder so further changes are auto-saved // copy to new instance before adding to current folder so further changes are auto-saved
this.currentFolder.add((T) this.model.copyTo(this.model.getName())); currentFolder.add((T) model.copyTo(model.getName()));
this.modelInStorage = true; model.setDirectory(currentFolder.getFullPath().substring(ForgeConstants.DECK_BASE_DIR.length()));
this.setSaved(true); modelInStorage = true;
setSaved(true);
VSubmenuConstructed.SINGLETON_INSTANCE.getLobby().updateDeckPanel(); VSubmenuConstructed.SINGLETON_INSTANCE.getLobby().updateDeckPanel();
} }
@@ -205,10 +207,10 @@ public class DeckController<T extends DeckBase> {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void saveAs(final String name0) { public void saveAs(final String name0) {
this.model = (T)this.model.copyTo(name0); model = (T)model.copyTo(name0);
this.modelInStorage = false; modelInStorage = false;
this.save(); save();
this.view.resetTables(); //ensure pool updated in CCurrentDeck view.resetTables(); //ensure pool updated in CCurrentDeck
} }
/** /**
@@ -217,7 +219,7 @@ public class DeckController<T extends DeckBase> {
* @return true, if is saved * @return true, if is saved
*/ */
public boolean isSaved() { public boolean isSaved() {
return this.saved; return saved;
} }
/** /**
@@ -227,18 +229,18 @@ public class DeckController<T extends DeckBase> {
* @return true, if successful * @return true, if successful
*/ */
public boolean fileExists(final String deckName) { public boolean fileExists(final String deckName) {
return this.currentFolder.contains(deckName); return currentFolder.contains(deckName);
} }
/** /**
* Refresh current model or create new one if none * Refresh current model or create new one if none
*/ */
public void refreshModel() { public void refreshModel() {
if (this.model == null) { if (model == null) {
newModel(); newModel();
} }
else { else {
setModel(this.model, this.modelInStorage); setModel(model, modelInStorage);
} }
} }
@@ -246,25 +248,25 @@ public class DeckController<T extends DeckBase> {
* New model. * New model.
*/ */
public void newModel() { public void newModel() {
this.model = this.newModelCreator.get(); model = newModelCreator.get();
this.setSaved(true); setSaved(true);
this.view.resetTables(); view.resetTables();
} }
public String getModelName() { public String getModelName() {
return this.model != null ? this.model.getName() : ""; return model != null ? model.getName() : "";
} }
public void updateCaptions() { public void updateCaptions() {
String tabCaption = "Current Deck"; String tabCaption = "Current Deck";
final String title = this.getModelName(); final String title = getModelName();
String itemManagerCaption = title.isEmpty() ? "[Untitled]" : title; String itemManagerCaption = title.isEmpty() ? "[Untitled]" : title;
if (!saved) { if (!saved) {
tabCaption = "*" + tabCaption; tabCaption = "*" + tabCaption;
itemManagerCaption = "*" + itemManagerCaption; itemManagerCaption = "*" + itemManagerCaption;
} }
itemManagerCaption += " - " + this.view.getSectionMode().name(); itemManagerCaption += " - " + view.getSectionMode().name();
VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText(tabCaption); VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText(tabCaption);
VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setText(title); VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setText(title);

View File

@@ -28,6 +28,7 @@ import forge.menu.FMenuItem;
import forge.menu.FPopupMenu; import forge.menu.FPopupMenu;
import forge.model.FModel; import forge.model.FModel;
import forge.planarconquest.ConquestUtil; import forge.planarconquest.ConquestUtil;
import forge.properties.ForgeConstants;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
import forge.quest.data.QuestPreferences.QPref; import forge.quest.data.QuestPreferences.QPref;
import forge.screens.FScreen; import forge.screens.FScreen;
@@ -1443,6 +1444,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
// copy to new instance before adding to current folder so further changes are auto-saved // copy to new instance before adding to current folder so further changes are auto-saved
currentFolder.add((T) model.copyTo(model.getName())); currentFolder.add((T) model.copyTo(model.getName()));
model.setDirectory(currentFolder.getFullPath().substring(ForgeConstants.DECK_BASE_DIR.length()));
modelInStorage = true; modelInStorage = true;
setSaved(true); setSaved(true);

View File

@@ -66,7 +66,7 @@ public class NetDeckCategory extends StorageBase<Deck> {
NetDeckCategory category = categories.get(name); NetDeckCategory category = categories.get(name);
if (category != null && category.map.isEmpty()) { if (category != null && category.map.isEmpty()) {
//if name passed in, try to load decks from current cached files //if name passed in, try to load decks from current cached files
File downloadDir = new File(category.getDownloadLocation()); File downloadDir = new File(category.getFullPath());
if (downloadDir.exists()) { if (downloadDir.exists()) {
for (File file : downloadDir.listFiles(DeckStorage.DCK_FILE_FILTER)) { for (File file : downloadDir.listFiles(DeckStorage.DCK_FILE_FILTER)) {
Deck deck = DeckSerializer.fromFile(file); Deck deck = DeckSerializer.fromFile(file);
@@ -86,7 +86,7 @@ public class NetDeckCategory extends StorageBase<Deck> {
WaitCallback<Boolean> callback = new WaitCallback<Boolean>() { WaitCallback<Boolean> callback = new WaitCallback<Boolean>() {
@Override @Override
public void run() { public void run() {
String downloadLoc = c.getDownloadLocation(); String downloadLoc = c.getFullPath();
GuiBase.getInterface().download(new GuiDownloadZipService(c.getName(), "decks", c.getUrl(), downloadLoc, downloadLoc, null) { GuiBase.getInterface().download(new GuiDownloadZipService(c.getName(), "decks", c.getUrl(), downloadLoc, downloadLoc, null) {
@Override @Override
protected void copyInputStream(InputStream in, String outPath) throws IOException { protected void copyInputStream(InputStream in, String outPath) throws IOException {
@@ -108,14 +108,10 @@ public class NetDeckCategory extends StorageBase<Deck> {
private final String url; private final String url;
private NetDeckCategory(String name0, String url0) { private NetDeckCategory(String name0, String url0) {
super(name0, new HashMap<String, Deck>()); super(name0, ForgeConstants.DECK_NET_DIR + name0, new HashMap<String, Deck>());
url = url0; url = url0;
} }
public String getDownloadLocation() {
return ForgeConstants.DECK_NET_DIR + name + "/";
}
public String getUrl() { public String getUrl() {
return url; return url;
} }

View File

@@ -24,7 +24,7 @@ import java.util.Map;
public class ConquestDeckMap extends StorageBase<Deck> { public class ConquestDeckMap extends StorageBase<Deck> {
public ConquestDeckMap(Map<String, Deck> in) { public ConquestDeckMap(Map<String, Deck> in) {
super("Conquest decks", in); super("Conquest decks", null, in);
} }
@Override @Override

View File

@@ -28,12 +28,11 @@ import forge.util.storage.StorageBase;
* *
*/ */
public class QuestDeckGroupMap extends StorageBase<DeckGroup> { public class QuestDeckGroupMap extends StorageBase<DeckGroup> {
/** /**
* Instantiates a new quest deck map. * Instantiates a new quest deck map.
*/ */
public QuestDeckGroupMap(Map<String, DeckGroup> in) { public QuestDeckGroupMap(Map<String, DeckGroup> in) {
super("Quest draft decks", in == null ? new HashMap<String, DeckGroup>() : in); super("Quest draft decks", null, in == null ? new HashMap<String, DeckGroup>() : in);
} }

View File

@@ -27,12 +27,11 @@ import java.util.Map;
* *
*/ */
public class QuestDeckMap extends StorageBase<Deck> { public class QuestDeckMap extends StorageBase<Deck> {
/** /**
* Instantiates a new quest deck map. * Instantiates a new quest deck map.
*/ */
public QuestDeckMap(Map<String, Deck> in) { public QuestDeckMap(Map<String, Deck> in) {
super("Quest decks", in); super("Quest decks", null, in);
} }