+++ /dev/null
-package org.simantics.structural.synchronization;
-
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-
-import java.util.ArrayList;
-import java.util.Map;
-
-import org.simantics.databoard.Bindings;
-import org.simantics.db.ReadGraph;
-import org.simantics.db.Resource;
-import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.genericrelation.DependencyChanges;
-import org.simantics.db.layer0.request.ModelInstances;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.db.layer0.variable.Variables;
-import org.simantics.layer0.Layer0;
-import org.simantics.structural.stubs.StructuralResource2;
-import org.simantics.structural2.utils.StructuralChangeVisitor;
-import org.simantics.structural2.utils.StructuralMetadataUtils;
-
-/**
- * Browses change metadata from the requested revision and
- * marks the components in a flat structural configuration
- * where changes have been occured.
- *
- * @author Hannu Niemistö
- */
-public class StructuralChangeFlattener {
-
- private static Variable[] EMPTY_VARIABLE_ARRAY = new Variable[0];
-
- public static TObjectIntHashMap<Variable> getModifiedComponents(ReadGraph graph,
- Variable rootVariable, long fromRevision) throws DatabaseException {
- Visitor visitor = new Visitor(graph, rootVariable);
- StructuralMetadataUtils.visitStructuralChangesFrom(graph,
- Variables.getModel(graph, rootVariable),
- fromRevision, visitor);
- return visitor.modifiedComponents;
- }
-
- public static TObjectIntHashMap<Variable> getModifiedComponents(ReadGraph graph,
- Variable rootVariable, DependencyChanges.Change[] changes) throws DatabaseException {
- Visitor visitor = new Visitor(graph, rootVariable);
- StructuralMetadataUtils.visitStructuralChangesFrom(graph,
- Variables.getModel(graph, rootVariable),
- changes, visitor);
- return visitor.modifiedComponents;
- }
-
- private static class Visitor implements StructuralChangeVisitor {
-
- Variable rootVariable;
- Resource rootResource;
- Resource model;
- THashMap<Resource, Variable[]> visitedVariables = new THashMap<Resource, Variable[]>();
- Layer0 L0;
- StructuralResource2 STR;
- TObjectIntHashMap<Variable> modifiedComponents = new TObjectIntHashMap<Variable>();
-
- public Visitor(ReadGraph graph, Variable rootVariable) throws DatabaseException {
- this.rootVariable = rootVariable;
- this.rootResource = rootVariable.getRepresents(graph);
- this.model = Variables.getModel(graph, rootVariable);
- this.L0 = Layer0.getInstance(graph);
- this.STR = StructuralResource2.getInstance(graph);
- }
-
- @Override
- public void visitComponentChange(ReadGraph graph, Resource component, boolean componentItselfModified)
- throws DatabaseException {
- Variable[] variables = visitedVariables.get(component);
- if(variables == null) {
- variables = visitUnseenComponent(graph, component);
- visitedVariables.put(component, variables);
- }
- if(componentItselfModified)
- for(Variable variable : variables)
- modifiedComponents.put(variable, 2);
- else
- for(Variable variable : variables)
- modifiedComponents.putIfAbsent(variable, 1);
- }
-
- private Variable[] visitUnseenComponent(ReadGraph graph, Resource component) throws DatabaseException {
- // Is root?
- if(component.equals(rootResource))
- return new Variable[] { rootVariable };
-
- // Check if this a component type root
- Resource componentType = graph.getPossibleObject(component, STR.Defines);
- if(componentType != null) {
- ArrayList<Variable> result = new ArrayList<Variable>();
- Map<String,Resource> instances = graph.syncRequest(new ModelInstances(model, componentType), TransientCacheAsyncListener.<Map<String,Resource>>instance());
- for(Resource instance : instances.values()) {
- visitComponentChange(graph, instance, false);
- for(Variable variable : visitedVariables.get(instance))
- result.add(variable);
- }
- if(result.isEmpty())
- return EMPTY_VARIABLE_ARRAY;
- else
- return result.toArray(new Variable[result.size()]);
- }
-
- // Check parent
- Resource parent = graph.getPossibleObject(component, L0.PartOf);
- String name = graph.getPossibleRelatedValue(component, L0.HasName, Bindings.STRING);
- if(parent == null || name == null || !graph.isInstanceOf(component, STR.Component))
- return EMPTY_VARIABLE_ARRAY;
-
- visitComponentChange(graph, parent, false);
- Variable[] parentCorrespondences = visitedVariables.get(parent);
- ArrayList<Variable> result = new ArrayList<Variable>(parentCorrespondences.length);
- for(Variable parentCorrespondence : parentCorrespondences) {
- Variable correspondence = parentCorrespondence.getPossibleChild(graph, name);
- if(correspondence != null)
- result.add(correspondence);
- }
- if(result.isEmpty())
- return EMPTY_VARIABLE_ARRAY;
- else
- return result.toArray(new Variable[result.size()]);
- }
-
- }
-}