abstract Query getQuery();
abstract CacheEntry pruneFirstParents();
+ abstract void pruneParentSet();
abstract void removeParent(CacheEntry entry);
abstract void addParent(CacheEntry entry);
abstract boolean hasParents();
}
}
-
+
+ @Override
+ void pruneParentSet() {
+ // First parent is discarded => look for more parents
+ if(p2OrParents instanceof QueryIdentityHashSet) {
+
+ QueryIdentityHashSet set = (QueryIdentityHashSet)p2OrParents;
+ set.removeDiscardedReally();
+ if(set.isEmpty()) p2OrParents = null;
+
+ } else if(p2OrParents instanceof CacheEntry) {
+
+ CacheEntry entry = (CacheEntry)p2OrParents;
+ if(entry.isDiscarded()) {
+ // Second entry is also discarded => all empty
+ p2OrParents = null;
+ }
+
+ } else {
+
+ // Nothing left
+
+ }
+ }
+
@Override
final public void removeParent(CacheEntry entry) {
final LinkedList<T> items = new LinkedList<T>();
protected ExternalRead<T> id;
- protected ReadGraphImpl graph;
+ protected QueryProcessor processor;
protected boolean registered = false;
@Override
public void discard() {
id.unregistered();
id = null;
- graph = null;
+ processor = null;
super.discard();
}
public ExternalReadEntry(ExternalRead<T> request, ReadGraphImpl graph) {
assert request != null;
this.id = request;
- this.graph = graph;
+ this.processor = graph.processor;
}
@Override
synchronized(items) {
items.addLast(result);
- graph.processor.updatePrimitive(id);
+ processor.updatePrimitive(id);
// TODO: implement flags/logic in ExternalRead to state that all but the latest request result can be evaporated
// In some cases where data is produced really fast this might be necessary but currently this queueing will do.
}
@Override
public boolean isDisposed() {
- return registered && (isDiscarded() || !graph.processor.isBound(this));
+ return registered && (isDiscarded() || !processor.isBound(this));
}
@Override
} else {
+ entry.pruneParentSet();
support.setLevel(entry, parent.getLevel() + 1);
}
// TODO Auto-generated method stub
return null;
}
-
+
+ @Override
+ void pruneParentSet() {
+ }
+
};
/**
}
}
-
+
+ final public void removeDiscardedReally() {
+
+ tempDisableAutoCompaction();
+ try {
+
+ for(int i=0;i<_set.length;i++) {
+ CacheEntry entry = _set[i];
+ if(entry != null && REMOVED != entry) {
+ if(entry.isDiscarded()) removeAt(i);
+ }
+ }
+
+ } finally {
+ reenableAutoCompaction(false);
+ }
+
+ }
+
/**
* Creates an iterator over the values of the set. The iterator
* supports element deletion.
@Override
public void run() {
- ListenerEntry entry = addedEntries.get(base);
+ ListenerEntry entry = addedEntries.remove(base);
if(entry != null) entry.setLastKnown(result);
}
b2.append('\n');
}
SCLDatabaseException exception = new SCLDatabaseException(b.toString()+b2.toString(), b2.toString(), e.getErrors());
- LOGGER.info(exception.getMessage(), exception);
throw exception;
} catch(Throwable e) {
// Should not happen!
import org.simantics.databoard.util.ObjectUtils;
import org.simantics.db.ReadGraph;
import org.simantics.db.common.request.ParametrizedPrimitiveRead;
-import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.variable.Variables.NodeStructure;
import org.simantics.db.procedure.Listener;
import org.simantics.simulator.variable.exceptions.NodeManagerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import gnu.trove.map.hash.THashMap;
@SuppressWarnings("rawtypes")
class NodeStructureRequest extends ParametrizedPrimitiveRead<VariableNode, NodeStructure> implements VariableNodeReadRunnable {
- private Listener<NodeStructure> listener = null;
- private NodeStructure value = Variables.PENDING_NODE_STRUCTURE;
- private boolean wasRun = false;
-
- static class Probe implements Runnable {
-
- private VariableNode node;
- public NodeStructure result;
-
- public Probe(VariableNode node) {
- this.node = node;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void run() {
- try {
- result = NodeStructureRequest.get(node);
- node.support.structureCache.put(node.node, result, 1000000000L);
- } catch (NodeManagerException e) {
- e.printStackTrace();
- }
- }
-
- }
-
- public NodeStructureRequest(VariableNode node) {
- super(node);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void register(ReadGraph graph, final Listener<NodeStructure> procedure) {
-
- if(procedure.isDisposed()) {
-
- // We are not listening
- NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node);
-
- if(result != null) {
- // Return cached value immediately
- procedure.execute(result);
- } else {
- NodeStructureRequest.Probe probe = new Probe(parameter);
- parameter.support.manager.getRealm().asyncExec(probe);
- if(probe.result != null) {
- procedure.execute(probe.result);
- } else {
- procedure.execute(Variables.PENDING_NODE_STRUCTURE);
- }
- }
-
- return;
-
- }
-
- // We need to listen
- listener = procedure;
- // Register listening
- parameter.support.manager.addNodeListener(parameter.node, this);
- synchronized(this) {
- if(wasRun) {
- procedure.execute(value);
- } else {
- NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node);
- if(result != null) {
- procedure.execute(result);
- } else {
- procedure.execute(Variables.PENDING_NODE_STRUCTURE);
- }
- }
- }
-
- }
-
- static class NodeListener implements VariableNodeReadRunnable {
-
- private VariableNode node;
- private NodeStructureRequest request;
-
- public NodeListener(VariableNode node, NodeStructureRequest request) {
- this.node = node;
- this.request = request;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void run() {
- node.support.manager.addNodeListener(node.node, request);
- }
-
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void unregistered() {
- parameter.support.manager.removeNodeListener(parameter.node, this);
- parameter.support.structureCache.removeListening(parameter.node);
- listener = null;
- }
-
- @SuppressWarnings("unchecked")
- public static NodeStructure get(VariableNode parameter) throws NodeManagerException {
- List<?> children = parameter.support.manager.getChildren(parameter.node);
- List<?> properties = parameter.support.manager.getProperties(parameter.node);
- Map<String, Object> childMap = Collections.emptyMap();
- Map<String, Object> propertyMap = childMap;
- if(!children.isEmpty()) {
- childMap = new THashMap<>(children.size());
- for(Object o : children) {
- String name = parameter.support.manager.getName(o);
- childMap.put(name, o);
- }
- }
- if(!properties.isEmpty()) {
- propertyMap = new THashMap<>(properties.size());
- for(Object o : properties) {
- String name = parameter.support.manager.getName(o);
- propertyMap.put(name, o);
- }
- }
- return new NodeStructure(childMap, propertyMap);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public synchronized void run() {
- try {
- // Cache this value with infinite cache time since we are listening
- NodeStructure newValue = get(parameter);
- if (wasRun && ObjectUtils.objectEquals(value, newValue)) {
- //System.out.println("CACHE VALUE MATCH (" + newValue + ") for " + node.node);
- return;
- }
- value = newValue;
- parameter.support.structureCache.put(parameter.node, value);
- } catch (Throwable e) {
- // Must catch everything to prevent DB client from getting stuck.
- Logger.defaultLogError(e);
- // Invoke the exception method of the listener
- Listener<NodeStructure> listener = this.listener;
- if (listener != null) listener.exception(new DatabaseException("External data access error", e));
- wasRun = true;
- return;
- }
-
- // Must always invoke an existing listener, regardless of earlier errors.
- Listener<NodeStructure> listener = this.listener;
- if (listener != null) {
- listener.execute(value);
- }
- wasRun = true;
- }
-
- @Override
- public String toString() {
- return "NodeStructureRequest.run @ " + System.identityHashCode(this);
- }
+ private static final Logger LOGGER = LoggerFactory.getLogger(NodeStructureRequest.class);
+
+ private Listener<NodeStructure> listener = null;
+ private NodeStructure value = Variables.PENDING_NODE_STRUCTURE;
+ private boolean wasRun = false;
+
+ static class Probe implements Runnable {
+
+ private VariableNode node;
+ public NodeStructure result;
+
+ public Probe(VariableNode node) {
+ this.node = node;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ try {
+ result = NodeStructureRequest.get(node);
+ node.support.structureCache.put(node.node, result, 1000000000L);
+ } catch (NodeManagerException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ public NodeStructureRequest(VariableNode node) {
+ super(node);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void register(ReadGraph graph, final Listener<NodeStructure> procedure) {
+
+ if(procedure.isDisposed()) {
+
+ // We are not listening
+ NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node);
+
+ if(result != null) {
+ // Return cached value immediately
+ procedure.execute(result);
+ } else {
+ NodeStructureRequest.Probe probe = new Probe(parameter);
+ parameter.support.manager.getRealm().asyncExec(probe);
+ if(probe.result != null) {
+ procedure.execute(probe.result);
+ } else {
+ procedure.execute(Variables.PENDING_NODE_STRUCTURE);
+ }
+ }
+
+ return;
+
+ }
+
+ // We need to listen
+ listener = procedure;
+ // Register listening
+ parameter.support.manager.addNodeListener(parameter.node, this);
+ synchronized(this) {
+ if(!wasRun) {
+ NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node);
+ if(result != null) {
+ procedure.execute(result);
+ } else {
+ procedure.execute(Variables.PENDING_NODE_STRUCTURE);
+ }
+ }
+ }
+
+ }
+
+ static class NodeListener implements VariableNodeReadRunnable {
+
+ private VariableNode node;
+ private NodeStructureRequest request;
+
+ public NodeListener(VariableNode node, NodeStructureRequest request) {
+ this.node = node;
+ this.request = request;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ node.support.manager.addNodeListener(node.node, request);
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void unregistered() {
+ parameter.support.manager.removeNodeListener(parameter.node, this);
+ parameter.support.structureCache.removeListening(parameter.node);
+ listener = null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static NodeStructure get(VariableNode parameter) throws NodeManagerException {
+ List<?> children = parameter.support.manager.getChildren(parameter.node);
+ List<?> properties = parameter.support.manager.getProperties(parameter.node);
+ Map<String, Object> childMap = Collections.emptyMap();
+ Map<String, Object> propertyMap = childMap;
+ if(!children.isEmpty()) {
+ childMap = new THashMap<>(children.size());
+ for(Object o : children) {
+ String name = parameter.support.manager.getName(o);
+ childMap.put(name, o);
+ }
+ }
+ if(!properties.isEmpty()) {
+ propertyMap = new THashMap<>(properties.size());
+ for(Object o : properties) {
+ String name = parameter.support.manager.getName(o);
+ propertyMap.put(name, o);
+ }
+ }
+ return new NodeStructure(childMap, propertyMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public synchronized void run() {
+ try {
+ // Cache this value with infinite cache time since we are listening
+ NodeStructure newValue = get(parameter);
+ if (wasRun && ObjectUtils.objectEquals(value, newValue)) {
+ //System.out.println("CACHE VALUE MATCH (" + newValue + ") for " + node.node);
+ return;
+ }
+ value = newValue;
+ parameter.support.structureCache.put(parameter.node, value);
+ } catch (Throwable e) {
+ // Must catch everything to prevent DB client from getting stuck.
+ LOGGER.error("Error while computing node structure", e);
+ // Invoke the exception method of the listener
+ Listener<NodeStructure> listener = this.listener;
+ if (listener != null) {
+ listener.exception(new DatabaseException("External data access error", e));
+ wasRun = true;
+ }
+ return;
+ }
+
+ // Must always invoke an existing listener, regardless of earlier errors.
+ Listener<NodeStructure> listener = this.listener;
+ if (listener != null) {
+ listener.execute(value);
+ wasRun = true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "NodeStructureRequest.run @ " + System.identityHashCode(this);
+ }
}
\ No newline at end of file
// Register listening
node.support.manager.addNodeListener(node.node, this);
synchronized(this) {
- if(wasRun) {
- procedure.execute(value);
- } else {
+ if(!wasRun) {
Variant result = (Variant)node.support.valueCache.get(node.node);
if(result != null) {
procedure.execute(result);
LOGGER.error("Error while computing node value", e);
// Invoke the exception method of the listener
Listener<Variant> listener = this.listener;
- if (listener != null) listener.exception(new DatabaseException("External data access error", e));
- wasRun = true;
+ if (listener != null) {
+ listener.exception(new DatabaseException("External data access error", e));
+ wasRun = true;
+ }
return;
}
// Must always invoke an existing listener, regardless of earlier errors.
if (listener != null) {
//System.out.println("LISTENER " + listener + " invoked with value " + value);
listener.execute(value);
+ wasRun = true;
}
- wasRun = true;
}
@Override
import org.simantics.diagram.symbolcontribution.CompositeSymbolGroup;
import org.simantics.diagram.symbolcontribution.IIdentifiedObject;
import org.simantics.diagram.symbolcontribution.ISymbolProvider;
-import org.simantics.diagram.symbolcontribution.IdentifiedObject;
import org.simantics.diagram.symbolcontribution.SymbolProviderFactory;
import org.simantics.diagram.symbollibrary.IModifiableSymbolGroup;
import org.simantics.diagram.symbollibrary.ISymbolGroup;
json.append(" \"res\" : [");
int pos = 0;
for(int i=0;i<res.length;i++) {
- if(pos > 0) json.append(",");
- Object r = res[i];
- if(r instanceof IdentifiedObject) {
- Object id = ((IdentifiedObject) r).getId();
- if(id instanceof IAdaptable) {
- Object resource = ((IAdaptable) id).getAdapter(Resource.class);
- if(resource != null) {
- long rid = ((Resource)resource).getResourceId();
- json.append(Long.toString(rid));
- pos++;
- }
- }
- }
+ if(pos > 0) json.append(",");
+ Object r = res[i];
+ if(r instanceof IAdaptable) {
+ Resource resource = ((IAdaptable) r).getAdapter(Resource.class);
+ if(resource != null) {
+ long rid = resource.getResourceId();
+ json.append(Long.toString(rid));
+ pos++;
+ }
+ }
}
json.append("] }");
- StringSelection text = new StringSelection(json.toString());
- PlaintextTransfer plainText = new PlaintextTransfer(json.toString());
+ String jsonText = json.toString();
+ StringSelection text = new StringSelection(jsonText);
+ PlaintextTransfer plainText = new PlaintextTransfer(jsonText);
return new MultiTransferable(local, text, plainText);
*******************************************************************************/
package org.simantics.diagram.synchronization.graph;
-import gnu.trove.map.hash.THashMap;
-
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import org.simantics.graph.db.TransferableGraphs;
import org.simantics.graph.representation.TransferableGraph1;
import org.simantics.layer0.Layer0;
+import org.simantics.utils.datastructures.BinaryFunction;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
/**
* This class contains utility methods for the basic cut/copy operations
public static final boolean DEBUG_COPY = DebugPolicy.DEBUG_COPY_PASTE;
+ private static class Statement4 {
+ public final Statement stm;
+ public final Resource inverse;
+ public Statement4(Statement stm, Resource inverse) {
+ this.stm = stm;
+ this.inverse = inverse;
+ }
+ }
+
/**
* @param context a synchronization context instance, such as
* {@link GraphToDiagramSynchronizer}
* @throws DatabaseException
*/
public static Resource copy2(WriteGraph graph, Resource source,
- BiFunction<ReadGraph, Statement, StatementEvaluation> advisor) throws DatabaseException {
- return copy2(graph, source, 0, advisor, new THashMap<Object, Object>());
+ BiFunction<ReadGraph, Statement, StatementEvaluation> advisor)
+ throws DatabaseException
+ {
+ return copy2(graph, source, advisor, new THashMap<>());
}
/**
* @throws DatabaseException
*/
public static Resource copy2(WriteGraph graph, Resource source,
- BiFunction<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap)
- throws DatabaseException {
- return copy2(graph, source, 0, advisor, copyMap);
+ BiFunction<ReadGraph, Statement, StatementEvaluation> advisor,
+ Map<Object, Object> copyMap)
+ throws DatabaseException
+ {
+ Set<Statement4> pendingStatements = new THashSet<>();
+ Resource result = copy2(graph, source, 0, advisor, copyMap, pendingStatements);
+ postProcessStatements(graph, copyMap, pendingStatements);
+ return result;
+ }
+
+ /**
+ * Post-process pending statement
+ *
+ * Rule: If both the subject and object of a pending source statement have
+ * been copied, then the pending statement should also be copied.
+ */
+ private static void postProcessStatements(
+ WriteGraph graph,
+ Map<Object, Object> copyMap,
+ Set<Statement4> pendingStatements)
+ throws DatabaseException
+ {
+ if (pendingStatements.isEmpty())
+ return;
+
+ if (DEBUG_COPY)
+ System.out.println("post processing " + pendingStatements.size() + " pending statements");
+ for (Statement4 srcStm : pendingStatements) {
+ // At this point, it is certain that srcStm subject has been copied
+ // but test it anyway.
+ Resource subjectCopy = (Resource) copyMap.get(srcStm.stm.getSubject());
+ Resource objectCopy = (Resource) copyMap.get(srcStm.stm.getObject());
+ if (subjectCopy == null || objectCopy == null) {
+ if (DEBUG_COPY)
+ System.out.println("skipping pending statement: " + NameUtils.toString(graph, srcStm.stm));
+ continue;
+ }
+ if (DEBUG_COPY)
+ System.out.println("copying pending statement: " + NameUtils.toString(graph, srcStm.stm));
+ graph.claim(subjectCopy, srcStm.stm.getPredicate(), srcStm.inverse, objectCopy);
+ }
}
private static Resource copy2(final WriteGraph graph, final Resource source, final int level,
- BiFunction<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap)
+ BiFunction<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap,
+ Set<Statement4> pendingSourceStatements)
throws DatabaseException {
if (DEBUG_COPY)
System.out.println("[" + level + "] CopyAdvisorUtil.copy(" + NameUtils.getSafeName(graph, source) + ", advisor=" + advisor + ")");
if (DEBUG_COPY)
System.out.println("[" + level + "]\t\tcopy whole object");
- Resource clone = copy2(graph, obj, level + 1, advisor, copyMap);
+ Resource clone = copy2(graph, obj, level + 1, advisor, copyMap, pendingSourceStatements);
graph.claim(copy, relation, inverse, clone);
}
} else {
- if (DEBUG_COPY)
- System.out.println("[" + level + "]\t\tskipping statement");
+ if (graph.isSubrelationOf(relation, L0.IsRelatedTo)) {
+ if (DEBUG_COPY)
+ System.out.println("[" + level + "]\t\tmarking statement as pending for post-processing");
+ pendingSourceStatements.add(new Statement4(stm, inverse));
+ } else {
+ if (DEBUG_COPY)
+ System.out.println("[" + level + "]\t\tskipping weak statement");
+ }
}
}
}
package org.simantics.document.server.request;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import org.simantics.db.AsyncReadGraph;
import org.simantics.db.ReadGraph;
import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
-import org.simantics.db.common.request.AsyncReadRequest;
+import org.simantics.db.common.request.UnaryAsyncRead;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.request.VariableRead;
import org.simantics.db.layer0.variable.Variable;
super(var);
}
- @Override
- public List<JSONObject> perform(ReadGraph graph) throws DatabaseException {
-
- long s = System.nanoTime();
-
- Set<Variable> nodes = graph.syncRequest(new NodesRequest(variable), TransientCacheAsyncListener.<Set<Variable>>instance());
- HashSet<JSONObject> rs = new HashSet<JSONObject>(); // result
- if(nodes.isEmpty()) {
- return Collections.emptyList();
- }
+ static class CollectNodesRequest extends UnaryAsyncRead<Collection<Variable>, Collection<JSONObject>> {
- if(PROFILE) {
- long dura = System.nanoTime()-s;
- System.err.println("DocumentRequest1 " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph));
+ public CollectNodesRequest(Collection<Variable> nodes) {
+ super(nodes);
}
- graph.syncRequest(new AsyncReadRequest() {
+ @Override
+ public void perform(AsyncReadGraph graph, AsyncProcedure<Collection<JSONObject>> procedure) {
+ HashSet<JSONObject> rs = new HashSet<JSONObject>(); // result
- @Override
- public void run(AsyncReadGraph graph) throws DatabaseException {
+ for(Variable node : parameter) {
+ graph.asyncRequest(new NodeRequest(node), new AsyncProcedure<JSONObject> () {
- for(Variable node : nodes) {
- graph.asyncRequest(new NodeRequest(node), new AsyncProcedure<JSONObject> () {
-
- @Override
- public void execute(AsyncReadGraph graph, JSONObject result) {
- synchronized (rs) {
- rs.add(result);
- }
+ @Override
+ public void execute(AsyncReadGraph graph, JSONObject result) {
+ synchronized(rs) {
+ rs.add(result);
}
+ }
- @Override
- public void exception(AsyncReadGraph graph, Throwable throwable) {
- }
+ @Override
+ public void exception(AsyncReadGraph graph, Throwable throwable) {
+ }
+
+ });
- });
-
- }
-
}
-
- });
+ procedure.execute(graph, rs);
+
+ }
+
+ }
+
+ @Override
+ public List<JSONObject> perform(ReadGraph graph) throws DatabaseException {
+
+ long s = System.nanoTime();
+
+ Set<Variable> nodes = graph.syncRequest(new NodesRequest(variable), TransientCacheAsyncListener.<Set<Variable>>instance());
+ if(nodes.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ if(PROFILE) {
+ long dura = System.nanoTime()-s;
+ System.err.println("DocumentRequest1 " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph));
+ }
+ Collection<JSONObject> rs = graph.syncRequest(new CollectNodesRequest(nodes));
if(PROFILE) {
long dura = System.nanoTime()-s;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
import org.simantics.db.AsyncReadGraph;
import org.simantics.db.ReadGraph;
-import org.simantics.db.common.request.AsyncReadRequest;
+import org.simantics.db.common.request.UnaryAsyncRead;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.request.VariableChildren;
import org.simantics.db.layer0.request.VariableRead;
import org.simantics.utils.threads.logger.ITask;
import org.simantics.utils.threads.logger.ThreadLogger;
-import gnu.trove.set.hash.THashSet;
-
public class NodesRequest extends VariableRead<Set<Variable>> {
public NodesRequest(Variable var) {
super(var);
}
- @Override
- public Set<Variable> perform(ReadGraph graph) throws DatabaseException {
+ static class CollectNodesRequest2 extends UnaryAsyncRead<Collection<Variable>, Set<Variable>> {
- ITask task = DocumentRequest.PROFILE ? ThreadLogger.task(this) : null;
+ public CollectNodesRequest2(Collection<Variable> nodes) {
+ super(nodes);
+ }
- StructuralResource2.getInstance(graph);
- if(variable == null)
- return Collections.emptySet();
+ @Override
+ public void perform(AsyncReadGraph graph, AsyncProcedure<Set<Variable>> procedure) {
+ HashSet<Variable> rs = new HashSet<Variable>(); // result
- Set<Variable> nodes = new THashSet<Variable>();
+ for(Variable node : parameter) {
+ graph.asyncRequest(new NodesRequest2(node), new AsyncProcedure<Set<Variable>> () {
- Collection<Variable> children = graph.syncRequest(new VariableChildren(variable));
+ @Override
+ public void execute(AsyncReadGraph graph, Set<Variable> result) {
+ synchronized(rs) {
+ rs.addAll(result);
+ }
+ }
- graph.syncRequest(new AsyncReadRequest() {
+ @Override
+ public void exception(AsyncReadGraph graph, Throwable throwable) {
+ }
- @Override
- public void run(AsyncReadGraph graph) throws DatabaseException {
+ });
- for(Variable child : children) {
- graph.asyncRequest(new NodesRequest2(child), new AsyncProcedure<Set<Variable>>() {
+ }
+ procedure.execute(graph, rs);
- @Override
- public void execute(AsyncReadGraph graph, Set<Variable> result) {
- synchronized(nodes) {
- nodes.addAll(result);
- }
- }
+ }
- @Override
- public void exception(AsyncReadGraph graph, Throwable throwable) {
- }
-
- });
- }
+ }
- }
+ @Override
+ public Set<Variable> perform(ReadGraph graph) throws DatabaseException {
+
+ ITask task = DocumentRequest.PROFILE ? ThreadLogger.task(this) : null;
+
+ StructuralResource2.getInstance(graph);
+ if(variable == null)
+ return Collections.emptySet();
+
+ Collection<Variable> children = graph.syncRequest(new VariableChildren(variable));
- });
+ Set<Variable> nodes = graph.syncRequest(new CollectNodesRequest2(children));
if(DocumentRequest.PROFILE) task.finish();
ctx.getThreadAccess().asyncExec(() -> {
//System.out.println(Thread.currentThread() + ": update scene graph(" + el + ")");
// Update scene graph and repaint.
- el.getElementClass().getSingleItem(GalleryItemSGNode.class).update(el);
- ctx.getContentContext().setDirty();
+ if (!ctx.isDisposed()) {
+ el.getElementClass().getSingleItem(GalleryItemSGNode.class).update(el);
+ ctx.getContentContext().setDirty();
+ }
});
break;
}
private static Path replaceExtension(Path p, String newExtension) {
String newName = p.getFileName().toString();
- if (newName.contains("."))
- newName = newName.split("\\.")[0];
+ int lastDot = newName.lastIndexOf('.');
+ if (lastDot > -1)
+ newName = newName.substring(0, lastDot);
return p.resolveSibling(newName + newExtension);
}
import org.simantics.modeling.services.ComponentNamingUtil;
import org.simantics.modeling.services.NamingException;
import org.simantics.project.IProject;
-import org.simantics.structural.stubs.StructuralResource2;
import gnu.trove.map.hash.THashMap;
@Override
public Object copy(ISynchronizationContext context, WriteGraph graph, Resource source, Resource sourceContainer,
Resource targetContainer, Map<Object, Object> map) throws DatabaseException {
- StructuralResource2 STR = StructuralResource2.getInstance(graph);
Resource copy = CopyAdvisorUtil.copy2(graph, source, null, map);
Layer0 L0 = Layer0.getInstance(graph);
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.procedure.SyncListener;
import org.simantics.db.request.Read;
+import org.simantics.db.request.ReadExt;
+import org.simantics.db.request.RequestFlags;
import org.simantics.layer0.Layer0;
import org.simantics.modeling.ModelingUtils;
import org.simantics.modeling.internal.Activator;
}
}
+ static class PossibleResourceIU extends UnaryRead<String,Resource> implements ReadExt {
+
+ public PossibleResourceIU(String parameter) {
+ super(parameter);
+ }
+
+ @Override
+ public Resource perform(ReadGraph graph) throws DatabaseException {
+ return graph.getPossibleResource(parameter);
+ }
+
+ @Override
+ public boolean isImmutable(ReadGraph graph) throws DatabaseException {
+ return false;
+ }
+
+ @Override
+ public int getType() {
+ return RequestFlags.IMMEDIATE_UPDATE;
+ }
+
+ }
+
static class ReadModuleSource extends UnaryRead<String, ModuleSource> {
public ReadModuleSource(String moduleName) {
super(moduleName);
@Override
public ModuleSource perform(ReadGraph graph) throws DatabaseException {
- Resource moduleResource = graph.getPossibleResource(parameter);
+ Resource moduleResource = graph.syncRequest(new PossibleResourceIU(parameter));
if(moduleResource == null)
return null;
Layer0 L0 = Layer0.getInstance(graph);
public void add(Resource item) {
//System.out.println("Add to group(" + this + "): " + item);
items.put(item, item);
- observer.update();
+ observer.update(style, item);
}
@Override
// new Exception().printStackTrace();
//System.out.println("Remove from group(" + this + "): " + item);
items.remove(item);
- observer.update();
+ observer.update(style, item);
}
@Override