X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.graph%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fquery%2FCompositeGraph.java;h=7fea92d0b9fe49aad6237d7042d62e7aa12c2446;hb=7a7f73011a6364cbb80ce4ef04424472d345a65a;hp=bad2777288a8bea52267dac8fbf76ab52a1e0f4c;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/query/CompositeGraph.java b/bundles/org.simantics.graph/src/org/simantics/graph/query/CompositeGraph.java index bad277728..7fea92d0b 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/query/CompositeGraph.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/query/CompositeGraph.java @@ -1,363 +1,363 @@ -package org.simantics.graph.query; - -import gnu.trove.list.array.TIntArrayList; -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; - -import org.simantics.databoard.adapter.AdaptException; -import org.simantics.databoard.adapter.RuntimeAdaptException; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.mutable.Variant; -import org.simantics.databoard.type.Datatype; -import org.simantics.graph.store.GraphStore; -import org.simantics.graph.store.IdRes; -import org.simantics.graph.store.IdentityStore; -import org.simantics.graph.store.PathPattern; -import org.simantics.graph.store.StatementStore; - -public class CompositeGraph implements IGraph { - - ArrayList fragments = new ArrayList(); - Paths paths; - - public CompositeGraph(Paths paths) { - this.paths = paths; - } - - public void addFragment(GraphStore fragment) { - fragments.add(fragment); - } - - public void undoAddFragment() { - fragments.remove(fragments.size()-1); - } - - public void addFragments(Collection fragments) { - fragments.addAll(fragments); - } - - protected void rawGetObjects(GraphStore fragment, int subject, Res predicate, Collection result) { - int predicateId; - if(predicate instanceof Path) { - predicateId = fragment.identities.pathToId((Path)predicate); - if(predicateId < 0) - return; - } - else { - IdRes idPredicate = (IdRes)predicate; - if(idPredicate.fragment != fragment) - return; - predicateId = idPredicate.id; - } - - TIntArrayList objects = fragment.statements.getObjects(subject, predicateId); - fragment.addIdsToResult(objects, result); - } - - private void rawGetObjects(Res subject, Res predicate, Collection result) { - if(subject instanceof Path) { - Path path = (Path)subject; - for(GraphStore fragment : fragments) { - int id = fragment.identities.pathToId(path); - if(id >= 0) - rawGetObjects(fragment, id, predicate, result); - } - } - else { - IdRes idRes = (IdRes)subject; - rawGetObjects(idRes.fragment, idRes.id, predicate, result); - } - } - - public boolean hasRawObjects(Res subject, Path predicate) { - ArrayList result = new ArrayList(); - rawGetObjects(subject, predicate, result); - return !result.isEmpty(); - } - - @Override - public Collection rawGetObjects(Res subject, Res predicate) { - ArrayList result = new ArrayList(); - rawGetObjects(subject, predicate, result); - return result; - } - - @Override - public Res singleRawObject(Res subject, Res predicate) throws NoUniqueObjectException { - ArrayList result = new ArrayList(1); - rawGetObjects(subject, predicate, result); - if(result.size() != 1) - throw new NoUniqueObjectException("No unique objects (" + result.size()+ ") for " + - subject + " -> " + predicate); - return result.get(0); - } - - @Override - public Collection getTypes(Res subject) { - THashSet result = new THashSet(); - rawGetObjects(subject, paths.InstanceOf, result); - for(Res type : result.toArray(new Res[result.size()])) - collectSupertypes(type, result); - return result; - } - - public Collection getSupertypes(Res subject) { - THashSet result = new THashSet(); - result.add(subject); - collectSupertypes(subject, result); - return result; - } - - private void collectSupertypes(Res type, THashSet result) { - for(Res supertype : rawGetObjects(type, paths.Inherits)) - if(result.add(supertype)) - collectSupertypes(supertype, result); - } - - @Override - public Collection getObjects(Res subject, Res predicate) { - ArrayList result = new ArrayList(); - rawGetObjects(subject, predicate, result); - for(Res type : getTypes(subject)) - for(Res assertion : rawGetObjects(type, paths.Asserts)) { - Res pred = singleRawObject(assertion, paths.HasPredicate); - if(equals(pred, predicate)) - result.add(singleRawObject(assertion, paths.HasObject)); - } - return result; - } - - public Collection getAssertedObjects(Res subject, Path predicate) { - ArrayList result = new ArrayList(); - for(Res type : getSupertypes(subject)) - for(Res assertion : rawGetObjects(type, paths.Asserts)) { - Res pred = singleRawObject(assertion, paths.HasPredicate); - if(equals(pred, predicate)) - result.add(singleRawObject(assertion, paths.HasObject)); - } - return result; - } - - private static boolean equals(Res r1, Res r2) { - return r1.equals(r2); - } - - interface ResourceProcedure { - public void execute(GraphStore fragment, int id); - } - - interface ResourceFunction { - public T execute(GraphStore fragment, int id); - } - - public void forEachFragmentContaining(Res resource, ResourceProcedure proc) { - if(resource instanceof Path) { - Path path = (Path)resource; - for(GraphStore fragment : fragments) { - int id = fragment.identities.pathToId(path); - if(id >= 0) - proc.execute(fragment, id); - } - } - else { - IdRes res = (IdRes)resource; - proc.execute(res.fragment, res.id); - } - } - - public T apply(Res resource, ResourceFunction func) { - if(resource instanceof Path) { - Path path = (Path)resource; - for(GraphStore fragment : fragments) { - int id = fragment.identities.pathToId(path); - if(id >= 0) { - T value = func.execute(fragment, id); - if(value != null) - return value; - } - } - return null; - } - else { - IdRes res = (IdRes)resource; - return func.execute(res.fragment, res.id); - } - } - - private static ResourceFunction getDatatype = - new ResourceFunction() { - @Override - public Datatype execute(GraphStore fragment, int id) { - return fragment.values.getDatatypeValue(id); - } - }; - - private static ResourceFunction getValue = - new ResourceFunction() { - @Override - public Variant execute(GraphStore fragment, int id) { - return fragment.values.getByteValue(id); - } - }; - - THashMap datatypeCache = new THashMap(); - - @Override - public Datatype getDatatype(Res resource) { - for(Res dt : getObjects(resource, paths.HasDatatype)) { - Datatype type = datatypeCache.get(dt); - if(type == null) { - type = apply(dt, getDatatype); - datatypeCache.put(dt, type); - } - return type; - } - return null; - } - - @Override - public Datatype getAssertedDatatype(Res resource) { - for(Res dt : getAssertedObjects(resource, paths.HasDatatype)) { - Datatype type = datatypeCache.get(dt); - if(type == null) { - type = apply(dt, getDatatype); - datatypeCache.put(dt, type); - } - return type; - } - return null; - } - - @Override - public Variant getValue(Res resource) { - return apply(resource, getValue); - } - - @Override - public Object getValue(Res resource, Binding binding) throws NoValueException { - Variant value = getValue(resource); - if(value == null) - throw new NoValueException(); - try { - return value.getValue(binding); - } catch (AdaptException e) { - throw new RuntimeAdaptException(e); - } - } - - @Override - public void setValue(Res resource, Object value, Binding binding) { - final Variant variant = new Variant(binding, value); - apply(resource, new ResourceFunction() { - @Override - public Object execute(GraphStore fragment, int id) { - fragment.values.setValue(id, variant); - return null; - } - }); - } - - /** - * Tells in how many fragments the resource occurs. - */ - public int countOccurences(Res resource) { - if(resource instanceof IdRes) - return 1; - else if(resource instanceof Path) { - Path path = (Path)resource; - int count = 0; - for(GraphStore fragment : fragments) - if(fragment.identities.contains(path)) - ++count; - return count; - } - else - return 0; - } - - private void collectSubtypes(THashSet types, Res type) { - if(types.add(type)) - for(Res subtype : rawGetObjects(type, paths.SupertypeOf)) - collectSubtypes(types, subtype); - } - - @Override - public Collection getInstances(Res supertype) { - THashSet types = new THashSet(); - collectSubtypes(types, supertype); - - ArrayList result = new ArrayList(); - fragmentLoop: - for(GraphStore fragment : fragments) { - IdentityStore identities = fragment.identities; - StatementStore statements = fragment.statements; - - TIntHashSet ids = new TIntHashSet(types.size()); - for(Res type : types) { - if(type instanceof Path) { - int id = identities.pathToId((Path)type); - if(id >= 0) - ids.add(id); - } - else { - IdRes idRes = (IdRes)type; - if(idRes.fragment == fragment) - ids.add(idRes.id); - } - } - if(ids.isEmpty()) - continue; - - int instanceOfId = identities.pathToId(paths.InstanceOf); - if(instanceOfId < 0) - continue; - - int resourceCount = identities.getResourceCount(); - nextResource: - for(int i=0;i getChildren(Res res) { - if(res instanceof Path) { - THashSet result = new THashSet(); - for(GraphStore store : fragments) { - IdentityStore ids = store.identities; - int id = ids.pathToId((Path)res); - if(id >= 0) { - for(int child : ids.getChildren(id)) - result.add(store.idToRes(child)); - } - } - return result; - } - else - return Collections.emptyList(); - } - - public Collection searchByPattern(String pattern) { - THashSet result = new THashSet(); - PathPattern pathPattern = PathPattern.compile(pattern); - for(GraphStore store : fragments) - pathPattern.search(store.identities, result); - return result; - } - - @Override - public Paths getPaths() { - return paths; - } -} +package org.simantics.graph.query; + +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.set.hash.TIntHashSet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import org.simantics.databoard.adapter.AdaptException; +import org.simantics.databoard.adapter.RuntimeAdaptException; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.databoard.type.Datatype; +import org.simantics.graph.store.GraphStore; +import org.simantics.graph.store.IdRes; +import org.simantics.graph.store.IdentityStore; +import org.simantics.graph.store.PathPattern; +import org.simantics.graph.store.StatementStore; + +public class CompositeGraph implements IGraph { + + ArrayList fragments = new ArrayList(); + Paths paths; + + public CompositeGraph(Paths paths) { + this.paths = paths; + } + + public void addFragment(GraphStore fragment) { + fragments.add(fragment); + } + + public void undoAddFragment() { + fragments.remove(fragments.size()-1); + } + + public void addFragments(Collection fragments) { + fragments.addAll(fragments); + } + + protected void rawGetObjects(GraphStore fragment, int subject, Res predicate, Collection result) { + int predicateId; + if(predicate instanceof Path) { + predicateId = fragment.identities.pathToId((Path)predicate); + if(predicateId < 0) + return; + } + else { + IdRes idPredicate = (IdRes)predicate; + if(idPredicate.fragment != fragment) + return; + predicateId = idPredicate.id; + } + + TIntArrayList objects = fragment.statements.getObjects(subject, predicateId); + fragment.addIdsToResult(objects, result); + } + + private void rawGetObjects(Res subject, Res predicate, Collection result) { + if(subject instanceof Path) { + Path path = (Path)subject; + for(GraphStore fragment : fragments) { + int id = fragment.identities.pathToId(path); + if(id >= 0) + rawGetObjects(fragment, id, predicate, result); + } + } + else { + IdRes idRes = (IdRes)subject; + rawGetObjects(idRes.fragment, idRes.id, predicate, result); + } + } + + public boolean hasRawObjects(Res subject, Path predicate) { + ArrayList result = new ArrayList(); + rawGetObjects(subject, predicate, result); + return !result.isEmpty(); + } + + @Override + public Collection rawGetObjects(Res subject, Res predicate) { + ArrayList result = new ArrayList(); + rawGetObjects(subject, predicate, result); + return result; + } + + @Override + public Res singleRawObject(Res subject, Res predicate) throws NoUniqueObjectException { + ArrayList result = new ArrayList(1); + rawGetObjects(subject, predicate, result); + if(result.size() != 1) + throw new NoUniqueObjectException("No unique objects (" + result.size()+ ") for " + + subject + " -> " + predicate); + return result.get(0); + } + + @Override + public Collection getTypes(Res subject) { + THashSet result = new THashSet(); + rawGetObjects(subject, paths.InstanceOf, result); + for(Res type : result.toArray(new Res[result.size()])) + collectSupertypes(type, result); + return result; + } + + public Collection getSupertypes(Res subject) { + THashSet result = new THashSet(); + result.add(subject); + collectSupertypes(subject, result); + return result; + } + + private void collectSupertypes(Res type, THashSet result) { + for(Res supertype : rawGetObjects(type, paths.Inherits)) + if(result.add(supertype)) + collectSupertypes(supertype, result); + } + + @Override + public Collection getObjects(Res subject, Res predicate) { + ArrayList result = new ArrayList(); + rawGetObjects(subject, predicate, result); + for(Res type : getTypes(subject)) + for(Res assertion : rawGetObjects(type, paths.Asserts)) { + Res pred = singleRawObject(assertion, paths.HasPredicate); + if(equals(pred, predicate)) + result.add(singleRawObject(assertion, paths.HasObject)); + } + return result; + } + + public Collection getAssertedObjects(Res subject, Path predicate) { + ArrayList result = new ArrayList(); + for(Res type : getSupertypes(subject)) + for(Res assertion : rawGetObjects(type, paths.Asserts)) { + Res pred = singleRawObject(assertion, paths.HasPredicate); + if(equals(pred, predicate)) + result.add(singleRawObject(assertion, paths.HasObject)); + } + return result; + } + + private static boolean equals(Res r1, Res r2) { + return r1.equals(r2); + } + + interface ResourceProcedure { + public void execute(GraphStore fragment, int id); + } + + interface ResourceFunction { + public T execute(GraphStore fragment, int id); + } + + public void forEachFragmentContaining(Res resource, ResourceProcedure proc) { + if(resource instanceof Path) { + Path path = (Path)resource; + for(GraphStore fragment : fragments) { + int id = fragment.identities.pathToId(path); + if(id >= 0) + proc.execute(fragment, id); + } + } + else { + IdRes res = (IdRes)resource; + proc.execute(res.fragment, res.id); + } + } + + public T apply(Res resource, ResourceFunction func) { + if(resource instanceof Path) { + Path path = (Path)resource; + for(GraphStore fragment : fragments) { + int id = fragment.identities.pathToId(path); + if(id >= 0) { + T value = func.execute(fragment, id); + if(value != null) + return value; + } + } + return null; + } + else { + IdRes res = (IdRes)resource; + return func.execute(res.fragment, res.id); + } + } + + private static ResourceFunction getDatatype = + new ResourceFunction() { + @Override + public Datatype execute(GraphStore fragment, int id) { + return fragment.values.getDatatypeValue(id); + } + }; + + private static ResourceFunction getValue = + new ResourceFunction() { + @Override + public Variant execute(GraphStore fragment, int id) { + return fragment.values.getByteValue(id); + } + }; + + THashMap datatypeCache = new THashMap(); + + @Override + public Datatype getDatatype(Res resource) { + for(Res dt : getObjects(resource, paths.HasDatatype)) { + Datatype type = datatypeCache.get(dt); + if(type == null) { + type = apply(dt, getDatatype); + datatypeCache.put(dt, type); + } + return type; + } + return null; + } + + @Override + public Datatype getAssertedDatatype(Res resource) { + for(Res dt : getAssertedObjects(resource, paths.HasDatatype)) { + Datatype type = datatypeCache.get(dt); + if(type == null) { + type = apply(dt, getDatatype); + datatypeCache.put(dt, type); + } + return type; + } + return null; + } + + @Override + public Variant getValue(Res resource) { + return apply(resource, getValue); + } + + @Override + public Object getValue(Res resource, Binding binding) throws NoValueException { + Variant value = getValue(resource); + if(value == null) + throw new NoValueException(); + try { + return value.getValue(binding); + } catch (AdaptException e) { + throw new RuntimeAdaptException(e); + } + } + + @Override + public void setValue(Res resource, Object value, Binding binding) { + final Variant variant = new Variant(binding, value); + apply(resource, new ResourceFunction() { + @Override + public Object execute(GraphStore fragment, int id) { + fragment.values.setValue(id, variant); + return null; + } + }); + } + + /** + * Tells in how many fragments the resource occurs. + */ + public int countOccurences(Res resource) { + if(resource instanceof IdRes) + return 1; + else if(resource instanceof Path) { + Path path = (Path)resource; + int count = 0; + for(GraphStore fragment : fragments) + if(fragment.identities.contains(path)) + ++count; + return count; + } + else + return 0; + } + + private void collectSubtypes(THashSet types, Res type) { + if(types.add(type)) + for(Res subtype : rawGetObjects(type, paths.SupertypeOf)) + collectSubtypes(types, subtype); + } + + @Override + public Collection getInstances(Res supertype) { + THashSet types = new THashSet(); + collectSubtypes(types, supertype); + + ArrayList result = new ArrayList(); + fragmentLoop: + for(GraphStore fragment : fragments) { + IdentityStore identities = fragment.identities; + StatementStore statements = fragment.statements; + + TIntHashSet ids = new TIntHashSet(types.size()); + for(Res type : types) { + if(type instanceof Path) { + int id = identities.pathToId((Path)type); + if(id >= 0) + ids.add(id); + } + else { + IdRes idRes = (IdRes)type; + if(idRes.fragment == fragment) + ids.add(idRes.id); + } + } + if(ids.isEmpty()) + continue; + + int instanceOfId = identities.pathToId(paths.InstanceOf); + if(instanceOfId < 0) + continue; + + int resourceCount = identities.getResourceCount(); + nextResource: + for(int i=0;i getChildren(Res res) { + if(res instanceof Path) { + THashSet result = new THashSet(); + for(GraphStore store : fragments) { + IdentityStore ids = store.identities; + int id = ids.pathToId((Path)res); + if(id >= 0) { + for(int child : ids.getChildren(id)) + result.add(store.idToRes(child)); + } + } + return result; + } + else + return Collections.emptyList(); + } + + public Collection searchByPattern(String pattern) { + THashSet result = new THashSet(); + PathPattern pathPattern = PathPattern.compile(pattern); + for(GraphStore store : fragments) + pathPattern.search(store.identities, result); + return result; + } + + @Override + public Paths getPaths() { + return paths; + } +}