1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.mapping.rule.instructions;
14 import org.simantics.db.ReadGraph;
15 import org.simantics.db.WriteGraph;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.request.Read;
18 import org.simantics.layer0.utils.triggers.IModification;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
22 import gnu.trove.map.hash.TIntIntHashMap;
23 import gnu.trove.procedure.TIntProcedure;
24 import gnu.trove.set.hash.TIntHashSet;
26 public class QueryRuleInstruction implements IRuleInstruction {
28 private static final Logger LOGGER = LoggerFactory.getLogger(QueryRuleInstruction.class);
29 IRuleInstruction rule;
33 public QueryRuleInstruction(IRuleInstruction rule) {
35 TIntHashSet reads = new TIntHashSet();
36 TIntHashSet writes = new TIntHashSet();
37 rule.collectVariables(reads, writes);
38 reads.removeAll(writes.toArray());
39 variables = reads.toArray();
40 final TIntIntHashMap map = new TIntIntHashMap();
41 for(int i = 0;i<variables.length;++i)
42 map.put(variables[i], i);
43 workSpace = variables.length;
44 writes.forEach(new TIntProcedure() {
47 public boolean execute(int arg0) {
48 map.put(arg0, workSpace++);
53 rule.mapVariables(map);
57 public void collectVariables(TIntHashSet reads, TIntHashSet writes) {
58 reads.addAll(variables);
61 class Query implements Read<IModification> {
65 public Query(Object[] parameters) {
66 this.parameters = parameters;
69 QueryRuleInstruction parent() {
70 return QueryRuleInstruction.this;
74 public boolean equals(Object other) {
77 if(other == null || other.getClass() != this.getClass())
79 Query q = (Query)other;
80 if(!parent().equals(q.parent()))
82 if(parameters.length != q.parameters.length)
84 for(int i=0;i<parameters.length;++i)
85 if(parameters[i] == null ? q.parameters[i] != null : !parameters[i].equals(q.parameters[i]))
91 public int hashCode() {
92 int result = QueryRuleInstruction.this.hashCode();
93 for(Object parameter : parameters) {
96 result += parameter.hashCode();
98 LOGGER.error("Parameter is null!!!");
104 public IModification perform(ReadGraph g) throws DatabaseException {
105 final Object[] bindings = new Object[workSpace];
106 System.arraycopy(parameters, 0, bindings, 0, parameters.length);
107 return rule.execute(g, bindings);
113 public IModification execute(ReadGraph g, Object[] bindings) throws DatabaseException {
114 Object[] parameters = new Object[variables.length];
115 for(int i=0;i<variables.length;++i)
116 parameters[i] = bindings[variables[i]];
117 IModification result = g.syncRequest(new Query(parameters));
122 public void doExecute(WriteGraph g, Object[] bindings) throws DatabaseException {
123 Object[] parameters = new Object[variables.length];
124 for(int i=0;i<variables.length;++i)
125 parameters[i] = bindings[variables[i]];
126 IModification modi = g.syncRequest(new Query(parameters));
132 public void mapVariables(TIntIntHashMap map) {
133 for(int i=0;i<variables.length;++i)
134 variables[i] = map.get(variables[i]);
138 public void toString(StringBuilder b, int indent) {
142 for(int i=0;i<variables.length;++i)
143 b.append(" " + variables[i] + "->" + i);
145 for(int i=0;i<indent;++i)
146 b.append(INDENTATION);
147 rule.toString(b, indent);