]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/GraphAccessorUtils.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / GraphAccessorUtils.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.layer0.util;
13
14 import java.util.Collection;
15
16 import org.simantics.databoard.Accessors;
17 import org.simantics.databoard.accessor.Accessor;
18 import org.simantics.databoard.accessor.error.AccessorConstructionException;
19 import org.simantics.databoard.accessor.error.AccessorException;
20 import org.simantics.databoard.accessor.event.Event;
21 import org.simantics.databoard.accessor.interestset.InterestSet;
22 import org.simantics.databoard.binding.Binding;
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.RequestProcessor;
25 import org.simantics.db.Resource;
26 import org.simantics.db.WriteGraph;
27 import org.simantics.db.common.request.WriteRequest;
28 import org.simantics.db.exception.DatabaseException;
29 import org.simantics.db.procedure.Listener;
30 import org.simantics.db.request.Read;
31
32 public class GraphAccessorUtils {
33
34         static private class ValueReadRequest implements Read<Object> {
35                 Resource resource;
36                 Binding binding;
37                 
38                 public ValueReadRequest(Resource resource, Binding binding) {
39                         this.resource = resource;
40                         this.binding = binding;
41                 }
42
43                 @Override
44                 public Object perform(ReadGraph graph) throws DatabaseException {
45                         return graph.getValue(resource, binding);
46                 }
47         }
48         
49
50         static private class ValueReadRequest2 implements Read<Object> {
51                 Resource resource;
52                 Resource relation;
53                 Object defaultValue;
54                 Binding binding;
55                 
56                 public ValueReadRequest2(Resource resource, Resource relation, Object defaultValue, Binding binding) {
57                         this.resource = resource;
58                         this.relation = relation;
59                         this.defaultValue = defaultValue;
60                         this.binding = binding;
61                 }
62
63                 @Override
64                 public Object perform(ReadGraph graph) throws DatabaseException {
65                         Object value = graph.getPossibleRelatedValue(resource, relation, binding);
66                         if(value != null)
67                                 return value;
68                         else
69                                 return defaultValue;
70                 }
71         }
72                 
73         static private class ValueReadListener implements Listener<Object> {
74
75                 Binding binding;
76                 Accessor accessor;              
77                 
78                 public ValueReadListener(Binding binding) {
79                         this.binding = binding;
80                 }
81
82                 @Override
83                 public void exception(Throwable t) {
84                 }
85
86                 @Override
87                 public void execute(Object result) {
88                         if(accessor == null)
89                                 try {
90                                         accessor = Accessors.getAccessor(binding, result);                                      
91                                 } catch (AccessorConstructionException e) {
92                                         e.printStackTrace();
93                                 }
94                         else
95                                 try {
96                                         if(!binding.equals(accessor.getValue(binding), result))
97                                                 accessor.setValue(binding, result);
98                                 } catch (AccessorException e) {
99                                         e.printStackTrace();
100                                 }                       
101                 }
102
103                 @Override
104                 public boolean isDisposed() {
105                         // TODO Auto-generated method stub
106                         return false;
107                 }
108                 
109         }
110         
111         static private class AccessorListener implements Accessor.Listener {
112
113                 Accessor accessor;
114                 RequestProcessor rp;
115                 Resource resource;
116                 Binding binding;
117                 
118                 public AccessorListener(Accessor accessor, RequestProcessor rp,
119                                 Resource resource, Binding binding) {
120                         this.accessor = accessor;
121                         this.rp = rp;
122                         this.resource = resource;
123                         this.binding = binding;
124                 }
125
126                 @Override
127                 public void onEvents(Collection<Event> event) {
128                         rp.asyncRequest(new WriteRequest() {                            
129                                 @Override
130                                 public void perform(WriteGraph graph) throws DatabaseException {
131                                         try {
132                                                 Object a = accessor.getValue(binding);
133                                                 Object b = graph.getValue(resource, binding);
134                                                 if(!binding.equals(a, b))
135                                                         graph.claimValue(resource, a, binding);
136                                         } catch (AccessorException e) {
137                                                 throw new DatabaseException(e);
138                                         }
139                                 }
140                         });
141                 }
142                 
143         }
144         
145         static private class AccessorListener2 implements Accessor.Listener {
146
147                 Accessor accessor;
148                 RequestProcessor rp;
149                 Resource resource;
150                 Resource relation;
151                 Binding binding;
152                 
153                 public AccessorListener2(Accessor accessor, RequestProcessor rp,
154                                 Resource resource, Resource relation, Binding binding) {
155                         this.accessor = accessor;
156                         this.rp = rp;
157                         this.resource = resource;
158                         this.relation = relation;
159                         this.binding = binding;
160                 }
161
162                 @Override
163                 public void onEvents(Collection<Event> event) {
164                         rp.asyncRequest(new WriteRequest() {                            
165                                 @Override
166                                 public void perform(WriteGraph graph) throws DatabaseException {
167                                         try {
168                                                 Object a = accessor.getValue(binding);
169                                                 
170                                                 Resource valueResource = graph.getPossibleObject(resource, relation);
171                                                 if(valueResource == null) {
172                                                         valueResource = graph.newResource(); 
173                                                         graph.claim(resource, relation, valueResource);
174                                                         graph.claimValue(valueResource, a, binding);
175                                                 }
176                                                 else {
177                                                         Object b = graph.getValue(valueResource, binding);
178                                                         if(!binding.equals(a, b))
179                                                                 graph.claimLiteral(resource, relation, a, binding);
180                                                 }
181                                         } catch (AccessorException e) {
182                                                 throw new DatabaseException(e);
183                                         }
184                                 }
185                         });
186                 }
187                 
188         }
189         
190         public static Accessor create(RequestProcessor rp, Resource resource, Binding binding) throws DatabaseException {
191                 ValueReadRequest request = new ValueReadRequest(resource, binding);
192                 ValueReadListener listener = new ValueReadListener(binding);
193                 rp.syncRequest(request, listener);
194                 try {
195                         listener.accessor.addListener(
196                                 new AccessorListener(listener.accessor, rp, resource, binding), 
197                                 InterestSet.newInterestSet(listener.accessor.type(), true, false, true),
198                                 null, null);
199                 } catch (AccessorException e) {
200                         e.printStackTrace();
201                 }
202                 return listener.accessor;               
203         }
204         
205         public static Accessor create(RequestProcessor rp, Resource resource, Resource relation, Object defaultValue, Binding binding) throws DatabaseException {
206                 ValueReadRequest2 request = new ValueReadRequest2(resource, relation, defaultValue, binding);
207                 ValueReadListener listener = new ValueReadListener(binding);
208                 rp.syncRequest(request, listener);
209                 try {
210                         listener.accessor.addListener(
211                                 new AccessorListener2(listener.accessor, rp, resource, relation, binding), 
212                                 InterestSet.newInterestSet(listener.accessor.type(), true, false, true),
213                                 null, null);
214                 } catch (AccessorException e) {
215                         e.printStackTrace();
216                 }
217                 return listener.accessor;               
218         }
219         
220 }