import org.simantics.db.ReadGraph;
import org.simantics.db.RequestProcessor;
import org.simantics.db.Resource;
+import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.exception.ResourceNotFoundException;
import org.simantics.db.layer0.variable.Variable;
for(Resource childContributionResource :
g.getObjects(browseContextResource, vr.BrowseContext_HasChildContribution)) {
- ChildContribution contribution = ChildContribution.create(g, childContributionResource);
- browseContext.childContributions.put(contribution.getParentNodeType(), contribution);
- browseContext.parentContributions.put(contribution.getChildNodeType(), contribution);
+ try {
+ ChildContribution contribution = ChildContribution.create(g, childContributionResource);
+ browseContext.childContributions.put(contribution.getParentNodeType(), contribution);
+ browseContext.parentContributions.put(contribution.getChildNodeType(), contribution);
+ } catch (DatabaseException e) {
+ LOGGER.error("Failed to load child contribution " + NameUtils.getSafeName(g, childContributionResource), e);
+ }
}
for(Resource visualsContributionResource :
g.getObjects(browseContextResource, vr.BrowseContext_HasVisualsContribution)) {
- VisualsContribution.load(g, visualsContributionResource,
- browseContext.labelContributions,
- browseContext.imageContributions,
- browseContext.checkedStateContributions,
- browseContext.labelDecorationContributions,
- browseContext.imageDecorationContributions,
- browseContext.modifierContributions,
- browseContext.sorterContributions,
- browseContext.flatNodeContributions,
- browseContext.tooltipContributions
+ try {
+ VisualsContribution.load(g, visualsContributionResource,
+ browseContext.labelContributions,
+ browseContext.imageContributions,
+ browseContext.checkedStateContributions,
+ browseContext.labelDecorationContributions,
+ browseContext.imageDecorationContributions,
+ browseContext.modifierContributions,
+ browseContext.sorterContributions,
+ browseContext.flatNodeContributions,
+ browseContext.tooltipContributions
);
+ } catch (DatabaseException e) {
+ LOGGER.error("Failed to load visuals contribution " + NameUtils.getSafeName(g, visualsContributionResource), e);
+ }
}
}
//browseContext.visualize();
public static Collection<Resource> findByName(ReadGraph graph, Resource model, String name) throws DatabaseException {
Layer0 L0 = Layer0.getInstance(graph);
HashSet<Resource> results = new HashSet<Resource>();
-
+
String search = IndexQueries.quoteTerm(Dependencies.FIELD_NAME, name);
for(Resource resource : findResources(graph, model, search)) {
}
public static Collection<Resource> findByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException {
-
- HashSet<Resource> results = new HashSet<Resource>();
- Layer0 L0 = Layer0.getInstance(graph);
- String typeName = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);
- String search = IndexQueries.quoteTerm(Dependencies.FIELD_TYPES, typeName);
+ HashSet<Resource> results = new HashSet<>();
+ String search = IndexQueries.resourceIdTerm(Dependencies.FIELD_TYPE_RESOURCE, type);
for(Resource resource : findResources(graph, model, search)) {
- if(graph.isInstanceOf(resource, type)) results.add(resource);
+ if(graph.isInstanceOf(resource, type)) results.add(resource);
}
return results;
}
public static Collection<Resource> findByTypeAndName(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {
-
- Layer0 L0 = Layer0.getInstance(graph);
-
HashSet<Resource> results = new HashSet<Resource>();
- String typeName = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);
-
- String search = IndexQueries.and(IndexQueries.quoteTerm(Dependencies.FIELD_TYPES, typeName), IndexQueries.quoteTerm(Dependencies.FIELD_NAME, name));
+ String search = IndexQueries.and(IndexQueries.resourceIdTerm(Dependencies.FIELD_TYPE_RESOURCE, type), IndexQueries.quoteTerm(Dependencies.FIELD_NAME, name));
for(Resource resource : findResources(graph, model, search)) {
- if(graph.isInstanceOf(resource, type)) results.add(resource);
+ if(graph.isInstanceOf(resource, type)) results.add(resource);
}
return results;
}
}
changeState(monitor, session, State.READY);
-
-// closeInternal();
-
+
return result;
}
try {
if(writer != null)
writer.commit();
- } catch (CorruptIndexException e) {
- e.printStackTrace();
} catch (IOException e) {
- e.printStackTrace();
+ getLogger().error("Index commit failed", e);
}
}
removedTerm = new Term(key, (String) keyValue);
} else {
// FIXME: should throw an exception for illegal input data but this would leave the index in an incoherent state
+ getLogger().error("Attempting to remove document from index of {} with key {} and unrecognized key value type {} : {}", input, key, keyValue, keyValue != null ? keyValue.getClass() : "null");
continue;
}
boolean done = false;
if(requireChangeInfoOnReplace()) {
TopDocs exist = searcher.search(new TermQuery(removedTerm), null, 2);
- if(exist.scoreDocs.length == 1 && requireChangeInfoOnReplace()) {
+ if(exist.scoreDocs.length == 1) {
Document doc = reader.document(exist.scoreDocs[0].doc);
if(!areSame(doc, document)) {
writer.deleteDocuments(removedTerm);
final static PerFieldAnalyzerWrapper analyzer = createAnalyzer();
static PerFieldAnalyzerWrapper createAnalyzer() {
-
- Map<String,Analyzer> analyzerPerField = new HashMap<>();
- analyzerPerField.put("Model", new KeywordAnalyzer());
- 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(false));
- analyzerPerField.put(Dependencies.FIELD_NAME_SEARCH, new LowerCaseWhitespaceAnalyzer(Version.LUCENE_4_9));
- analyzerPerField.put(Dependencies.FIELD_TYPES_SEARCH, new TypeStringAnalyzer(true));
-
+
+ Map<String,Analyzer> analyzerPerField = new HashMap<>();
+ analyzerPerField.put(Dependencies.FIELD_MODEL, new KeywordAnalyzer());
+ analyzerPerField.put(Dependencies.FIELD_PARENT, new KeywordAnalyzer());
+ analyzerPerField.put(Dependencies.FIELD_RESOURCE, new KeywordAnalyzer());
+ analyzerPerField.put(Dependencies.FIELD_GUID, new KeywordAnalyzer());
+ analyzerPerField.put(Dependencies.FIELD_NAME, new KeywordAnalyzer());
+ analyzerPerField.put(Dependencies.FIELD_TYPES, new TypeStringAnalyzer(false));
+ analyzerPerField.put(Dependencies.FIELD_NAME_SEARCH, new LowerCaseWhitespaceAnalyzer(Version.LUCENE_4_9));
+ analyzerPerField.put(Dependencies.FIELD_TYPES_SEARCH, new TypeStringAnalyzer(true));
+ analyzerPerField.put(Dependencies.FIELD_TYPE_RESOURCE, new WhitespaceAnalyzer(Version.LUCENE_4_9));
+
PerFieldAnalyzerWrapper analyzer = new PerFieldAnalyzerWrapper(new LowerCaseWhitespaceAnalyzer(Version.LUCENE_4_9), analyzerPerField);
return analyzer;
-
+
}
static PerFieldAnalyzerWrapper getAnalyzer() {
/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
import java.util.List;
import java.util.Set;
-import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.common.primitiverequest.Adapter;
import org.simantics.db.common.request.TernaryRead;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.db.layer0.genericrelation.Dependencies;
import org.simantics.db.layer0.genericrelation.IndexQueries;
import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.db.request.ReadExt;
StringBuilder sb = new StringBuilder();
boolean emptyFilter = filter.isEmpty();
if (emptyFilter || !type.equals(L0.Entity)) {
- String typeName = graph.getPossibleRelatedValue(type, L0.HasName, Bindings.STRING);
- if (typeName == null || typeName.isEmpty())
- return null;
- sb.append("Types:").append( IndexQueries.quoteTerm(typeName) );
+ IndexQueries.appendResourceIdTerm(sb, Dependencies.FIELD_TYPE_RESOURCE, type);
}
if (!emptyFilter) {
if (sb.length() > 0)
public static final String FIELD_GUID = "GUID";
public static final String FIELD_NAME_SEARCH = "NameSearch";
public static final String FIELD_TYPES_SEARCH = "TypesSearch";
+ public static final String FIELD_TYPE_RESOURCE = "TypeId";
protected Resource getIndexRelation(ReadGraph graph) {
return Layer0X.getInstance(graph).DependenciesRelation;
}
protected static String getBindingPattern() {
- return "bfffffff";
+ return "bffffffff";
}
@Override
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
import org.simantics.databoard.Bindings;
Pair.make(Dependencies.FIELD_TYPES, "Text"),
Pair.make(Dependencies.FIELD_GUID, "Text"),
Pair.make(Dependencies.FIELD_NAME_SEARCH, "Text"),
- Pair.make(Dependencies.FIELD_TYPES_SEARCH, "Text")
+ Pair.make(Dependencies.FIELD_TYPES_SEARCH, "Text"),
+ Pair.make(Dependencies.FIELD_TYPE_RESOURCE, "Text")
};
final Resource resource;
});
- Map<Resource, String> typeStrings = cs.createMap(String.class);
+ Map<Resource, Pair<String, String>> typeStrings = cs.createMap(String.class);
for(Entry e : result) {
if(e.principalType != null) {
- String typeString = typeStrings.get(e.principalType);
- if(typeString == null) {
- typeString = graph.syncRequest(new SuperTypeString(e.principalType));
- if (typeString.isEmpty()) {
- LOGGER.error("No name for type", new DatabaseException("No name for type " + NameUtils.getURIOrSafeNameInternal(graph, e.resource) + " (" + e.resource + ")"));
- }
- typeStrings.put(e.principalType, typeString);
- }
- e.types = typeString;
+ Pair<String, String> typeString = typeStrings.get(e.principalType);
+ if(typeString == null) {
+ String superTypeString = graph.syncRequest(new SuperTypeString(e.principalType));
+ if (superTypeString.isEmpty()) {
+ LOGGER.error("No name for type", new DatabaseException("No name for type " + NameUtils.getURIOrSafeNameInternal(graph, e.resource) + " (" + e.resource + ")"));
+ }
+ String superTypeIds = IndexQueries.toResourceIdString(e.principalType, graph.getSupertypes(e.principalType));
+ typeString = Pair.make(superTypeString, superTypeIds);
+ typeStrings.put(e.principalType, typeString);
+ }
+ e.types = typeString.first;
+ e.typeId = typeString.second;
} else {
- e.types = graph.syncRequest(new TypeString(L0, graph.getTypes(e.resource)));
+ Set<Resource> typeSet = graph.getTypes(e.resource);
+ e.types = graph.syncRequest(new TypeString(L0, typeSet));
+ e.typeId = IndexQueries.toResourceIdString(typeSet);
}
- GUID id = graph.getPossibleRelatedValue(e.resource, L0.identifier, GUID.BINDING);
- if(id != null)
- e.id = id.indexString();
- else
- e.id = "";
+ e.id = IndexQueries.idFromGUID( graph.getPossibleRelatedValue(e.resource, L0.identifier, GUID.BINDING) );
}
//SessionGarbageCollection.gc(null, graph.getSession(), false, null);
-
+
}
}
long time = System.nanoTime();
- SerialisationSupport ss = graph.getService(SerialisationSupport.class);
+ SerialisationSupport ss = graph.getService(SerialisationSupport.class);
Resource subject = ss.getResource(subjectId);
-
+
Collection<Entry> entries = find(graph, subject);
long time2 = System.nanoTime();
if (PROFILE)
LOGGER.info("Found " + entries.size() + " dependencies in " + 1e-6 * (time2 - time) + "ms for " + graph.getPossibleURI(subject) + ".");
- ArrayList<Object[]> result = new ArrayList<Object[]>();
+ ArrayList<Object[]> result = new ArrayList<>();
for (Entry entry : entries) {
if(entry.name == null) continue;
- result.add(new Object[] { ss.getRandomAccessId(entry.parent), ss.getRandomAccessId(entry.resource), entry.name, entry.types, entry.id, entry.name, entry.types });
+ result.add(new Object[] { ss.getRandomAccessId(entry.parent), ss.getRandomAccessId(entry.resource), entry.name, entry.types, entry.id, entry.name, entry.types, entry.typeId });
}
return result;
@Override
public synchronized void trackAndIndex(RequestProcessor processor, Resource model__) {
- if(trackers == 0) {
+ if(trackers == 0) {
- if(listener != null) throw new IllegalStateException("Dependency tracking was active");
-
- listener = new GenericChangeListener<DependencyChangesRequest, DependencyChanges>() {
-
- @Override
- public boolean preEventRequest() {
- return !Indexing.isDependenciesIndexingDisabled();
- }
-
- @Override
- public void onEvent(ReadGraph graph, MetadataI metadata, DependencyChanges event) throws DatabaseException {
-
- TimeLogger.log(DependenciesRelation.class, "trackAndIndex.onEvent: starting index update processing");
-
- if(DEBUG)
- LOGGER.info("Adding metadata " + event + " in revision " + graph.getService(ManagementSupport.class).getHeadRevisionId());
-
- WriteGraph w = (WriteGraph)graph;
- if(!event.isEmpty())
- w.addMetadata(event);
-
- final Session session = graph.getSession();
- final IndexedRelations indexer = session.getService(IndexedRelations.class);
- Layer0 L0 = Layer0.getInstance(graph);
- SerialisationSupport ss = graph.getService(SerialisationSupport.class);
-
- for(Map.Entry<Resource, Change[]> modelEntry : event.get().entrySet()) {
-
- final Resource model = modelEntry.getKey();
- final Change[] changes = modelEntry.getValue();
-
- boolean linkChange = false;
-
- Collection<Object[]> _additions = Collections.emptyList();
- Collection<Object> _removals = Collections.emptyList();
- Collection<Object> _replacementKeys = Collections.emptyList();
- Collection<Object[]> _replacementObjects = Collections.emptyList();
- Collection<Pair<String, String>> _typeChanges = Collections.emptyList();
-
- if(DEBUG) LOGGER.info("MODEL: " + NameUtils.getSafeLabel(graph, model));
- // final Change[] changes = event.get(model);
- if(DEBUG) LOGGER.info(" CHANGES: " + Arrays.toString(changes));
- if (changes != null) {
- _additions = new ArrayList<Object[]>();
- _removals = new ArrayList<Object>();
- _replacementKeys = new ArrayList<Object>();
- _replacementObjects = new ArrayList<Object[]>();
- _typeChanges = new HashSet<Pair<String, String>>();
-
- for (Change _entry : changes) {
- if (_entry instanceof ComponentAddition) {
- ComponentAddition entry = (ComponentAddition)_entry;
- final String name = graph.getPossibleRelatedValue(entry.component, L0.HasName, Bindings.STRING);
- final GUID id = graph.getPossibleRelatedValue(entry.component, L0.identifier, GUID.BINDING);
- final String types = graph.syncRequest(new TypeString(L0, graph.getTypes(entry.component)));
- if (name != null && types != null) {
- if(!entry.isValid(graph)) continue;
- Resource parent = graph.getPossibleObject(entry.component, L0.PartOf);
- if (parent != null) {
- _additions.add(new Object[] { ss.getRandomAccessId(parent), ss.getRandomAccessId(entry.component), name, types, id != null ? id.indexString() : "", name, types});
- } else {
- //LOGGER.info("resource " + entry.component + ": no parent for entry " + name + " " + types);
- }
- } else {
- //LOGGER.info("resource " + entry.component + ": " + name + " " + types);
- }
- } else if(_entry instanceof ComponentModification) {
- ComponentModification entry = (ComponentModification)_entry;
- final String name = graph.getPossibleRelatedValue(entry.component, L0.HasName, Bindings.STRING);
- final GUID id = graph.getPossibleRelatedValue(entry.component, L0.identifier, GUID.BINDING);
- if(graph.isInstanceOf(entry.component, L0.Type)) {
- SerialisationSupport support = session.getService(SerialisationSupport.class);
- _typeChanges.add(new Pair<String, String>(name, String.valueOf(support.getRandomAccessId((Resource) entry.component))));
- } else {
- final String types = graph.syncRequest(new TypeString(L0, graph.getTypes(entry.component)));
- if (name != null && types != null) {
- Resource part = graph.getPossibleObject(entry.component, L0.PartOf);
- if(part != null) {
- _replacementKeys.add(ss.getRandomAccessId(entry.component));
- _replacementObjects.add(new Object[] { ss.getRandomAccessId(part),
- ss.getRandomAccessId(entry.component), name, types, id != null ? id.indexString() : "", name, types});
- }
- }
- }
- } else if (_entry instanceof ComponentRemoval) {
- ComponentRemoval entry = (ComponentRemoval)_entry;
- if(!entry.isValid(graph)) continue;
- _removals.add(ss.getRandomAccessId(((ComponentRemoval)_entry).component));
- } else if (_entry instanceof LinkChange) {
- linkChange = true;
- }
- }
- }
-
- final boolean reset = linkChange || event.hasUnresolved;
- //LOGGER.info("dependencies(" + NameUtils.getSafeLabel(graph, model) + "): reset=" + reset + " linkChange=" + linkChange + " unresolved=" + event.hasUnresolved );
-
- if (reset || !_additions.isEmpty() || !_removals.isEmpty() || !_replacementKeys.isEmpty() || !_typeChanges.isEmpty()) {
-
- TimeLogger.log(DependenciesRelation.class, "trackAndIndex.onEvent: starting index update");
-
- final Collection<Object[]> additions = _additions;
- final Collection<Object> removals = _removals;
- final Collection<Object> replacementKeys = _replacementKeys;
- final Collection<Object[]> replacementObjects = _replacementObjects;
- final boolean typeNameChanges = typeNameChanges(graph, indexer, model, _typeChanges);
-
- final UUID pending = Indexing.makeIndexPending();
-
- {
- {
- try {
- boolean didChange = false;
- // Unresolved and linkChanges are not relevant any more
- boolean doReset = typeNameChanges;
-
- if (doReset) {
-
- if(DEBUG) {
- LOGGER.info("resetIndex " + reset + " " + typeNameChanges);
- }
-
- indexer.removeAll(null, graph, DependenciesRelation.this, resource, model);
- didChange = true;
-
- } else {
-
- if (!replacementKeys.isEmpty() && (replacementKeys.size() == replacementObjects.size())) {
- if(DEBUG) {
- LOGGER.info(replacementKeys.size() + " index replacements: " + replacementKeys);
- }
- didChange |= indexer.replace(null, graph, DependenciesRelation.this, resource, model, Dependencies.FIELD_RESOURCE, replacementKeys, replacementObjects);
- }
- if (!removals.isEmpty()) {
- if(DEBUG) {
- LOGGER.info(removals.size() + " index removals: " + removals);
- }
- indexer.remove(null, graph, DependenciesRelation.this, resource, model, Dependencies.FIELD_RESOURCE, removals);
- didChange = true;
- }
- if (!additions.isEmpty()) {
- if(DEBUG) {
- for(Object[] os : additions) LOGGER.info("Adding to index " + model + ": " + Arrays.toString(os));
- }
- //LOGGER.info(additions.size() + " index insertions");
- indexer.insert(null, graph, DependenciesRelation.this, resource, model, additions);
- didChange = true;
- }
-
- }
-
- if (didChange)
- // TODO: because this data is ran with
- // ThreadUtils.getBlockingWorkExecutor()
- // fireListeners needs to use peekService,
- // not getService since there is no
- // guarantee that the session isn't being
- // disposed while this method is executing.
- fireListeners(graph, model);
-
- } catch (Throwable t) {
- // Just to know if something unexpected happens here.
- LOGGER.error("Dependencies index update failed for model "
- + model + " and relation " + resource + ".", t);
-
- // NOTE: Last resort: failure to update index
- // properly results in removal of the whole index.
- // This is the only thing that can be done
- // at this point to ensure that the index will
- // return correct results in the future, through
- // complete reinitialization.
- //indexer.removeAll(null, session, DependenciesRelation.this, resource, model);
- } finally {
- Indexing.releaseIndexPending(pending);
- Indexing.clearCaches(model);
- }
- }
- }
-
- TimeLogger.log(DependenciesRelation.class, "trackAndIndex.onEvent: index update done");
- }
- }
-
- }
-
- };
+ if(listener != null) throw new IllegalStateException("Dependency tracking was active");
- GraphChangeListenerSupport changeSupport = processor.getService(GraphChangeListenerSupport.class);
- changeSupport.addMetadataListener(listener);
+ listener = new GenericChangeListener<DependencyChangesRequest, DependencyChanges>() {
- }
+ @Override
+ public boolean preEventRequest() {
+ return !Indexing.isDependenciesIndexingDisabled();
+ }
+
+ @Override
+ public void onEvent(ReadGraph graph, MetadataI metadata, DependencyChanges event) throws DatabaseException {
+
+ TimeLogger.log(DependenciesRelation.class, "trackAndIndex.onEvent: starting index update processing");
+
+ if(DEBUG)
+ LOGGER.info("Adding metadata " + event + " in revision " + graph.getService(ManagementSupport.class).getHeadRevisionId());
+
+ WriteGraph w = (WriteGraph)graph;
+ if(!event.isEmpty())
+ w.addMetadata(event);
+
+ final Session session = graph.getSession();
+ final IndexedRelations indexer = session.getService(IndexedRelations.class);
+ Layer0 L0 = Layer0.getInstance(graph);
+ SerialisationSupport ss = graph.getService(SerialisationSupport.class);
+
+ for(Map.Entry<Resource, Change[]> modelEntry : event.get().entrySet()) {
+
+ final Resource model = modelEntry.getKey();
+ final Change[] changes = modelEntry.getValue();
+
+ boolean linkChange = false;
+
+ Collection<Object[]> _additions = Collections.emptyList();
+ Collection<Object> _removals = Collections.emptyList();
+ Collection<Object> _replacementKeys = Collections.emptyList();
+ Collection<Object[]> _replacementObjects = Collections.emptyList();
+ Collection<Pair<String, String>> _typeChanges = Collections.emptyList();
+
+ if(DEBUG) LOGGER.info("MODEL: " + NameUtils.getSafeLabel(graph, model));
+ if (changes != null) {
+ if (DEBUG) {
+ LOGGER.info(" CHANGE COUNT: " + changes.length);
+ for (Change c : changes)
+ LOGGER.info(" CHANGE: " + c.toString(graph));
+ }
+ _additions = new ArrayList<>();
+ _removals = new ArrayList<>();
+ _replacementKeys = new ArrayList<>();
+ _replacementObjects = new ArrayList<>();
+ _typeChanges = new HashSet<>();
+
+ for (Change _entry : changes) {
+ if (_entry instanceof ComponentAddition) {
+ ComponentAddition entry = (ComponentAddition)_entry;
+ final String name = graph.getPossibleRelatedValue(entry.component, L0.HasName, Bindings.STRING);
+ Set<Resource> typeSet = graph.getTypes(entry.component);
+ if (name != null && typeSet != null) {
+ if (!entry.isValid(graph))
+ continue;
+ Resource parent = graph.getPossibleObject(entry.component, L0.PartOf);
+ if (parent != null) {
+ final GUID id = graph.getPossibleRelatedValue(entry.component, L0.identifier, GUID.BINDING);
+ final String types = graph.syncRequest(new TypeString(L0, typeSet));
+ final String typeIds = IndexQueries.toResourceIdString(typeSet);
+ _additions.add(new Object[] { ss.getRandomAccessId(parent), ss.getRandomAccessId(entry.component), name, types, IndexQueries.idFromGUID(id), name, types, typeIds});
+ } else {
+ //LOGGER.info("resource " + entry.component + ": no parent for entry " + name + " " + types);
+ }
+ } else {
+ //LOGGER.info("resource " + entry.component + ": " + name + " " + types);
+ }
+ } else if(_entry instanceof ComponentModification) {
+ ComponentModification entry = (ComponentModification)_entry;
+ final String name = graph.getPossibleRelatedValue(entry.component, L0.HasName, Bindings.STRING);
+ if(graph.isInstanceOf(entry.component, L0.Type)) {
+ SerialisationSupport support = session.getService(SerialisationSupport.class);
+ _typeChanges.add(new Pair<String, String>(name, String.valueOf(support.getRandomAccessId((Resource) entry.component))));
+ } else {
+ Set<Resource> typeSet = graph.getTypes(entry.component);
+ if (name != null && !typeSet.isEmpty()) {
+ Resource part = graph.getPossibleObject(entry.component, L0.PartOf);
+ if(part != null) {
+ final GUID id = graph.getPossibleRelatedValue(entry.component, L0.identifier, GUID.BINDING);
+ final String types = graph.syncRequest(new TypeString(L0, typeSet));
+ final String typeIds = IndexQueries.toResourceIdString(typeSet);
+ _replacementKeys.add(ss.getRandomAccessId(entry.component));
+ _replacementObjects.add(new Object[] { ss.getRandomAccessId(part),
+ ss.getRandomAccessId(entry.component), name, types, IndexQueries.idFromGUID(id), name, types, typeIds});
+ }
+ }
+ }
+ } else if (_entry instanceof ComponentRemoval) {
+ ComponentRemoval entry = (ComponentRemoval)_entry;
+ if(!entry.isValid(graph)) continue;
+ _removals.add(ss.getRandomAccessId(((ComponentRemoval)_entry).component));
+ } else if (_entry instanceof LinkChange) {
+ linkChange = true;
+ }
+ }
+ }
+
+ final boolean reset = linkChange || event.hasUnresolved;
+ //LOGGER.info("dependencies(" + NameUtils.getSafeLabel(graph, model) + "): reset=" + reset + " linkChange=" + linkChange + " unresolved=" + event.hasUnresolved );
+
+ if (reset || !_additions.isEmpty() || !_removals.isEmpty() || !_replacementKeys.isEmpty() || !_typeChanges.isEmpty()) {
+
+ TimeLogger.log(DependenciesRelation.class, "trackAndIndex.onEvent: starting index update");
+
+ final Collection<Object[]> additions = _additions;
+ final Collection<Object> removals = _removals;
+ final Collection<Object> replacementKeys = _replacementKeys;
+ final Collection<Object[]> replacementObjects = _replacementObjects;
+ final boolean typeNameChanges = typeNameChanges(graph, indexer, model, _typeChanges);
+
+ final UUID pending = Indexing.makeIndexPending();
+ try {
+ boolean didChange = false;
+ // Unresolved and linkChanges are not relevant any more
+ boolean doReset = typeNameChanges;
+
+ if (doReset) {
+
+ if(DEBUG) {
+ LOGGER.info("resetIndex " + reset + " " + typeNameChanges);
+ }
+
+ indexer.removeAll(null, graph, DependenciesRelation.this, resource, model);
+ didChange = true;
+
+ } else {
+
+ if (!replacementKeys.isEmpty() && (replacementKeys.size() == replacementObjects.size())) {
+ if(DEBUG) {
+ LOGGER.info(replacementKeys.size() + " index replacements: " + replacementKeys);
+ }
+ didChange |= indexer.replace(null, graph, DependenciesRelation.this, resource, model, Dependencies.FIELD_RESOURCE, replacementKeys, replacementObjects);
+ }
+ if (!removals.isEmpty()) {
+ if(DEBUG) {
+ LOGGER.info(removals.size() + " index removals: " + removals);
+ }
+ indexer.remove(null, graph, DependenciesRelation.this, resource, model, Dependencies.FIELD_RESOURCE, removals);
+ didChange = true;
+ }
+ if (!additions.isEmpty()) {
+ if(DEBUG) {
+ for(Object[] os : additions) LOGGER.info("Adding to index " + model + ": " + Arrays.toString(os));
+ }
+ //LOGGER.info(additions.size() + " index insertions");
+ indexer.insert(null, graph, DependenciesRelation.this, resource, model, additions);
+ didChange = true;
+ }
+
+ }
+
+ if (didChange)
+ // TODO: because this data is ran with
+ // ThreadUtils.getBlockingWorkExecutor()
+ // fireListeners needs to use peekService,
+ // not getService since there is no
+ // guarantee that the session isn't being
+ // disposed while this method is executing.
+ fireListeners(graph, model);
+
+ } catch (Throwable t) {
+ // Just to know if something unexpected happens here.
+ LOGGER.error("Dependencies index update failed for model "
+ + model + " and relation " + resource + ".", t);
+
+ // NOTE: Last resort: failure to update index
+ // properly results in removal of the whole index.
+ // This is the only thing that can be done
+ // at this point to ensure that the index will
+ // return correct results in the future, through
+ // complete reinitialization.
+ //indexer.removeAll(null, session, DependenciesRelation.this, resource, model);
+ } finally {
+ Indexing.releaseIndexPending(pending);
+ Indexing.clearCaches(model);
+ }
+
+ TimeLogger.log(DependenciesRelation.class, "trackAndIndex.onEvent: index update done");
+ }
+ }
- trackers++;
+ }
+
+ };
+
+ GraphChangeListenerSupport changeSupport = processor.getService(GraphChangeListenerSupport.class);
+ changeSupport.addMetadataListener(listener);
+
+ }
+
+ trackers++;
}
}
public static void addSubtree(ReadGraph graph, Resource indexRoot, Resource subtreeRoot) throws DatabaseException {
-
+
DependenciesRelation dr = new DependenciesRelation(graph, indexRoot);
- SerialisationSupport ss = graph.getService(SerialisationSupport.class);
+ SerialisationSupport ss = graph.getService(SerialisationSupport.class);
- ArrayList<Entry> entries = dr.find(graph, subtreeRoot);
- entries.add(new Entry(graph, subtreeRoot));
+ ArrayList<Entry> entries = dr.find(graph, subtreeRoot);
+ entries.add(new Entry(graph, subtreeRoot));
ArrayList<Object[]> result = new ArrayList<Object[]>(entries.size());
for (Entry entry : entries) {
- result.add(new Object[] { ss.getRandomAccessId(entry.parent), ss.getRandomAccessId(entry.resource), entry.name, entry.types, entry.id, entry.name, entry.types });
+ result.add(new Object[] { ss.getRandomAccessId(entry.parent), ss.getRandomAccessId(entry.resource), entry.name, entry.types, entry.id, entry.name, entry.types, entry.typeId });
}
Layer0X L0X = Layer0X.getInstance(graph);
- IndexedRelations indexer = graph.getService(IndexedRelations.class);
- indexer.insert(null, graph, dr, L0X.DependenciesRelation, indexRoot, result);
-
+ IndexedRelations indexer = graph.getService(IndexedRelations.class);
+ indexer.insert(null, graph, dr, L0X.DependenciesRelation, indexRoot, result);
+
}
-
+
}
package org.simantics.db.layer0.genericrelation;
+import java.util.Set;
+
import org.simantics.databoard.Bindings;
import org.simantics.datatypes.literal.GUID;
import org.simantics.db.ReadGraph;
this.parent = graph.getPossibleObject(resource, L0.PartOf);
this.resource = resource;
this.name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING);
- this.types = graph.syncRequest(new TypeString(L0, graph.getTypes(resource)));
- this.id = idFromGUID(graph.getPossibleRelatedValue(resource, L0.identifier, GUID.BINDING));
- }
-
- private static String idFromGUID(GUID guid) {
- if(guid == null) return "";
- return guid.indexString();
+ Set<Resource> typeSet = graph.getTypes(resource);
+ this.types = graph.syncRequest(new TypeString(L0, typeSet));
+ this.id = IndexQueries.idFromGUID(graph.getPossibleRelatedValue(resource, L0.identifier, GUID.BINDING));
+ this.typeId = IndexQueries.toResourceIdString(typeSet);
}
Entry(ReadGraph graph, Resource resource) throws DatabaseException {
String types;
String name;
String id;
+ String typeId;
Resource principalType;
@Override
package org.simantics.db.layer0.genericrelation;
+import java.util.Collection;
+
+import org.simantics.datatypes.literal.GUID;
+import org.simantics.db.Resource;
/**
* This class contains utilities related to queries made into Lucene indexes,
).toString();
}
+ public static StringBuilder appendLongTerm(StringBuilder sb, String field, long term) {
+ return sb.append(field).append(':').append(term);
+ }
+
+ public static String longTerm(String field, long term) {
+ return appendLongTerm(new StringBuilder(), field, term).toString();
+ }
+
+ public static StringBuilder appendResourceIdTerm(StringBuilder sb, String field, Resource term) {
+ return appendLongTerm(sb, field, term.getResourceId());
+ }
+
+ public static String resourceIdTerm(String field, Resource term) {
+ return appendLongTerm(new StringBuilder(), field, term.getResourceId()).toString();
+ }
+
private static String join(String withString, String... exps) {
if (exps.length == 0)
return "";
return join(" OR ", exps);
}
+ public static String idFromGUID(GUID guid) {
+ return guid != null ? guid.indexString() : "";
+ }
+
+ public static String toResourceIdString(Resource r, Collection<Resource> rs) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(r.getResourceId());
+ for (Resource rr : rs)
+ sb.append(' ').append(rr.getResourceId());
+ return sb.toString();
+ }
+
+ public static String toResourceIdString(Collection<Resource> rs) {
+ if (rs.isEmpty())
+ return "";
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (Resource rr : rs) {
+ if (!first)
+ sb.append(' ');
+ first = false;
+ sb.append(rr.getResourceId());
+ }
+ return sb.toString();
+ }
+
// public static void main(String[] args) {
// System.out.println("esc: " + escape("AND01", true, true));
// System.out.println("esc: " + escape("AND 01", true, true));
package org.simantics.db.layer0.request;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
import org.simantics.db.ReadGraph;
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;
+import org.simantics.db.layer0.QueryIndexUtils;
public class IndexedInstances extends ResourceRead2<Set<Resource>> {
@Override
public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
-
- Layer0 L0 = Layer0.getInstance(graph);
- Layer0X L0X = Layer0X.getInstance(graph);
-
- String typeName = graph.getRelatedValue(resource, L0.HasName);
-
- Function dependencies = graph.adapt(L0X.Dependencies, Function.class);
-
- Collection<Map<String, Object>> results = (Collection<Map<String, Object>>)dependencies.apply(graph, resource2, "Types:" + IndexQueries.quoteTerm(typeName));
- if (results == null)
- return Collections.emptySet();
-
- HashSet<Resource> result = new HashSet<Resource>(results.size());
- for(Map<String, Object> entry : results) {
- Resource res = (Resource)entry.get("Resource");
- if(res != null) {
- if (graph.isInstanceOf(res, resource))
- result.add(res);
- }
- }
- return result;
-
+ return new HashSet<>(QueryIndexUtils.searchByTypeShallow(graph, resource2, resource));
}
}
/*******************************************************************************
- * Copyright (c) 2007, 2016 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
Resource project = Simantics.peekProjectResource();
if (project != null) {
+ Layer0 L0 = Layer0.getInstance(graph);
IResourceFilter rf = resourceFilter;
- String filter = getFilterForResourceFilter(rf);
+ String filter = getFilterForResourceFilter(L0, rf);
if (!filter.isEmpty())
filter += " AND "; //$NON-NLS-1$
filter += Arrays.stream(terms).map(term -> "+" + IndexQueries.escape(term.toLowerCase(), false) + "*").collect(Collectors.joining(" ")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
filter +=")"; //$NON-NLS-1$
- Layer0 L0 = Layer0.getInstance(graph);
-
Set<Resource> indexRoots = new HashSet<>();
indexRoots.addAll(graph.syncRequest(new ObjectsWithType(project, L0.ConsistsOf, L0.IndexRoot)));
indexRoots.addAll(graph.syncRequest(new OntologiesFromLibrary(graph.getRootLibrary())));
this.resourceFilter = resourceFilter;
}
- private String getFilterForResourceFilter(IResourceFilter filter) {
+ private String getFilterForResourceFilter(Layer0 l0, IResourceFilter filter) {
if (filter == null || filter == ResourceSearch.FILTER_ALL)
return ""; //$NON-NLS-1$
if (filter == ResourceSearch.FILTER_RELATIONS)
- return "Types:Relation"; //$NON-NLS-1$
+ return IndexQueries.resourceIdTerm(Dependencies.FIELD_TYPE_RESOURCE, l0.Relation);
if (filter == ResourceSearch.FILTER_TYPES)
- return "Types:Type"; //$NON-NLS-1$
+ return IndexQueries.resourceIdTerm(Dependencies.FIELD_TYPE_RESOURCE, l0.Type);
return ""; //$NON-NLS-1$
}
if (indexRoot == null)
return Collections.emptySet();
-// @SuppressWarnings("rawtypes")
-// Function modules = graph.adapt(Layer0X.getInstance(graph).Dependencies, Function.class);
-// @SuppressWarnings("unchecked")
-// List<Map<String, Object>> result = (List<Map<String, Object>>) modules.apply(graph, root, "Types:\"" + IndexQueries.escape(componentTypeName) + "\"");
-// if (result.isEmpty()) {
-// justRemove(graph);
-// return;
-// }
-//
-// final Set<Resource> instances = new HashSet<Resource>();
-// for (Map<String, Object> entry : result) {
-// Resource c = (Resource) entry.get(Dependencies.FIELD_RESOURCE);
-// if (c != null && graph.hasStatement(c, L0.InstanceOf, resource)) {
-// instances.add(c);
-// }
-// }
-
Set<Resource> result = new THashSet<Resource>();
Instances search = graph.adapt(type, Instances.class);
discoverInstances(graph, type, indexRoot, search, result);
*******************************************************************************/
package org.simantics.modeling.adapters;
-import gnu.trove.set.hash.THashSet;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.simantics.databoard.Bindings;
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.exception.VariableException;
-import org.simantics.db.layer0.genericrelation.IndexQueries;
+import org.simantics.db.layer0.QueryIndexUtils;
import org.simantics.db.layer0.request.PossibleModel;
import org.simantics.db.layer0.variable.RVI;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.diagram.stubs.DiagramResource;
import org.simantics.layer0.Layer0;
import org.simantics.modeling.ModelingResources;
-import org.simantics.operation.Layer0X;
-import org.simantics.scl.runtime.function.Function;
import org.simantics.structural.stubs.StructuralResource2;
import org.simantics.utils.ui.ErrorLogger;
+import gnu.trove.set.hash.THashSet;
+
/**
* @author Tuukka Lehtonen
*/
return;
NamedResource namedRoot = new NamedResource(rootName, root);
- @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:" + IndexQueries.quoteTerm(result.componentType.getName()));
- if (rows.isEmpty())
+ List<Resource> components = QueryIndexUtils.searchByTypeShallow(graph, root, result.componentType.getResource());
+ if (components.isEmpty())
return;
ModelingResources MOD = ModelingResources.getInstance(graph);
StructuralResource2 STR = StructuralResource2.getInstance(graph);
- for (Map<String, Object> row : rows) {
- Resource component = (Resource) row.get("Resource");
- if (graph.isInstanceOf(component, result.componentType.getResource())) {
- String componentName = graph.getPossibleRelatedValue(component, L0.HasName, Bindings.STRING);
- next_connection:
- for (Resource connection : graph.getObjects(component, connectionRelation)) {
- if (graph.isInstanceOf(connection, STR.Connection)) {
-
- if (diagramConnectionRelation != null) {
- // When diagram connection relation is defined, validate that
- // exactly the specified diagram connection relation is being
- // used and not some other relation from another symbol.
- for (Resource element : graph.getObjects(component, MOD.ComponentToElement)) {
- for (Resource diagramConnector : graph.getObjects(element, diagramConnectionRelation)) {
- Resource diagramConnection = ConnectionUtil.tryGetConnection(graph, diagramConnector);
- if (diagramConnection == null)
- continue;
- Resource correspondingConnection = graph.getPossibleObject(diagramConnection, MOD.DiagramConnectionToConnection);
- Resource correspondingConnectionSpecial = graph.getPossibleObject(diagramConnection, MOD.DiagramConnectionToConnectionSpecial);
- if (connection.equals(correspondingConnection) || connection.equals(correspondingConnectionSpecial)) {
- addUse(graph, component, componentName, namedRoot, rootURI, result);
- continue next_connection;
- }
+ for (Resource component : components) {
+ String componentName = graph.getPossibleRelatedValue(component, L0.HasName, Bindings.STRING);
+ next_connection:
+ for (Resource connection : graph.getObjects(component, connectionRelation)) {
+ if (graph.isInstanceOf(connection, STR.Connection)) {
+
+ if (diagramConnectionRelation != null) {
+ // When diagram connection relation is defined, validate that
+ // exactly the specified diagram connection relation is being
+ // used and not some other relation from another symbol.
+ for (Resource element : graph.getObjects(component, MOD.ComponentToElement)) {
+ for (Resource diagramConnector : graph.getObjects(element, diagramConnectionRelation)) {
+ Resource diagramConnection = ConnectionUtil.tryGetConnection(graph, diagramConnector);
+ if (diagramConnection == null)
+ continue;
+ Resource correspondingConnection = graph.getPossibleObject(diagramConnection, MOD.DiagramConnectionToConnection);
+ Resource correspondingConnectionSpecial = graph.getPossibleObject(diagramConnection, MOD.DiagramConnectionToConnectionSpecial);
+ if (connection.equals(correspondingConnection) || connection.equals(correspondingConnectionSpecial)) {
+ addUse(graph, component, componentName, namedRoot, rootURI, result);
+ continue next_connection;
}
}
- } else {
- addUse(graph, component, componentName, namedRoot, rootURI, result);
}
+ } else {
+ addUse(graph, component, componentName, namedRoot, rootURI, result);
}
-
}
- }
+ }
}
}
SimanticsConsole sc = new SimanticsConsole();
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new SimanticsConsole[] {sc});
+ sc.activate();
return sc;
}
* Semantum Oy - initial API and implementation
*******************************************************************************/
package org.simantics.platform.ui.internal;
+
import java.io.PrintWriter;
import java.io.StringWriter;
@Override
public void stop(BundleContext context) throws Exception {
- context = null;
+ this.context = null;
super.stop(context);
}
b.append('[');
b.append(formatter.format(new Date(e.getTimeStamp())));
b.append("]: ");
- b.append(e.getMessage());
+ b.append(e.getFormattedMessage());
console.write(b.toString());
}
package org.simantics.structural.synchronization.client;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import org.simantics.structural.synchronization.protocol.SynchronizationEventHandler;
import org.simantics.structural.synchronization.protocol.SynchronizationException;
import org.simantics.structural2.variables.VariableConnectionPointDescriptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
public class Synchronizer {
- public static boolean TRACE = false;
+ private static final Logger LOGGER = LoggerFactory.getLogger(Synchronizer.class);
ReadGraph graph;
Layer0 L0;
*/
public void fullSynchronization(Variable variable, SynchronizationEventHandler handler) throws DatabaseException {
long duration = 0;
- if(TRACE) {
- System.out.println("fullSynchronization " + variable.getURI(graph));
+ if(LOGGER.isTraceEnabled()) {
+ LOGGER.trace("fullSynchronization {}", variable.getURI(graph));
duration -= System.nanoTime();
}
SCLContext context = SCLContext.getCurrent();
} finally {
context.put("graph", oldGraph);
}
- if(TRACE) {
+ if(LOGGER.isTraceEnabled()) {
duration += System.nanoTime();
- System.out.println("full sync in " + 1e-9*duration + "s.");
+ LOGGER.trace("full sync done in {} s", 1e-9*duration);
}
}
public void partialSynchronization(Variable variable, SynchronizationEventHandler handler, TObjectIntHashMap<Variable> changeFlags) throws DatabaseException {
long duration = 0;
- if(TRACE) {
- System.out.println("partialSynchronization " + variable.getURI(graph));
+ if(LOGGER.isTraceEnabled()) {
+ LOGGER.trace("partialSynchronization {}", variable.getURI(graph));
duration -= System.nanoTime();
}
int changeStatus = changeFlags.get(variable);
} finally {
context.put("graph", oldGraph);
}
- if(TRACE) {
+ if(LOGGER.isTraceEnabled()) {
duration += System.nanoTime();
- System.out.println("partial sync in " + 1e-9*duration + "s.");
+ LOGGER.trace("partial sync in {} s", 1e-9*duration);
}
}
public void partialSynchronization(Variable variable, SynchronizationEventHandler handler, long fromRevision) throws DatabaseException {
+ boolean trace = LOGGER.isTraceEnabled();
+ if (trace)
+ LOGGER.trace("Partial synchronization for {} from rev {}", variable.getURI(graph), fromRevision);
+
TObjectIntHashMap<Variable> modifiedComponents = StructuralChangeFlattener.getModifiedComponents(graph, variable, fromRevision);
- /*System.out.println("----------------");
- modifiedComponents.forEachEntry(
- new TObjectIntProcedure<Variable>() {
- @Override
- public boolean execute(Variable a, int b) {
- try {
- System.out.println("Changed: " + a.getURI(graph) + " " + b);
- } catch (DatabaseException e) {
- e.printStackTrace();
- }
- return true;
- }
- });*/
+
+ if (trace) {
+ LOGGER.trace("----------------");
+ modifiedComponents.forEachEntry((Variable a, int b) -> {
+ try {
+ LOGGER.trace("Changed: " + a.getURI(graph) + " " + b);
+ } catch (DatabaseException e) {
+ LOGGER.error("Variable.getURI failed", e);
+ }
+ return true;
+ });
+ }
+
partialSynchronization(variable, handler, modifiedComponents);
}
return graph.getService(ManagementSupport.class).getHeadRevisionId()+1;
}
-
}