X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.selection%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fselection%2FElementSelector.java;h=bf051b4c9828e3f9d4d0b08a3e8409a3d4d3c091;hb=50306ed44f39142ec59265c7329e8e5930b9ff38;hp=7d429e4e04a5669667b11d35d678851f0af06874;hpb=c21f2dc656cbd621185a0bb88175db618d78eef9;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.selection/src/org/simantics/district/selection/ElementSelector.java b/org.simantics.district.selection/src/org/simantics/district/selection/ElementSelector.java index 7d429e4e..bf051b4c 100644 --- a/org.simantics.district.selection/src/org/simantics/district/selection/ElementSelector.java +++ b/org.simantics.district.selection/src/org/simantics/district/selection/ElementSelector.java @@ -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 findDiagrams() { + try { + return Simantics.getSession().syncRequest(new Read>() { + @Override + public Map perform(ReadGraph graph) throws DatabaseException { + Map result = new HashMap<>(); + Resource model = graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource())); + List 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 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 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 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 conditionResources = graph.getObjects(resource, ES.HasSubcondition); List 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 exps = new ArrayList<>(); Collection 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 filterElementsFrom(ReadGraph graph, Collection 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 generate(ReadGraph graph, Resource model) throws DatabaseException; } - static class ModelGenerator extends Generator { + public static class ModelGenerator extends Generator { @Override Collection 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 elements) { this.elements = elements; } - Collection elements; + public Collection elements; @Override Collection generate(ReadGraph graph, Resource model) { @@ -425,11 +515,11 @@ public class ElementSelector { // Selectors - static abstract class Selector { + public static abstract class Selector { abstract Collection select(ReadGraph graph, Collection elements); } - static class All extends Selector { + public static class All extends Selector { public All() { } @@ -439,27 +529,26 @@ 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 Collection select(ReadGraph graph, Collection elements) { - List result = new ArrayList<>(elements); List result2 = Lists.map(new FunctionImpl1() { @Override public Tuple2 apply(Resource r) { return new Tuple2(r, getPropertyValue(graph, r, propertyName)); } - }, result); + }, new ArrayList<>(elements)); result2 = Lists.filter(new FunctionImpl1() { @Override @@ -470,38 +559,48 @@ public class ElementSelector { result2.sort((t1, t2) -> smallest ? Double.compare((Double) t1.c1, (Double) t2.c1) : Double.compare((Double) t2.c1, (Double) t1.c1)); - if (resultCount < result2.size()) - result2 = result2.subList(0, resultCount); + if (resultCount < result2.size()) { + double limitValue = (double) result2.get(resultCount-1).c1; + + // Expand selection to contain all items with the same value as the nth one + int count = resultCount; + while (count < result2.size() && (double)result2.get(count).c1 == limitValue) count++; + result2 = result2.subList(0, count); + } - result = Lists.map(new FunctionImpl1() { + return (List) Lists.map(new FunctionImpl1() { @Override public Resource apply(Tuple2 p0) { return (Resource) p0.c0; } }, result2); - - return result; } } // 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 +609,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 +623,10 @@ public class ElementSelector { path.closePath(); this.path = path; + this.regionResource = regionResoruce; } + public Resource regionResource; double[] region; Path2D path; @@ -538,12 +639,14 @@ public class ElementSelector { } } - static class RouteCondition extends Condition { - public RouteCondition(Set routePoints) { - super(); + public static class RouteCondition extends Condition { + public RouteCondition(Resource r, Resource routeResource, Set routePoints) { + super(r); this.routePoints = routePoints; + this.routeResource = routeResource; } + public Resource routeResource; Set routePoints; @Override @@ -552,31 +655,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 conditions) { - super(); + public AggregateCondition(Resource r, Type type, List conditions) { + super(r); this.type = type; this.conditions = conditions; } - Type type; - List conditions; + public Type type; + public List conditions; @Override boolean match(ReadGraph graph, Resource r) throws DatabaseException { @@ -610,4 +699,26 @@ public class ElementSelector { return new ElementSelector(graph, resource); } } + + public final static class SelectionExpressionRequest extends ResourceRead { + 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 { + public SelectionConditionRequest(Resource resource) { + super(resource); + } + + @Override + public Condition perform(ReadGraph graph) throws DatabaseException { + return buildCondition(graph, resource); + } + } }