package org.simantics.structural.synchronization.utils;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import gnu.trove.map.hash.THashMap;
import gnu.trove.procedure.TObjectObjectProcedure;
import gnu.trove.procedure.TObjectProcedure;
import gnu.trove.set.hash.THashSet;
-import java.io.PrintWriter;
-import java.util.function.Consumer;
-
/**
* The entry point to the mapping structure between Simantics database and a
* designated solver. It is used to synchronize changes from Simantics to the
*/
abstract public class MappingBase<T extends ComponentBase<T>> {
+ private final transient Logger LOGGER = LoggerFactory.getLogger(getClass());
+
abstract public T getConfiguration();
/**
* Set of all components indexed by their UID.
*/
transient protected THashMap<String, T> configurationByUid;
-
+
+ /**
+ * Set of all components indexed by their solver name.
+ */
+ transient protected Map<String, T> configurationBySolverName;
+
/**
* Set of components whose removal is delayed because they might
* have been moved somewhere else.
}
}
+ public Map<String, T> getConfigurationBySolverName() {
+ Map<String, T> result = configurationBySolverName;
+ if (result == null) {
+ T configuration = getConfiguration();
+ if (configuration != null)
+ result = configurationBySolverName = createConfigurationBySolverName(configuration);
+ else
+ result = Collections.emptyMap();
+ }
+ return result;
+ }
+
+ protected Map<String, T> createConfigurationBySolverName(T configuration) {
+ THashMap<String, T> configurationBySolverName = new THashMap<>();
+ browseConfigurationBySolverName(configurationBySolverName, configuration);
+ return configurationBySolverName;
+ }
+
+ private void browseConfigurationBySolverName(
+ THashMap<String, T> configurationBySolverName,
+ T configuration) {
+ if (configuration.solverComponentName != null) {
+ configurationBySolverName.put(configuration.solverComponentName, configuration);
+ } else if (configuration.componentId != 0) {
+ LOGGER.warn("configuration.solverComponentName is null! configuration uid is {} and component id {}", configuration.getUid(), configuration.componentId);
+ }
+ for(T child : configuration.getChildren()) {
+ browseConfigurationBySolverName(configurationBySolverName, child);
+ child.parent = configuration;
+ }
+ }
+
public T detachOrCreateComponent(String uid) {
T result = configurationByUid.get(uid);
if(result == null) {
result = componentFactory.create(uid);
configurationByUid.put(uid, result);
+ configurationBySolverName = null; // forces recalculation
}
else {
if(result.getParent() == null)
public void remove(final Solver solver, T component) {
if(configurationByUid != null)
configurationByUid.remove(component.uid);
+ if (configurationBySolverName != null && component.solverComponentName != null)
+ configurationBySolverName.remove(component.solverComponentName);
if(component.getChildMap() != null)
component.getChildMap().forEachValue(new TObjectProcedure<T>() {
@Override
public void dispose() {
if (configurationByUid != null)
configurationByUid.clear();
+ if (configurationBySolverName != null) {
+ configurationBySolverName.clear();
+ configurationBySolverName = null;
+ }
pendingRemoval.clear();
}