Test nested named VCs

Change-Id: I2e0c773e2ab7c7f8589aa47468699a9d4b9ef846
diff --git a/src/main/java/de/ids_mannheim/korap/KrillCollection.java b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
index 6cdcdca..a5f5008 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillCollection.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
@@ -68,6 +68,8 @@
     private CollectionBuilder.Interface cbi;
     private byte[] pl = new byte[4];
 
+    private ObjectMapper mapper = new ObjectMapper();
+    
 	private Filter prefiltered = null;
     // private static ByteBuffer bb = ByteBuffer.allocate(4);
 
@@ -105,7 +107,7 @@
      *            The KoralQuery document as a JSON string.
      */
     public KrillCollection (String jsonString) {
-        ObjectMapper mapper = new ObjectMapper();
+
         try {
             JsonNode json = mapper.readTree(jsonString);
 
@@ -161,7 +163,6 @@
      * @throws QueryException
      */
     public KrillCollection fromKoral (String jsonString) throws QueryException {
-        ObjectMapper mapper = new ObjectMapper();
 		this.prefiltered = null;
         try {
             this.fromKoral((JsonNode) mapper.readTree(jsonString));
@@ -175,7 +176,7 @@
     };
 
 
-	public KrillCollection fromCache (String ref) throws QueryException {
+	public KrillCollection fromStore (String ref) throws QueryException {
         Properties prop = KrillProperties.loadDefaultProperties();
 		this.prefiltered = null;
 	
diff --git a/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java b/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
index 3abc0e4..de00b5a 100644
--- a/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
+++ b/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
@@ -22,9 +22,6 @@
 
 import org.apache.commons.io.IOUtils;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
 import de.ids_mannheim.korap.KrillCollection;
 import de.ids_mannheim.korap.index.TextPrependedTokenStream;
 import de.ids_mannheim.korap.util.KrillDate;
@@ -293,17 +290,14 @@
         };
 
         public Filter toFilter () throws QueryException {
-			ObjectMapper mapper = new ObjectMapper();
-
 			Element element = KrillCollection.cache.get(this.reference);
             if (element == null) {
-
                 KrillCollection kc = new KrillCollection();
 
-				kc.fromCache(this.reference);
+				kc.fromStore(this.reference);
 
-				if (kc.hasErrors()) {
-					throw new QueryException(
+				if (kc.hasErrors()) {                    
+                    throw new QueryException(
 						kc.getError(0).getCode(),
 						kc.getError(0).getMessage()
 						);
diff --git a/src/test/java/de/ids_mannheim/korap/collection/TestCollectionBuilder.java b/src/test/java/de/ids_mannheim/korap/collection/TestCollectionBuilder.java
index f923423..2ee8cb1 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestCollectionBuilder.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestCollectionBuilder.java
@@ -91,6 +91,23 @@
         assertEquals("referTo(ndiewald/myCorpus)",
                 kc.referTo("ndiewald/myCorpus").toString());
     };
+
+
+    @Test
+    public void builderReferenceNested () throws IOException {
+        CollectionBuilder kc = new CollectionBuilder();
+
+        // The group can't stringify, because the filtering
+        // phase won't work. This is acceptable.
+        assertEquals(
+            "",
+            kc.orGroup().with(
+                kc.referTo("example")
+                ).with(
+                    kc.term("opennlp","check")
+                    ).toString()
+            );
+    };
 	
 
     @Test
diff --git a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
index b2466dd..445b539 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
@@ -26,6 +26,7 @@
 
 import static org.junit.Assert.*;
 import org.junit.Test;
+import org.junit.Ignore;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
@@ -545,15 +546,302 @@
 		assertEquals("[[a]] d e", result.getMatch(1).getSnippetBrackets());
 		assertEquals(result.getMatches().size(), 2);
 		
-		prop.setProperty("krill.namedVC", tempVC);
-
 		// testClearCache
 		KrillCollection.cache.removeAll();
 
         element = KrillCollection.cache.get("named-vc1");
         assertNull(element);
+
+		prop.setProperty("krill.namedVC", tempVC);
     };
 
+	@Test
+    public void testNestedNamedVCs () throws IOException {
+        Properties prop = KrillProperties.loadDefaultProperties();
+
+        String vcPath = getClass().getResource(path + "named-vcs").getFile();
+        String tempVC = prop.getProperty("krill.namedVC");
+        prop.setProperty("krill.namedVC", vcPath);
+        
+        ki = new KrillIndex();
+        ki.addDoc(createDoc1());
+        ki.addDoc(createDoc2());
+        ki.addDoc(createDoc3());
+        ki.commit();
+
+        // Check cache
+        Element element = KrillCollection.cache.get("named-vc1");
+        assertNull(element);
+
+        element = KrillCollection.cache.get("named-vc2");
+        assertNull(element);
+
+        QueryBuilder kq = new QueryBuilder("tokens");
+        KrillCollection kc = new KrillCollection(ki);
+        CollectionBuilder cb = kc.build();
+        Krill krill = new Krill(kq.seg("i:a"));
+
+        kc.fromBuilder(
+            cb.orGroup().with(
+                cb.referTo("named-vc1")
+                ).with(
+                    cb.referTo("named-vc2")
+                    )
+            );
+        krill.setCollection(kc);
+        // named-vc1: UID:[2,3]
+        // named-vc2: author:Frank (doc-1)
+
+        assertEquals("OrGroup(referTo(named-vc1) referTo(named-vc2))",
+                     krill.getCollection().toString());
+
+        assertEquals("tokens:i:a", krill.getSpanQuery().toString());
+        
+        Result result = krill.apply(ki);
+        assertEquals("[[a]] b c", result.getMatch(0).getSnippetBrackets());
+        assertEquals("[[a]] c d", result.getMatch(1).getSnippetBrackets());
+        assertEquals("[[a]] d e", result.getMatch(2).getSnippetBrackets());
+        assertEquals(3, result.getMatches().size());
+
+        element = KrillCollection.cache.get("named-vc2");
+        CachedVCData cc = (CachedVCData) element.getObjectValue();
+        assertTrue(cc.getDocIdMap().size() > 0);
+        
+        kc.fromBuilder(
+            cb.orGroup().with(
+                cb.referTo("named-vc1")
+                ).with(
+                    cb.referTo("named-vc2")
+                    )
+            );
+        
+        assertEquals("OrGroup(referTo(cached:named-vc1) referTo(cached:named-vc2))",
+                     krill.getCollection().toString());
+
+        result = krill.apply(ki);
+        assertEquals("[[a]] b c", result.getMatch(0).getSnippetBrackets());
+        assertEquals("[[a]] c d", result.getMatch(1).getSnippetBrackets());
+        assertEquals("[[a]] d e", result.getMatch(2).getSnippetBrackets());
+        assertEquals(3, result.getMatches().size());
+
+        kc.fromBuilder(
+            cb.orGroup().with(
+                cb.referTo("named-vc1")
+                ).with(
+                    cb.referTo("named-vc2")
+                    )
+            );
+        
+        assertEquals("OrGroup(referTo(cached:named-vc1) referTo(cached:named-vc2))",
+                     krill.getCollection().toString());
+
+        result = krill.apply(ki);
+        assertEquals("[[a]] b c", result.getMatch(0).getSnippetBrackets());
+        assertEquals("[[a]] c d", result.getMatch(1).getSnippetBrackets());
+        assertEquals("[[a]] d e", result.getMatch(2).getSnippetBrackets());
+        assertEquals(3, result.getMatches().size());
+
+        kc.fromBuilder(cb.referTo("named-vc1"));
+        
+        assertEquals("referTo(cached:named-vc1)",
+                     krill.getCollection().toString());
+
+        result = krill.apply(ki);
+        assertEquals("[[a]] c d", result.getMatch(0).getSnippetBrackets());
+        assertEquals("[[a]] d e", result.getMatch(1).getSnippetBrackets());
+        assertEquals(2, result.getMatches().size());
+
+
+        kc.fromBuilder(cb.referTo("named-vc2"));
+        
+        assertEquals("referTo(cached:named-vc2)",
+                     krill.getCollection().toString());
+
+        result = krill.apply(ki);
+        assertEquals("[[a]] b c", result.getMatch(0).getSnippetBrackets());
+        assertEquals(1, result.getMatches().size());
+        
+        prop.setProperty("krill.namedVC", tempVC);
+    };
+
+
+	@Test
+    public void testNamedVCsAfterQueryWithMissingDocs () throws IOException {
+        Properties prop = KrillProperties.loadDefaultProperties();
+
+        String vcPath = getClass().getResource(path + "named-vcs").getFile();
+        String tempVC = prop.getProperty("krill.namedVC");
+        prop.setProperty("krill.namedVC", vcPath);
+        
+        ki = new KrillIndex();
+        ki.addDoc(createDoc1());
+        ki.commit();
+        ki.addDoc(createDoc2());
+        ki.commit();
+        ki.addDoc(createDoc3());
+        ki.commit();
+
+        // Check cache
+        Element element = KrillCollection.cache.get("named-vc1");
+        assertNull(element);
+
+        element = KrillCollection.cache.get("named-vc2");
+        assertNull(element);
+
+        QueryBuilder kq = new QueryBuilder("tokens");
+        KrillCollection kc = new KrillCollection(ki);
+        CollectionBuilder cb = kc.build();
+
+        // Check only for c and cache
+        Krill krill = new Krill(kq.seg("i:c"));
+
+        kc.fromBuilder(
+            cb.orGroup().with(
+                cb.referTo("named-vc1")
+                ).with(
+                    cb.referTo("named-vc2")
+                    )
+            );
+        krill.setCollection(kc);
+        // named-vc1: UID:[2,3]
+        // named-vc2: author:Frank (doc-1)
+
+        assertEquals("OrGroup(referTo(named-vc1) referTo(named-vc2))",
+                     krill.getCollection().toString());
+
+        assertEquals("tokens:i:c", krill.getSpanQuery().toString());
+        
+        Result result = krill.apply(ki);
+        assertEquals("a b [[c]]", result.getMatch(0).getSnippetBrackets());
+        assertEquals("a [[c]] d", result.getMatch(1).getSnippetBrackets());
+        assertEquals(2, result.getMatches().size());
+
+        element = KrillCollection.cache.get("named-vc2");
+        CachedVCData cc = (CachedVCData) element.getObjectValue();
+        assertTrue(cc.getDocIdMap().size() > 0);
+        
+        kc.fromBuilder(
+            cb.orGroup().with(
+                cb.referTo("named-vc1")
+                ).with(
+                    cb.referTo("named-vc2")
+                    )
+            );
+        
+        assertEquals("OrGroup(referTo(cached:named-vc1) referTo(cached:named-vc2))",
+                     krill.getCollection().toString());
+
+        // Check again for c with cache
+        result = krill.apply(ki);
+        assertEquals("a b [[c]]", result.getMatch(0).getSnippetBrackets());
+        assertEquals("a [[c]] d", result.getMatch(1).getSnippetBrackets());
+        assertEquals(2, result.getMatches().size());
+
+        // Check for a with cache
+        krill = new Krill(kq.seg("i:a"));
+        krill.setCollection(kc);
+
+        assertEquals("OrGroup(referTo(cached:named-vc1) referTo(cached:named-vc2))",
+                     krill.getCollection().toString());
+
+        // Check again for c with cache
+        result = krill.apply(ki);
+        assertEquals("[[a]] b c", result.getMatch(0).getSnippetBrackets());
+        assertEquals("[[a]] c d", result.getMatch(1).getSnippetBrackets());
+        assertEquals("[[a]] d e", result.getMatch(2).getSnippetBrackets());
+        assertEquals(3, result.getMatches().size());
+                
+        prop.setProperty("krill.namedVC", tempVC);
+    };
+
+
+	@Ignore
+    public void testNamedVCsAfterCorpusWithMissingDocs () throws IOException {
+        Properties prop = KrillProperties.loadDefaultProperties();
+
+        String vcPath = getClass().getResource(path + "named-vcs").getFile();
+        String tempVC = prop.getProperty("krill.namedVC");
+        prop.setProperty("krill.namedVC", vcPath);
+        
+        ki = new KrillIndex();
+        ki.addDoc(createDoc1());
+        ki.commit();
+        ki.addDoc(createDoc2());
+        ki.commit();
+        ki.addDoc(createDoc3());
+        ki.commit();
+
+        // Check cache
+        Element element = KrillCollection.cache.get("named-vc1");
+        assertNull(element);
+
+        element = KrillCollection.cache.get("named-vc2");
+        assertNull(element);
+
+        QueryBuilder kq = new QueryBuilder("tokens");
+        KrillCollection kc = new KrillCollection(ki);
+        CollectionBuilder cb = kc.build();
+
+        // Check only for c and cache
+        Krill krill = new Krill(kq.seg("i:a"));
+
+        kc.fromBuilder(
+            cb.andGroup().with(
+                cb.term("textClass","kultur")
+                ).with(
+                    cb.orGroup().with(
+                        cb.referTo("named-vc1")
+                        ).with(
+                            cb.referTo("named-vc2")
+                            )
+                    )
+            );
+        krill.setCollection(kc);
+        // named-vc1: UID:[2,3]
+        // named-vc2: author:Frank (doc-1)
+        // textClass:kultur (doc-1,doc-2)
+
+        assertEquals(
+            "AndGroup(textClass:kultur OrGroup(referTo(named-vc1) referTo(named-vc2)))",
+            krill.getCollection().toString());
+        
+        assertEquals("tokens:i:a", krill.getSpanQuery().toString());
+        
+        Result result = krill.apply(ki);
+        assertEquals("[[a]] b c", result.getMatch(0).getSnippetBrackets());
+        assertEquals("[[a]] c d", result.getMatch(1).getSnippetBrackets());
+        assertEquals(2, result.getMatches().size());
+
+        element = KrillCollection.cache.get("named-vc1");
+        CachedVCData cc = (CachedVCData) element.getObjectValue();
+        assertTrue(cc.getDocIdMap().size() > 0);
+
+        element = KrillCollection.cache.get("named-vc2");
+        cc = (CachedVCData) element.getObjectValue();
+        assertTrue(cc.getDocIdMap().size() > 0);
+
+        kc.fromBuilder(
+            cb.orGroup().with(
+                cb.referTo("named-vc1")
+                ).with(
+                    cb.referTo("named-vc2")
+                    )
+            );
+        
+        assertEquals("OrGroup(referTo(cached:named-vc1) referTo(cached:named-vc2))",
+                     krill.getCollection().toString());
+
+        // Check again for c with cache
+        result = krill.apply(ki);
+		assertEquals("[[a]] b c", result.getMatch(0).getSnippetBrackets());
+        assertEquals("[[a]] c d", result.getMatch(1).getSnippetBrackets());
+        assertEquals("[[a]] d e", result.getMatch(2).getSnippetBrackets());
+        assertEquals(3, result.getMatches().size());
+
+        prop.setProperty("krill.namedVC", tempVC);
+    };
+    
+    
 
     @Test
     public void filterExampleFromLegacy () throws Exception {
diff --git a/src/test/resources/queries/collections/named-vcs/named-vc2.jsonld b/src/test/resources/queries/collections/named-vcs/named-vc2.jsonld
index be882a0..82d1dcc 100644
--- a/src/test/resources/queries/collections/named-vcs/named-vc2.jsonld
+++ b/src/test/resources/queries/collections/named-vcs/named-vc2.jsonld
@@ -1,13 +1,9 @@
 {"collection": {
     "name" : "named-vc2",
     "@type": "koral:doc",
-    "key": "textSigle",
+    "key": "author",
     "match": "match:eq",
     "type" : "type:string",
-    "value": [
-        "GOE/AGA/02232",
-        "GOE/AGA/02616",
-        "GOE/AGA/03828"
-    ],
+    "value": "Frank",
     "cache" : "true"
 }}