diff --git a/RefactorToVisitorPatternKata/.classpath b/RefactorToVisitorPatternKata/.classpath
new file mode 100644
index 0000000..f619a53
--- /dev/null
+++ b/RefactorToVisitorPatternKata/.classpath
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RefactorToVisitorPatternKata/.gitignore b/RefactorToVisitorPatternKata/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/RefactorToVisitorPatternKata/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/RefactorToVisitorPatternKata/.project b/RefactorToVisitorPatternKata/.project
new file mode 100644
index 0000000..cb3d351
--- /dev/null
+++ b/RefactorToVisitorPatternKata/.project
@@ -0,0 +1,23 @@
+
+
+ RefactorToVisitorPatternKata
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/RefactorToVisitorPatternKata/.settings/org.eclipse.jdt.core.prefs b/RefactorToVisitorPatternKata/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ec4300d
--- /dev/null
+++ b/RefactorToVisitorPatternKata/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/RefactorToVisitorPatternKata/.settings/org.eclipse.m2e.core.prefs b/RefactorToVisitorPatternKata/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/RefactorToVisitorPatternKata/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/RefactorToVisitorPatternKata/README.md b/RefactorToVisitorPatternKata/README.md
new file mode 100644
index 0000000..df8b9f7
--- /dev/null
+++ b/RefactorToVisitorPatternKata/README.md
@@ -0,0 +1,138 @@
+Refactoring to Visitor pattern
+==============================
+
+Import the project, run the tests (`FullSystemTest`). Refactor the classes `Partition` and `Session` to visitor pattern.
+
+If you want to increase the challenge, follow these rules:
+
+* you may NOT modify the contract of ColumnStorage nor the TableStorage classes - they're used in production and must be backwards compatible
+* you may NOT modify the Storage interface
+
+
+The Problem Domain
+------------------
+
+This is simplified production code, and the domain centers around storing of data objects. In this code base, there are
+two different types of data storage: `ColumnStorage` and `TableStorage`. In order to load data from either of these
+you start out with a `Session`. You tell the `Session` what storages to use (Column or Table) and then you can ask the
+`Session` to: `load` data; `refresh` the data (by rereading all storage's files to get the latest available); `getSize`
+to see how many bytes of RAM this session is consuming; `getLatestCommitId` to get the latest seen commit id.
+
+The objects stored are actually version controlled (well they are in the _real_ code base, you can't really see it in
+this simplified version) and each "save" is given an ever increasing "commit id".
+
+Now, there's one more concept to this data model, and that is `Partition`. A `Session` actually doesn't hold references
+to `Storage` objects, but to `Partition` objects. These `Partition` objects in turn can hold either other `Partitions`,
+and/or `Storage` objects.
+
+While all the operations are available from the `Session` class, they're also available on the `Partition` level, but
+not all `Storage` types support the `refresh` operation for instance.
+
+A typical tree would look like this:
+
+ Session
+ |
+ +---Partition
+ | |
+ | +---ColumnStorage (file:/tmp/dump1.json)
+ | |
+ | +---TableStorage (file:/tmp/dump2.sql)
+ |
+ +---Partition
+ |
+ +---Partition
+ | |
+ | +--- ColumnStorage (file:/tmp/dump3.json)
+ |
+ +---ColumnStorage (file:/tmp/dump4.json)
+ |
+ +---TableStorage (file:/tmp/dump5.sql)
+
+
+(In the real code base, the Partitions are clever filters that applies a filter and only shows the data objects that
+pass the filter. In this simplified example, they're only kept to make the Visitor pattern more obvious.)
+
+
+The Problem
+-----------
+
+There are currently several "operations" which, when invoked, traverse the tree structure and does some work on each node in the graph.
+Code to handle traversing this structure is found in _all_ of these "operations".
+You should refactor this into a pattern that follows a Visitor pattern.
+
+The operations are:
+
+* printInfo
+* load
+* refresh
+* getLatestCommitId
+* getSize
+
+
+Refactoring
+===========
+
+The refactoring cycle:
+
+* run the tests and make sure everything is passing
+* comment out the code you want to refactor
+* put a dumb implementation in place
+* run the tests and see some of them fail
+* if no tests are failing, undo back to the beginning, add tests and start over until you have a sufficient test suite
+* write the new code
+* run the tests and make sure everything is passing
+
+
+Visitor Pattern
+===============
+
+Don't read this unless you get stuck, or have no clue on how to use the Visitor pattern. Perhaps try reading http://en.wikipedia.org/wiki/Visitor_pattern
+
+Each concrete Visitor knows what to do at each level in the structure, such as representing the visited object/node as JSON. The visitor, however, doesn't know how to traverse the structure. If it knew this, all visitors would have to know this which may lead to duplication of code, and certainly breaks Single Responsibility Principle. The Visitor thus has one method per object type that it visits.
+
+Each visited object (node), knows how to "welcome" the Visotor object (traditionally the method is called `accept`), and pass the Visitor object around. This 'traversing the structure'-logic is put into the structure itself, and is typically marked with an interface, Visitable.
+
+
+ class Visitable():
+ def accept(self, visitor):
+ pass
+
+ class Visitor():
+ def processParent(self, parent):
+ pass
+ def processChild(self, child):
+ pass
+
+ class Parent(Visitable):
+ def accept(self, visitor):
+ visitor.processParent(self)
+ for c in self.children:
+ c.accept(visitor)
+
+ class SomeVisitor():
+ def processParent(self, parent_object):
+ doSomething ...
+ def processChild(self, child_object):
+ doSomethingElse ...
+
+
+Additional Tasks
+----------------
+
+* Consider adding a way to save the structure, as XML, to a File.
+* Consider adding a way to save the structure, as JSON, to a File.
+
+* Consider doing away with the accept method, see
+ http://perfectjpattern.sourceforge.net/dp-visitor.html and
+ http://perfectjpattern.sourceforge.net/xref/org/perfectjpattern/core/behavioral/visitor/AbstractVisitor.html
+
+
+Notes
+-----
+
+The Storage interface is not present in the Python version of this exercise. Python uses duck typing and as such doesn't need a common base class in order to invoke methods on objects that share a common name.
+
+Yes, the Logging.out is a replacement for System.out - the Python code does this much butter.
+
+Yes, the `_mock_data` loading is so much simple with duck typing and object literal declaration support in the language, ie Python wins again. :-)
+
diff --git a/RefactorToVisitorPatternKata/pom.xml b/RefactorToVisitorPatternKata/pom.xml
new file mode 100644
index 0000000..05e54ec
--- /dev/null
+++ b/RefactorToVisitorPatternKata/pom.xml
@@ -0,0 +1,19 @@
+
+
+ 4.0.0
+ coding.dojo
+ ref-to-visitor
+ 1.0.0
+
+ 1.7
+ 1.7
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+
diff --git a/RefactorToVisitorPatternKata/src/main/java/data/ColumnStorage.java b/RefactorToVisitorPatternKata/src/main/java/data/ColumnStorage.java
new file mode 100644
index 0000000..1f5d666
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/data/ColumnStorage.java
@@ -0,0 +1,10 @@
+package data;
+
+/**
+ * Implementation omitted, we use test doubles for testing
+ */
+public abstract class ColumnStorage implements Storage {
+
+ abstract public void dump();
+
+}
diff --git a/RefactorToVisitorPatternKata/src/main/java/data/LoadVisitor.java b/RefactorToVisitorPatternKata/src/main/java/data/LoadVisitor.java
new file mode 100644
index 0000000..8b40b74
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/data/LoadVisitor.java
@@ -0,0 +1,20 @@
+package data;
+
+import tree.Visitor;
+
+public class LoadVisitor implements Visitor {
+
+ @Override
+ public void handle(Session session) {
+ }
+
+ @Override
+ public void handle(Partition partition) {
+ }
+
+ @Override
+ public void handle(Storage storage) {
+ storage.load();
+ }
+
+}
diff --git a/RefactorToVisitorPatternKata/src/main/java/data/Logging.java b/RefactorToVisitorPatternKata/src/main/java/data/Logging.java
new file mode 100644
index 0000000..b118abf
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/data/Logging.java
@@ -0,0 +1,9 @@
+package data;
+
+import java.io.PrintStream;
+
+public class Logging {
+
+ public static PrintStream out;
+
+}
diff --git a/RefactorToVisitorPatternKata/src/main/java/data/Partition.java b/RefactorToVisitorPatternKata/src/main/java/data/Partition.java
new file mode 100644
index 0000000..b4a1fd1
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/data/Partition.java
@@ -0,0 +1,107 @@
+package data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import tree.Visitable;
+import tree.Visitor;
+
+public class Partition implements Visitable {
+
+ private String name;
+ private List storages;
+ private List partitions;
+
+ public Partition(String name, List partitions,
+ List storages) {
+ this.partitions = partitions;
+ this.storages = storages;
+ this.name = name;
+ }
+
+ public Partition(String name) {
+ this(name, new ArrayList(), new ArrayList());
+ }
+
+ public void addPartition(Partition partition) {
+ partitions.add(partition);
+ }
+
+ public void addStorage(Storage storage) {
+ storages.add(storage);
+ }
+
+ public void printInfo() {
+ Logging.out.println("Partition: " + name);
+ for (Partition p : partitions) {
+ p.printInfo();
+ }
+ for (Storage s : storages) {
+ if (s instanceof TableStorage) {
+ ((TableStorage) s).printout();
+ }
+ if (s instanceof ColumnStorage) {
+ ((ColumnStorage) s).dump();
+ }
+ }
+ }
+
+ public void load() { // Visitor
+// Visitor visitor = new LoadVisitor();
+// accept(visitor);
+// return visitor;
+ }
+
+ public void refresh() {
+ for (Partition p : partitions) {
+ p.refresh();
+ }
+ for (Storage s : storages) {
+ if (s instanceof TableStorage) {
+ ((TableStorage) s).refresh();
+ }
+ }
+ }
+
+ public int getSize() {
+ int total_size = 0;
+ for (Partition p : partitions) {
+ total_size += p.getSize();
+ }
+ for (Storage s : storages) {
+ total_size += s.getSize();
+ }
+ return total_size;
+ }
+
+ public int getLatestCommitId() {
+ int latestCommitId = 0;
+ for (Partition p : partitions) {
+ int partitionCommitId = p.getLatestCommitId();
+ if (partitionCommitId > latestCommitId) {
+ latestCommitId = partitionCommitId;
+ }
+ }
+ for (Storage s : storages) {
+ if (s instanceof TableStorage) {
+ int storageCommitId = ((TableStorage) s).getLatestCommitId();
+ if (storageCommitId > latestCommitId) {
+ latestCommitId = storageCommitId;
+ }
+ }
+ }
+ return latestCommitId;
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.handle(this);
+
+ for (Partition p : partitions) {
+ p.accept(visitor);
+ }
+ for (Storage s : storages) {
+ s.accept(visitor);
+ }
+ }
+}
diff --git a/RefactorToVisitorPatternKata/src/main/java/data/RefreshVisitor.java b/RefactorToVisitorPatternKata/src/main/java/data/RefreshVisitor.java
new file mode 100644
index 0000000..b2ca0f4
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/data/RefreshVisitor.java
@@ -0,0 +1,27 @@
+package data;
+
+import tree.Visitor;
+
+public class RefreshVisitor implements Visitor {
+
+ @Override
+ public void handle(Session session) {
+ // TODO Auto-generated method stub
+ throw new RuntimeException();
+ }
+
+ @Override
+ public void handle(Partition partition) {
+ // TODO Auto-generated method stub
+ throw new RuntimeException();
+
+ }
+
+ @Override
+ public void handle(Storage storage) {
+ // TODO Auto-generated method stub
+ throw new RuntimeException();
+
+ }
+
+}
diff --git a/RefactorToVisitorPatternKata/src/main/java/data/Session.java b/RefactorToVisitorPatternKata/src/main/java/data/Session.java
new file mode 100644
index 0000000..c53ffd8
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/data/Session.java
@@ -0,0 +1,65 @@
+package data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import tree.Visitable;
+import tree.Visitor;
+
+public class Session implements Visitable {
+
+ private List partitions = new ArrayList<>();
+
+ public void addPartition(Partition partition) {
+ partitions.add(partition);
+ }
+
+ public void printInfo() {
+ Logging.out.println("Session:");
+ for (Partition p : partitions) {
+ p.printInfo();
+ }
+ }
+
+ public Session load() {
+ Visitor visitor = new LoadVisitor();
+ accept(visitor);
+ return this;
+ }
+
+ public Session refresh() {
+// for (Partition p : partitions) {
+// p.refresh();
+// }
+ Visitor visitor = new RefreshVisitor();
+ return this;
+ }
+
+ public int getLatestCommitId() {
+ int latestCommitId = 0;
+ for (Partition p : partitions) {
+ int partitionCommitId = p.getLatestCommitId();
+ if (partitionCommitId > latestCommitId) {
+ latestCommitId = partitionCommitId;
+ }
+ }
+ return latestCommitId;
+ }
+
+ public int getSize() {
+ int totalSize = 0;
+ for (Partition p : partitions) {
+ totalSize += p.getSize();
+ }
+ return totalSize;
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.handle(this);
+
+ for (Partition p : partitions) {
+ p.accept(visitor);
+ }
+ }
+}
diff --git a/RefactorToVisitorPatternKata/src/main/java/data/Storage.java b/RefactorToVisitorPatternKata/src/main/java/data/Storage.java
new file mode 100644
index 0000000..d94c580
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/data/Storage.java
@@ -0,0 +1,11 @@
+package data;
+
+import tree.Visitable;
+
+public interface Storage extends Visitable {
+
+ int getSize();
+
+ void load();
+
+}
diff --git a/RefactorToVisitorPatternKata/src/main/java/data/TableStorage.java b/RefactorToVisitorPatternKata/src/main/java/data/TableStorage.java
new file mode 100644
index 0000000..0233e2a
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/data/TableStorage.java
@@ -0,0 +1,18 @@
+package data;
+
+/**
+ * Implementation omitted, we use test doubles for testing
+ */
+public abstract class TableStorage implements Storage {
+
+ abstract public int getSize();
+
+ abstract public int getLatestCommitId();
+
+ abstract public void printout();
+
+ abstract public void load();
+
+ abstract public void refresh();
+
+}
diff --git a/RefactorToVisitorPatternKata/src/main/java/tree/Visitable.java b/RefactorToVisitorPatternKata/src/main/java/tree/Visitable.java
new file mode 100644
index 0000000..2cd5498
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/tree/Visitable.java
@@ -0,0 +1,6 @@
+package tree;
+
+public interface Visitable {
+ void accept (Visitor visitor);
+
+}
diff --git a/RefactorToVisitorPatternKata/src/main/java/tree/Visitor.java b/RefactorToVisitorPatternKata/src/main/java/tree/Visitor.java
new file mode 100644
index 0000000..5bc1a06
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/main/java/tree/Visitor.java
@@ -0,0 +1,13 @@
+package tree;
+
+import data.Partition;
+import data.Session;
+import data.Storage;
+
+public interface Visitor {
+ void handle (Session session);
+
+ void handle (Partition partition);
+
+ void handle (Storage storage);
+}
diff --git a/RefactorToVisitorPatternKata/src/test/java/data/ColumnStorageFake.java b/RefactorToVisitorPatternKata/src/test/java/data/ColumnStorageFake.java
new file mode 100644
index 0000000..a0cf963
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/test/java/data/ColumnStorageFake.java
@@ -0,0 +1,48 @@
+package data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import tree.Visitor;
+
+public class ColumnStorageFake extends ColumnStorage {
+
+ private String name;
+ private int size = 0;
+ private static final Map _mock_data;
+
+ static {
+ _mock_data = new HashMap<>();
+ _mock_data.put("JSON storage 1", 6645);
+ _mock_data.put("JSON storage 2", 321);
+ _mock_data.put("JSON storage 3", 566);
+ }
+
+ public ColumnStorageFake(String name) {
+ this.name = name;
+ }
+
+ public void dump() {
+ Logging.out.println("ColumnStorage: " + name);
+ }
+
+ @Override
+ public int getSize() {
+ return size;
+ }
+
+ @Override
+ public void load() {
+ if (_mock_data.containsKey(name)) {
+ size = _mock_data.get(name);
+ } else {
+ size = -1;
+ }
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.handle(this);
+ }
+
+}
diff --git a/RefactorToVisitorPatternKata/src/test/java/data/FakeOut.java b/RefactorToVisitorPatternKata/src/test/java/data/FakeOut.java
new file mode 100644
index 0000000..268aae7
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/test/java/data/FakeOut.java
@@ -0,0 +1,27 @@
+package data;
+
+import java.io.*;
+
+public class FakeOut extends PrintStream {
+
+ private StringBuffer sb = new StringBuffer();
+
+ public FakeOut(OutputStream out) {
+ super(out);
+ }
+
+ public FakeOut() throws FileNotFoundException, IOException {
+ super((OutputStream) new FileOutputStream(File.createTempFile("fake", "out")));
+ }
+
+ @Override
+ public void println(String x) {
+ sb.append(x);
+ sb.append("\n");
+ }
+
+ public String getOut() {
+ return sb.toString();
+ }
+
+}
diff --git a/RefactorToVisitorPatternKata/src/test/java/data/FakeOutTest.java b/RefactorToVisitorPatternKata/src/test/java/data/FakeOutTest.java
new file mode 100644
index 0000000..ed20e0e
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/test/java/data/FakeOutTest.java
@@ -0,0 +1,17 @@
+package data;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class FakeOutTest {
+
+ @Test
+ public void simpleFlow() throws Exception {
+ FakeOut f = new FakeOut();
+ f.println("Hello");
+ f.println("World");
+ assertEquals("Hello\nWorld\n", f.getOut());
+ }
+
+}
diff --git a/RefactorToVisitorPatternKata/src/test/java/data/FullSystemTest.java b/RefactorToVisitorPatternKata/src/test/java/data/FullSystemTest.java
new file mode 100644
index 0000000..a4bae88
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/test/java/data/FullSystemTest.java
@@ -0,0 +1,88 @@
+package data;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class FullSystemTest {
+
+ private Session session;
+ private static final int size_after_load = 46544 + 344 + 465 + 6645 + 321 + 566;
+ private static final int size_after_refreshes = 51345 + 545 + 513 + 6645 + 321 + 566;
+
+ @Before
+ public void setup() throws Exception {
+ Logging.out = new FakeOut();
+
+ this.session = new Session();
+ Partition p1 = new Partition("partition 1");
+ p1.addStorage(new TableStorageFake("SQL storage 1"));
+ p1.addStorage(new ColumnStorageFake("JSON storage 1"));
+ session.addPartition(p1);
+
+ Partition p2 = new Partition("partition 2");
+ p2.addStorage(new TableStorageFake("SQL storage 2"));
+ session.addPartition(p2);
+
+ Partition p3 = new Partition("partition 3");
+ p3.addStorage(new TableStorageFake("SQL storage 3"));
+ p3.addStorage(new ColumnStorageFake("JSON storage 2"));
+ p3.addStorage(new ColumnStorageFake("JSON storage 3"));
+ p2.addPartition(p3);
+ }
+
+ @Test
+ public void initialCommitIdIsZero() throws Exception {
+ assertEquals(0, session.getLatestCommitId());
+ }
+
+ @Test
+ public void commitIdIs125AfterLoad() throws Exception {
+ session.load();
+ assertEquals(125, session.getLatestCommitId());
+ }
+
+ @Test
+ public void commitIdAfterTwoRefreshesIs137() throws Exception {
+ session.load();
+ session.refresh();
+ session.refresh();
+ assertEquals(137, session.getLatestCommitId());
+ }
+
+ @Test
+ public void initialSizeIsZero() throws Exception {
+ assertEquals(0, session.getSize());
+ }
+
+ @Test
+ public void sizeAfterLoadIs_MagicNumber() throws Exception {
+ session.load();
+ assertEquals(size_after_load, session.getSize());
+ }
+
+ @Test
+ public void sizeAfterTwoRefreshesIs_MagicNumber() throws Exception {
+ session.load().refresh().refresh();
+ assertEquals(size_after_refreshes, session.getSize());
+ }
+
+ @Test
+ public void printSession() throws Exception {
+ session.printInfo();
+ String actual = ((FakeOut) Logging.out).getOut();
+ String expected = "Session:\n" +
+ "Partition: partition 1\n" +
+ "TableStorage: SQL storage 1\n" +
+ "ColumnStorage: JSON storage 1\n" +
+ "Partition: partition 2\n" +
+ "Partition: partition 3\n" +
+ "TableStorage: SQL storage 3\n" +
+ "ColumnStorage: JSON storage 2\n" +
+ "ColumnStorage: JSON storage 3\n" +
+ "TableStorage: SQL storage 2\n";
+ assertEquals(expected, actual);
+ }
+
+}
diff --git a/RefactorToVisitorPatternKata/src/test/java/data/TableStorageFake.java b/RefactorToVisitorPatternKata/src/test/java/data/TableStorageFake.java
new file mode 100644
index 0000000..a6f0034
--- /dev/null
+++ b/RefactorToVisitorPatternKata/src/test/java/data/TableStorageFake.java
@@ -0,0 +1,83 @@
+package data;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import tree.Visitable;
+import tree.Visitor;
+
+public class TableStorageFake extends TableStorage implements Visitable {
+
+ private static final Map>> _mock_data;
+
+ static {
+ _mock_data = new HashMap<>();
+ _mock_data.put("SQL storage 1",
+ m("cids", "0, 123, 126, 134, 156, 158",
+ "sizes", "0, 46544, 50444, 51345, 52333, 55991"));
+ _mock_data.put("SQL storage 2",
+ m("cids", "0, 125, 133, 134, 143, 155",
+ "sizes", "0, 344, 544, 545, 633, 791"));
+ _mock_data.put("SQL storage 3",
+ m("cids", "0, 124, 127, 137, 177, 199",
+ "sizes", "0, 465, 504, 513, 523, 559"));
+ }
+
+ private String name;
+ private int mockDataIndex = 0;
+
+ public TableStorageFake(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public void printout() {
+ Logging.out.println("TableStorage: " + name);
+ }
+
+ @Override
+ public int getSize() {
+ // return DaveStorageMock._mock_data[name]["sizes"][index]
+ return _mock_data.get(name).get("sizes").get(mockDataIndex);
+ }
+
+ @Override
+ public int getLatestCommitId() {
+ // return DaveStorageMock._mock_data[name]["cids"][index]
+ return _mock_data.get(name).get("cids").get(mockDataIndex);
+ }
+
+ @Override
+ public void load() {
+ this.mockDataIndex = 1;
+ }
+
+ @Override
+ public void refresh() {
+ this.mockDataIndex++;
+ if (this.mockDataIndex > _mock_data.get(name).get("cids").size()) {
+ throw new IllegalStateException("out of mock data!");
+ }
+ }
+
+ // this is soo ugly
+ private static Map> m(Object... args) {
+ Map> map = new HashMap<>();
+ for (int index = 0; index < args.length; index = index + 2) {
+ String key = (String) args[index];
+ List values = new ArrayList();
+ for (String n : ((String) args[index + 1]).split(",")) {
+ values.add(new Integer(n.trim()));
+ }
+ map.put(key, values);
+ }
+ return map;
+ }
+
+ @Override
+ public void accept (Visitor visitor) {
+ visitor.handle(this);
+ }
+}