X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.structural2%2Fsrc%2Forg%2Fsimantics%2Fstructural2%2Fvariables%2FConnectionBrowser.java;fp=bundles%2Forg.simantics.structural2%2Fsrc%2Forg%2Fsimantics%2Fstructural2%2Fvariables%2FConnectionBrowser.java;h=ac1dceceb3ddfce6739ece5c01909ebc7c618c7a;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hp=d1ec55f6d898b31c743ffc6fbbedc3c699c798f6;hpb=24e2b34260f219f0d1644ca7a138894980e25b14;p=simantics%2Fplatform.git 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 d1ec55f6d..ac1dceceb 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,645 +1,645 @@ -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; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -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.procedure.adapter.TransientCacheAsyncListener; -import org.simantics.db.common.request.BinaryRead; -import org.simantics.db.common.request.ResourceRead; -import org.simantics.db.common.request.TransientUnaryRead; -import org.simantics.db.common.utils.CommonDBUtils; -import org.simantics.db.common.utils.NameUtils; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.exception.NoSingleResultException; -import org.simantics.db.layer0.exception.MissingVariableException; -import org.simantics.db.layer0.exception.MissingVariableValueException; -import org.simantics.db.layer0.request.VariableRead; -import org.simantics.db.layer0.variable.Variable; -import org.simantics.db.service.CollectionSupport; -import org.simantics.db.service.QueryControl; -import org.simantics.layer0.Layer0; -import org.simantics.modeling.ModelingResources; -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.variables.StandardProceduralChildVariable.FixedConnection; -import org.simantics.utils.datastructures.Pair; - -public class ConnectionBrowser { - - /** - * Finds the components connected by the connection. Also connections - * in - * - * @param graph - * @param connection A connection whose related modules are searched. - * @param configuration A variable that represents the composite where the connection belongs to. - * @return A map whose keys are components and they are mapped to - * related variables. - */ - public static Collection findConnectedComponents( - ReadGraph graph, Resource connection, Variable configuration) - throws DatabaseException { - // Create state - ArrayList result = - new ArrayList(); - THashSet visitedConnections = new THashSet(); - - // Do actual work - findConnectedComponents(graph, connection, configuration, result, - visitedConnections); - return result; - } - - private static void findConnectedComponents( - ReadGraph graph, Resource connection, Variable configuration, - ArrayList result, - THashSet visitedConnections) throws DatabaseException { - if(visitedConnections.add(connection)) { - StructuralResource2 STR = StructuralResource2.getInstance(graph); - Layer0 L0 = Layer0.getInstance(graph); - - // Browse related components - for(Statement stat : graph.getStatements(connection, STR.Connects)) { - Resource component = stat.getObject(); - 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 def = type != null ? graph.getPossibleObject(type, STR.IsDefinedBy) : null; - if(boundConnection != null && def != null) { - // The connection point is bound in component type - Variable newContext = configuration.browsePossible(graph, component); - Resource newComposite = getCompositeOfConnection(graph, boundConnection); - if(newContext != null && newComposite != null) { - newContext = browse(graph, def, newContext, newComposite); - if (newContext != null) - findConnectedComponents(graph, boundConnection, - newContext, - result, visitedConnections); - } - } - else { - //System.out.println("added result"); - // A primitive connection point - Variable context = configuration.browsePossible(graph, component); - if (context != null) - result.add(new ResourceWithContext(component, context)); - } - } - - // Browse over connection joins - for(Resource join : graph.getObjects(connection, STR.IsJoinedBy)) - for(Resource otherConnection : graph.getObjects(join, STR.Joins)) - if(!connection.equals(otherConnection)) { - Resource sourceComposite = getCompositeOfConnection(graph, connection); - Resource targetComposite = getCompositeOfConnection(graph, otherConnection); - if (sourceComposite != null && targetComposite != null) { - Variable sibling = browseSibling(graph, - sourceComposite, - configuration, - targetComposite); - if (sibling != null) - findConnectedComponents(graph, otherConnection, - sibling, result, visitedConnections); - } - } - - // Browse to parents - try { - for(Resource relation : graph.getObjects(connection, STR.Binds)) { - Resource composite = getCompositeOfConnection(graph, connection); - if (composite == null) - continue; - - Variable curConfiguration = configuration; - while(!graph.hasStatement(composite, STR.Defines)) { - composite = graph.getSingleObject(composite, L0.PartOf); - curConfiguration = curConfiguration.getParent(graph); - } - Variable parent = curConfiguration.getParent(graph); - Resource component = curConfiguration.getRepresents(graph); - for(Resource c : graph.getObjects(component, relation)) - findConnectedComponents(graph, c, - parent, result, visitedConnections); - } - } catch(NoSingleResultException e) { - } catch(MissingVariableException e) { - } catch(MissingVariableValueException e) { - } - } - } - - public static Collection drill(ReadGraph graph, VariableConnectionPointDescriptor pair) throws DatabaseException { - - Collection interfaceDescription = pair.getInterfaceDescription(graph); - if(interfaceDescription != null && interfaceDescription.size() > 0) { - - Variable cp = pair.getVariable(graph); - Variable context = cp.getParent(graph); - String cpName = cp.getName(graph); - - Collection result = new ArrayList(); - for(InterfaceResolution r : interfaceDescription) { - if(r.interfaceName.equals(cpName)) { - String path = Functions.resolveInterfacePath(graph, context, r.componentName, r.connectionPoint); - result.add(new BrowseConnectionDescriptor(context, path)); - } - } - - if(result.isEmpty()) return null; - - return result; - - } else { - return Collections.singleton(pair); - } - - } - - public static class JoinConnections extends ResourceRead> { - - public JoinConnections(Resource join) { - super(join); - } - - @Override - public Collection perform(ReadGraph graph) throws DatabaseException { - ConnectionSet cs = new ConnectionSet(graph); - cs.addJoin(graph, resource); - return cs.getConnections(); - } - - } - - - public static final class VariableChildren extends TransientUnaryRead> { - - public VariableChildren(ReadGraph graph, Variable variable) throws DatabaseException { - super(graph, variable); - } - - public VariableChildren(ReadGraph graph, QueryControl qc, Variable variable) throws DatabaseException { - super(graph, qc, variable); - } - - @Override - public Map perform(ReadGraph graph, Variable parameter) throws DatabaseException { - CollectionSupport cs = graph.getService(CollectionSupport.class); - Map result = cs.createMap(Variable.class); - for(Variable child : parameter.getChildren(graph)) { - Resource represents = child.getPossibleRepresents(graph); - if(represents != null) result.put(represents, child); - } - return result; - } - - } - - static Variable resolve(ReadGraph graph, Variable base, Resource component) throws DatabaseException { - Map map = graph.syncRequest(new VariableChildren(graph, base), TransientCacheAsyncListener.>instance()); - Variable result = map.get(component); - if(result != null) return result; - else { - Layer0 L0 = Layer0.getInstance(graph); - Resource parent = graph.getPossibleObject(component, L0.PartOf); - if(parent == null) return null; - Variable v = resolve(graph, base, parent); - if (v == null) return null; - map = graph.syncRequest(new VariableChildren(graph, v), TransientCacheAsyncListener.>instance()); - return map.get(component); - } - } - - public static class ConnectionComponentsWithAncestor extends TransientUnaryRead> { - - final private List result; - - public ConnectionComponentsWithAncestor(ReadGraph graph, Resource conn) throws DatabaseException { - this(graph, conn, null); - } - - public ConnectionComponentsWithAncestor(ReadGraph graph, QueryControl qc, Resource conn, List result) throws DatabaseException { - super(graph, qc, conn); - this.result = result; - } - - public ConnectionComponentsWithAncestor(ReadGraph graph, Resource conn, List result) throws DatabaseException { - super(graph, conn); - this.result = result; - } - - private ConnectionSet connSet(ReadGraph graph, Resource r ) throws DatabaseException { - ConnectionSet cs = new ConnectionSet(graph); - cs.addConnection(graph, r); - return cs; - } - - @Override - public List perform(ReadGraph graph, Resource resource) throws DatabaseException { - - if(result != null) return result; - - Layer0 L0 = Layer0.getInstance(graph); - StructuralResource2 STR = StructuralResource2.getInstance(graph); - CollectionSupport colls = graph.getService(CollectionSupport.class); - THashSet ancestorGenerators = new THashSet(); - Set parts = colls.createSet(); - ConnectionSet cs = connSet(graph, resource); - for(Resource connRes : cs.getConnections()) { - for(Statement stm : graph.getStatements(connRes, STR.Connects)) { - Resource component = stm.getObject(); - Resource parent = graph.getPossibleObject(component, L0.PartOf); - if(parent != null && !graph.isInstanceOf(component, ModelingResources.getInstance(graph).ReferenceElement)) - ancestorGenerators.add(parent); - } - parts.add(connRes); - } - for (Resource join : cs.getJoins()) { - parts.add(join); - for (Resource composite : graph.getObjects(join, STR.JoinsComposite)) - ancestorGenerators.add(composite); - } - Resource ancestor = ancestorGenerators.size() == 1 ? ancestorGenerators.iterator().next() : CommonDBUtils.getNearestOwner(graph, ancestorGenerators); - - List result = colls.createList(); - result.add(ancestor); - result.addAll(colls.asSortedList(parts)); - - if(parameter != WITH_PARENT) { - for(int i=1;i>instance()); - } - } - - return result; - - } - - } - - public static Collection climb(ReadGraph graph, Variable child, Resource cp, String subPath_) throws DatabaseException { - - boolean isStructural = false; - - Variable curConfiguration = child.getParent(graph); - - { - - Collection interfaceDescription = Functions.computeInterfacePaths(graph, curConfiguration); - if(interfaceDescription != null) { - isStructural = interfaceDescription != Functions.BUILTIN_STRUCTURAL_CPS; - if(interfaceDescription.size() > 0) { - - if(subPath_ == null) { - - String childName = child.getName(graph); - for(InterfaceResolution r : interfaceDescription) { - if(r.componentName.equals(childName) && r.connectionPoint.equals(cp)) { - Variable pConn = curConfiguration.getPossibleProperty(graph, r.interfaceName); - if(pConn != null) { - Resource cp2 = pConn.getPossiblePredicateResource(graph); - Collection res = climb(graph, curConfiguration, cp2, null); - if(res != null) return res; - } - return Collections.emptyList(); - } - } - - } else { - throw new UnsupportedOperationException(""); - } - } - } - - } - - if(child instanceof StandardProceduralChildVariable) { - - Variable conn = child.getPossibleProperty(graph, cp); - FixedConnection fc = (FixedConnection)conn.getValue(graph); - Set result = new THashSet(1+fc.cps.size()); - result.add(new ComponentConnectionDescriptor(child, cp));// (graph, STR, curConfiguration, "/" + c.name + "#" + conn.getName(graph))); - for(Pair cpzz : fc.cps) { - if(cpzz.first == null) { - throw new DatabaseException("Lifted connection was not resolved."); - } - result.add(new PairConnectionDescriptor(curConfiguration, cpzz)); - } - return result; - - } else { - - Resource res = cp; - Resource represents = child.getRepresents(graph); - - if(isStructural) { - - Collection conns = graph.getObjects(represents, res); - HashSet result = new HashSet(); - for(Resource c : conns) { - List rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, c), TransientCacheAsyncListener.>instance()); - result.addAll(graph.syncRequest(ConnectionVariables.forStructural(graph, curConfiguration, rs))); - } - return result; - - } else { - - Resource connection = graph.getPossibleObject(represents, res); - if(connection != null) { - List rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, connection), TransientCacheAsyncListener.>instance()); - return graph.syncRequest(ConnectionVariables.forConfiguration(graph, curConfiguration, rs)); - } - else { - Collection conns = graph.getObjects(represents, res); - HashSet result = new HashSet(); - for(Resource c : conns) { - List rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, c), TransientCacheAsyncListener.>instance()); - result.addAll(graph.syncRequest(ConnectionVariables.forConfiguration(graph, curConfiguration, rs))); - } - return result; - } - - } - - } - - } - - public static class ConnectionVariables extends BinaryRead, Collection> { - - private ConnectionVariables(Variable parameter1, List parameter2) { - super(parameter1, parameter2); - } - - public static ConnectionVariables forConfiguration(ReadGraph graph, Variable configuration, List rs) throws DatabaseException { - return new ConnectionVariables(parent(graph, configuration, rs.get(0)), rs); - } - - public static ConnectionVariables forStructural(ReadGraph graph, Variable configuration, List rs) throws DatabaseException { - return new ConnectionVariables(configuration, rs); - } - - /** - * Finds the parent variable of configuration that - * represents ancestor. - * - * @param graph - * @param configuration - * @param ancestor - * @return - * @throws DatabaseException if no parent was found that represents ancestor - */ - private static Variable parent(ReadGraph graph, Variable configuration, Resource ancestor) throws DatabaseException { - Variable v = configuration; - Resource represents = v.getRepresents(graph); - while(!represents.equals(ancestor)) { - v = v.getParent(graph); - if (v == null) { - throw new DatabaseException( - "parent representing ancestor not found for variable, configuration=" - + safeURI(graph, configuration) - + ", ancestor=" - + NameUtils.getURIOrSafeNameInternal(graph, ancestor)); - } - represents = v.getRepresents(graph); - } - return v; - } - - @Override - public Collection perform(ReadGraph graph) throws DatabaseException { - if(parameter == null) return Collections.emptyList(); - StructuralResource2 STR = StructuralResource2.getInstance(graph); - ArrayList result = null; - for(int i=1;i(); - result.add(new ActualConnectionDescriptor(parameter, component, connectionPoint)); - } - } - if(result == null) return Collections.emptyList(); - return result; - } - - } - - static class IsLeafType extends ResourceRead { - - protected IsLeafType(Resource type) { - super(type); - } - - @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; - - } - - } - - static class ChildMapOfVariable extends VariableRead> { - - public ChildMapOfVariable(Variable variable) { - super(variable); - } - - @Override - public Map perform(ReadGraph graph) throws DatabaseException { - HashMap result = new HashMap(); - for(Variable child : variable.getChildren(graph)) { - Resource represents = child.getPossibleRepresents(graph); - if(represents != null) result.put(represents, child); - } - return result; - } - - } - - /** - * Given a root composite, related variable and some other component inside the composite, - * finds the related variable for that component. - */ - public static Variable browse(ReadGraph graph, Resource root, Variable rootContext, Resource target) throws DatabaseException { - if(target.equals(root)) - return rootContext; - else { - Layer0 L0 = Layer0.getInstance(graph); - String name = (String)graph.getPossibleRelatedValue(target, L0.HasName, Bindings.STRING); - Resource parent = graph.getPossibleObject(target, L0.PartOf); - if(name == null || parent == null) - return null; - Variable parentVariable = browse(graph, root, rootContext, parent); - if(parentVariable == null) - return null; - return parentVariable.getPossibleChild(graph, name); - } - } - - /** - * Finds a variable whose location related to sourceContext is the same as - * between target and source. In other words, the method solves {@code targetContext} - * in the following equations: - *
-     *     URI(source)        = resourceURIBase + sourceSuffix
-     *     URI(sourceContext) = variableURIBase + sourceSuffix
-     *     URI(target)        = resourceURIBase + targetSuffix
-     *     URI(targetContext) = variableURIBase + targetSuffix
-     * 
- */ - public static Variable browseSibling(ReadGraph graph, Resource source, Variable sourceContext, Resource target) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - THashMap sourceMap = new THashMap(); - while(source != null && sourceContext != null) { - sourceMap.put(source, sourceContext); - source = graph.getPossibleObject(source, L0.PartOf); - sourceContext = sourceContext.getParent(graph); - } - return browseSibling(graph, sourceMap, target); - } - - private static Variable browseSibling(ReadGraph graph, THashMap sourceMap, Resource target) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - Variable result = sourceMap.get(target); - if(result != null) - return result; - String name = (String)graph.getPossibleRelatedValue(target, L0.HasName, Bindings.STRING); - Resource parent = graph.getPossibleObject(target, L0.PartOf); - if(name == null || parent == null) - return null; - Variable parentVariable = browseSibling(graph, sourceMap, parent); - if(parentVariable == null) - return null; - return parentVariable.getPossibleChild(graph, name); - } - - /** - * Returns the composite where the connection given as a parameter resides. - */ - public static Resource getCompositeOfConnection(ReadGraph graph, Resource connection) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - StructuralResource2 STR = StructuralResource2.getInstance(graph); - // First from connected components - for(Resource component : graph.getObjects(connection, STR.Connects)) - for(Resource composite : graph.getObjects(component, L0.PartOf)) - return composite; - // It could be that the connection is only supported by joins (input flag -> output flag) - use diagram info TODO!! - Resource connToDiagramConn = graph.getPossibleResource("http://www.simantics.org/Modeling-1.2/ConnectionToDiagramConnection"); - if(connToDiagramConn != null) { - Resource diagramConnection = graph.getPossibleObject(connection, connToDiagramConn); - if(diagramConnection != null) { - Resource diagram = graph.getPossibleObject(diagramConnection, L0.PartOf); - if(diagram != null) { - Resource diagramToComposite = graph.getPossibleResource("http://www.simantics.org/Modeling-1.2/DiagramToComposite"); - if(diagramToComposite != null) { - return graph.getPossibleObject(diagram, diagramToComposite); - } - } - } - } - return null; - } - - static class Flatten extends BinaryRead> { - - public Flatten(Variable parameter1, - Resource parameter2) { - super(parameter1, parameter2); - } - - @Override - public Collection perform(ReadGraph graph) - throws DatabaseException { - return doFlatten(graph, parameter, parameter2, null); - } - - } - - public static Collection flatten(ReadGraph graph, Variable child, Resource cp, Resource relationType) throws DatabaseException { - - if(relationType == null) return graph.syncRequest(new Flatten(child, cp)); - - return doFlatten(graph, child, cp, relationType); - - } - - public static Collection doFlatten(ReadGraph graph, Variable child, Resource cp, Resource relationType) throws DatabaseException { - - Collection climbed = climb(graph, child, cp, null); - boolean needDrill = false; - for(VariableConnectionPointDescriptor desc : climbed) { - if(!desc.isLeaf(graph)) { - needDrill = true; - break; - } - } - - if(!needDrill) { - if(relationType != null) { - ArrayList filtered = new ArrayList(climbed.size()); - for(VariableConnectionPointDescriptor desc : climbed) - if(filterByRelationType(graph, desc, relationType)) - filtered.add(desc); - return filtered; - } - return climbed; - } - - THashSet result = new THashSet(climbed.size()); - for(VariableConnectionPointDescriptor top : climbed) { - Collection drilled = drill(graph, top); - if(drilled != null) { - for(VariableConnectionPointDescriptor drill : drilled) { - if(relationType != null) { - if(!filterByRelationType(graph, drill, relationType)) - continue; - } - result.add(drill); - } - } - } - return result; - - } - - private static boolean filterByRelationType(ReadGraph graph, VariableConnectionPointDescriptor desc, Resource relationType) throws DatabaseException { - Resource predicateResource = desc.getConnectionPointResource(graph); - return predicateResource != null && graph.isInstanceOf(predicateResource, relationType); - } - - private static String safeURI(ReadGraph graph, Variable v) { - if (v == null) - return "null variable"; - try { - return v.getURI(graph); - } catch (DatabaseException e) { - return v.toString(); - } - } -} +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; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +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.procedure.adapter.TransientCacheAsyncListener; +import org.simantics.db.common.request.BinaryRead; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.common.request.TransientUnaryRead; +import org.simantics.db.common.utils.CommonDBUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.NoSingleResultException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.exception.MissingVariableValueException; +import org.simantics.db.layer0.request.VariableRead; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.service.CollectionSupport; +import org.simantics.db.service.QueryControl; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +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.variables.StandardProceduralChildVariable.FixedConnection; +import org.simantics.utils.datastructures.Pair; + +public class ConnectionBrowser { + + /** + * Finds the components connected by the connection. Also connections + * in + * + * @param graph + * @param connection A connection whose related modules are searched. + * @param configuration A variable that represents the composite where the connection belongs to. + * @return A map whose keys are components and they are mapped to + * related variables. + */ + public static Collection findConnectedComponents( + ReadGraph graph, Resource connection, Variable configuration) + throws DatabaseException { + // Create state + ArrayList result = + new ArrayList(); + THashSet visitedConnections = new THashSet(); + + // Do actual work + findConnectedComponents(graph, connection, configuration, result, + visitedConnections); + return result; + } + + private static void findConnectedComponents( + ReadGraph graph, Resource connection, Variable configuration, + ArrayList result, + THashSet visitedConnections) throws DatabaseException { + if(visitedConnections.add(connection)) { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + + // Browse related components + for(Statement stat : graph.getStatements(connection, STR.Connects)) { + Resource component = stat.getObject(); + 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 def = type != null ? graph.getPossibleObject(type, STR.IsDefinedBy) : null; + if(boundConnection != null && def != null) { + // The connection point is bound in component type + Variable newContext = configuration.browsePossible(graph, component); + Resource newComposite = getCompositeOfConnection(graph, boundConnection); + if(newContext != null && newComposite != null) { + newContext = browse(graph, def, newContext, newComposite); + if (newContext != null) + findConnectedComponents(graph, boundConnection, + newContext, + result, visitedConnections); + } + } + else { + //System.out.println("added result"); + // A primitive connection point + Variable context = configuration.browsePossible(graph, component); + if (context != null) + result.add(new ResourceWithContext(component, context)); + } + } + + // Browse over connection joins + for(Resource join : graph.getObjects(connection, STR.IsJoinedBy)) + for(Resource otherConnection : graph.getObjects(join, STR.Joins)) + if(!connection.equals(otherConnection)) { + Resource sourceComposite = getCompositeOfConnection(graph, connection); + Resource targetComposite = getCompositeOfConnection(graph, otherConnection); + if (sourceComposite != null && targetComposite != null) { + Variable sibling = browseSibling(graph, + sourceComposite, + configuration, + targetComposite); + if (sibling != null) + findConnectedComponents(graph, otherConnection, + sibling, result, visitedConnections); + } + } + + // Browse to parents + try { + for(Resource relation : graph.getObjects(connection, STR.Binds)) { + Resource composite = getCompositeOfConnection(graph, connection); + if (composite == null) + continue; + + Variable curConfiguration = configuration; + while(!graph.hasStatement(composite, STR.Defines)) { + composite = graph.getSingleObject(composite, L0.PartOf); + curConfiguration = curConfiguration.getParent(graph); + } + Variable parent = curConfiguration.getParent(graph); + Resource component = curConfiguration.getRepresents(graph); + for(Resource c : graph.getObjects(component, relation)) + findConnectedComponents(graph, c, + parent, result, visitedConnections); + } + } catch(NoSingleResultException e) { + } catch(MissingVariableException e) { + } catch(MissingVariableValueException e) { + } + } + } + + public static Collection drill(ReadGraph graph, VariableConnectionPointDescriptor pair) throws DatabaseException { + + Collection interfaceDescription = pair.getInterfaceDescription(graph); + if(interfaceDescription != null && interfaceDescription.size() > 0) { + + Variable cp = pair.getVariable(graph); + Variable context = cp.getParent(graph); + String cpName = cp.getName(graph); + + Collection result = new ArrayList(); + for(InterfaceResolution r : interfaceDescription) { + if(r.interfaceName.equals(cpName)) { + String path = Functions.resolveInterfacePath(graph, context, r.componentName, r.connectionPoint); + result.add(new BrowseConnectionDescriptor(context, path)); + } + } + + if(result.isEmpty()) return null; + + return result; + + } else { + return Collections.singleton(pair); + } + + } + + public static class JoinConnections extends ResourceRead> { + + public JoinConnections(Resource join) { + super(join); + } + + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + ConnectionSet cs = new ConnectionSet(graph); + cs.addJoin(graph, resource); + return cs.getConnections(); + } + + } + + + public static final class VariableChildren extends TransientUnaryRead> { + + public VariableChildren(ReadGraph graph, Variable variable) throws DatabaseException { + super(graph, variable); + } + + public VariableChildren(ReadGraph graph, QueryControl qc, Variable variable) throws DatabaseException { + super(graph, qc, variable); + } + + @Override + public Map perform(ReadGraph graph, Variable parameter) throws DatabaseException { + CollectionSupport cs = graph.getService(CollectionSupport.class); + Map result = cs.createMap(Variable.class); + for(Variable child : parameter.getChildren(graph)) { + Resource represents = child.getPossibleRepresents(graph); + if(represents != null) result.put(represents, child); + } + return result; + } + + } + + static Variable resolve(ReadGraph graph, Variable base, Resource component) throws DatabaseException { + Map map = graph.syncRequest(new VariableChildren(graph, base), TransientCacheAsyncListener.>instance()); + Variable result = map.get(component); + if(result != null) return result; + else { + Layer0 L0 = Layer0.getInstance(graph); + Resource parent = graph.getPossibleObject(component, L0.PartOf); + if(parent == null) return null; + Variable v = resolve(graph, base, parent); + if (v == null) return null; + map = graph.syncRequest(new VariableChildren(graph, v), TransientCacheAsyncListener.>instance()); + return map.get(component); + } + } + + public static class ConnectionComponentsWithAncestor extends TransientUnaryRead> { + + final private List result; + + public ConnectionComponentsWithAncestor(ReadGraph graph, Resource conn) throws DatabaseException { + this(graph, conn, null); + } + + public ConnectionComponentsWithAncestor(ReadGraph graph, QueryControl qc, Resource conn, List result) throws DatabaseException { + super(graph, qc, conn); + this.result = result; + } + + public ConnectionComponentsWithAncestor(ReadGraph graph, Resource conn, List result) throws DatabaseException { + super(graph, conn); + this.result = result; + } + + private ConnectionSet connSet(ReadGraph graph, Resource r ) throws DatabaseException { + ConnectionSet cs = new ConnectionSet(graph); + cs.addConnection(graph, r); + return cs; + } + + @Override + public List perform(ReadGraph graph, Resource resource) throws DatabaseException { + + if(result != null) return result; + + Layer0 L0 = Layer0.getInstance(graph); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + CollectionSupport colls = graph.getService(CollectionSupport.class); + THashSet ancestorGenerators = new THashSet(); + Set parts = colls.createSet(); + ConnectionSet cs = connSet(graph, resource); + for(Resource connRes : cs.getConnections()) { + for(Statement stm : graph.getStatements(connRes, STR.Connects)) { + Resource component = stm.getObject(); + Resource parent = graph.getPossibleObject(component, L0.PartOf); + if(parent != null && !graph.isInstanceOf(component, ModelingResources.getInstance(graph).ReferenceElement)) + ancestorGenerators.add(parent); + } + parts.add(connRes); + } + for (Resource join : cs.getJoins()) { + parts.add(join); + for (Resource composite : graph.getObjects(join, STR.JoinsComposite)) + ancestorGenerators.add(composite); + } + Resource ancestor = ancestorGenerators.size() == 1 ? ancestorGenerators.iterator().next() : CommonDBUtils.getNearestOwner(graph, ancestorGenerators); + + List result = colls.createList(); + result.add(ancestor); + result.addAll(colls.asSortedList(parts)); + + if(parameter != WITH_PARENT) { + for(int i=1;i>instance()); + } + } + + return result; + + } + + } + + public static Collection climb(ReadGraph graph, Variable child, Resource cp, String subPath_) throws DatabaseException { + + boolean isStructural = false; + + Variable curConfiguration = child.getParent(graph); + + { + + Collection interfaceDescription = Functions.computeInterfacePaths(graph, curConfiguration); + if(interfaceDescription != null) { + isStructural = interfaceDescription != Functions.BUILTIN_STRUCTURAL_CPS; + if(interfaceDescription.size() > 0) { + + if(subPath_ == null) { + + String childName = child.getName(graph); + for(InterfaceResolution r : interfaceDescription) { + if(r.componentName.equals(childName) && r.connectionPoint.equals(cp)) { + Variable pConn = curConfiguration.getPossibleProperty(graph, r.interfaceName); + if(pConn != null) { + Resource cp2 = pConn.getPossiblePredicateResource(graph); + Collection res = climb(graph, curConfiguration, cp2, null); + if(res != null) return res; + } + return Collections.emptyList(); + } + } + + } else { + throw new UnsupportedOperationException(""); + } + } + } + + } + + if(child instanceof StandardProceduralChildVariable) { + + Variable conn = child.getPossibleProperty(graph, cp); + FixedConnection fc = (FixedConnection)conn.getValue(graph); + Set result = new THashSet(1+fc.cps.size()); + result.add(new ComponentConnectionDescriptor(child, cp));// (graph, STR, curConfiguration, "/" + c.name + "#" + conn.getName(graph))); + for(Pair cpzz : fc.cps) { + if(cpzz.first == null) { + throw new DatabaseException("Lifted connection was not resolved."); + } + result.add(new PairConnectionDescriptor(curConfiguration, cpzz)); + } + return result; + + } else { + + Resource res = cp; + Resource represents = child.getRepresents(graph); + + if(isStructural) { + + Collection conns = graph.getObjects(represents, res); + HashSet result = new HashSet(); + for(Resource c : conns) { + List rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, c), TransientCacheAsyncListener.>instance()); + result.addAll(graph.syncRequest(ConnectionVariables.forStructural(graph, curConfiguration, rs))); + } + return result; + + } else { + + Resource connection = graph.getPossibleObject(represents, res); + if(connection != null) { + List rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, connection), TransientCacheAsyncListener.>instance()); + return graph.syncRequest(ConnectionVariables.forConfiguration(graph, curConfiguration, rs)); + } + else { + Collection conns = graph.getObjects(represents, res); + HashSet result = new HashSet(); + for(Resource c : conns) { + List rs = graph.syncRequest(new ConnectionComponentsWithAncestor(graph, c), TransientCacheAsyncListener.>instance()); + result.addAll(graph.syncRequest(ConnectionVariables.forConfiguration(graph, curConfiguration, rs))); + } + return result; + } + + } + + } + + } + + public static class ConnectionVariables extends BinaryRead, Collection> { + + private ConnectionVariables(Variable parameter1, List parameter2) { + super(parameter1, parameter2); + } + + public static ConnectionVariables forConfiguration(ReadGraph graph, Variable configuration, List rs) throws DatabaseException { + return new ConnectionVariables(parent(graph, configuration, rs.get(0)), rs); + } + + public static ConnectionVariables forStructural(ReadGraph graph, Variable configuration, List rs) throws DatabaseException { + return new ConnectionVariables(configuration, rs); + } + + /** + * Finds the parent variable of configuration that + * represents ancestor. + * + * @param graph + * @param configuration + * @param ancestor + * @return + * @throws DatabaseException if no parent was found that represents ancestor + */ + private static Variable parent(ReadGraph graph, Variable configuration, Resource ancestor) throws DatabaseException { + Variable v = configuration; + Resource represents = v.getRepresents(graph); + while(!represents.equals(ancestor)) { + v = v.getParent(graph); + if (v == null) { + throw new DatabaseException( + "parent representing ancestor not found for variable, configuration=" + + safeURI(graph, configuration) + + ", ancestor=" + + NameUtils.getURIOrSafeNameInternal(graph, ancestor)); + } + represents = v.getRepresents(graph); + } + return v; + } + + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + if(parameter == null) return Collections.emptyList(); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + ArrayList result = null; + for(int i=1;i(); + result.add(new ActualConnectionDescriptor(parameter, component, connectionPoint)); + } + } + if(result == null) return Collections.emptyList(); + return result; + } + + } + + static class IsLeafType extends ResourceRead { + + protected IsLeafType(Resource type) { + super(type); + } + + @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; + + } + + } + + static class ChildMapOfVariable extends VariableRead> { + + public ChildMapOfVariable(Variable variable) { + super(variable); + } + + @Override + public Map perform(ReadGraph graph) throws DatabaseException { + HashMap result = new HashMap(); + for(Variable child : variable.getChildren(graph)) { + Resource represents = child.getPossibleRepresents(graph); + if(represents != null) result.put(represents, child); + } + return result; + } + + } + + /** + * Given a root composite, related variable and some other component inside the composite, + * finds the related variable for that component. + */ + public static Variable browse(ReadGraph graph, Resource root, Variable rootContext, Resource target) throws DatabaseException { + if(target.equals(root)) + return rootContext; + else { + Layer0 L0 = Layer0.getInstance(graph); + String name = (String)graph.getPossibleRelatedValue(target, L0.HasName, Bindings.STRING); + Resource parent = graph.getPossibleObject(target, L0.PartOf); + if(name == null || parent == null) + return null; + Variable parentVariable = browse(graph, root, rootContext, parent); + if(parentVariable == null) + return null; + return parentVariable.getPossibleChild(graph, name); + } + } + + /** + * Finds a variable whose location related to sourceContext is the same as + * between target and source. In other words, the method solves {@code targetContext} + * in the following equations: + *
+     *     URI(source)        = resourceURIBase + sourceSuffix
+     *     URI(sourceContext) = variableURIBase + sourceSuffix
+     *     URI(target)        = resourceURIBase + targetSuffix
+     *     URI(targetContext) = variableURIBase + targetSuffix
+     * 
+ */ + public static Variable browseSibling(ReadGraph graph, Resource source, Variable sourceContext, Resource target) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + THashMap sourceMap = new THashMap(); + while(source != null && sourceContext != null) { + sourceMap.put(source, sourceContext); + source = graph.getPossibleObject(source, L0.PartOf); + sourceContext = sourceContext.getParent(graph); + } + return browseSibling(graph, sourceMap, target); + } + + private static Variable browseSibling(ReadGraph graph, THashMap sourceMap, Resource target) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Variable result = sourceMap.get(target); + if(result != null) + return result; + String name = (String)graph.getPossibleRelatedValue(target, L0.HasName, Bindings.STRING); + Resource parent = graph.getPossibleObject(target, L0.PartOf); + if(name == null || parent == null) + return null; + Variable parentVariable = browseSibling(graph, sourceMap, parent); + if(parentVariable == null) + return null; + return parentVariable.getPossibleChild(graph, name); + } + + /** + * Returns the composite where the connection given as a parameter resides. + */ + public static Resource getCompositeOfConnection(ReadGraph graph, Resource connection) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + // First from connected components + for(Resource component : graph.getObjects(connection, STR.Connects)) + for(Resource composite : graph.getObjects(component, L0.PartOf)) + return composite; + // It could be that the connection is only supported by joins (input flag -> output flag) - use diagram info TODO!! + Resource connToDiagramConn = graph.getPossibleResource("http://www.simantics.org/Modeling-1.2/ConnectionToDiagramConnection"); + if(connToDiagramConn != null) { + Resource diagramConnection = graph.getPossibleObject(connection, connToDiagramConn); + if(diagramConnection != null) { + Resource diagram = graph.getPossibleObject(diagramConnection, L0.PartOf); + if(diagram != null) { + Resource diagramToComposite = graph.getPossibleResource("http://www.simantics.org/Modeling-1.2/DiagramToComposite"); + if(diagramToComposite != null) { + return graph.getPossibleObject(diagram, diagramToComposite); + } + } + } + } + return null; + } + + static class Flatten extends BinaryRead> { + + public Flatten(Variable parameter1, + Resource parameter2) { + super(parameter1, parameter2); + } + + @Override + public Collection perform(ReadGraph graph) + throws DatabaseException { + return doFlatten(graph, parameter, parameter2, null); + } + + } + + public static Collection flatten(ReadGraph graph, Variable child, Resource cp, Resource relationType) throws DatabaseException { + + if(relationType == null) return graph.syncRequest(new Flatten(child, cp)); + + return doFlatten(graph, child, cp, relationType); + + } + + public static Collection doFlatten(ReadGraph graph, Variable child, Resource cp, Resource relationType) throws DatabaseException { + + Collection climbed = climb(graph, child, cp, null); + boolean needDrill = false; + for(VariableConnectionPointDescriptor desc : climbed) { + if(!desc.isLeaf(graph)) { + needDrill = true; + break; + } + } + + if(!needDrill) { + if(relationType != null) { + ArrayList filtered = new ArrayList(climbed.size()); + for(VariableConnectionPointDescriptor desc : climbed) + if(filterByRelationType(graph, desc, relationType)) + filtered.add(desc); + return filtered; + } + return climbed; + } + + THashSet result = new THashSet(climbed.size()); + for(VariableConnectionPointDescriptor top : climbed) { + Collection drilled = drill(graph, top); + if(drilled != null) { + for(VariableConnectionPointDescriptor drill : drilled) { + if(relationType != null) { + if(!filterByRelationType(graph, drill, relationType)) + continue; + } + result.add(drill); + } + } + } + return result; + + } + + private static boolean filterByRelationType(ReadGraph graph, VariableConnectionPointDescriptor desc, Resource relationType) throws DatabaseException { + Resource predicateResource = desc.getConnectionPointResource(graph); + return predicateResource != null && graph.isInstanceOf(predicateResource, relationType); + } + + private static String safeURI(ReadGraph graph, Variable v) { + if (v == null) + return "null variable"; + try { + return v.getURI(graph); + } catch (DatabaseException e) { + return v.toString(); + } + } +}