/******************************************************************************* * Copyright (c) 2012-2015 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.api.vfs.server.impl.memory; import org.eclipse.che.api.vfs.server.VirtualFile; import org.eclipse.che.api.vfs.server.search.LuceneSearcher; import org.eclipse.che.api.vfs.shared.dto.Item; import org.eclipse.che.api.vfs.shared.dto.ItemList; import org.eclipse.che.commons.lang.Pair; import org.apache.lucene.analysis.core.SimpleAnalyzer; import org.apache.lucene.index.Term; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.PrefixQuery; import org.apache.lucene.search.SearcherFactory; import org.apache.lucene.search.SearcherManager; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.everrest.core.impl.ContainerResponse; import org.everrest.core.tools.ByteArrayContainerResponseWriter; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author andrew00x */ public class SearcherTest extends MemoryFileSystemTest { private Pair<String[], String>[] queryToResult; private VirtualFile searchTestFolder; private String searchTestPath; private String file1; private String file2; private String file3; private LuceneSearcher searcher; private SearcherManager searcherManager; @SuppressWarnings("unchecked") @Override protected void setUp() throws Exception { super.setUp(); searchTestFolder = mountPoint.getRoot().createFolder("SearcherTest"); searcher = (LuceneSearcher)mountPoint.getSearcherProvider().getSearcher(mountPoint, true); searcherManager = new SearcherManager(searcher.getIndexWriter(), true, new SearcherFactory()); VirtualFile searchTestFolder = this.searchTestFolder.createFolder("SearcherTest_Folder"); searchTestPath = searchTestFolder.getPath(); file1 = searchTestFolder.createFile("SearcherTest_File01", "text/xml", new ByteArrayInputStream("to be or not to be".getBytes())) .getPath(); file2 = searchTestFolder.createFile("SearcherTest_File02", "text/plain", new ByteArrayInputStream("to be or not to be".getBytes())) .getPath(); VirtualFile folder = searchTestFolder.createFolder("folder01"); String folder1 = folder.getPath(); file3 = folder.createFile("SearcherTest_File03", "text/plain", new ByteArrayInputStream("to be or not to be".getBytes())).getPath(); queryToResult = new Pair[10]; // text queryToResult[0] = new Pair<>(new String[]{file1, file2, file3}, "text=to%20be%20or%20not%20to%20be"); queryToResult[1] = new Pair<>(new String[]{file1, file2, file3}, "text=to%20be%20or"); // text + media type queryToResult[2] = new Pair<>(new String[]{file2, file3}, "text=to%20be%20or&mediaType=text/plain"); queryToResult[3] = new Pair<>(new String[]{file1}, "text=to%20be%20or&mediaType=text/xml"); // text + name queryToResult[4] = new Pair<>(new String[]{file2}, "text=to%20be%20or&name=*File02"); queryToResult[5] = new Pair<>(new String[]{file1, file2, file3}, "text=to%20be%20or&name=SearcherTest*"); // text + path queryToResult[6] = new Pair<>(new String[]{file3}, "text=to%20be%20or&path=" + folder1); queryToResult[7] = new Pair<>(new String[]{file1, file2, file3}, "text=to%20be%20or&path=" + searchTestPath); // name + media type queryToResult[8] = new Pair<>(new String[]{file2, file3}, "name=SearcherTest*&mediaType=text/plain"); queryToResult[9] = new Pair<>(new String[]{file1}, "name=SearcherTest*&mediaType=text/xml"); } @SuppressWarnings({"rawtypes", "unchecked"}) public void testSearch() throws Exception { ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter(); String requestPath = SERVICE_URI + "search"; Map<String, List<String>> h = new HashMap<>(1); h.put("Content-Type", Arrays.asList("application/x-www-form-urlencoded")); for (Pair<String[], String> pair : queryToResult) { ContainerResponse response = launcher.service("POST", requestPath, BASE_URI, h, pair.second.getBytes(), writer, null); //log.info(new String(writer.getBody())); assertEquals("Error: " + response.getEntity(), 200, response.getStatus()); List<Item> result = ((ItemList)response.getEntity()).getItems(); assertEquals(String.format( "Expected %d but found %d for query %s", pair.first.length, result.size(), pair.second), pair.first.length, result.size()); List<String> resultPaths = new ArrayList<>(result.size()); for (Item item : result) { resultPaths.add(item.getPath()); } List<String> copy = new ArrayList<>(resultPaths); copy.removeAll(Arrays.asList(pair.first)); assertTrue(String.format("Expected result is %s but found %s", Arrays.toString(pair.first), resultPaths), copy.isEmpty()); writer.reset(); } } public void testDelete() throws Exception { searcherManager.maybeRefresh(); IndexSearcher luceneSearcher = searcherManager.acquire(); TopDocs topDocs = luceneSearcher.search(new TermQuery(new Term("path", file1)), 10); assertEquals(1, topDocs.totalHits); searcherManager.release(luceneSearcher); mountPoint.getVirtualFile(file1).delete(null); searcherManager.maybeRefresh(); luceneSearcher = searcherManager.acquire(); topDocs = luceneSearcher.search(new TermQuery(new Term("path", file1)), 10); assertEquals(0, topDocs.totalHits); searcherManager.release(luceneSearcher); } public void testDelete2() throws Exception { searcherManager.maybeRefresh(); IndexSearcher luceneSearcher = searcherManager.acquire(); TopDocs topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", searchTestPath)), 10); assertEquals(3, topDocs.totalHits); searcherManager.release(luceneSearcher); mountPoint.getVirtualFile(searchTestPath).delete(null); searcherManager.maybeRefresh(); luceneSearcher = searcherManager.acquire(); topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", searchTestPath)), 10); assertEquals(0, topDocs.totalHits); searcherManager.release(luceneSearcher); } public void testAdd() throws Exception { searcherManager.maybeRefresh(); IndexSearcher luceneSearcher = searcherManager.acquire(); TopDocs topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", searchTestPath)), 10); assertEquals(3, topDocs.totalHits); searcherManager.release(luceneSearcher); mountPoint.getVirtualFile(searchTestPath).createFile("new_file", "text/plain", new ByteArrayInputStream(DEFAULT_CONTENT_BYTES)); searcherManager.maybeRefresh(); luceneSearcher = searcherManager.acquire(); topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", searchTestPath)), 10); assertEquals(4, topDocs.totalHits); searcherManager.release(luceneSearcher); } public void testUpdate() throws Exception { searcherManager.maybeRefresh(); IndexSearcher luceneSearcher = searcherManager.acquire(); TopDocs topDocs = luceneSearcher.search( new QueryParser("text", new SimpleAnalyzer()).parse("updated"), 10); assertEquals(0, topDocs.totalHits); searcherManager.release(luceneSearcher); mountPoint.getVirtualFile(file2).updateContent("text/plain", new ByteArrayInputStream("updated content".getBytes()), null); searcherManager.maybeRefresh(); luceneSearcher = searcherManager.acquire(); topDocs = luceneSearcher.search(new QueryParser("text", new SimpleAnalyzer()).parse("updated"), 10); assertEquals(1, topDocs.totalHits); searcherManager.release(luceneSearcher); } public void testMove() throws Exception { searcherManager.maybeRefresh(); IndexSearcher luceneSearcher = searcherManager.acquire(); String destination = searchTestFolder.createFolder("___destination").getPath(); String expected = destination + '/' + "SearcherTest_File03"; TopDocs topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", expected)), 10); assertEquals(0, topDocs.totalHits); searcherManager.release(luceneSearcher); mountPoint.getVirtualFile(file3).moveTo(mountPoint.getVirtualFile(destination), null); searcherManager.maybeRefresh(); luceneSearcher = searcherManager.acquire(); topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", expected)), 10); assertEquals(1, topDocs.totalHits); topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", file3)), 10); assertEquals(0, topDocs.totalHits); searcherManager.release(luceneSearcher); } public void testCopy() throws Exception { searcherManager.maybeRefresh(); IndexSearcher luceneSearcher = searcherManager.acquire(); String destination = searchTestFolder.createFolder("___destination").getPath(); String expected = destination + '/' + "SearcherTest_File03"; TopDocs topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", expected)), 10); assertEquals(0, topDocs.totalHits); searcherManager.release(luceneSearcher); mountPoint.getVirtualFile(file3).copyTo(mountPoint.getVirtualFile(destination)); searcherManager.maybeRefresh(); luceneSearcher = searcherManager.acquire(); topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", expected)), 10); assertEquals(1, topDocs.totalHits); topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", file3)), 10); assertEquals(1, topDocs.totalHits); searcherManager.release(luceneSearcher); } public void testRename() throws Exception { String newName = "___renamed"; searcherManager.maybeRefresh(); IndexSearcher luceneSearcher = searcherManager.acquire(); TopDocs topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", file3)), 10); assertEquals(1, topDocs.totalHits); searcherManager.release(luceneSearcher); mountPoint.getVirtualFile(file2).rename(newName, null, null); searcherManager.maybeRefresh(); luceneSearcher = searcherManager.acquire(); topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", searchTestPath + '/' + newName)), 10); assertEquals(1, topDocs.totalHits); topDocs = luceneSearcher.search(new PrefixQuery(new Term("path", file2)), 10); assertEquals(0, topDocs.totalHits); searcherManager.release(luceneSearcher); } }