/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.db.layer0.util; import java.util.Collection; import org.simantics.databoard.Accessors; import org.simantics.databoard.accessor.Accessor; import org.simantics.databoard.accessor.error.AccessorConstructionException; import org.simantics.databoard.accessor.error.AccessorException; import org.simantics.databoard.accessor.event.Event; import org.simantics.databoard.accessor.interestset.InterestSet; import org.simantics.databoard.binding.Binding; import org.simantics.db.ReadGraph; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.Listener; import org.simantics.db.request.Read; public class GraphAccessorUtils { static private class ValueReadRequest implements Read { Resource resource; Binding binding; public ValueReadRequest(Resource resource, Binding binding) { this.resource = resource; this.binding = binding; } @Override public Object perform(ReadGraph graph) throws DatabaseException { return graph.getValue(resource, binding); } } static private class ValueReadRequest2 implements Read { Resource resource; Resource relation; Object defaultValue; Binding binding; public ValueReadRequest2(Resource resource, Resource relation, Object defaultValue, Binding binding) { this.resource = resource; this.relation = relation; this.defaultValue = defaultValue; this.binding = binding; } @Override public Object perform(ReadGraph graph) throws DatabaseException { Object value = graph.getPossibleRelatedValue(resource, relation, binding); if(value != null) return value; else return defaultValue; } } static private class ValueReadListener implements Listener { Binding binding; Accessor accessor; public ValueReadListener(Binding binding) { this.binding = binding; } @Override public void exception(Throwable t) { } @Override public void execute(Object result) { if(accessor == null) try { accessor = Accessors.getAccessor(binding, result); } catch (AccessorConstructionException e) { e.printStackTrace(); } else try { if(!binding.equals(accessor.getValue(binding), result)) accessor.setValue(binding, result); } catch (AccessorException e) { e.printStackTrace(); } } @Override public boolean isDisposed() { // TODO Auto-generated method stub return false; } } static private class AccessorListener implements Accessor.Listener { Accessor accessor; RequestProcessor rp; Resource resource; Binding binding; public AccessorListener(Accessor accessor, RequestProcessor rp, Resource resource, Binding binding) { this.accessor = accessor; this.rp = rp; this.resource = resource; this.binding = binding; } @Override public void onEvents(Collection event) { rp.asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { try { Object a = accessor.getValue(binding); Object b = graph.getValue(resource, binding); if(!binding.equals(a, b)) graph.claimValue(resource, a, binding); } catch (AccessorException e) { throw new DatabaseException(e); } } }); } } static private class AccessorListener2 implements Accessor.Listener { Accessor accessor; RequestProcessor rp; Resource resource; Resource relation; Binding binding; public AccessorListener2(Accessor accessor, RequestProcessor rp, Resource resource, Resource relation, Binding binding) { this.accessor = accessor; this.rp = rp; this.resource = resource; this.relation = relation; this.binding = binding; } @Override public void onEvents(Collection event) { rp.asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { try { Object a = accessor.getValue(binding); Resource valueResource = graph.getPossibleObject(resource, relation); if(valueResource == null) { valueResource = graph.newResource(); graph.claim(resource, relation, valueResource); graph.claimValue(valueResource, a, binding); } else { Object b = graph.getValue(valueResource, binding); if(!binding.equals(a, b)) graph.claimLiteral(resource, relation, a, binding); } } catch (AccessorException e) { throw new DatabaseException(e); } } }); } } public static Accessor create(RequestProcessor rp, Resource resource, Binding binding) throws DatabaseException { ValueReadRequest request = new ValueReadRequest(resource, binding); ValueReadListener listener = new ValueReadListener(binding); rp.syncRequest(request, listener); try { listener.accessor.addListener( new AccessorListener(listener.accessor, rp, resource, binding), InterestSet.newInterestSet(listener.accessor.type(), true, false, true), null, null); } catch (AccessorException e) { e.printStackTrace(); } return listener.accessor; } public static Accessor create(RequestProcessor rp, Resource resource, Resource relation, Object defaultValue, Binding binding) throws DatabaseException { ValueReadRequest2 request = new ValueReadRequest2(resource, relation, defaultValue, binding); ValueReadListener listener = new ValueReadListener(binding); rp.syncRequest(request, listener); try { listener.accessor.addListener( new AccessorListener2(listener.accessor, rp, resource, relation, binding), InterestSet.newInterestSet(listener.accessor.type(), true, false, true), null, null); } catch (AccessorException e) { e.printStackTrace(); } return listener.accessor; } }