X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.workbench.search%2Fsrc%2Forg%2Fsimantics%2Fworkbench%2Fsearch%2FSearching.java;h=0c848582c094838621aeabe304f535d7751b5c1e;hb=refs%2Fchanges%2F38%2F238%2F2;hp=00d5de7e671f9692693beb1576e67e22186791b8;hpb=24e2b34260f219f0d1644ca7a138894980e25b14;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.workbench.search/src/org/simantics/workbench/search/Searching.java b/bundles/org.simantics.workbench.search/src/org/simantics/workbench/search/Searching.java index 00d5de7e6..0c848582c 100644 --- a/bundles/org.simantics.workbench.search/src/org/simantics/workbench/search/Searching.java +++ b/bundles/org.simantics.workbench.search/src/org/simantics/workbench/search/Searching.java @@ -1,280 +1,280 @@ -package org.simantics.workbench.search; - -import java.io.CharArrayWriter; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.osgi.framework.Bundle; -import org.simantics.NameLabelMode; -import org.simantics.NameLabelUtil; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.exception.DatabaseException; -import org.simantics.scl.runtime.function.Function; -import org.simantics.scl.runtime.function.Function4; -import org.simantics.utils.datastructures.MapList; -import org.simantics.utils.datastructures.Pair; - -import freemarker.template.Configuration; -import freemarker.template.DefaultObjectWrapper; -import freemarker.template.Template; -import freemarker.template.TemplateException; - -/** - * @author Tuukka Lehtonen - * @author Marko Luukkainen - */ -public final class Searching { - - static final boolean USE_PAGING = false; // create multipage results (currently paging is handled by DataTables (JavaScript)) - static final int MAX_PER_PAGE = 100; - - - /** - * @param graph - * @param query - * @throws DatabaseException - */ - public static Collection> performSearch(ReadGraph graph, Resource searchFunction, Resource model, String query, int maxResults) - throws DatabaseException { - @SuppressWarnings("unchecked") - Function4>> f = graph.adapt(searchFunction, Function.class); - Collection> results = f.apply(graph, model, query, maxResults); - return results; - } - - /** - * @param graph - * @param query - * @param maxResultsPerModel - * @param results - * @return - * @throws IOException - * @throws TemplateException - * @throws DatabaseException - */ - public static List generatePage(ReadGraph graph, Collection searchEngines, SearchQuery query, int maxResultsPerModel, - MapList> results) throws IOException, TemplateException, DatabaseException { - URL fileUrl = getSearchFileURL(); - File dataDir = getAbsoluteFile(fileUrl); - - SearchData data = new SearchData(); - data.dataUrl = fileUrl.toString(); - data.dataDirectory = dataDir; - data.query = query; - data.maxResults = maxResultsPerModel; - data.model = null; - data.results = new SearchResult(); - data.resultCount = 0; - data.searchEngines = searchEngines; - - - int resultCount = 0; - int resultNumber = 0; - - int itemsOnPreviousPage = 0; - - - List result = new ArrayList(); - - QueryResult header = applyTemplate(graph, "header.ftl", data); - QueryResult footer = applyTemplate(graph, "footer.ftl", data); - StringBuilder body = new StringBuilder(1024 * 80); - - if (USE_PAGING) { - List> allResults = results.getAllValuesSnapshot(); - for (Pair entry : allResults) { - List items = entry.second.rows; - resultCount += items.size(); - } - data.resultCount = resultCount; - - - for (Resource model : results.getKeys()) { - List> modelResults = results.getValues(model); - for (Pair entry : modelResults) { - - - List items = entry.second.rows; - int start = 0; - int count = items.size(); - - while (count + itemsOnPreviousPage > MAX_PER_PAGE) { - int toPage = MAX_PER_PAGE-itemsOnPreviousPage; - QueryResult content = generateResultTable(graph, query, maxResultsPerModel, data, resultNumber, resultCount, model, entry.first,entry.second.subset(start, start+toPage)); - body.append( content.getHtml() ); - result.add( new QueryResult(header.getHtml(),body.toString(),footer.getHtml(), resultCount)); - start += toPage; - count -= toPage; - itemsOnPreviousPage = 0; - body = new StringBuilder(1024 * 80); - } - if (count > 0) { - QueryResult content = generateResultTable(graph, query, maxResultsPerModel, data, resultNumber, resultCount, model, entry.first,entry.second.subset(start, start+count)); - body.append( content.getHtml() ); - itemsOnPreviousPage += count; - } - - ++resultNumber; - - - } - } - if (body.length() > 0) - result.add( new QueryResult(header.getHtml(),body.toString(),footer.getHtml(), resultCount)); - } else { - List> allResults = results.getAllValuesSnapshot(); - for (Pair entry : allResults) { - List items = entry.second.rows; - resultCount += items.size(); - } - data.resultCount = resultCount; - - for (Resource model : results.getKeys()) { - List> modelResults = results.getValues(model); - for (Pair entry : modelResults) { - QueryResult content = generateResultTable(graph, query, maxResultsPerModel, data, resultNumber, resultCount, model, entry.first, entry.second); - body.append( content.getHtml() ); - ++resultNumber; - } - } - result.add( new QueryResult(header.getHtml(),body.toString(),footer.getHtml(), resultCount)); - } - if (result.size() == 0) { - result.add( new QueryResult(header.getHtml(),body.toString(),footer.getHtml(), resultCount)); - } - - return result; - - - } - - /** - * @param graph - * @param query - * @param maxResultsPerModel - * @param resultNumber - * @param results - * @return - * @throws IOException - * @throws TemplateException - * @throws DatabaseException - */ - public static QueryResult generateResultTable(ReadGraph graph, SearchQuery query, int maxResultsPerModel, - SearchData template, int resultNumber, int resultCount, Resource model, SearchEngine searchEngine, SearchResult results) - throws IOException, TemplateException, DatabaseException { - SearchData data = template.clone(); - data.resultNumber = resultNumber; - data.query = query; - data.maxResults = maxResultsPerModel; - data.model = NamedResource.of(graph, model); - data.results = results; - data.searchEngine = searchEngine; - - return applyTemplate(graph, "searchtable.ftl", data); - } - - /** - * @return - * @throws IOException - */ - private static URL getSearchFileURL() throws IOException { - Bundle b = Platform.getBundle(Activator.PLUGIN_ID); - URL dataUrl = FileLocator.find(b, new Path("search"), null); - if (dataUrl == null) - throw new IOException("Could not find search template data"); - - URL fileUrl = FileLocator.toFileURL(dataUrl); - return fileUrl; - } - - /** - * @return - * @throws IOException - */ - private static File getAbsoluteFile(URL fileUrl) throws IOException { - File dataDir = new File(URLDecoder.decode(fileUrl.getPath(), "UTF-8")).getAbsoluteFile(); - return dataDir; - } - - - /** - * @param graph - * @param templateName - * @param data - * @return - * @throws IOException - * @throws TemplateException - * @throws DatabaseException - */ - public static QueryResult applyTemplate(ReadGraph graph, String templateName, SearchData data) - throws IOException, TemplateException, DatabaseException { - Configuration cfg = new Configuration(); - cfg.setDirectoryForTemplateLoading(data.getDataDirectory()); - cfg.setObjectWrapper(new DefaultObjectWrapper()); - - Template temp = cfg.getTemplate(templateName); - CharArrayWriter writer = new CharArrayWriter(1024 * 128); - temp.process(data, writer); - - return new QueryResult(writer.toString(), data.results.rows.size()); - } - - /** - * @param graph - * @param results - * @return map: model -> SearchResult - * @throws DatabaseException - */ - public static final SearchResult generateDependenciesSearchResult(ReadGraph graph, - Collection> results) throws DatabaseException { - Set processed = new HashSet(); - SearchResult result = new SearchResult(NameAndTypeRow.columns); - - NameLabelMode mode = NameLabelUtil.getNameLabelMode(graph); - - for (Map r : results) { - Resource resource = (Resource) r.get("Resource"); - - // Prevent index corruption from producing duplicate results. - if (!processed.add(resource)) - continue; - - Resource parent = (Resource) r.get("Parent"); - String name = (String) r.get("Name"); - - NameAndTypeRow rst = new NameAndTypeRow(); - rst.resource = NamedResource.of(graph, resource, name); - rst.parent = NamedResource.of(graph, parent, NameLabelUtil.modalName(graph, parent, mode)); - - Collection typeResources = graph.getTypes(resource); - Collection principalTypeResources = graph.getPrincipalTypes(resource); - if (!typeResources.isEmpty()) { - rst.types = new ArrayList(typeResources.size()); - rst.principalTypes = new ArrayList(principalTypeResources.size()); - for (Resource t : typeResources) { - NamedResource nr = NamedResource.of(graph, t); - rst.types.add(nr); - if (principalTypeResources.contains(t)) - rst.principalTypes.add(nr); - } - } - - result.addRow(rst); - } - - return result; - } - -} +package org.simantics.workbench.search; + +import java.io.CharArrayWriter; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.simantics.NameLabelMode; +import org.simantics.NameLabelUtil; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.scl.runtime.function.Function; +import org.simantics.scl.runtime.function.Function4; +import org.simantics.utils.datastructures.MapList; +import org.simantics.utils.datastructures.Pair; + +import freemarker.template.Configuration; +import freemarker.template.DefaultObjectWrapper; +import freemarker.template.Template; +import freemarker.template.TemplateException; + +/** + * @author Tuukka Lehtonen + * @author Marko Luukkainen + */ +public final class Searching { + + static final boolean USE_PAGING = false; // create multipage results (currently paging is handled by DataTables (JavaScript)) + static final int MAX_PER_PAGE = 100; + + + /** + * @param graph + * @param query + * @throws DatabaseException + */ + public static Collection> performSearch(ReadGraph graph, Resource searchFunction, Resource model, String query, int maxResults) + throws DatabaseException { + @SuppressWarnings("unchecked") + Function4>> f = graph.adapt(searchFunction, Function.class); + Collection> results = f.apply(graph, model, query, maxResults); + return results; + } + + /** + * @param graph + * @param query + * @param maxResultsPerModel + * @param results + * @return + * @throws IOException + * @throws TemplateException + * @throws DatabaseException + */ + public static List generatePage(ReadGraph graph, Collection searchEngines, SearchQuery query, int maxResultsPerModel, + MapList> results) throws IOException, TemplateException, DatabaseException { + URL fileUrl = getSearchFileURL(); + File dataDir = getAbsoluteFile(fileUrl); + + SearchData data = new SearchData(); + data.dataUrl = fileUrl.toString(); + data.dataDirectory = dataDir; + data.query = query; + data.maxResults = maxResultsPerModel; + data.model = null; + data.results = new SearchResult(); + data.resultCount = 0; + data.searchEngines = searchEngines; + + + int resultCount = 0; + int resultNumber = 0; + + int itemsOnPreviousPage = 0; + + + List result = new ArrayList(); + + QueryResult header = applyTemplate(graph, "header.ftl", data); + QueryResult footer = applyTemplate(graph, "footer.ftl", data); + StringBuilder body = new StringBuilder(1024 * 80); + + if (USE_PAGING) { + List> allResults = results.getAllValuesSnapshot(); + for (Pair entry : allResults) { + List items = entry.second.rows; + resultCount += items.size(); + } + data.resultCount = resultCount; + + + for (Resource model : results.getKeys()) { + List> modelResults = results.getValues(model); + for (Pair entry : modelResults) { + + + List items = entry.second.rows; + int start = 0; + int count = items.size(); + + while (count + itemsOnPreviousPage > MAX_PER_PAGE) { + int toPage = MAX_PER_PAGE-itemsOnPreviousPage; + QueryResult content = generateResultTable(graph, query, maxResultsPerModel, data, resultNumber, resultCount, model, entry.first,entry.second.subset(start, start+toPage)); + body.append( content.getHtml() ); + result.add( new QueryResult(header.getHtml(),body.toString(),footer.getHtml(), resultCount)); + start += toPage; + count -= toPage; + itemsOnPreviousPage = 0; + body = new StringBuilder(1024 * 80); + } + if (count > 0) { + QueryResult content = generateResultTable(graph, query, maxResultsPerModel, data, resultNumber, resultCount, model, entry.first,entry.second.subset(start, start+count)); + body.append( content.getHtml() ); + itemsOnPreviousPage += count; + } + + ++resultNumber; + + + } + } + if (body.length() > 0) + result.add( new QueryResult(header.getHtml(),body.toString(),footer.getHtml(), resultCount)); + } else { + List> allResults = results.getAllValuesSnapshot(); + for (Pair entry : allResults) { + List items = entry.second.rows; + resultCount += items.size(); + } + data.resultCount = resultCount; + + for (Resource model : results.getKeys()) { + List> modelResults = results.getValues(model); + for (Pair entry : modelResults) { + QueryResult content = generateResultTable(graph, query, maxResultsPerModel, data, resultNumber, resultCount, model, entry.first, entry.second); + body.append( content.getHtml() ); + ++resultNumber; + } + } + result.add( new QueryResult(header.getHtml(),body.toString(),footer.getHtml(), resultCount)); + } + if (result.size() == 0) { + result.add( new QueryResult(header.getHtml(),body.toString(),footer.getHtml(), resultCount)); + } + + return result; + + + } + + /** + * @param graph + * @param query + * @param maxResultsPerModel + * @param resultNumber + * @param results + * @return + * @throws IOException + * @throws TemplateException + * @throws DatabaseException + */ + public static QueryResult generateResultTable(ReadGraph graph, SearchQuery query, int maxResultsPerModel, + SearchData template, int resultNumber, int resultCount, Resource model, SearchEngine searchEngine, SearchResult results) + throws IOException, TemplateException, DatabaseException { + SearchData data = template.clone(); + data.resultNumber = resultNumber; + data.query = query; + data.maxResults = maxResultsPerModel; + data.model = NamedResource.of(graph, model); + data.results = results; + data.searchEngine = searchEngine; + + return applyTemplate(graph, "searchtable.ftl", data); + } + + /** + * @return + * @throws IOException + */ + private static URL getSearchFileURL() throws IOException { + Bundle b = Platform.getBundle(Activator.PLUGIN_ID); + URL dataUrl = FileLocator.find(b, new Path("search"), null); + if (dataUrl == null) + throw new IOException("Could not find search template data"); + + URL fileUrl = FileLocator.toFileURL(dataUrl); + return fileUrl; + } + + /** + * @return + * @throws IOException + */ + private static File getAbsoluteFile(URL fileUrl) throws IOException { + File dataDir = new File(URLDecoder.decode(fileUrl.getPath(), "UTF-8")).getAbsoluteFile(); + return dataDir; + } + + + /** + * @param graph + * @param templateName + * @param data + * @return + * @throws IOException + * @throws TemplateException + * @throws DatabaseException + */ + public static QueryResult applyTemplate(ReadGraph graph, String templateName, SearchData data) + throws IOException, TemplateException, DatabaseException { + Configuration cfg = new Configuration(); + cfg.setDirectoryForTemplateLoading(data.getDataDirectory()); + cfg.setObjectWrapper(new DefaultObjectWrapper()); + + Template temp = cfg.getTemplate(templateName); + CharArrayWriter writer = new CharArrayWriter(1024 * 128); + temp.process(data, writer); + + return new QueryResult(writer.toString(), data.results.rows.size()); + } + + /** + * @param graph + * @param results + * @return map: model -> SearchResult + * @throws DatabaseException + */ + public static final SearchResult generateDependenciesSearchResult(ReadGraph graph, + Collection> results) throws DatabaseException { + Set processed = new HashSet(); + SearchResult result = new SearchResult(NameAndTypeRow.columns); + + NameLabelMode mode = NameLabelUtil.getNameLabelMode(graph); + + for (Map r : results) { + Resource resource = (Resource) r.get("Resource"); + + // Prevent index corruption from producing duplicate results. + if (!processed.add(resource)) + continue; + + Resource parent = (Resource) r.get("Parent"); + String name = (String) r.get("Name"); + + NameAndTypeRow rst = new NameAndTypeRow(); + rst.resource = NamedResource.of(graph, resource, name); + rst.parent = NamedResource.of(graph, parent, NameLabelUtil.modalName(graph, parent, mode)); + + Collection typeResources = graph.getTypes(resource); + Collection principalTypeResources = graph.getPrincipalTypes(resource); + if (!typeResources.isEmpty()) { + rst.types = new ArrayList(typeResources.size()); + rst.principalTypes = new ArrayList(principalTypeResources.size()); + for (Resource t : typeResources) { + NamedResource nr = NamedResource.of(graph, t); + rst.types.add(nr); + if (principalTypeResources.contains(t)) + rst.principalTypes.add(nr); + } + } + + result.addRow(rst); + } + + return result; + } + +}