]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/RelatedValueAccessor.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.objmap2 / src / org / simantics / objmap / graph / rules / domain / RelatedValueAccessor.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2013 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.objmap.graph.rules.domain;
13
14 import java.util.Arrays;
15
16 import org.simantics.databoard.binding.Binding;
17 import org.simantics.databoard.binding.OptionalBinding;
18 import org.simantics.db.ReadGraph;
19 import org.simantics.db.Resource;
20 import org.simantics.db.Statement;
21 import org.simantics.db.WriteGraph;
22 import org.simantics.db.exception.BindingException;
23 import org.simantics.db.exception.DatabaseException;
24 import org.simantics.db.exception.DoesNotContainValueException;
25 import org.simantics.db.exception.ServiceException;
26 import org.simantics.layer0.Layer0;
27 import org.simantics.objmap.exceptions.MappingException;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * Accesses a value attached to the element by given functional relation.
33  * @author Hannu Niemist�
34  */
35 public class RelatedValueAccessor implements IDomainAccessor<Resource,Object> {
36
37     static Logger LOGGER = LoggerFactory.getLogger(RelatedValueAccessor.class);
38     
39         Resource relation;
40         Resource valueType;
41         Binding valueBinding;
42
43         public RelatedValueAccessor(Resource relation, Resource valueType, Binding valueBinding) {
44                 this.relation = relation;
45                 this.valueType = valueType;
46                 this.valueBinding = valueBinding;
47         }
48
49         @Override
50         public Object get(ReadGraph g, Resource element) throws MappingException {
51                 try {
52                     LOGGER.trace("        RelatedValueAccessor.get");
53                         Resource valueResource = g.getPossibleObject(element, relation);
54                         if(valueResource == null)
55                                 return null;
56                         return getValue(g, valueResource);
57                 } catch (DatabaseException e) {
58                         throw new MappingException(e);
59                 }
60         }
61
62         @Override
63         public boolean set(WriteGraph g, Resource element, Object value)
64                         throws MappingException {
65                 try {
66                     LOGGER.trace("        RelatedValueAccessor.set");
67                     Statement valueStatement = g.getPossibleStatement(element, relation);
68                         if(valueStatement == null) {
69                                 if(value == null)
70                                         return false;
71                                 Resource valueResource = g.newResource();
72                                 g.claim(valueResource, Layer0.getInstance(g).InstanceOf, null,
73                                                 valueType);
74                                 g.claim(element, relation, valueResource);
75                                 claimValue(g, valueResource, value);
76                                 
77                                 return true;
78                         }
79                         else {
80                                 if(value == null) {
81                                         if (!valueStatement.isAsserted(element)) {
82                                                 g.deny(valueStatement.getObject());
83                                                 return true;
84                                         } else {
85                                                 return false;
86                                         }
87                                 }                               
88                                 Object currentValue = getValue(g, valueStatement.getObject());
89                                 if(equals(currentValue,value))
90                                         return false;
91                                 if (!valueStatement.isAsserted(element))
92                                         g.claimValue(valueStatement.getObject(), value);
93                                 else {
94                                         Resource valueResource = g.newResource();
95                                         g.claim(valueResource, Layer0.getInstance(g).InstanceOf, null,
96                                                         valueType);
97                                         g.claim(element, relation, valueResource);
98                                         claimValue(g, valueResource, value);
99                                 }
100                                 return true;
101                         }
102                 } catch (DatabaseException e) {
103                         throw new MappingException(e);
104                 }
105                 
106         }
107
108         private Object getValue(ReadGraph g, Resource valueResource)
109                         throws DoesNotContainValueException, BindingException, ServiceException {
110                 if (valueBinding != null) {
111                         return g.getValue(valueResource, getBaseBinding(valueBinding));
112                 }
113                 else {
114                         return g.getValue(valueResource);
115                 }
116         }
117         
118         private void claimValue(WriteGraph g, Resource valueResource, Object value) throws ServiceException {
119                 if (valueBinding != null)
120                         g.claimValue(valueResource, value, getBaseBinding(valueBinding));
121                 else
122                         g.claimValue(valueResource, value);
123         }
124
125         private static Binding getBaseBinding(Binding binding) {
126                 return binding instanceof OptionalBinding ? ((OptionalBinding)binding).getComponentBinding() : binding;
127         }
128         
129         private boolean equals(Object o1, Object o2) {
130                 if (valueBinding != null)
131                         return valueBinding.equals(o1, o2);
132                 
133                 if (o1 instanceof boolean[])
134                         Arrays.equals((boolean[])o1,(boolean[])o2);
135                 if (o1 instanceof int[])
136                         Arrays.equals((int[])o1,(int[])o2);
137                 if (o1 instanceof float[])
138                         Arrays.equals((float[])o1,(float[])o2);
139                 if (o1 instanceof double[])
140                         Arrays.equals((double[])o1,(double[])o2);
141                 if (o1 instanceof byte[])
142                         Arrays.equals((byte[])o1,(byte[])o2);
143                 return o1.equals(o2);
144         }
145
146 }