]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.district.selection/src/org/simantics/district/selection/ElementSelector.java
UI for diagram element selection
[simantics/district.git] / org.simantics.district.selection / src / org / simantics / district / selection / ElementSelector.java
index 7d429e4e04a5669667b11d35d678851f0af06874..74eaa227096a06b011e230d47089328c210bacab 100644 (file)
@@ -3,22 +3,29 @@ package org.simantics.district.selection;
 import java.awt.geom.Path2D;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.simantics.Simantics;
 import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.common.utils.ListUtils;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.QueryIndexUtils;
 import org.simantics.db.layer0.request.ActiveModels;
 import org.simantics.db.layer0.request.ActiveRuns;
 import org.simantics.db.layer0.request.Configuration;
+import org.simantics.db.layer0.request.PossibleActiveModel;
 import org.simantics.db.layer0.variable.RVI;
 import org.simantics.db.layer0.variable.Variable;
 import org.simantics.db.layer0.variable.Variables;
+import org.simantics.db.request.Read;
 import org.simantics.diagram.stubs.DiagramResource;
 import org.simantics.district.network.ontology.DistrictNetworkResource;
 import org.simantics.district.region.ontology.DiagramRegionsResource;
@@ -35,7 +42,7 @@ import org.slf4j.LoggerFactory;
 public class ElementSelector {
        String name;
        String expression;
-       Integer count;
+       
        Resource resource;
        
        Generator generator;
@@ -51,6 +58,8 @@ public class ElementSelector {
        static DiagramResource DIA;
        static DistrictNetworkResource DN;
        
+       private static Logger LOGGER = LoggerFactory.getLogger(ElementSelector.class);
+       
        ElementSelector(ReadGraph graph, Resource resource) throws DatabaseException {
                super();
                
@@ -62,32 +71,169 @@ public class ElementSelector {
                DN = DistrictNetworkResource.getInstance(graph);
                
                this.resource = resource;
-               this.count = -1;
                try {
                        this.name = graph.getRelatedValue(resource, L0.HasLabel);
-                       this.expression = buildExpression(graph, resource);
+                       this.expression = getExpression(graph, resource);
                } catch (DatabaseException e) {
                        LOG.error("Error reading element selector", e);
                        throw e;
                }
        }
        
-       public static ElementSelector getSelector(ReadGraph graph, Resource resource) throws DatabaseException {
+       /**
+        * Instantiate an element selector object for an ES.Selection resource.
+        */
+       public static ElementSelector getSelector(RequestProcessor graph, Resource resource) throws DatabaseException {
                return graph.syncRequest(new ElementSelectorQuery(resource));
        }
+       
+       /**
+        * Get an SQL-like textual description of an ES.Selection resource.
+        */
+       public static String getExpression(RequestProcessor graph, Resource resource) throws DatabaseException {
+               return graph.syncRequest(new SelectionExpressionRequest(resource));
+       }
+
+       /**
+        * Get a Java object representation of an ES.Condition resource.
+        */
+       public static Condition getCondition(RequestProcessor graph, Resource condition) throws DatabaseException {
+               return graph.syncRequest(new SelectionConditionRequest(condition));
+       }
 
+       /**
+        * Get the name of the element selector.
+        */
        public String getName() {
                return name;
        }
 
+       /**
+        * Get a textual SQL-like description of the element selector.
+        */
        public String getExpression() {
                return expression;
        }
 
+       /**
+        * Get the resource that this selector represents. 
+        */
        public Resource getResource() {
                return resource;
        }
 
+       /**
+        * Get the generator component. Use {@link #buildSelection(ReadGraph)} to make it available first.
+        */
+       public Generator getGenerator() {
+               return generator;
+       }
+
+       /**
+        * Get the selector component. Use {@link #buildSelection(ReadGraph)} to make it available first.
+        */
+       public Selector getSelector() {
+               return selector;
+       }
+
+       /**
+        * Get the condition component. Use {@link #buildSelection(ReadGraph)} to make it available first.
+        */
+       public Condition getCondition() {
+               return condition;
+       }
+
+       /**
+        * 
+        * @param graph
+        * @throws DatabaseException
+        */
+       public void buildSelection(ReadGraph graph) throws DatabaseException {
+               Resource selector = graph.getSingleObject(resource, ES.Selection_HasSelector);
+               Resource generator = graph.getSingleObject(resource, ES.Selection_HasGenerator);
+               Resource condition = graph.getPossibleObject(resource, ES.Selection_HasCondition);
+               
+               this.selector = buildSelector(graph, selector);
+               this.generator = buildGenerator(graph, generator);
+               this.condition = buildCondition(graph, condition);
+       }
+
+       public static Map<Resource, String> findDiagrams() {
+               try {
+                       return Simantics.getSession().syncRequest(new Read<Map<Resource, String>>() {
+                               @Override
+                               public Map<Resource, String> perform(ReadGraph graph) throws DatabaseException {
+                                       Map<Resource, String> result = new HashMap<>();
+                                       Resource model = graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
+                                       List<Resource> composites = QueryIndexUtils.searchByType(graph, model, StructuralResource2.getInstance(graph).Composite);
+                                       for (Resource r : composites) {
+                                               // Get diagram
+                                               Resource diagram = graph.getPossibleObject(r, ModelingResources.getInstance(graph).CompositeToDiagram);
+                                               if (diagram == null) continue;
+                                               
+                                               // Filter out user component diagrams
+                                               Resource parent = graph.getPossibleObject(r, Layer0.getInstance(graph).PartOf);
+                                               if (parent == null || graph.isInheritedFrom(parent, StructuralResource2.getInstance(graph).Component))
+                                                       continue;
+                                               
+                                               result.put(r, graph.getRelatedValue(r, Layer0.getInstance(graph).HasName));
+                                       }
+                                       
+                                       return result;
+                               }
+                       });
+               } catch (DatabaseException e) {
+                       LOGGER.error("Query for model diagrams failed", e);
+                       return Collections.emptyMap();
+               }
+       }
+
+       public static Variable getVariableForElement(ReadGraph graph, Resource element) throws DatabaseException {
+               Resource component = graph.getPossibleObject(element, MOD.ElementToComponent);
+               if (component != null) {
+                       Variable var = Variables.getVariable(graph, component);
+                       RVI realRvi = var.getRVI(graph);
+                       
+                       for (Resource activeModel : graph.syncRequest(new ActiveModels(Simantics.getProjectResource()))) {
+                               for (Variable run : graph.syncRequest(new ActiveRuns(activeModel))) {
+                                       Variable v = realRvi.resolvePossible(graph, run);
+                                       if (v != null) {
+                                               return v;
+                                       }
+                               }
+                               Variable configuration = Variables.getPossibleConfigurationContext(graph, activeModel);
+                               if (configuration != null) {
+                                       Variable v = realRvi.resolvePossible(graph, configuration);
+                                       if (v != null) {
+                                               return v;
+                                       }
+                               }
+                       }
+               }
+               
+               return null;
+       }
+
+       public static Double getPropertyValue(ReadGraph graph, Resource element, String propertyName) {
+               try {
+                       Variable v = getVariableForElement(graph, element);
+                       if (v != null) {
+                               Number value = v.getPossiblePropertyValue(graph, propertyName);
+                               if (value != null)
+                                       return value.doubleValue();
+                       }
+                       
+                       // No property found - try possible mapped element property as well
+                       Resource mappedElement = graph.getPossibleObject(element, DN.MappedComponent);
+                       if (mappedElement != null)
+                               return getPropertyValue(graph, mappedElement, propertyName);
+               }
+               catch (DatabaseException e) {
+               }
+               
+               return null;
+       }
+
        public List<Resource> selectElementsFrom(ReadGraph graph, Resource model) throws DatabaseException {
                if (selector == null) {
                        buildSelection(graph);
@@ -147,19 +293,20 @@ public class ElementSelector {
                        String propertyName = graph.getRelatedValue(resource, ES.PropertyCondition_HasPropertyName);
                        Double lowerLimit = graph.getPossibleRelatedValue(resource, ES.PropertyCondition_HasLowerLimit);
                        Double upperLimit = graph.getPossibleRelatedValue(resource, ES.PropertyCondition_HasUpperLimit);
-                       cond = new PropertyCondition(propertyName, lowerLimit, upperLimit);
+                       cond = new PropertyCondition(resource, propertyName, lowerLimit, upperLimit);
                }
                else if (graph.isInstanceOf(resource, ES.RegionCondition)) {
                        DiagramRegionsResource DR = DiagramRegionsResource.getInstance(graph);
-                       double[] region = graph.getRelatedValue(graph.getSingleObject(resource, ES.RegionCondition_HasRegion), DR.Region_area);
-                       cond = new RegionCondition(region);
+                       Resource regionResource = graph.getSingleObject(resource, ES.RegionCondition_HasRegion);
+                       double[] region = graph.getRelatedValue(regionResource, DR.Region_area);
+                       cond = new RegionCondition(resource, regionResource, region);
                }
                else if (graph.isInstanceOf(resource, ES.RouteCondition)) {
-                       Set<Resource> routePoints = new HashSet<>(ListUtils.toList(graph, graph.getSingleObject(resource, ES.RouteCondition_HasRoute)));
-                       cond = new RouteCondition(routePoints);
+                       Resource routeResource = graph.getSingleObject(resource, ES.RouteCondition_HasRoute);
+                       Set<Resource> routePoints = new HashSet<>(ListUtils.toList(graph, routeResource));
+                       cond = new RouteCondition(resource, routeResource, routePoints);
                }
                else if (graph.isInstanceOf(resource, ES.AggregateCondition)) {
-                       boolean isDisjunction = graph.isInstanceOf(resource, ES.Disjunction);
                        Collection<Resource> conditionResources = graph.getObjects(resource, ES.HasSubcondition);
                        List<Condition> conditions = new ArrayList<>(conditionResources.size());
                        for (Resource c : conditionResources) {
@@ -175,23 +322,22 @@ public class ElementSelector {
                        else
                                throw new IllegalArgumentException("Unknown aggreate condition type " + graph.getURI(graph.getSingleType(resource)));
                                
-                       cond = new AggregateCondition(type, conditions);
+                       cond = new AggregateCondition(resource, type, conditions);
                }
                else {
                        throw new IllegalArgumentException("Unknown condition type " + graph.getURI(graph.getSingleType(resource)));
                }
                
-               cond.isInverse = graph.hasStatement(resource, ES.Condition_IsInverse, resource);
                return cond;
        }
 
        private static String buildExpression(ReadGraph graph, Resource r) throws DatabaseException {
                if (graph.isInstanceOf(r, ES.Selection)) {
-                       String exp = "select " + buildExpression(graph, graph.getSingleObject(r, ES.Selection_HasSelector)) + 
-                                    " from " + buildExpression(graph, graph.getSingleObject(r, ES.Selection_HasGenerator));
+                       String exp = "select " + getExpression(graph, graph.getSingleObject(r, ES.Selection_HasSelector)) + 
+                                    " from " + getExpression(graph, graph.getSingleObject(r, ES.Selection_HasGenerator));
                        
                        Resource cond = graph.getPossibleObject(r, ES.Selection_HasCondition);
-                       return cond != null ? exp + " where {" + buildExpression(graph, cond) + "}" : exp;
+                       return cond != null ? exp + " where {" + getExpression(graph, cond) + "}" : exp;
                }
                else if (graph.isInstanceOf(r, ES.Condition)) {
                        if (graph.isInstanceOf(r, ES.PropertyCondition)) {
@@ -212,7 +358,7 @@ public class ElementSelector {
                                List<String> exps = new ArrayList<>();
                                Collection<Resource> objects = graph.getObjects(r, ES.HasSubcondition);
                                for (Resource c : objects) {
-                                       String exp = buildExpression(graph, c);
+                                       String exp = getExpression(graph, c);
                                        exps.add(objects.size() > 1 ? "{" + exp + "}" : exp);
                                }
                                String result = String.join(op, exps);
@@ -300,16 +446,6 @@ public class ElementSelector {
                return result;
        }
 
-       private void buildSelection(ReadGraph graph) throws DatabaseException {
-               Resource selector = graph.getSingleObject(resource, ES.Selection_HasSelector);
-               Resource generator = graph.getSingleObject(resource, ES.Selection_HasGenerator);
-               Resource condition = graph.getPossibleObject(resource, ES.Selection_HasCondition);
-               
-               this.selector = buildSelector(graph, selector);
-               this.generator = buildGenerator(graph, generator);
-               this.condition = buildCondition(graph, condition);
-       }
-
        private Collection<Resource> filterElementsFrom(ReadGraph graph, Collection<Resource> elements) throws DatabaseException {
                if (condition == null) return elements;
                
@@ -326,59 +462,13 @@ public class ElementSelector {
                return selector.select(graph, filterElementsFrom(graph, generator.generate(graph, model)));
        }
        
-       static Variable getVariableForElement(ReadGraph graph, Resource element) throws DatabaseException {
-               Resource component = graph.getPossibleObject(element, MOD.ElementToComponent);
-               if (component != null) {
-                       Variable var = Variables.getVariable(graph, component);
-                       RVI realRvi = var.getRVI(graph);
-                       
-                       for (Resource activeModel : graph.syncRequest(new ActiveModels(Simantics.getProjectResource()))) {
-                               for (Variable run : graph.syncRequest(new ActiveRuns(activeModel))) {
-                                       Variable v = realRvi.resolvePossible(graph, run);
-                                       if (v != null) {
-                                               return v;
-                                       }
-                               }
-                               Variable configuration = Variables.getPossibleConfigurationContext(graph, activeModel);
-                               if (configuration != null) {
-                                       Variable v = realRvi.resolvePossible(graph, configuration);
-                                       if (v != null) {
-                                               return v;
-                                       }
-                               }
-                       }
-               }
-               
-               return null;
-       }
-       
-       static Double getPropertyValue(ReadGraph graph, Resource element, String propertyName) {
-               try {
-                       Variable v = getVariableForElement(graph, element);
-                       if (v != null) {
-                               Number value = v.getPossiblePropertyValue(graph, propertyName);
-                               if (value != null)
-                                       return value.doubleValue();
-                       }
-                       
-                       // No property found - try possible mapped element property as well
-                       Resource mappedElement = graph.getPossibleObject(element, DN.MappedComponent);
-                       if (mappedElement != null)
-                               return getPropertyValue(graph, mappedElement, propertyName);
-               }
-               catch (DatabaseException e) {
-               }
-               
-               return null;
-       }
-       
        // Generators
        
-       static abstract class Generator {
+       public static abstract class Generator {
                abstract Collection<Resource> generate(ReadGraph graph, Resource model) throws DatabaseException;
        }
        
-       static class ModelGenerator extends Generator {
+       public static class ModelGenerator extends Generator {
                @Override
                Collection<Resource> generate(ReadGraph graph, Resource model) throws DatabaseException {
                        Resource conf = graph.syncRequest(new Configuration(model));
@@ -397,8 +487,8 @@ public class ElementSelector {
                }
        }
        
-       static class DiagramGenerator extends Generator {
-               Resource diagram;
+       public static class DiagramGenerator extends Generator {
+               public Resource diagram;
                
                public DiagramGenerator(Resource diagram) {
                        this.diagram = diagram;
@@ -410,12 +500,12 @@ public class ElementSelector {
                }
        }
        
-       static class ExplicitGenerator extends Generator {
+       public static class ExplicitGenerator extends Generator {
                public ExplicitGenerator(Collection<Resource> elements) {
                        this.elements = elements;
                }
 
-               Collection<Resource> elements;
+               public Collection<Resource> elements;
 
                @Override
                Collection<Resource> generate(ReadGraph graph, Resource model) {
@@ -425,11 +515,11 @@ public class ElementSelector {
        
        // Selectors
        
-       static abstract class Selector {
+       public static abstract class Selector {
                abstract Collection<Resource> select(ReadGraph graph, Collection<Resource> elements);
        }
        
-       static class All extends Selector {
+       public static class All extends Selector {
                public All() {
                }
 
@@ -439,16 +529,16 @@ public class ElementSelector {
                }
        }
        
-       static class PropertySelector extends Selector {
+       public static class PropertySelector extends Selector {
                public PropertySelector(boolean smallest, String propertyName, int resultCount) {
                        this.smallest = smallest;
                        this.propertyName = propertyName;
                        this.resultCount = resultCount;
                }
                
-               boolean smallest;
-               String propertyName;
-               int resultCount;
+               public boolean smallest;
+               public String propertyName;
+               public int resultCount;
                
                @SuppressWarnings("unchecked")
                @Override
@@ -486,22 +576,28 @@ public class ElementSelector {
        
        // Conditions
        
-       static abstract class Condition {
-               boolean isInverse;
+       public static abstract class Condition {
+               public Resource resource;
+               
+               Condition(Resource r) {
+                       resource = r;
+               }
+               
                abstract boolean match(ReadGraph graph, Resource r) throws DatabaseException;
        }
        
-       static class PropertyCondition extends Condition {
-               public PropertyCondition(String propertyName, Double lowerLimit, Double upperLimit) {
-                       super();
+       public static class PropertyCondition extends Condition {
+               public PropertyCondition(Resource r, String propertyName, Double lowerLimit, Double upperLimit) {
+                       super(r);
+                       
                        this.propertyName = propertyName;
                        this.lowerLimit = lowerLimit;
                        this.upperLimit = upperLimit;
                }
                
-               String propertyName;
-               Double lowerLimit;
-               Double upperLimit;
+               public String propertyName;
+               public Double lowerLimit;
+               public Double upperLimit;
                
                @Override
                boolean match(ReadGraph graph, Resource r) {
@@ -510,9 +606,9 @@ public class ElementSelector {
                }
        }
        
-       static class RegionCondition extends Condition {
-               public RegionCondition(double[] region) {
-                       super();
+       public static class RegionCondition extends Condition {
+               public RegionCondition(Resource r, Resource regionResoruce, double[] region) {
+                       super(r);
                        this.region = region;
                        
                        Path2D path = new Path2D.Double();
@@ -524,8 +620,10 @@ public class ElementSelector {
                        path.closePath();
 
                        this.path = path;
+                       this.regionResource = regionResoruce;
                }
 
+               public Resource regionResource;
                double[] region;
                Path2D path;
 
@@ -538,12 +636,14 @@ public class ElementSelector {
                } 
        }
        
-       static class RouteCondition extends Condition {
-               public RouteCondition(Set<Resource> routePoints) {
-                       super();
+       public static class RouteCondition extends Condition {
+               public RouteCondition(Resource r, Resource routeResource, Set<Resource> routePoints) {
+                       super(r);
                        this.routePoints = routePoints;
+                       this.routeResource = routeResource;
                }
 
+               public Resource routeResource;
                Set<Resource> routePoints;
 
                @Override
@@ -552,31 +652,17 @@ public class ElementSelector {
                }
        }
        
-       static class DiagramCondition extends Condition {
-               public DiagramCondition(Resource diagram) {
-                       super();
-                       this.diagram = diagram;
-               }
-
-               Resource diagram;
-
-               @Override
-               boolean match(ReadGraph graph, Resource r) throws DatabaseException {
-                       return graph.getSingleObject(r, L0.PartOf).equals(diagram);
-               }
-       }
-       
-       static class AggregateCondition extends Condition {
-               static enum Type { DISJUNCTION, CONJUNCTION, NEGATION };
+       public static class AggregateCondition extends Condition {
+               public static enum Type { DISJUNCTION, CONJUNCTION, NEGATION };
                
-               public AggregateCondition(Type type, List<Condition> conditions) {
-                       super();
+               public AggregateCondition(Resource r, Type type, List<Condition> conditions) {
+                       super(r);
                        this.type = type;
                        this.conditions = conditions;
                }
                
-               Type type;
-               List<Condition> conditions;
+               public Type type;
+               public List<Condition> conditions;
                
                @Override
                boolean match(ReadGraph graph, Resource r) throws DatabaseException {
@@ -610,4 +696,26 @@ public class ElementSelector {
                        return new ElementSelector(graph, resource);
                }
        }
+
+       public final static class SelectionExpressionRequest extends ResourceRead<String> {
+               public SelectionExpressionRequest(Resource condition) {
+                       super(condition);
+               }
+       
+               @Override
+               public String perform(ReadGraph graph) throws DatabaseException {
+                       return ElementSelector.buildExpression(graph, resource);
+               }
+       }
+
+       public static final class SelectionConditionRequest extends ResourceRead<Condition> {
+               public SelectionConditionRequest(Resource resource) {
+                       super(resource);
+               }
+       
+               @Override
+               public Condition perform(ReadGraph graph) throws DatabaseException {
+                       return buildCondition(graph, resource);
+               }
+       }
 }