1 package org.simantics.db.impl.query;
4 import java.io.IOException;
5 import java.io.UnsupportedEncodingException;
6 import java.net.MalformedURLException;
8 import java.net.URLDecoder;
10 import org.simantics.utils.FileUtils;
12 public class CodeGen {
16 String[] signatureR1RelationInfo = { "int r", "r", "keyR", "long", "InternalProcedure<RelationInfo>", "entry.id" };
17 String[] signatureR1Bytes = { "int r", "r", "keyR", "long", "InternalProcedure<byte[]>", "entry.id" };
18 String[] signatureR1IntSet = { "int r", "r", "keyR", "long", "InternalProcedure<IntSet>", "entry.id" };
19 String[] signatureR1IP = { "int r", "r", "keyR", "long", "IntProcedure", "entry.id" };
20 String[] signatureR2IP = { "int r1, int r2", "r1,r2", "keyR2", "long", "IntProcedure", "entry.id" };
21 String[] signatureR2TIP = { "int r1, int r2", "r1,r2", "keyR2", "long", "TripleIntProcedure", "entry.id" };
22 String[] signatureID1 = { "String id", "id", "keyID", "String", "InternalProcedure<Integer>", "entry.id" };
23 String[] signatureID2 = { "String id", "id", "keyID", "String", "InternalProcedure<TObjectIntHashMap<String>>", "entry.id" };
24 String[] signatureChildMap = { "int r", "r", "keyR", "long", "InternalProcedure<ObjectResourceIdMap<String>>", "entry.id" };
25 String[] signatureRead = { "Read<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
26 String[] signatureAsyncRead = { "AsyncRead<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
27 String[] signatureMultiRead = { "MultiRead<?> r", "r", "id", "long", "SyncMultiProcedure", "entry.request" };
28 String[] signatureAsyncMultiRead = { "AsyncMultiRead<?> r", "r", "id", "long", "AsyncMultiProcedure", "entry.request" };
29 String[] signatureExternalRead = { "ExternalRead<?> r", "r", "id", "long", "AsyncProcedure", "entry.request" };
31 private void line(StringBuilder content, String line) {
32 for(int i=0;i<indent;i++)
38 public void generateQuery(StringBuilder content, String clazz, String[] signature, boolean runnerShortcut, boolean genReturn) {
39 generateGetOrCreate(content, clazz, signature);
40 generateRemove(content, clazz, signature);
41 generateRunner(content, clazz, signature, runnerShortcut, genReturn);
44 public void generateRunner(StringBuilder content, String clazz, String[] signature, boolean shortcut, boolean genReturn) {
46 line(content, "public static " + (genReturn ? "Object" : "void") + " runner" + clazz + "(ReadGraphImpl graph, " + signature[0] + ", CacheEntry parent, ListenerBase listener, final " + signature[4] + " procedure) throws DatabaseException {");
47 line(content, " QueryCache cache = graph.processor.cache;");
49 line(content, " if(parent == null && listener == null && !cache.shouldCache(graph.processor, " + signature[1] + ")) {");
50 line(content, " " + (genReturn ? "return " : "") + clazz + ".computeForEach(graph, " + signature[1] + ", null, procedure);");
51 if(!genReturn) line(content, " return;");
54 line(content, " " + clazz + " entry = (" + clazz + ")cache.getOrCreate" + clazz + "(graph, " + signature[1] + ");");
55 line(content, " " + signature[4] + " procedure_ = procedure != null ? procedure : emptyProcedure" + clazz + ";");
56 line(content, " ListenerEntry listenerEntry = cache.registerDependencies(graph, entry, parent, listener, procedure_, false);");
57 line(content, " if(entry.isReady()) " + (genReturn ? "return " : "") + "entry.performFromCache(graph, procedure_);");
58 line(content, " else {");
59 line(content, " assert(entry.isPending());");
60 if(shortcut) line(content, " " + (genReturn ? "Object result = " : "") + clazz + ".computeForEach(graph, " + signature[1] + ", entry, procedure_);");
61 else line(content, " entry.compute(graph, procedure_);");
62 line(content, " if(listenerEntry != null) cache.primeListenerEntry(listenerEntry, entry.getResult());");
63 if(genReturn) line(content, " return result;");
70 public void generateRemove(StringBuilder content, String clazz, String[] signature) {
72 String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1);
74 line(content, "void remove(" + clazz + " entry) {");
75 line(content, " synchronized(" + lower + "Map) {");
76 line(content, " " + lower + "Map.remove(" + signature[5] + ");");
83 public void generateGetOrCreate(StringBuilder content, String clazz, String[] signature) {
85 String lower = Character.toLowerCase(clazz.charAt(0)) + clazz.substring(1);
87 line(content, "" + clazz + " getOrCreate" + clazz + "(ReadGraphImpl graph, " + signature[0] + ") throws DatabaseException {");
88 line(content, " " + clazz + " existing = null;");
89 line(content, " synchronized(" + lower + "Map) {");
90 line(content, " existing = (" + clazz + ")" + lower + "Map.get(" + signature[1] + ");");
91 line(content, " if(existing == null) {");
92 line(content, " existing = new " + clazz + "(" + signature[1] + ");");
93 line(content, " existing.clearResult(querySupport);");
94 line(content, " existing.setPending();");
95 line(content, " " + lower + "Map.put(" + signature[2] + "(" + signature[1] + "), existing);");
96 line(content, " size++;");
97 line(content, " return existing;");
99 line(content, " if(existing.requiresComputation()) {");
100 line(content, " existing.setPending();");
101 line(content, " return existing;");
104 line(content, " if(existing.isPending()) waitPending(graph, existing);");
105 line(content, " return existing;");
111 public void generate() {
113 URL classLocation = CodeGen.class.getResource(".");
114 if (classLocation != null) {
115 if (classLocation.getProtocol().equals("file")) {
117 URL resource = new URL(classLocation, ".");
118 File path = new File(URLDecoder.decode(resource.getPath(), "UTF-8"));
119 String target = path.getAbsolutePath().replace("\\", "/");
120 target = target.replace("/bin/", "/src/") + "/QueryCache.java";
121 System.err.println("target=" + target);
122 File source = new File(target);
123 StringBuilder content = new StringBuilder();
124 content.append("package org.simantics.db.impl.query;\n");
125 content.append("\n");
127 content.append("import org.simantics.db.ObjectResourceIdMap;\n");
128 content.append("import org.simantics.db.RelationInfo;\n");
129 content.append("import org.simantics.db.common.utils.Logger;\n");
130 content.append("import org.simantics.db.exception.DatabaseException;\n");
131 content.append("import org.simantics.db.impl.graph.ReadGraphImpl;\n");
132 content.append("import org.simantics.db.impl.procedure.InternalProcedure;\n");
133 content.append("import org.simantics.db.impl.query.QueryProcessor.SessionTask;\n");
134 content.append("import org.simantics.db.procedure.AsyncMultiProcedure;\n");
135 content.append("import org.simantics.db.procedure.AsyncProcedure;\n");
136 content.append("import org.simantics.db.procedure.ListenerBase;\n");
137 content.append("import org.simantics.db.procedure.SyncMultiProcedure;\n");
138 content.append("import org.simantics.db.request.AsyncMultiRead;\n");
139 content.append("import org.simantics.db.request.AsyncRead;\n");
140 content.append("import org.simantics.db.request.ExternalRead;\n");
141 content.append("import org.simantics.db.request.MultiRead;\n");
142 content.append("import org.simantics.db.request.Read;\n");
143 content.append("\n");
145 content.append("public class QueryCache extends QueryCacheBase {\n");
146 content.append("\n");
147 line(content,"public QueryCache(QuerySupport querySupport, int threads) {");
148 line(content," super(querySupport, threads);");
150 content.append("\n");
152 generateQuery(content, "Objects", signatureR2IP, true, false);
153 generateQuery(content, "Statements", signatureR2TIP, true, false);
154 generateQuery(content, "DirectObjects", signatureR2IP, true, false);
155 generateQuery(content, "RelationInfoQuery", signatureR1RelationInfo, true, false);
156 generateQuery(content, "URIToResource", signatureID1, true, false);
157 generateQuery(content, "ValueQuery", signatureR1Bytes, true, false);
158 generateQuery(content, "OrderedSet", signatureR1IP, true, false);
159 generateQuery(content, "PrincipalTypes", signatureR1IP, true, false);
160 generateQuery(content, "DirectPredicates", signatureR1IntSet, true, false);
161 generateQuery(content, "Predicates", signatureR1IntSet, true, false);
162 generateQuery(content, "ReadEntry", signatureRead, true, true);
163 generateQuery(content, "AsyncReadEntry", signatureAsyncRead, true, true);
164 generateQuery(content, "Types", signatureR1IntSet, true, false);
165 generateQuery(content, "ChildMap", signatureChildMap, true, false);
166 generateQuery(content, "TypeHierarchy", signatureR1IntSet, true, false);
167 generateQuery(content, "SuperTypes", signatureR1IntSet, true, false);
168 generateQuery(content, "SuperRelations", signatureR1IntSet, true, false);
170 generateQuery(content, "AssertedPredicates", signatureR1IP, false, false);
171 generateQuery(content, "AssertedStatements", signatureR2TIP, false, false);
172 generateQuery(content, "DirectSuperRelations", signatureR1IP, false, false);
173 generateQuery(content, "MultiReadEntry", signatureMultiRead, false, false);
174 generateQuery(content, "AsyncMultiReadEntry", signatureAsyncMultiRead, false, false);
175 generateQuery(content, "ExternalReadEntry", signatureExternalRead, false, false);
176 content.append("}\n");
177 FileUtils.writeFile(source, content.toString().getBytes());
178 } catch (MalformedURLException e) {
180 } catch (UnsupportedEncodingException e) {
182 } catch (IOException e) {
190 public static void main(String[] args) {
191 new CodeGen().generate();