1 package org.simantics.graph.representation;
3 import java.util.Comparator;
5 import java.util.TreeMap;
6 import java.util.TreeSet;
8 import org.simantics.databoard.util.URIStringUtils;
10 import gnu.trove.impl.Constants;
11 import gnu.trove.list.array.TIntArrayList;
12 import gnu.trove.map.hash.TIntObjectHashMap;
13 import gnu.trove.map.hash.TObjectIntHashMap;
14 import gnu.trove.procedure.TObjectProcedure;
16 public class TransferableGraphQueries {
18 private static final int NOT_FOUND = TransferableGraphUtils.NOT_FOUND;
20 private final TransferableGraph1 tg;
22 private final TIntObjectHashMap<Identity> internalIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
23 private final TIntObjectHashMap<Identity> externalIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
24 private final TIntObjectHashMap<Identity> rootIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
26 private final TObjectIntHashMap<String> internalIdentitiesByURI = new TObjectIntHashMap<>();
27 private final TObjectIntHashMap<String> externalIdentitiesByURI = new TObjectIntHashMap<>();
28 private final TObjectIntHashMap<String> rootIdentitiesByURI = new TObjectIntHashMap<>();
30 private final TIntObjectHashMap<TIntArrayList> statementsCache = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
32 public TransferableGraphQueries(TransferableGraph1 graph) {
35 // Calculate internals
36 initializeIdentities();
39 private void initializeIdentities() {
40 for (Identity identity : tg.identities) {
41 IdentityDefinition definition = identity.definition;
42 if (definition instanceof Internal) {
43 Internal internal = (Internal) definition;
44 internalIdentities.put(identity.resource, identity);
45 internalIdentitiesByURI.put(getURI(identity), identity.resource);
46 } else if (definition instanceof External) {
47 External external = (External) definition;
48 externalIdentities.put(identity.resource, identity);
49 externalIdentitiesByURI.put(getURI(identity), identity.resource);
50 } else if (definition instanceof Root) {
51 Root root = (Root) definition;
52 rootIdentities.put(identity.resource, identity);
53 rootIdentitiesByURI.put(getURI(identity), identity.resource);
58 public String getURI(Identity identity) {
59 IdentityDefinition definition = identity.definition;
60 if(definition instanceof External) {
61 External def = (External)definition;
62 if(def.parent == -1) return "http:/";
63 else return getURI(def.parent) + "/" + URIStringUtils.escape(def.name);
64 } else if(definition instanceof Root) {
65 Root def = (Root)definition;
66 if(def.name.isEmpty()) return "http:/";
68 } else if (definition instanceof Internal) {
69 Internal def = (Internal)definition;
70 return getURI(def.parent) + "/" + URIStringUtils.escape(def.name);
76 public String getURI(int id) {
77 Identity identity = getIdentity(id);
79 return "<internal reference " + id + ">:";
80 return getURI(identity);
83 private static final Comparator<Identity> IDENTITY_NAME_COMPARATOR = new Comparator<Identity>() {
86 public int compare(Identity o1, Identity o2) {
87 if (o1.definition instanceof Internal && o2.definition instanceof Internal) {
88 Internal i1 = (Internal) o1.definition;
89 Internal i2 = (Internal) o2.definition;
90 return i1.name.compareTo(i2.name);
91 } else if (o1.definition instanceof External && o2.definition instanceof External) {
92 External e1 = (External) o1.definition;
93 External e2 = (External) o2.definition;
94 return e1.name.compareTo(e2.name);
96 throw new IllegalArgumentException(o1 + " " + o2);
101 public Set<Identity> getChildren(Identity parent) {
102 TreeSet<Identity> children = new TreeSet<>(IDENTITY_NAME_COMPARATOR);
103 internalIdentities.forEachEntry((resource, identity) -> {
104 Internal internal = (Internal) identity.definition;
105 if (internal.parent == parent.resource)
106 children.add(identity);
113 public Identity findInternalByName(String name) {
114 int internal = internalIdentitiesByURI.get(name);
115 if (internal == NOT_FOUND)
117 return internalIdentities.get(internal);
120 private Identity findExternalByName(String name) {
121 int external = externalIdentitiesByURI.get(name);
122 if (external == NOT_FOUND)
124 return externalIdentities.get(external);
127 private Identity findExternalByNameAndParent(String name, int parent) {
128 Identity external = findExternalByName(name);
129 if (external.resource == parent)
134 public Identity findExternalByURI(String uri) {
135 int v = externalIdentitiesByURI.get(uri);
138 return externalIdentities.get(v);
141 public Identity findRootByName(String name) {
142 int root = rootIdentitiesByURI.get(name);
143 if (root == NOT_FOUND)
145 return rootIdentities.get(root);
148 public String getName(Identity identity) {
149 return TransferableGraphUtils.getName(identity);
152 public void forIdentities(TObjectProcedure<Identity> procedure) {
153 for (Identity identity : tg.identities) {
154 if (!procedure.execute(identity)) {
160 public Identity getIdentity(int resource) {
161 Identity result = rootIdentities.get(resource);
163 result = externalIdentities.get(resource);
165 result = internalIdentities.get(resource);
169 public Value findValue(int object) {
170 return TransferableGraphUtils.findValue(tg, object);
173 public TreeMap<String, TreeSet<Integer>> sortByPredicateUniqueStatements(int resource) {
174 TreeMap<String, TreeSet<Integer>> results = new TreeMap<>();
175 TIntArrayList statements = getStatements(resource);
176 for (int i = 0; i < statements.size(); i += 2) {
177 int predicate = statements.get(i);
178 String predicateURI = getURI(predicate);
179 TreeSet<Integer> objects = results.get(predicateURI);
180 if (objects == null) {
181 objects = new TreeSet<>();
183 objects.add(statements.get(i + 1));
184 results.put(predicateURI, objects);
189 public TIntArrayList getStatements(int resource) {
190 // System.out.println("getting statements with " + resource);
191 TIntArrayList statements = statementsCache.get(resource);
192 if (statements == null) {
193 statements = TransferableGraphUtils.getStatements(tg, resource);
194 statementsCache.put(resource, statements);
199 public int getPossibleObject(int subject, Identity predicate) {
200 return TransferableGraphUtils.getPossibleObject2(tg, subject, predicate);
203 public TransferableGraph1 getGraph() {