/******************************************************************************* * Copyright (c) 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.databoard.accessor.binary; import java.io.IOException; import org.simantics.databoard.Bindings; import org.simantics.databoard.accessor.Accessor; import org.simantics.databoard.accessor.LongAccessor; import org.simantics.databoard.accessor.error.AccessorConstructionException; import org.simantics.databoard.accessor.error.AccessorException; import org.simantics.databoard.accessor.error.ReferenceException; import org.simantics.databoard.accessor.event.Event; import org.simantics.databoard.accessor.event.ValueAssigned; import org.simantics.databoard.accessor.file.FileLongAccessor; import org.simantics.databoard.accessor.impl.AccessorParams; import org.simantics.databoard.accessor.impl.ListenerEntry; import org.simantics.databoard.accessor.interestset.LongInterestSet; import org.simantics.databoard.accessor.reference.ChildReference; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.LongBinding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.type.LongType; import org.simantics.databoard.util.binary.Blob; public class BinaryLong extends BinaryObject implements LongAccessor, FileLongAccessor { public BinaryLong(BinaryObject parent, Blob blob, LongType type, AccessorParams params) throws AccessorConstructionException { super(parent, blob, type, params); try { blob.setLength(8L); } catch (IOException e) { throw new AccessorConstructionException(e); } } @Override public LongType type() { return (LongType) type; } @Override public long getValue() throws AccessorException { assert b.isOpen(); readLock(); try { b.position(0L); return b.readLong(); } catch (IOException e) { throw new AccessorException(e); } finally { readUnlock(); } } @Override Event applyLocal(Event e, boolean makeRollback) throws AccessorException { Event rollback = makeRollback ? new ValueAssigned( Bindings.LONG, getValue() ) : null; if (e instanceof ValueAssigned) { ValueAssigned va = (ValueAssigned) e; if (va.newValue == null) throw new AccessorException("Long value expected, got null"); setValueNoflush(va.newValue.getBinding(), va.newValue.getValue()); return rollback; } else { throw new AccessorException("Cannot apply "+e.getClass().getName()+" to Long"); } } @SuppressWarnings("unchecked") @Override public T getComponent(ChildReference reference) throws AccessorConstructionException { if (reference==null) return (T) this; throw new ReferenceException(reference.getClass()+" is not a subreference of LongType"); } @Override public Object getValue(Binding binding) throws AccessorException { try { LongBinding bb = (LongBinding) binding; long v = getValue(); return bb.create(v); } catch(BindingException e) { throw new AccessorException(e); } } public void setValueNoflush(long newValue) throws AccessorException { assert b.isOpen(); writeLock(); try { // Set value b.position(0); b.writeLong( newValue ); // Notify ListenerEntry le = listeners; while (le!=null) { LongInterestSet is = le.getInterestSet(); if (is.inNotifications()) { Event e = new ValueAssigned( Bindings.LONG, is.inValues() ? newValue : null ); emitEvent(le, e); } le = le.next; } } catch (IOException e) { throw new AccessorException(e); } finally { writeUnlock(); } } @Override public void setValue(long newValue) throws AccessorException { assert b.isOpen(); writeLock(); try { setValueNoflush(newValue); b.flush(); } catch (IOException e) { throw new AccessorException(e); } finally { writeUnlock(); } } @Override public void setValueNoflush(Binding binding, Object newValue) throws AccessorException { try { long nv = ((LongBinding)binding).getValue_(newValue); setValueNoflush(nv); } catch (BindingException e) { throw new AccessorException(e); } } }