* @author Hannu Niemistö\r
*/\r
public class MappedElementsRule implements IMappingRule {\r
- \r
+\r
static Logger LOGGER = Logger.getLogger("org.simantics.objmap");\r
- \r
- IDomainAccessor<Collection<Resource>> domainAccessor;\r
- IRangeAccessor<Collection<Object>> rangeAccessor;\r
- \r
- public MappedElementsRule(IDomainAccessor<Collection<Resource>> domainAccessor,\r
- IRangeAccessor<Collection<Object>> rangeAccessor) {\r
- this.domainAccessor = domainAccessor;\r
- this.rangeAccessor = rangeAccessor;\r
- }\r
\r
- @Override\r
- public boolean updateDomain(WriteGraph g, IFunction<Object, Resource> map,\r
- Resource domainElement, Object rangeElement)\r
- throws MappingException {\r
- LOGGER.info(" MappedElementsRule.updateDomain");\r
- Collection<Object> value = rangeAccessor.get(rangeElement);\r
- ArrayList<Resource> mappedValue = new ArrayList<Resource>(value.size());\r
- for(Object obj : value)\r
- mappedValue.add(map.get(obj));\r
- return domainAccessor.set(g, domainElement, mappedValue);\r
- }\r
+ IDomainAccessor<Collection<Resource>> domainAccessor;\r
+ IRangeAccessor<Collection<Object>> rangeAccessor;\r
+ Object[] rangeSnapshot = new Object[0];\r
+\r
+ public MappedElementsRule(IDomainAccessor<Collection<Resource>> domainAccessor,\r
+ IRangeAccessor<Collection<Object>> rangeAccessor) {\r
+ this.domainAccessor = domainAccessor;\r
+ this.rangeAccessor = rangeAccessor;\r
+ }\r
+\r
+ @Override\r
+ public boolean updateDomain(WriteGraph g, IFunction<Object, Resource> map,\r
+ Resource domainElement, Object rangeElement)\r
+ throws MappingException {\r
+ LOGGER.info(" MappedElementsRule.updateDomain");\r
+ // Snapshot the accessed range value for concurrency safety.\r
+ // NOTE: still assumes that the accessed collection is concurrent or\r
+ // synchronized for toArray to be atomic.\r
+ Collection<Object> value = rangeAccessor.get(rangeElement);\r
+ Object[] rangeSnapshot = value.toArray();\r
+ ArrayList<Resource> mappedValue = new ArrayList<Resource>(rangeSnapshot.length);\r
+ for (Object obj : rangeSnapshot)\r
+ mappedValue.add(map.get(obj));\r
+ return domainAccessor.set(g, domainElement, mappedValue);\r
+ }\r
\r
- @Override\r
- public boolean updateRange(ReadGraph g, IFunction<Resource, Object> map,\r
- Resource domainElement, Object rangeElement)\r
- throws MappingException {\r
- LOGGER.info(" MappedElementsRule.updateRange");\r
- Collection<Resource> value = domainAccessor.get(g, domainElement);\r
+ @Override\r
+ public boolean updateRange(ReadGraph g, IFunction<Resource, Object> map,\r
+ Resource domainElement, Object rangeElement)\r
+ throws MappingException {\r
+ LOGGER.info(" MappedElementsRule.updateRange");\r
+ Collection<Resource> value = domainAccessor.get(g, domainElement);\r
ArrayList<Object> mappedValue = new ArrayList<Object>(value.size());\r
for(Resource r : value)\r
mappedValue.add(map.get(r));\r
return rangeAccessor.set(rangeElement, mappedValue);\r
- } \r
+ }\r
}\r