From 7402926f3949dbb38e9f8f45e864ba4dd65b59b9 Mon Sep 17 00:00:00 2001 From: Antti Villberg Date: Fri, 17 Aug 2018 14:01:31 +0300 Subject: [PATCH] Replaceable Defined Component Types gitlab #83 Change-Id: I26ec5d8f6a66805999663e0856601e5ab2f98cb0 --- .../db/layer0/variable/AbstractVariable.java | 118 ++++-- .../org.simantics.layer0/graph/Layer0.pgraph | 3 + .../graph/Structural.pgraph | 14 +- .../scl/Simantics/Structural.scl | 1 + .../structural2/ConnectionImpl2.java | 85 ++++ .../structural2/DefinedUCInterfaceMap.java | 58 +++ .../org/simantics/structural2/Functions.java | 390 ++++++++++-------- .../queries/ConnectionPointMapOfResource.java | 79 ++-- .../structural2/utils/StructuralUtils.java | 48 ++- .../variables/ActualConnectionDescriptor.java | 71 +++- .../variables/ConnectionBrowser.java | 74 +++- ...ctionBrowserConnectionPointDescriptor.java | 29 ++ .../VariableConnectionPointDescriptor.java | 7 +- 13 files changed, 689 insertions(+), 288 deletions(-) create mode 100644 bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl2.java create mode 100644 bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java create mode 100644 bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java index d9366b132..53c5fb5b7 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java @@ -39,6 +39,8 @@ import org.simantics.db.layer0.variable.RVI.ResourceRVIPart; import org.simantics.db.layer0.variable.RVI.StringRVIPart; import org.simantics.db.layer0.variable.Variables.Role; import org.simantics.layer0.Layer0; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function2; /** * Abstract implementation of Variable -interface. @@ -187,18 +189,6 @@ public abstract class AbstractVariable implements Variable { return graph.getPossibleRelatedValue2(represents, graph.getService(Layer0.class).HasLabel, getParent(graph), Bindings.STRING); } - public Resource getType(ReadGraph graph) throws DatabaseException { - - Resource resource = getPossibleRepresents(graph); - if(resource == null) { - String uri = getPossiblePropertyValue(graph, "typeURI"); - if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.instance()); - throw new DatabaseException("No type for " + getURI(graph)); - } - return graph.getSingleType(resource); - - } - public RVIPart getRVIPart(ReadGraph graph) throws DatabaseException { throw new UnsupportedOperationException(); } @@ -950,42 +940,108 @@ public abstract class AbstractVariable implements Variable { } } - @Override - public Resource getPossibleType(ReadGraph graph) throws DatabaseException { + public Resource getType(ReadGraph graph) throws DatabaseException { + Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, Layer0.getInstance(graph).Entity, getPossibleTypeFunction(graph)); + if (typeFromFunction != null) + return typeFromFunction; + Resource resource = getPossibleRepresents(graph); - if(resource == null) { - String uri = getPossiblePropertyValue(graph, "typeURI"); - if(uri != null) return graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.instance()); + if (resource == null) { + String uri = getPossiblePropertyValue(graph, "typeURI"); + if (uri != null) + return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), + TransientCacheAsyncListener. instance()); + throw new DatabaseException("No type for " + getURI(graph)); + } + return graph.getSingleType(resource); + } + + @Override + public Resource getPossibleType(ReadGraph graph) throws DatabaseException { + try { + Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, Layer0.getInstance(graph).Entity, getPossibleTypeFunction(graph)); + if (typeFromFunction != null) + return typeFromFunction; + } catch (Throwable t) { + return null; + } + + Resource resource = getPossibleRepresents(graph); + if (resource == null) { + String uri = getPossiblePropertyValue(graph, "typeURI"); + if (uri != null) + return graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener. instance()); return null; } return graph.getPossibleObject(resource, Layer0.getInstance(graph).InstanceOf); - } + } public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException { + Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, baseType, getPossibleTypeFunction(graph)); + if (typeFromFunction != null) + return typeFromFunction; + Resource resource = getPossibleRepresents(graph); - if(resource == null) { - String uri = getPossiblePropertyValue(graph, "typeURI"); - if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.instance()); + if (resource == null) { + String uri = getPossiblePropertyValue(graph, "typeURI"); + if (uri != null) + return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), + TransientCacheAsyncListener. instance()); throw new DatabaseException("No type for " + getURI(graph)); } return graph.getSingleType(resource, baseType); } - @Override - public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException { + @Override + public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException { + try { + Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, baseType, getPossibleTypeFunction(graph)); + if (typeFromFunction != null) + return typeFromFunction; + } catch (Throwable t) { + return null; + } + Resource resource = getPossibleRepresents(graph); if(resource == null) { - String uri = getPossiblePropertyValue(graph, "typeURI"); - if(uri != null) { - Resource type = graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.instance()); - if(type == null) return null; - if(graph.isInheritedFrom(type, baseType)) return type; - else return null; - } + String uri = getPossiblePropertyValue(graph, "typeURI"); + if(uri != null) { + Resource type = graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.instance()); + if(type == null) return null; + if(graph.isInheritedFrom(type, baseType)) return type; + else return null; + } return null; } return graph.getPossibleType(resource, baseType); - } + } + + private Resource getTypeFromPossibleTypeFunction(ReadGraph graph, Resource baseType, + Function2 fn) throws DatabaseException { + if (fn == null) + // Type function was not defined - return nothing + return null; + + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.put("graph", graph); + try { + return (Resource) fn.apply(this, baseType); + } catch (Throwable t) { + if (t instanceof DatabaseException) + throw (DatabaseException) t; + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); + } + } + + @SuppressWarnings("unchecked") + private Function2 getPossibleTypeFunction(ReadGraph graph) throws DatabaseException { + Variable custom = getPossibleProperty(graph, "typeResource"); + return custom != null + ? (Function2) custom.getPossibleValue(graph) + : null; + } public Map collectDomainProperties(ReadGraph graph, String classification, Map map) throws DatabaseException { Map all = collectDomainProperties(graph, null); diff --git a/bundles/org.simantics.layer0/graph/Layer0.pgraph b/bundles/org.simantics.layer0/graph/Layer0.pgraph index ec2048acb..5fe74ec01 100644 --- a/bundles/org.simantics.layer0/graph/Layer0.pgraph +++ b/bundles/org.simantics.layer0/graph/Layer0.pgraph @@ -25,6 +25,9 @@ L0.Entity : L0.Type >-- L0.typeURI L0.String + >-- L0.typeResource "Variable -> Resource -> Resource" >-- L0.HasComment --> L0.String -- L0.ConsistsOf --> L0.Entity -- STR.ProceduralComponentType.code --> STR.ProceduralComponentTypeCode -- STR.ProceduralComponentType.environment --> L0.SCLValue.Environment Resource -> Resource" STR.Run @L0.assert L0.domainChildren @@ -343,4 +349,10 @@ STR.ComponentTypeScript -- STR.TypeOverride.HasOriginalType --> STR.ComponentType -- STR.TypeOverride.HasReplacementType --> STR.ComponentType STR.TypeOverride Resource -> [Variable] + structuralTypeResource :: Variable -> Resource -> Resource \ No newline at end of file diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl2.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl2.java new file mode 100644 index 000000000..e4b898a6b --- /dev/null +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl2.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.structural2; + +import java.util.Collection; +import java.util.Set; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.structural2.variables.Connection; +import org.simantics.structural2.variables.ConnectionBrowser; +import org.simantics.structural2.variables.VariableConnectionPointDescriptor; + +import gnu.trove.set.hash.THashSet; + +public class ConnectionImpl2 implements Connection { + + private final Variable component; + private final Resource predicate; + + public ConnectionImpl2(Variable component, Resource predicate) { + this.component = component; + this.predicate = predicate; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((predicate == null) ? 0 : predicate.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ConnectionImpl2 other = (ConnectionImpl2) obj; + if (predicate == null) { + if (other.predicate != null) + return false; + } else if (!predicate.equals(other.predicate)) + return false; + return true; + } + + @Override + public Collection getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException { + Set result = new THashSet(); + for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, predicate, relationType)) { + result.add(desc.getVariable(graph)); + } + return result; + } + + @Override + public Collection getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException { + Set result = new THashSet(); + for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, predicate, relationType)) { + result.add(desc.getURI(graph)); + } + return result; + } + + @Override + public Collection getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException { + return ConnectionBrowser.flatten(graph, component, predicate, relationType); + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java new file mode 100644 index 000000000..eb2b19510 --- /dev/null +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.structural2; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.structural2.Functions.InterfaceResolution; + +public class DefinedUCInterfaceMap extends ResourceRead> { + + public DefinedUCInterfaceMap(Resource resource) { + super(resource); + } + + @Override + public Collection perform(ReadGraph graph) + throws DatabaseException { + + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy); + if(definition != null) { + Collection result = new ArrayList<>(); + Layer0 L0 = Layer0.getInstance(graph); + for(Resource cp : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, STR.ConnectionRelation))) { + String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING); + for(Resource conn : graph.getObjects(cp, STR.IsBoundBy)) { + Statement stm = graph.getPossibleStatement(conn, STR.Connects); + if(stm == null) continue; + Resource component = stm.getObject(); + String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING); + result.add(new InterfaceResolution(cp, cpName, componentName, graph.getInverse(stm.getPredicate()))); + } + } + return result; + } + return null; + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java index d9d8857af..f429fdc91 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java @@ -27,6 +27,7 @@ import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.request.PossibleObjectWithType; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.common.uri.UnescapedChildMapOfResource; import org.simantics.db.exception.DatabaseException; @@ -47,6 +48,7 @@ import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.VariableMap; import org.simantics.db.layer0.variable.VariableMapImpl; import org.simantics.db.layer0.variable.VariableNode; +import org.simantics.db.service.CollectionSupport; import org.simantics.issues.common.IssueUtils; import org.simantics.layer0.Layer0; import org.simantics.scl.reflection.annotations.SCLValue; @@ -66,14 +68,12 @@ import org.simantics.structural2.queries.ConnectionPointMapOfResource; import org.simantics.structural2.queries.PossibleConnectionPointInfo; import org.simantics.structural2.scl.CompileStructuralValueRequest; import org.simantics.structural2.scl.procedural.CompileProceduralComponentTypeRequest; +import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass; import org.simantics.structural2.variables.Connection; -import org.simantics.structural2.variables.ConnectionBrowser; import org.simantics.structural2.variables.StandardProceduralChildVariable; -import org.simantics.structural2.variables.VariableConnectionPointDescriptor; import org.simantics.utils.datastructures.MapList; import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; public class Functions { @@ -153,39 +153,6 @@ public class Functions { }; - static class ConnectionImpl implements Connection { - - final private StandardGraphPropertyVariable connectionPoint; - - public ConnectionImpl(StandardGraphPropertyVariable connectionPoint) { - this.connectionPoint = connectionPoint; - } - - @Override - public Collection getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException { - Set result = new THashSet(); - for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) { - result.add(desc.getVariable(graph)); - } - return result; - } - - @Override - public Collection getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException { - Set result = new THashSet(); - for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) { - result.add(desc.getURI(graph)); - } - return result; - } - - @Override - public Collection getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException { - return ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType); - } - - } - @SCLValue(type="ValueAccessor") public static final ValueAccessor connectionValueAccessor = new ValueAccessor() { @@ -213,7 +180,7 @@ public class Functions { @Override public Object getValue(ReadGraph graph, Variable context) throws DatabaseException { StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context; - return new ConnectionImpl(variable); + return new ConnectionImpl2(context.getParent(graph), variable.property.predicate); } @Override @@ -233,10 +200,10 @@ public class Functions { public Variable getPossibleConnectionPointFromContext(ReadGraph graph, Variable variable, Resource context, String name) throws DatabaseException { - Map connectionPoints = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.>instance()); - Resource cp = connectionPoints.get(name); + Map connectionPoints = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.>instance()); + PropertyInfo cp = connectionPoints.get(name); if(cp == null) return null; - else return new StandardGraphPropertyVariable(graph, variable, cp); + else return new StandardGraphPropertyVariable(graph, variable, cp.predicate); } @@ -244,16 +211,16 @@ public class Functions { if(graph.isImmutable(context)) { - Map cps = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.>instance()); + Map cps = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.>instance()); if(cps.size() == 0) return map; if(map == null) map = new THashMap(cps.size()); - for(Map.Entry entry : cps.entrySet()) { + for(Map.Entry entry : cps.entrySet()) { String name = entry.getKey(); - Resource cp = entry.getValue(); - if(needSynchronized && !graph.isInstanceOf(cp, STR.SynchronizedConnectionRelation)) continue; - map.put(name, new StandardGraphPropertyVariable(graph, variable, cp)); + PropertyInfo cp = entry.getValue(); + if(needSynchronized && !graph.isInstanceOf(cp.predicate, STR.SynchronizedConnectionRelation)) continue; + map.put(name, new StandardGraphPropertyVariable(graph, variable, cp.predicate)); } return map; @@ -313,78 +280,30 @@ public class Functions { }; - static class StructuralChildMapOfResource extends ResourceRead> { + static class StructuralRunContext extends ResourceRead { - public StructuralChildMapOfResource(Resource resource) { + public StructuralRunContext(Resource resource) { super(resource); } @Override - public Map perform(ReadGraph graph) throws DatabaseException { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - Resource type = graph.getPossibleType(resource, STR.Component); - if(type != null) { - Resource definition = graph.getPossibleObject(type, STR.IsDefinedBy); - if(definition != null) { - Map map = graph.syncRequest(new UnescapedChildMapOfResource(definition)); - if (!map.isEmpty()) - return map; - } - } - Map directChildren = graph.syncRequest(new UnescapedChildMapOfResource(resource)); - return directChildren; - } - - } - - static class StructuralChildMapOfResourceT extends ResourceRead> { - - public StructuralChildMapOfResourceT(Resource resource) { - super(resource); - } - - @Override - public Map perform(ReadGraph graph) throws DatabaseException { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy); - if(definition != null) { - Map map = graph.syncRequest(new UnescapedChildMapOfResource(definition)); - if (!map.isEmpty()) - return map; - } - return Collections.emptyMap(); - } - - } - - static class StructuralRunChildMapOfResource extends ResourceRead> { - - public StructuralRunChildMapOfResource(Resource resource) { - super(resource); - } - - public Map fromContext(ReadGraph graph, Resource context) throws DatabaseException { - return graph.sync(new StructuralChildMapOfResource(context)); - } - - @Override - public Map perform(ReadGraph graph) throws DatabaseException { + public Resource perform(ReadGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); SimulationResource SIMU = SimulationResource.getInstance(graph); Resource model = graph.sync(new PossibleIndexRoot(resource)); if(graph.isInstanceOf(model, L0.RVIContext)) { - return fromContext(graph, model); + return model; } Resource configuration = graph.getPossibleObject(model, SIMU.HasConfiguration); if(configuration != null) { if(graph.isInstanceOf(configuration, L0.RVIContext)) { - return fromContext(graph, configuration); + return configuration; } } - - return Collections.emptyMap(); - + + return null; + } } @@ -488,6 +407,143 @@ public class Functions { } } + public static class StructuralTypeOverrideMap extends ResourceRead> { + + protected StructuralTypeOverrideMap(Resource composite) { + super(composite); + } + + @Override + public Map perform(ReadGraph graph) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + + StructuralResource2 STR = StructuralResource2.getInstance(graph); + + CollectionSupport cs = graph.getService(CollectionSupport.class); + + Map result = null; + + for(Resource override : graph.getObjects(resource, STR.HasTypeOverride)) { + Resource original = graph.getSingleObject(override, STR.TypeOverride_HasOriginalType); + Resource replacement = graph.getSingleObject(override, STR.TypeOverride_HasReplacementType); + if(result == null) result = cs.createMap(Resource.class); + result.put(original, replacement); + } + + if(result == null) return Collections.emptyMap(); + + return result; + + } + + } + + public static class StructuralOverrideData { + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((actualRepresents == null) ? 0 : actualRepresents.hashCode()); + result = prime * result + ((actualType == null) ? 0 : actualType.hashCode()); + result = prime * result + ((overrideType == null) ? 0 : overrideType.hashCode()); + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StructuralOverrideData other = (StructuralOverrideData) obj; + if (actualRepresents == null) { + if (other.actualRepresents != null) + return false; + } else if (!actualRepresents.equals(other.actualRepresents)) + return false; + if (actualType == null) { + if (other.actualType != null) + return false; + } else if (!actualType.equals(other.actualType)) + return false; + if (overrideType == null) { + if (other.overrideType != null) + return false; + } else if (!overrideType.equals(other.overrideType)) + return false; + return true; + } + Resource actualRepresents; + Resource actualType; + Resource overrideType; + public StructuralOverrideData(Resource actualRepresents, Resource actualType, Resource overrideType) { + this.actualRepresents = actualRepresents; + this.actualType = actualType; + this.overrideType = overrideType; + } + + public static StructuralOverrideData compute(ReadGraph graph, Variable context) throws DatabaseException { + return graph.syncRequest(new StructuralOverrideDataRequest(context)); + } + + public Resource type() { + if(overrideType != null) + return overrideType; + return actualType; + } + + public Resource represents() { + return actualRepresents; + } + + } + + public static class StructuralOverrideDataRequest extends VariableRead { + + public StructuralOverrideDataRequest(Variable component) { + super(component); + } + + public StructuralOverrideData walk(ReadGraph graph, Variable component, Resource actualRepresents, Resource actualType) throws DatabaseException { + Resource represents = component.getPossibleRepresents(graph); + if(represents != null) { + Layer0 L0 = Layer0.getInstance(graph); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource container = graph.syncRequest(new PossibleObjectWithType(represents, L0.PartOf, STR.Composite)); + if(container != null) { + Map overrides = graph.syncRequest(new StructuralTypeOverrideMap(container)); + Resource override = overrides.get(actualType); + if(override != null) { + return new StructuralOverrideData(actualRepresents, actualType, override); + } + } + } + Variable parent = component.getParent(graph); + if(parent == null) return new StructuralOverrideData(actualRepresents, actualType, null); + else return walk(graph, parent, represents, actualType); + } + + @Override + public StructuralOverrideData perform(ReadGraph graph) throws DatabaseException { + + Resource represents = variable.getPossibleRepresents(graph); + if(represents == null) { + String uri = variable.getPossiblePropertyValue(graph, "typeURI"); + if(uri != null) { + Resource actualType = graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.instance()); + return walk(graph, variable, null, actualType); + } + throw new DatabaseException("No type for " + variable.getURI(graph)); + } else { + return walk(graph, variable, represents, graph.getPossibleType(represents, Layer0.getInstance(graph).Entity)); + } + + } + + } + @SCLValue(type = "VariableMap") public static VariableMap structuralChildDomainChildren = new VariableMapImpl() { @@ -495,53 +551,64 @@ public class Functions { @Override public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException { - final Resource type = context.getPossibleType(graph); - if(type != null) { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - if(graph.isInstanceOf(type, STR.ProceduralComponentType)) { - Map map = graph.syncRequest(new ProceduralSubstructureRequest(context), - TransientCacheListener.>instance()); - if(map != null) return map.get(name); - } - } - - Resource represents = context.getPossibleRepresents(graph); - if(represents == null) { - Map children = graph.syncRequest(new StructuralChildMapOfResourceT(type)); + Resource type = context.getPossibleType(graph); + if(type == null) return null; + + StructuralComponentClass clazz = StructuralComponentClass.get(graph, type); + if(StructuralComponentClass.PROCEDURAL.equals(clazz)) { + Map map = graph.syncRequest(new ProceduralSubstructureRequest(context), + TransientCacheListener.>instance()); + if(map != null) return map.get(name); + return null; + } else if (StructuralComponentClass.DEFINED.equals(clazz)) { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource def = graph.getSingleObject(type, STR.IsDefinedBy); + Map children = graph.syncRequest(new UnescapedChildMapOfResource(def)); Resource child = children.get(name); - return All.getStandardChildDomainChildVariable(graph, context, child, name); - } - Map children = graph.syncRequest(new StructuralChildMapOfResource(represents)); - Resource child = children.get(name); - return All.getStandardChildDomainChildVariable(graph, context, child, name); + if(child == null) return null; + return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name); + } else { + Resource represents = context.getPossibleRepresents(graph); + if(represents == null) return null; + Map children = graph.syncRequest(new UnescapedChildMapOfResource(represents)); + Resource child = children.get(name); + if(child == null) return null; + return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name); + } + } @Override public Map getVariables(ReadGraph graph, Variable context, Map map) throws DatabaseException { - final Resource type = context.getPossibleType(graph); - if(type != null) { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - if(graph.isInstanceOf(type, STR.ProceduralComponentType)) { - Map mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context), - TransientCacheListener.>instance()); - if(mapPrime != null) { - if(map != null) { - map.putAll(mapPrime); - return map; - } - else - return mapPrime; - } - } - } - Resource represents = context.getPossibleRepresents(graph); - if(represents == null) { - Map children = graph.syncRequest(new StructuralChildMapOfResourceT(type)); + Resource type = context.getPossibleType(graph); + if(type == null) return null; + + StructuralComponentClass clazz = StructuralComponentClass.get(graph, type); + if(StructuralComponentClass.PROCEDURAL.equals(clazz)) { + Map mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context), + TransientCacheListener.>instance()); + if(mapPrime != null) { + if(map != null) { + map.putAll(mapPrime); + return map; + } + else + return mapPrime; + } + return map; + } else if (StructuralComponentClass.DEFINED.equals(clazz)) { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource def = graph.getSingleObject(type, STR.IsDefinedBy); + Map children = graph.syncRequest(new UnescapedChildMapOfResource(def)); return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map); - } - Map children = graph.syncRequest(new StructuralChildMapOfResource(represents)); - return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map); + } else { + Resource represents = context.getPossibleRepresents(graph); + if(represents == null) return null; + Map children = graph.syncRequest(new UnescapedChildMapOfResource(represents)); + return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map); + } + } }; @@ -551,15 +618,18 @@ public class Functions { @Override public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException { - Map children = graph.syncRequest(new StructuralRunChildMapOfResource(context.getRepresents(graph))); + Resource ctx = graph.syncRequest(new StructuralRunContext(context.getRepresents(graph))); + if(ctx == null) return null; + Map children = graph.syncRequest(new UnescapedChildMapOfResource(ctx)); Resource child = children.get(name); return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name); } @Override public Map getVariables(ReadGraph graph, Variable context, Map map) throws DatabaseException { - StandardGraphChildVariable variable = (StandardGraphChildVariable)context; - Map children = graph.syncRequest(new StructuralRunChildMapOfResource(variable.resource)); + Resource ctx = graph.syncRequest(new StructuralRunContext(context.getRepresents(graph))); + if(ctx == null) return map; + Map children = graph.syncRequest(new UnescapedChildMapOfResource(ctx)); return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map); } @@ -765,38 +835,6 @@ public class Functions { } - static class DefinedUCInterfaceMap extends ResourceRead> { - - public DefinedUCInterfaceMap(Resource resource) { - super(resource); - } - - @Override - public Collection perform(ReadGraph graph) - throws DatabaseException { - - StructuralResource2 STR = StructuralResource2.getInstance(graph); - Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy); - if(definition != null) { - Collection result = new ArrayList(); - Layer0 L0 = Layer0.getInstance(graph); - for(Resource cp : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, STR.ConnectionRelation))) { - String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING); - for(Resource conn : graph.getObjects(cp, STR.IsBoundBy)) { - Statement stm = graph.getPossibleStatement(conn, STR.Connects); - if(stm == null) continue; - Resource component = stm.getObject(); - String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING); - result.add(new InterfaceResolution(cp, cpName, componentName, graph.getInverse(stm.getPredicate()))); - } - } - return result; - } - return null; - } - - } - public static final Collection BUILTIN_STRUCTURAL_CPS = new ArrayList(); @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/queries/ConnectionPointMapOfResource.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/queries/ConnectionPointMapOfResource.java index 3b2e42ae7..2cfc97296 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/queries/ConnectionPointMapOfResource.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/queries/ConnectionPointMapOfResource.java @@ -13,6 +13,7 @@ package org.simantics.structural2.queries; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import org.simantics.db.ReadGraph; @@ -26,47 +27,45 @@ import org.simantics.db.service.QueryControl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import gnu.trove.map.hash.THashMap; - -public class ConnectionPointMapOfResource extends TransientResourceRead> { +public class ConnectionPointMapOfResource extends TransientResourceRead> { private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionPointMapOfResource.class); - public ConnectionPointMapOfResource(ReadGraph graph, Resource resource) throws DatabaseException { - super(graph, resource); - } - - public ConnectionPointMapOfResource(ReadGraph graph, QueryControl qc, Resource resource) throws DatabaseException { - super(graph, qc, resource); - } - - @Override - public Map perform(ReadGraph graph, Resource resource) throws DatabaseException { - - Collection predicates = graph.getPredicates(resource); - - THashMap result = null; - - for(Resource predicate : predicates) { - - PropertyInfo info = graph.syncRequest(new PossibleConnectionPointInfo(predicate), TransientCacheAsyncListener.instance()); - if(info != null) { - if (result == null) result = new THashMap(predicates.size()); - if (result.put(info.name, predicate) != null) - LOGGER.error("The database contains siblings with the same name " + info.name + " (resource=$" + resource.getResourceId() + ")."); - } - - } - - if(result != null) return result; - - else return Collections.emptyMap(); - - } - - @Override - public int getType() { - return RequestFlags.INVALIDATE; - } - + public ConnectionPointMapOfResource(ReadGraph graph, Resource resource) throws DatabaseException { + super(graph, resource); + } + + public ConnectionPointMapOfResource(ReadGraph graph, QueryControl qc, Resource resource) throws DatabaseException { + super(graph, qc, resource); + } + + @Override + public Map perform(ReadGraph graph, Resource resource) throws DatabaseException { + + Collection predicates = graph.getPredicates(resource); + + HashMap result = null; + + for(Resource predicate : predicates) { + + PropertyInfo info = graph.syncRequest(new PossibleConnectionPointInfo(predicate), TransientCacheAsyncListener.instance()); + if(info != null) { + if (result == null) result = new HashMap<>(predicates.size()); + if (result.put(info.name, info) != null) + LOGGER.error("The database contains siblings with the same name " + info.name + " (resource=$" + resource.getResourceId() + ")."); + } + + } + + if(result != null) return result; + + else return Collections.emptyMap(); + + } + + @Override + public int getType() { + return RequestFlags.INVALIDATE; + } + } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java index 9a77d100f..584b4acf7 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java @@ -1,3 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ package org.simantics.structural2.utils; import java.util.ArrayList; @@ -23,6 +34,7 @@ import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.structural2.Functions.StructuralOverrideData; import org.simantics.structural2.internal.queries.ConnectedTo; import org.simantics.structural2.internal.queries.RelatedConnections; import org.simantics.structural2.internal.queries.RelatedConnectionsOfConnectionJoin; @@ -39,6 +51,25 @@ import gnu.trove.set.hash.THashSet; */ public class StructuralUtils { + public static enum StructuralComponentClass { + + PRIMITIVE,REPLACEABLE,DEFINED,PROCEDURAL; + + public static StructuralComponentClass get(ReadGraph graph, Resource componentType) throws DatabaseException { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Set types = graph.getTypes(componentType); + if(types.contains(STR.ProceduralComponentType)) + return StructuralComponentClass.PROCEDURAL; + else if(graph.hasStatement(componentType, STR.IsDefinedBy)) + return StructuralComponentClass.DEFINED; + else if(types.contains(STR.ReplaceableDefinedComponentType)) + return StructuralComponentClass.REPLACEABLE; + else + return StructuralComponentClass.PRIMITIVE; + } + + } + public static Collection getConnectionRelations(ReadGraph graph, Resource componentType) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); StructuralResource2 STR = StructuralResource2.getInstance(graph); @@ -168,6 +199,7 @@ public class StructuralUtils { * Returns the component type of the given component or null if the * parameter is not a component. */ + @Deprecated public static Resource getComponentType(ReadGraph g, Resource component) throws DatabaseException { StructuralResource2 STR = StructuralResource2.getInstance(g); return g.getPossibleType(component, STR.Component); @@ -288,7 +320,21 @@ public class StructuralUtils { } public static List structuralConnectionConnectionPoints(ReadGraph graph, Connection conn, Resource relationType) throws DatabaseException { - return new ArrayList(conn.getConnectionPoints(graph, relationType)); + return new ArrayList(conn.getConnectionPoints(graph, relationType)); + } + + public static Resource structuralTypeResource(ReadGraph graph, Variable component, Resource baseType) throws DatabaseException { + StructuralOverrideData od = StructuralOverrideData.compute(graph, component); + return od.type(); } + + public static Resource getComponentType(ReadGraph graph, Variable configuration, Resource component) throws DatabaseException { + + Variable componentVariable = configuration.browse(graph, component); + return componentVariable.getType(graph); + + } + + } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java index e0b93837e..716d4a001 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java @@ -14,50 +14,93 @@ import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.structural2.DefinedUCInterfaceMap; import org.simantics.structural2.Functions; import org.simantics.structural2.Functions.InterfaceResolution; +import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass; import org.simantics.structural2.variables.ConnectionBrowser.IsLeafType; /* - * This connection descriptor variable + * This connection descriptor + * * -has not been lifted into interface * -has a structural configuration defined as resources - * -has not been drilled + * -might not be drilled + * + * Note: these are constructed after climb (before drill) phase of the connection browser. This means that + * the component can still contain sub structure during connection browsing. This means that some descriptors + * are not final and are replaced by correct descriptors during drill phase. + * */ class ActualConnectionDescriptor extends AbstractVariableConnectionPointDescriptor { - final private Variable root; - final private Resource component; - final private Resource cp; + /* + * This is the nearest known ancestor variable + */ + final Variable root; + /* + * A component on variable path under the root variable. + */ + final Resource component; + /* + * TODO + */ + final Resource componentType; + /* + * The connection point that has type of the component as its domain + */ + final Resource cp; - public ActualConnectionDescriptor(Variable root, Resource component, Resource cp) { + public ActualConnectionDescriptor(Variable root, Resource component, Resource componentType, Resource cp) { this.root = root; this.component = component; + this.componentType = componentType; this.cp = cp; } - static class ComputeInterfaceDescription extends UnaryRead> { + static class ActualConnectionDescriptorInterfaceDescription extends UnaryRead> { - public ComputeInterfaceDescription(ActualConnectionDescriptor desc) { + public ActualConnectionDescriptorInterfaceDescription(ActualConnectionDescriptor desc) { super(desc); } @Override public Collection perform(ReadGraph graph) throws DatabaseException { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - Resource type = graph.getPossibleType(parameter.component, STR.Component); - if(graph.syncRequest(new IsLeafType(type))) return null; - - return Functions.computeInterfacePaths(graph, parameter.getVariable(graph).getParent(graph)); +// ConnectionBrowser.reportDescriptor(graph, parameter); + + /* + * The componentType is the possibly replaced (STR.ReplaceableDefinedComponentType) type + */ + StructuralComponentClass clazz = StructuralComponentClass.get(graph, parameter.componentType); + if(StructuralComponentClass.PRIMITIVE.equals(clazz)) { + return null; + } else if(StructuralComponentClass.DEFINED.equals(clazz)) { + final Collection interfaces = graph.syncRequest(new DefinedUCInterfaceMap(parameter.componentType)); + if(interfaces != null) return interfaces; + else return Functions.BUILTIN_STRUCTURAL_CPS; + } else if(StructuralComponentClass.REPLACEABLE.equals(clazz)) { + throw new DatabaseException("ConnectionBrowser does not support nested replaceable defined structural types."); + } else { + return Functions.computeInterfacePaths(graph, parameter.getVariable(graph).getParent(graph)); + } } } + @Override + public boolean isLeaf(ReadGraph graph) throws DatabaseException { + + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource type = graph.getPossibleType(component, STR.Component); + return graph.syncRequest(new IsLeafType(type)); + + } + @Override public Collection getInterfaceDescription(ReadGraph graph) throws DatabaseException { - return graph.syncRequest(new ComputeInterfaceDescription(this), TransientCacheAsyncListener.>instance()); + return graph.syncRequest(new ActualConnectionDescriptorInterfaceDescription(this), TransientCacheAsyncListener.>instance()); } public Resource getConnectionPointResource(ReadGraph graph) throws DatabaseException { diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java index ac1dceceb..7f43f59d1 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java @@ -1,8 +1,5 @@ package org.simantics.structural2.variables; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -36,9 +33,14 @@ import org.simantics.structural.stubs.StructuralResource2; import org.simantics.structural2.Functions; import org.simantics.structural2.Functions.InterfaceResolution; import org.simantics.structural2.queries.ConnectionSet; +import org.simantics.structural2.utils.StructuralUtils; +import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass; import org.simantics.structural2.variables.StandardProceduralChildVariable.FixedConnection; import org.simantics.utils.datastructures.Pair; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + public class ConnectionBrowser { /** @@ -79,7 +81,7 @@ public class ConnectionBrowser { Resource relation = graph.getInverse(stat.getPredicate()); //System.out.println(NameUtils.getSafeName(graph, component) + "." + NameUtils.getSafeName(graph, relation)); Resource boundConnection = graph.getPossibleObject(relation, STR.IsBoundBy); - Resource type = graph.getPossibleObject(component, L0.InstanceOf); + Resource type = StructuralUtils.getComponentType(graph, configuration, component); Resource def = type != null ? graph.getPossibleObject(type, STR.IsDefinedBy) : null; if(boundConnection != null && def != null) { // The connection point is bound in component type @@ -383,6 +385,21 @@ public class ConnectionBrowser { } + public static void reportDescriptor(ReadGraph graph, VariableConnectionPointDescriptor d) throws DatabaseException { + + if(d instanceof ActualConnectionDescriptor) { + ActualConnectionDescriptor d2 = (ActualConnectionDescriptor)d; + + System.err.println("--ActualConnectionPointDescriptor2"); + System.err.println("---root: " + d2.root.getURI(graph)); + System.err.println("---component: " + graph.getPossibleURI(d2.component)); + System.err.println("---type: " + graph.getPossibleURI(d2.componentType)); + System.err.println("---cp: " + graph.getPossibleURI(d2.cp)); + System.err.println("---var: " + d2.getVariable(graph).getURI(graph)); + } + + } + public static class ConnectionVariables extends BinaryRead, Collection> { private ConnectionVariables(Variable parameter1, List parameter2) { @@ -427,6 +444,7 @@ public class ConnectionBrowser { @Override public Collection perform(ReadGraph graph) throws DatabaseException { if(parameter == null) return Collections.emptyList(); + Layer0 L0 = Layer0.getInstance(graph); StructuralResource2 STR = StructuralResource2.getInstance(graph); ArrayList result = null; for(int i=1;i(); - result.add(new ActualConnectionDescriptor(parameter, component, connectionPoint)); + String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING); + Variable possibleChild = parameter.getPossibleChild(graph, componentName); + if(possibleChild != null) { + result.add(new ActualConnectionDescriptor(parameter, component, possibleChild.getType(graph), connectionPoint)); + } else { + throw new DatabaseException("No child with name " + componentName + " could be resolved for variable " + parameter.getURI(graph)); + } } } if(result == null) return Collections.emptyList(); @@ -453,12 +477,8 @@ public class ConnectionBrowser { @Override public Boolean perform(ReadGraph graph) throws DatabaseException { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - - if(graph.isInstanceOf(resource, STR.ProceduralComponentType)) return false; - if(graph.hasStatement(resource, STR.IsDefinedBy)) return false; - - return true; + StructuralComponentClass clazz = StructuralComponentClass.get(graph, resource); + return StructuralComponentClass.PRIMITIVE.equals(clazz); } @@ -591,28 +611,42 @@ public class ConnectionBrowser { public static Collection doFlatten(ReadGraph graph, Variable child, Resource cp, Resource relationType) throws DatabaseException { - Collection climbed = climb(graph, child, cp, null); - boolean needDrill = false; + Set result = null; + Set needDrill = null; + + Collection climbed = climb(graph, child, cp, null); for(VariableConnectionPointDescriptor desc : climbed) { if(!desc.isLeaf(graph)) { - needDrill = true; - break; + if(needDrill == null) + needDrill = new THashSet(climbed.size()); + needDrill.add(desc); + } else { + if(result == null) + result = new THashSet(climbed.size()); + result.add(desc); } } - if(!needDrill) { + if(needDrill == null) { + /* + * All descriptors were already flat - just take case of filtering + */ if(relationType != null) { ArrayList filtered = new ArrayList(climbed.size()); for(VariableConnectionPointDescriptor desc : climbed) if(filterByRelationType(graph, desc, relationType)) filtered.add(desc); return filtered; + } else { + return climbed; } - return climbed; } - THashSet result = new THashSet(climbed.size()); - for(VariableConnectionPointDescriptor top : climbed) { + + /* + * There were some descriptors that require drill + */ + for(VariableConnectionPointDescriptor top : needDrill) { Collection drilled = drill(graph, top); if(drilled != null) { for(VariableConnectionPointDescriptor drill : drilled) { @@ -620,6 +654,8 @@ public class ConnectionBrowser { if(!filterByRelationType(graph, drill, relationType)) continue; } + if(result == null) + result = new THashSet(climbed.size()); result.add(drill); } } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java new file mode 100644 index 000000000..08a0a0222 --- /dev/null +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.structural2.variables; + +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.structural2.Functions.InterfaceResolution; + +/* + * @author Antti Villberg + * @since 1.36 + */ +public interface ConnectionBrowserConnectionPointDescriptor { + + public boolean isLeaf(ReadGraph graph) throws DatabaseException; + public Collection getInterfaceDescription(ReadGraph graph) throws DatabaseException; + +} diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java index 403280aea..c4a3fee48 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java @@ -1,21 +1,16 @@ package org.simantics.structural2.variables; -import java.util.Collection; - import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; -import org.simantics.structural2.Functions.InterfaceResolution; -public interface VariableConnectionPointDescriptor { +public interface VariableConnectionPointDescriptor extends ConnectionBrowserConnectionPointDescriptor { public boolean isFlattenedFrom(ReadGraph graph, Variable possiblyStructuralCp) throws DatabaseException; public Variable getVariable(ReadGraph graph) throws DatabaseException; public Resource getConnectionPointResource(ReadGraph graph) throws DatabaseException; public String getURI(ReadGraph graph) throws DatabaseException; - public Collection getInterfaceDescription(ReadGraph graph) throws DatabaseException; - public boolean isLeaf(ReadGraph graph) throws DatabaseException; public boolean hasClassification(ReadGraph graph, String classification) throws DatabaseException; public String getRelativeRVI(ReadGraph graph, Variable base) throws DatabaseException; -- 2.43.2