final StringBuilder b = new StringBuilder();
String name = graph.getPossibleRelatedValue(parameter, L0.HasName, Bindings.STRING);
if(name != null) {
- b.append(name);
+ b.append(TypeString.escapeToken(name));
for (Resource r : supers) {
name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
if(name != null) {
b.append(parameter2);
- b.append(name);
+ b.append(TypeString.escapeToken(name));
} else {
Logger.defaultLogError(new DatabaseException("No name for type " + r));
}
} else {
Logger.defaultLogError(new DatabaseException("No name for type " + parameter));
}
-
+
return b.toString();
}
boolean first = true;
for(Resource r : parameter) {
String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
- if(!first) result.append(parameter2);
- else first = false;
- result.append(name);
+ if (name != null) {
+ if(!first) result.append(parameter2);
+ else first = false;
+ result.append(escapeToken(name));
+ }
}
return result.toString();
}
+
+ public static String escapeToken(String token) {
+ return token.replaceAll("( |\\\\)", "\\\\$0");
+ }
}
\ No newline at end of file
import org.simantics.db.Session;
import org.simantics.db.common.procedure.adapter.TransientCacheListener;
import org.simantics.db.common.request.ObjectsWithType;
-import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.db.service.CollectionSupport;
import org.simantics.layer0.Layer0;
public static Collection<Resource> findByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException {
HashSet<Resource> results = new HashSet<Resource>();
-
- String search = "Types:*" + NameUtils.getSafeName(graph, type);
+ Layer0 L0 = Layer0.getInstance(graph);
+ String typeName = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);
+ String search = "Types:" + IndexQueries.quoteTerm(typeName);
for(Map<String, Object> entry : find(graph, model, search)) {
Resource resource = (Resource)entry.get("Resource");
Layer0 L0 = Layer0.getInstance(graph);
HashSet<Resource> results = new HashSet<Resource>();
-
- String search = "Types:*" + type + " AND Name:" + name;
+ String typeName = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);
+ String search = "Types:" + IndexQueries.quoteTerm(typeName) + " AND Name:" + IndexQueries.quoteTerm(name);
for(Map<String, Object> entry : find(graph, model, search)) {
Resource resource = (Resource)entry.get("Resource");
- if(graph.isInstanceOf(resource, type) && name.equals(graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING))) results.add(resource);
+ if(graph.isInstanceOf(resource, type)) results.add(resource);
}
return results;
}
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Pattern;
import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
+import org.apache.lucene.analysis.pattern.PatternReplaceFilter;
+import org.apache.lucene.analysis.pattern.PatternTokenizer;
import org.apache.lucene.analysis.util.CharTokenizer;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
}
}
+ static final class TypeStringAnalyzer extends Analyzer {
+
+ @Override
+ protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
+ Tokenizer tokenizer = new PatternTokenizer(reader, Pattern.compile("(([^\\\\ ]|\\\\\\\\|\\\\ )+)( *)"), 1);
+ TokenFilter filter = new PatternReplaceFilter(tokenizer, Pattern.compile("(\\\\(\\\\| ))"), "$2", true);
+
+ return new TokenStreamComponents(tokenizer, filter);
+ }
+
+ }
+
private static AtomicReference<Pair<Query, String>> queryCache = new AtomicReference<>();
final static PerFieldAnalyzerWrapper analyzer = createAnalyzer();
analyzerPerField.put("Parent", new KeywordAnalyzer());
analyzerPerField.put("Resource", new KeywordAnalyzer());
analyzerPerField.put("GUID", new KeywordAnalyzer());
+ analyzerPerField.put("Name", new KeywordAnalyzer());
+ analyzerPerField.put("Types", new TypeStringAnalyzer());
PerFieldAnalyzerWrapper analyzer = new PerFieldAnalyzerWrapper(new LowerCaseWhitespaceAnalyzer(Version.LUCENE_4_9), analyzerPerField);
return analyzer;
//System.err.println("parse " + search + " (cached=" + (cachedQuery != null ? cachedQuery.second : "null") + ")" );
CustomQueryParser parser = new CustomQueryParser(Version.LUCENE_4_9, "Name", getAnalyzer(), schema);
+ parser.setLowercaseExpandedTerms(false);
Query query = parser.parse(search);
queryCache.set(Pair.make(query, search));
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.Instances;
import org.simantics.db.layer0.adapter.impl.EntityInstances.QueryIndex;
+import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.layer0.Layer0;
import org.simantics.scl.runtime.function.Function1;
}
public static List<Resource> searchByGUID(ReadGraph graph, Resource indexRoot, String indexString) throws DatabaseException {
- return searchByQueryShallow(graph, indexRoot, "GUID:" + indexString);
+ return searchByQueryShallow(graph, indexRoot, "GUID:" + IndexQueries.quoteTerm(indexString));
}
public static List<Resource> searchByQueryShallow(ReadGraph graph, Resource model, String query) throws DatabaseException {
}
public static List<Resource> searchByTypeAndNameShallow(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {
- return graph.syncRequest(new QueryIndex(model, type, name), TransientCacheListener.<List<Resource>>instance());
+ return graph.syncRequest(new QueryIndex(model, type, IndexQueries.quoteTerm(name)), TransientCacheListener.<List<Resource>>instance());
}
}
String typeName = graph.getPossibleRelatedValue(type, L0.HasName, Bindings.STRING);
if (typeName == null || typeName.isEmpty())
return null;
- sb.append("Types:").append( IndexQueries.escape( typeName, true ) );
+ sb.append("Types:").append( IndexQueries.quoteTerm(typeName) );
}
if (!emptyFilter) {
if (sb.length() > 0)
sb.append(" AND ");
sb.append(filter);
}
+ if (sb.length() == 0) {
+ sb.append("*:*");
+ }
return sb.toString();
}
@Override
public int getType() {
- return RequestFlags.IMMEDIATE_UPDATE;
+ // This query should not be immediate update since it takes a long time!
+ return RequestFlags.INVALIDATE;
}
}
@Override
public Collection<Resource> findByName(ReadGraph graph, Resource model,
String name) throws DatabaseException {
- Layer0 L0 = Layer0.getInstance(graph);
- CollectionSupport coll = graph.getService(CollectionSupport.class);
- List<Resource> results = coll.createList();
- for(Resource match : find(graph, model, name)) {
- if(name.equals(graph.getPossibleRelatedValue(match, L0.HasName, Bindings.STRING))) results.add(match);
- }
- return results;
+ return find(graph, model, IndexQueries.quoteTerm(name));
}
}
// These characters are part of the query syntax and must be escaped
if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':'
|| c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~'
- || c == '|' || c == '&' || c == '/' || (escapeWildcards && (c == '*' || c == '?'))) {
+ || c == '|' || c == '&' || c == '/' || c == ' ' || (escapeWildcards && (c == '*' || c == '?'))) {
sb.append('\\');
sb.append(c);
lastWhitespace = false;
// These characters are part of the query syntax and must be escaped
if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':'
|| c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~'
- || c == '|' || c == '&' || c == '/' || (escapeWildcards && (c == '*' || c == '?'))) {
+ || c == '|' || c == '&' || c == '/' || c == ' ' || (escapeWildcards && (c == '*' || c == '?'))) {
return true;
} else if (Character.isWhitespace(c)) {
lastWhitespace = true;
}
private static final String[] RESERVED_WORDS = {
- "AND", "and",
- "OR", "or"
+ "AND", "\\AND",
+ "OR", "\\OR",
+ "NOT", "\\NOT",
};
/**
StringBuilder sb = new StringBuilder();
return escapeTerm(field, term, escapeWildcards, sb).toString();
}
+
+ public static String quoteTerm(String term) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("\"");
+ sb.append(term.replaceAll("(\"|\\\\)", "\\\\$0"));
+ sb.append("\"");
+ return sb.toString();
+ }
// public static void main(String[] args) {
// System.out.println("esc: " + escape("AND01", true, true));
import org.simantics.db.Resource;
import org.simantics.db.common.request.ResourceRead2;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.layer0.Layer0;
import org.simantics.operation.Layer0X;
import org.simantics.scl.runtime.function.Function;
Function dependencies = graph.adapt(L0X.Dependencies, Function.class);
- Collection<Map<String, Object>> results = (Collection<Map<String, Object>>)dependencies.apply(graph, resource2, "Types:*" + typeName);
+ Collection<Map<String, Object>> results = (Collection<Map<String, Object>>)dependencies.apply(graph, resource2, "Types:" + IndexQueries.quoteTerm(typeName));
if (results == null)
return Collections.emptySet();
import org.simantics.db.common.request.PossibleIndexRoot;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.impl.EntityInstances.QueryIndex;
+import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.db.layer0.util.ConsistsOfProcess.ConsistsOfProcessEntry;
import org.simantics.db.layer0.util.DomainProcessor3.ExclusionDecision;
import org.simantics.db.layer0.util.TransferableGraphConfiguration2.SeedSpec;
Layer0 L0 = Layer0.getInstance(graph);
GUID guid = graph.getPossibleRelatedValue(source, L0.identifier, GUID.BINDING);
if(guid != null) {
- List<Resource> exist = graph.syncRequest(new QueryIndex(targetIndex, L0.Entity, "GUID:" + guid.indexString()));
+ List<Resource> exist = graph.syncRequest(new QueryIndex(targetIndex, L0.Entity, "GUID:" + IndexQueries.quoteTerm(guid.indexString())));
return !exist.isEmpty();
}
return false;
if (buttonId == SHOW_IN_BROWSER_ID) {
okPressed();
LabeledResource lr = (LabeledResource) getFirstResult();
- ShowInBrowser.defaultExecute(new StructuredSelection(new ResourceWorkbenchSelectionElement(lr.resource)));
+ if (lr != null) {
+ ShowInBrowser.defaultExecute(new StructuredSelection(new ResourceWorkbenchSelectionElement(lr.resource)));
+ }
return;
}
super.buttonPressed(buttonId);
import org.simantics.db.layer0.adapter.GenericRelationIndex;
import org.simantics.db.layer0.adapter.Instances;
import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
-import org.simantics.db.layer0.adapter.impl.EntityInstances.QueryIndex;
import org.simantics.db.layer0.adapter.impl.ImportAdvisorFactory;
import org.simantics.db.layer0.genericrelation.DependenciesRelation.DependencyChangesRequest;
import org.simantics.db.layer0.genericrelation.DependencyChanges;
import org.simantics.structural.stubs.StructuralResource2;
import org.simantics.structural2.scl.StructuralComponent;
import org.simantics.structural2.utils.StructuralUtils;
-import org.simantics.ui.SimanticsUI;
import org.simantics.utils.ObjectUtils;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.datastructures.Triple;
public static void importModel(String fileName) {
- Resource project = SimanticsUI.getProject().get();
+ Resource project = Simantics.getProject().get();
try (StreamingTransferableGraphFileReader importer = new StreamingTransferableGraphFileReader(new File(fileName))) {
TransferableGraphSource tg = importer.readTG();
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.exception.VariableException;
+import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.db.layer0.request.PossibleModel;
import org.simantics.db.layer0.variable.RVI;
import org.simantics.db.layer0.variable.Variable;
@SuppressWarnings("rawtypes")
Function modules = graph.adapt(Layer0X.getInstance(graph).Dependencies, Function.class);
@SuppressWarnings("unchecked")
- List<Map<String, Object>> rows = (List<Map<String, Object>>) modules.apply(graph, root, "Types:\"" + result.componentType.getName() + "\"");
+ List<Map<String, Object>> rows = (List<Map<String, Object>>) modules.apply(graph, root, "Types:" + IndexQueries.quoteTerm(result.componentType.getName()));
if (rows.isEmpty())
return;
if (propositionPreFilter != null)
proposition = propositionPreFilter.apply(proposition);
- String search = "Name:" + IndexQueries.escape( proposition ) + "*";
+ String search = "Name:" + IndexQueries.quoteTerm( proposition );
@SuppressWarnings("unchecked")
List<Resource> components = (List<Resource>) index.apply(graph, indexRoot, search, Integer.MAX_VALUE);