-/*******************************************************************************\r
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.history.util;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.adapter.AdaptException;\r
-import org.simantics.databoard.adapter.Adapter;\r
-import org.simantics.databoard.adapter.AdapterConstructionException;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.BooleanBinding;\r
-import org.simantics.databoard.binding.ByteBinding;\r
-import org.simantics.databoard.binding.DoubleBinding;\r
-import org.simantics.databoard.binding.FloatBinding;\r
-import org.simantics.databoard.binding.NumberBinding;\r
-import org.simantics.databoard.binding.RecordBinding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.databoard.binding.error.RuntimeBindingException;\r
-import org.simantics.databoard.type.RecordType;\r
-import org.simantics.history.HistoryException;\r
-\r
-/**\r
- * Value band is an utility class intended for reading and writing to samples.\r
- * There are many different formats of samples, their fields, order and datatypes vary.\r
- *\r
- * @author toni.kalajainen\r
- */\r
-public class ValueBand {\r
- \r
- public static final Byte QUALITY_GOOD = Byte.valueOf( (byte) 0 ); \r
- public static final Byte QUALITY_NOVALUE = Byte.valueOf( (byte) -1 ); \r
- \r
- protected RecordBinding binding;\r
- protected RecordType type;\r
- protected Object sample;\r
- \r
- /** Field value cloners */\r
- FieldAdapter timeField, endTimeField, valueField, lastValueField, avgField, medianField, minField, maxField, countField, qualityField;\r
- /** Default value*/\r
- Object defaultValue;\r
- \r
- public ValueBand(Binding sampleBinding)\r
- {\r
- if ( sampleBinding instanceof RecordBinding == false ) {\r
- throw new IllegalArgumentException();\r
- }\r
- \r
- this.binding = (RecordBinding) sampleBinding; \r
- type = this.binding.type();\r
- \r
- timeField = new FieldAdapter("time");\r
- endTimeField = new FieldAdapter("endTime");\r
- valueField = new FieldAdapter("value");\r
- lastValueField = new FieldAdapter("lastValue");\r
- avgField = new FieldAdapter("avg");\r
- medianField = new FieldAdapter("median");\r
- minField = new FieldAdapter("min");\r
- maxField = new FieldAdapter("max");\r
- countField = new FieldAdapter("count");\r
- qualityField = new FieldAdapter("quality");\r
- \r
- try {\r
- defaultValue = binding.createDefault();\r
- } catch (BindingException e) {\r
- throw new RuntimeBindingException( e );\r
- }\r
- }\r
- \r
- public ValueBand(Binding sampleBinding, Object sample)\r
- {\r
- this( sampleBinding );\r
- this.sample = sample;\r
- }\r
- \r
- \r
- public void reset()\r
- {\r
- try {\r
- binding.readFrom(binding, defaultValue, sample);\r
- } catch (BindingException e) {\r
- throw new RuntimeBindingException( e );\r
- }\r
- }\r
- \r
- public Binding getBinding()\r
- {\r
- return binding;\r
- }\r
-\r
- /**\r
- * Get the internal sample instance\r
- * \r
- * @return the internal sample instance\r
- */\r
- public Object getSample() {\r
- return sample;\r
- }\r
-\r
- /**\r
- * Change the internal sample instance\r
- * \r
- * @param sample\r
- */\r
- public void setSample(Object sample) {\r
- this.sample = sample;\r
- }\r
-\r
- /**\r
- * Write to the internal sample instance \r
- * \r
- * @param sample\r
- */\r
- public void writeSample(Object sample) {\r
- try {\r
- binding.readFrom(binding, sample, this.sample);\r
- } catch (BindingException e) {\r
- throw new RuntimeBindingException(e);\r
- }\r
- }\r
- \r
- /**\r
- * Write to the internal sample instance \r
- * \r
- * @param binding\r
- * @param sample\r
- */\r
- public void writeSample(Binding binding, Object sample) {\r
- try {\r
- binding.readFrom(binding, sample, this.sample);\r
- } catch (BindingException e) {\r
- throw new RuntimeBindingException(e);\r
- }\r
- }\r
- \r
- \r
- /// Time ///\r
- public boolean hasTime() {\r
- return timeField.isEnabled();\r
- }\r
- \r
- public Binding getTimeBinding() {\r
- return timeField.binding;\r
- }\r
- \r
- public Object getTime() throws HistoryException {\r
- return timeField.getValue();\r
- }\r
-\r
- public Object getTime(Binding b) throws HistoryException {\r
- return timeField.getValue(b);\r
- }\r
- \r
- public double getTimeDouble() throws HistoryException {\r
- return timeField.getDoubleValue();\r
- }\r
- \r
- public void setTime(Object v) throws HistoryException {\r
- timeField.setValue(v);\r
- }\r
- \r
- public void setTime(Binding binding, Object v) throws HistoryException\r
- {\r
- timeField.setValue(binding, v);\r
- }\r
-\r
- /// EndTime ///\r
- public boolean hasEndTime() {\r
- return endTimeField.isEnabled();\r
- }\r
- \r
- public Binding getEndTimeBinding() {\r
- return endTimeField.binding;\r
- }\r
- \r
- public Object getEndTime() throws HistoryException {\r
- return endTimeField.getValue();\r
- }\r
-\r
- public Object getEndTime(Binding b) throws HistoryException {\r
- return endTimeField.getValue(b);\r
- }\r
- \r
- public double getEndTimeDouble() throws HistoryException {\r
- return endTimeField.getDoubleValue();\r
- }\r
- \r
- \r
- public void setEndTime(Object v) throws HistoryException {\r
- endTimeField.setValue(v);\r
- }\r
-\r
- public void setEndTime(Binding binding, Object v) throws HistoryException\r
- {\r
- endTimeField.setValue(binding, v);\r
- }\r
- \r
- /// Value ///\r
- public boolean hasValue() {\r
- return valueField.isEnabled();\r
- }\r
- \r
- public Binding getValueBinding() {\r
- return valueField.binding;\r
- }\r
- \r
- public Object getValue() throws HistoryException {\r
- return valueField.getValue();\r
- }\r
-\r
- public Object getValue(Binding b) throws HistoryException {\r
- return valueField.getValue(b);\r
- }\r
-\r
- public double getValueDouble() throws HistoryException {\r
- return valueField.getDoubleValue();\r
- }\r
- \r
- public Object getPossibleValue() throws HistoryException {\r
- if ( isNullValue() ) return null;\r
- return valueField.getValue();\r
- }\r
-\r
- public Object getPossibleValue(Binding b) throws HistoryException {\r
- if ( isNullValue() ) return null;\r
- return valueField.getValue(b);\r
- }\r
-\r
- public Double getPossibleValueDouble() throws HistoryException {\r
- if ( isNullValue() ) return null;\r
- return valueField.getDoubleValue();\r
- }\r
- \r
- \r
- public boolean getValueBoolean() throws HistoryException {\r
- return valueField.getBooleanValue();\r
- }\r
- \r
- public void setValue(Object v) throws HistoryException {\r
- valueField.setValue(v);\r
- }\r
-\r
- public void setValue(Binding binding, Object v) throws HistoryException\r
- {\r
- valueField.setValue(binding, v);\r
- }\r
- \r
- /// LastValue ///\r
- public boolean hasLastValue() {\r
- return lastValueField.isEnabled();\r
- }\r
- \r
- public Binding getLastValueBinding() {\r
- return lastValueField.binding;\r
- }\r
- \r
- public Object getLastValue() throws HistoryException {\r
- return lastValueField.getValue();\r
- }\r
-\r
- public Object getLastValue(Binding b) throws HistoryException {\r
- return lastValueField.getValue(b);\r
- }\r
-\r
- public void setLastValue(Object v) throws HistoryException {\r
- lastValueField.setValue(v);\r
- }\r
- \r
- public void setLastValue(Binding binding, Object v) throws HistoryException {\r
- lastValueField.setValue(binding, v);\r
- }\r
- \r
- /// Avg ///\r
- public boolean hasAvg() {\r
- return avgField.isEnabled();\r
- }\r
- \r
- public Binding getAvgBinding() {\r
- return avgField.binding;\r
- }\r
- \r
- public Object getAvg() throws HistoryException {\r
- return avgField.getValue();\r
- }\r
-\r
- public Object getAvg(Binding b) throws HistoryException {\r
- return avgField.getValue(b);\r
- }\r
- \r
- public double getAvgDouble() throws HistoryException {\r
- return avgField.getDoubleValue();\r
- } \r
- \r
- public void setAvg(Object v) throws HistoryException {\r
- avgField.setValue(v);\r
- }\r
-\r
- public void setAvg(Binding binding, Object v) throws HistoryException\r
- {\r
- avgField.setValue(binding, v);\r
- }\r
- \r
- /// Median ///\r
- public boolean hasMedian() {\r
- return medianField.isEnabled();\r
- }\r
- \r
- public Binding getMedianBinding() {\r
- return medianField.binding;\r
- }\r
- \r
- public Object getMedian() throws HistoryException {\r
- return medianField.getValue();\r
- }\r
-\r
- public Object getMedian(Binding b) throws HistoryException {\r
- return medianField.getValue(b);\r
- }\r
- \r
- public double getMedianDouble() throws HistoryException {\r
- return medianField.getDoubleValue();\r
- }\r
- \r
- public void setMedian(Object v) throws HistoryException {\r
- medianField.setValue(v);\r
- }\r
-\r
- public void setMedian(Binding binding, Object v) throws HistoryException\r
- {\r
- medianField.setValue(binding, v);\r
- }\r
- \r
- /// Min ///\r
- public boolean hasMin() {\r
- return minField.isEnabled();\r
- }\r
- \r
- public Binding getMinBinding() {\r
- return minField.binding;\r
- }\r
- \r
- public Object getMin() throws HistoryException {\r
- return minField.getValue();\r
- }\r
-\r
- public Object getMin(Binding b) throws HistoryException {\r
- return minField.getValue(b);\r
- }\r
- \r
- public double getMinDouble() throws HistoryException {\r
- return minField.getDoubleValue();\r
- }\r
- \r
- public void setMin(Object v) throws HistoryException {\r
- minField.setValue(v);\r
- } \r
-\r
- public void setMin(Binding binding, Object v) throws HistoryException\r
- {\r
- minField.setValue(binding, v);\r
- }\r
- \r
- /// Max ///\r
- public boolean hasMax() {\r
- return maxField.isEnabled();\r
- }\r
- \r
- public Binding getMaxBinding() {\r
- return maxField.binding;\r
- }\r
- \r
- public Object getMax() throws HistoryException {\r
- return maxField.getValue();\r
- }\r
-\r
- public Object getMax(Binding b) throws HistoryException {\r
- return maxField.getValue(b);\r
- }\r
- \r
- public double getMaxDouble() throws HistoryException {\r
- return maxField.getDoubleValue();\r
- }\r
- \r
- public void setMax(Object v) throws HistoryException {\r
- maxField.setValue(v);\r
- } \r
- \r
- public void setMax(Binding binding, Object v) throws HistoryException\r
- {\r
- maxField.setValue(binding, v);\r
- }\r
- \r
- \r
- /// Count ///\r
- public boolean hasCount() {\r
- return countField.isEnabled();\r
- }\r
- \r
- public NumberBinding getCountBinding() {\r
- return (NumberBinding) countField.binding;\r
- }\r
- \r
- public int getCount() throws HistoryException {\r
- Integer i = (Integer) countField.getValue( Bindings.INTEGER );\r
- return i == null ? 0 : i;\r
- }\r
-\r
- public Object getCount(Binding b) throws HistoryException {\r
- return countField.getValue(b);\r
- }\r
- \r
- public void setCount(int v) throws HistoryException {\r
- countField.setValue(Bindings.INTEGER, v);\r
- } \r
-\r
- /// Quality ///\r
- public boolean hasQuality() {\r
- return qualityField.isEnabled();\r
- }\r
- \r
- public Binding getQualityBinding() {\r
- return qualityField.binding;\r
- }\r
- \r
- public Object getQuality() throws HistoryException {\r
- return qualityField.getValue();\r
- }\r
-\r
- public Object getQuality(Binding b) throws HistoryException {\r
- return qualityField.getValue(b);\r
- }\r
- \r
- public void setQuality(Object v) throws HistoryException {\r
- qualityField.setValue(v);\r
- } \r
-\r
- public void setQuality(Binding binding, Object v) throws HistoryException\r
- {\r
- qualityField.setValue(binding, v);\r
- }\r
- \r
- \r
- /**\r
- * Value band is a region of one or more samples.\r
- * This method returns true, if value band is expressed with a single sample.\r
- * \r
- * If value band is expressed with two samples, there is start and end\r
- * sample. The format is typicaly simple (time, value). \r
- * \r
- * @return true if it can represent more than one sample\r
- */\r
- public boolean isRanged()\r
- {\r
- return endTimeField.isEnabled();\r
- }\r
- \r
- public boolean isValidValue() throws HistoryException {\r
- return !isNanSample() && !isNullValue();\r
- }\r
-\r
- /**\r
- * Return true, if this sample \r
- * \r
- * @return true if the value is Not-a-number\r
- */\r
- public boolean isNanSample() {\r
- try {\r
- if (valueField.binding instanceof DoubleBinding) {\r
- DoubleBinding db = (DoubleBinding) valueField.binding;\r
- double d = db.getValue_( binding.getComponent(sample, valueField.index) );\r
- return Double.isNaN( d );\r
- }\r
- if (valueField.binding instanceof FloatBinding) {\r
- FloatBinding db = (FloatBinding) valueField.binding;\r
- float d = db.getValue_( binding.getComponent(sample, valueField.index) );\r
- return Float.isNaN( d );\r
- }\r
- return false;\r
- } catch (BindingException e) {\r
- return false;\r
- }\r
- }\r
- \r
- /**\r
- * Returns true, if this sample format supports a way to express \r
- * discontinuation regions. \r
- * \r
- * @return true if can support discontinuation\r
- */\r
- public boolean supportsNullValue() {\r
- return qualityField.isEnabled();\r
- }\r
- \r
- /**\r
- * Marks this sample as discontinuation sample\r
- * @throws HistoryException \r
- */\r
- public void setValueNull() throws HistoryException {\r
- qualityField.setValue(Bindings.BYTE, QUALITY_NOVALUE);\r
- }\r
- \r
- /**\r
- * Returns true, if the sample is discontinuation sample\r
- * \r
- * @return true, if the sample is discontinuation sample\r
- * @throws HistoryException \r
- */\r
- public boolean isNullValue() throws HistoryException {\r
- Byte b = (Byte) qualityField.getValue(Bindings.BYTE);\r
- return b == null ? false : b.equals( QUALITY_NOVALUE );\r
- }\r
- \r
- public boolean isNumericValue() {\r
- return valueField.isNumeric();\r
- }\r
- \r
- @Override\r
- public String toString() {\r
- try {\r
- return binding.toString(sample);\r
- } catch (BindingException e) {\r
- return e.toString();\r
- }\r
- }\r
- \r
- class FieldAdapter {\r
- /** Binding of the field, with possible optionalbinding stripped */\r
- Binding binding;\r
- \r
- /// Adapter1 is cached adapter for setValue \r
- Binding adapter1binding;\r
- Adapter adapter1;\r
- \r
- /// Adapter2 is cached adapter for getValue\r
- Binding adapter2binding;\r
- Adapter adapter2;\r
- \r
- /** Field index in sample record */\r
- int index;\r
- \r
- /** Field name */\r
- String fieldName;\r
- \r
- public FieldAdapter(String fieldName) {\r
- this.fieldName = fieldName;\r
- index = ValueBand.this.binding.type().getComponentIndex2( fieldName );\r
- if (index<0) return;\r
- \r
- this.binding = ValueBand.this.binding.getComponentBinding(index);\r
- }\r
- \r
- public boolean getBooleanValue() throws HistoryException {\r
- if (sample == null || index==-1) return false;\r
- try {\r
- Object value = ValueBand.this.binding.getComponent(sample, index);\r
- if (binding instanceof BooleanBinding) {\r
- return ValueBand.this.binding.getBoolean(sample, index);\r
-// BooleanBinding bb = (BooleanBinding) binding;\r
-// return bb.getValue_( value );\r
- }\r
- if (binding instanceof ByteBinding) {\r
- ByteBinding nb = (ByteBinding) binding;\r
- return nb.getValue_( value ) != 0;\r
- }\r
- if (binding instanceof DoubleBinding) {\r
- DoubleBinding nb = (DoubleBinding) binding;\r
- return nb.getValue_( value ) != 0.;\r
- }\r
- if (binding instanceof NumberBinding) {\r
- NumberBinding nb = (NumberBinding) binding;\r
- return nb.getValue( value ).doubleValue() != 0.;\r
- }\r
- return false;\r
- } catch (BindingException e) {\r
- throw new HistoryException( e );\r
- } \r
- }\r
-\r
- public double getDoubleValue() throws HistoryException {\r
- if (sample == null || index==-1) return Double.NaN;\r
- try {\r
- // Read field from record\r
- if (binding != Bindings.DOUBLE) {\r
- Object result = ValueBand.this.binding.getComponent(sample, index);\r
- result = Bindings.adapt(result, binding, Bindings.DOUBLE);\r
- return (Double) result;\r
- } else {\r
- return ValueBand.this.binding.getDouble(sample, index);\r
- }\r
- } catch (BindingException e) {\r
- throw new HistoryException( e );\r
- } catch (AdaptException e) {\r
- throw new HistoryException( e );\r
- } \r
- }\r
-\r
- public boolean isEnabled() {\r
- return index>=0;\r
- }\r
- \r
- /**\r
- * Get the value\r
- * \r
- * @return value or null, if value is not available\r
- * @throws HistoryException\r
- */\r
- public Object getValue() throws HistoryException {\r
- if (sample == null || index==-1) return null;\r
- try {\r
- // Read field from record\r
- Object result = ValueBand.this.binding.getComponent(sample, index);\r
-\r
- return result;\r
- } catch (BindingException e) {\r
- throw new HistoryException( e );\r
- }\r
- }\r
-\r
- /**\r
- * Get the value\r
- * @param binding\r
- * @return value in given binding or null, if value is not available\r
- * @throws HistoryException\r
- */\r
- public Object getValue(Binding binding) throws HistoryException {\r
- if (sample == null || index==-1) return null;\r
- try {\r
- // Read field from record\r
- Object result = ValueBand.this.binding.getComponent(sample, index);\r
- \r
- // Adapt value\r
- if ( binding != this.binding ) {\r
- if ( binding != adapter2binding ) {\r
- adapter2 = Bindings.adapterFactory.getAdapter(this.binding, binding, true, false);\r
- adapter2binding = binding;\r
- }\r
- result = adapter2.adapt( result );\r
- }\r
-\r
- return result;\r
- } catch (BindingException e) {\r
- throw new HistoryException( e );\r
- } catch (AdaptException e) {\r
- throw new HistoryException( e );\r
- } catch (AdapterConstructionException e) {\r
- throw new HistoryException( e );\r
- }\r
- }\r
- \r
- public void setValue(Object object) throws HistoryException {\r
- if (sample == null || index==-1) return;\r
- setValue(binding, object);\r
- } \r
- \r
- public void setValue(Binding binding, Object object) throws HistoryException {\r
- if (sample == null || index==-1) return;\r
- \r
- try {\r
- // Adapt value \r
- if (this.binding != binding) { \r
- // Create new adapter\r
- if (binding != adapter1binding) {\r
- adapter1 = Bindings.adapterFactory.getAdapter(binding, this.binding, true, !binding.isImmutable()); \r
- adapter1binding = binding;\r
- }\r
- \r
- // Adapt\r
- object = adapter1.adapt(object); \r
- }\r
- \r
- // Write value\r
- ValueBand.this.binding.setComponent(sample, index, object);\r
- \r
- } catch (AdaptException e) {\r
- throw new HistoryException( e ); \r
- } catch (BindingException e) {\r
- throw new HistoryException( e ); \r
- } catch (AdapterConstructionException e) {\r
- throw new HistoryException( e ); \r
- }\r
- } \r
- \r
- public boolean isNumeric() {\r
- return binding instanceof NumberBinding;\r
- } \r
- \r
- }\r
- \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 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.history.util;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.adapter.AdaptException;
+import org.simantics.databoard.adapter.Adapter;
+import org.simantics.databoard.adapter.AdapterConstructionException;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.BooleanBinding;
+import org.simantics.databoard.binding.ByteBinding;
+import org.simantics.databoard.binding.DoubleBinding;
+import org.simantics.databoard.binding.FloatBinding;
+import org.simantics.databoard.binding.NumberBinding;
+import org.simantics.databoard.binding.RecordBinding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.databoard.binding.error.RuntimeBindingException;
+import org.simantics.databoard.type.RecordType;
+import org.simantics.history.HistoryException;
+
+/**
+ * Value band is an utility class intended for reading and writing to samples.
+ * There are many different formats of samples, their fields, order and datatypes vary.
+ *
+ * @author toni.kalajainen
+ */
+public class ValueBand {
+
+ public static final Byte QUALITY_GOOD = Byte.valueOf( (byte) 0 );
+ public static final Byte QUALITY_NOVALUE = Byte.valueOf( (byte) -1 );
+
+ protected RecordBinding binding;
+ protected RecordType type;
+ protected Object sample;
+
+ /** Field value cloners */
+ FieldAdapter timeField, endTimeField, valueField, lastValueField, avgField, medianField, minField, maxField, countField, qualityField;
+ /** Default value*/
+ Object defaultValue;
+
+ public ValueBand(Binding sampleBinding)
+ {
+ if ( sampleBinding instanceof RecordBinding == false ) {
+ throw new IllegalArgumentException();
+ }
+
+ this.binding = (RecordBinding) sampleBinding;
+ type = this.binding.type();
+
+ timeField = new FieldAdapter("time");
+ endTimeField = new FieldAdapter("endTime");
+ valueField = new FieldAdapter("value");
+ lastValueField = new FieldAdapter("lastValue");
+ avgField = new FieldAdapter("avg");
+ medianField = new FieldAdapter("median");
+ minField = new FieldAdapter("min");
+ maxField = new FieldAdapter("max");
+ countField = new FieldAdapter("count");
+ qualityField = new FieldAdapter("quality");
+
+ try {
+ defaultValue = binding.createDefault();
+ } catch (BindingException e) {
+ throw new RuntimeBindingException( e );
+ }
+ }
+
+ public ValueBand(Binding sampleBinding, Object sample)
+ {
+ this( sampleBinding );
+ this.sample = sample;
+ }
+
+
+ public void reset()
+ {
+ try {
+ binding.readFrom(binding, defaultValue, sample);
+ } catch (BindingException e) {
+ throw new RuntimeBindingException( e );
+ }
+ }
+
+ public Binding getBinding()
+ {
+ return binding;
+ }
+
+ /**
+ * Get the internal sample instance
+ *
+ * @return the internal sample instance
+ */
+ public Object getSample() {
+ return sample;
+ }
+
+ /**
+ * Change the internal sample instance
+ *
+ * @param sample
+ */
+ public void setSample(Object sample) {
+ this.sample = sample;
+ }
+
+ /**
+ * Write to the internal sample instance
+ *
+ * @param sample
+ */
+ public void writeSample(Object sample) {
+ try {
+ binding.readFrom(binding, sample, this.sample);
+ } catch (BindingException e) {
+ throw new RuntimeBindingException(e);
+ }
+ }
+
+ /**
+ * Write to the internal sample instance
+ *
+ * @param binding
+ * @param sample
+ */
+ public void writeSample(Binding binding, Object sample) {
+ try {
+ binding.readFrom(binding, sample, this.sample);
+ } catch (BindingException e) {
+ throw new RuntimeBindingException(e);
+ }
+ }
+
+
+ /// Time ///
+ public boolean hasTime() {
+ return timeField.isEnabled();
+ }
+
+ public Binding getTimeBinding() {
+ return timeField.binding;
+ }
+
+ public Object getTime() throws HistoryException {
+ return timeField.getValue();
+ }
+
+ public Object getTime(Binding b) throws HistoryException {
+ return timeField.getValue(b);
+ }
+
+ public double getTimeDouble() throws HistoryException {
+ return timeField.getDoubleValue();
+ }
+
+ public void setTime(Object v) throws HistoryException {
+ timeField.setValue(v);
+ }
+
+ public void setTime(Binding binding, Object v) throws HistoryException
+ {
+ timeField.setValue(binding, v);
+ }
+
+ /// EndTime ///
+ public boolean hasEndTime() {
+ return endTimeField.isEnabled();
+ }
+
+ public Binding getEndTimeBinding() {
+ return endTimeField.binding;
+ }
+
+ public Object getEndTime() throws HistoryException {
+ return endTimeField.getValue();
+ }
+
+ public Object getEndTime(Binding b) throws HistoryException {
+ return endTimeField.getValue(b);
+ }
+
+ public double getEndTimeDouble() throws HistoryException {
+ return endTimeField.getDoubleValue();
+ }
+
+
+ public void setEndTime(Object v) throws HistoryException {
+ endTimeField.setValue(v);
+ }
+
+ public void setEndTime(Binding binding, Object v) throws HistoryException
+ {
+ endTimeField.setValue(binding, v);
+ }
+
+ /// Value ///
+ public boolean hasValue() {
+ return valueField.isEnabled();
+ }
+
+ public Binding getValueBinding() {
+ return valueField.binding;
+ }
+
+ public Object getValue() throws HistoryException {
+ return valueField.getValue();
+ }
+
+ public Object getValue(Binding b) throws HistoryException {
+ return valueField.getValue(b);
+ }
+
+ public double getValueDouble() throws HistoryException {
+ return valueField.getDoubleValue();
+ }
+
+ public Object getPossibleValue() throws HistoryException {
+ if ( isNullValue() ) return null;
+ return valueField.getValue();
+ }
+
+ public Object getPossibleValue(Binding b) throws HistoryException {
+ if ( isNullValue() ) return null;
+ return valueField.getValue(b);
+ }
+
+ public Double getPossibleValueDouble() throws HistoryException {
+ if ( isNullValue() ) return null;
+ return valueField.getDoubleValue();
+ }
+
+
+ public boolean getValueBoolean() throws HistoryException {
+ return valueField.getBooleanValue();
+ }
+
+ public void setValue(Object v) throws HistoryException {
+ valueField.setValue(v);
+ }
+
+ public void setValue(Binding binding, Object v) throws HistoryException
+ {
+ valueField.setValue(binding, v);
+ }
+
+ /// LastValue ///
+ public boolean hasLastValue() {
+ return lastValueField.isEnabled();
+ }
+
+ public Binding getLastValueBinding() {
+ return lastValueField.binding;
+ }
+
+ public Object getLastValue() throws HistoryException {
+ return lastValueField.getValue();
+ }
+
+ public Object getLastValue(Binding b) throws HistoryException {
+ return lastValueField.getValue(b);
+ }
+
+ public void setLastValue(Object v) throws HistoryException {
+ lastValueField.setValue(v);
+ }
+
+ public void setLastValue(Binding binding, Object v) throws HistoryException {
+ lastValueField.setValue(binding, v);
+ }
+
+ /// Avg ///
+ public boolean hasAvg() {
+ return avgField.isEnabled();
+ }
+
+ public Binding getAvgBinding() {
+ return avgField.binding;
+ }
+
+ public Object getAvg() throws HistoryException {
+ return avgField.getValue();
+ }
+
+ public Object getAvg(Binding b) throws HistoryException {
+ return avgField.getValue(b);
+ }
+
+ public double getAvgDouble() throws HistoryException {
+ return avgField.getDoubleValue();
+ }
+
+ public void setAvg(Object v) throws HistoryException {
+ avgField.setValue(v);
+ }
+
+ public void setAvg(Binding binding, Object v) throws HistoryException
+ {
+ avgField.setValue(binding, v);
+ }
+
+ /// Median ///
+ public boolean hasMedian() {
+ return medianField.isEnabled();
+ }
+
+ public Binding getMedianBinding() {
+ return medianField.binding;
+ }
+
+ public Object getMedian() throws HistoryException {
+ return medianField.getValue();
+ }
+
+ public Object getMedian(Binding b) throws HistoryException {
+ return medianField.getValue(b);
+ }
+
+ public double getMedianDouble() throws HistoryException {
+ return medianField.getDoubleValue();
+ }
+
+ public void setMedian(Object v) throws HistoryException {
+ medianField.setValue(v);
+ }
+
+ public void setMedian(Binding binding, Object v) throws HistoryException
+ {
+ medianField.setValue(binding, v);
+ }
+
+ /// Min ///
+ public boolean hasMin() {
+ return minField.isEnabled();
+ }
+
+ public Binding getMinBinding() {
+ return minField.binding;
+ }
+
+ public Object getMin() throws HistoryException {
+ return minField.getValue();
+ }
+
+ public Object getMin(Binding b) throws HistoryException {
+ return minField.getValue(b);
+ }
+
+ public double getMinDouble() throws HistoryException {
+ return minField.getDoubleValue();
+ }
+
+ public void setMin(Object v) throws HistoryException {
+ minField.setValue(v);
+ }
+
+ public void setMin(Binding binding, Object v) throws HistoryException
+ {
+ minField.setValue(binding, v);
+ }
+
+ /// Max ///
+ public boolean hasMax() {
+ return maxField.isEnabled();
+ }
+
+ public Binding getMaxBinding() {
+ return maxField.binding;
+ }
+
+ public Object getMax() throws HistoryException {
+ return maxField.getValue();
+ }
+
+ public Object getMax(Binding b) throws HistoryException {
+ return maxField.getValue(b);
+ }
+
+ public double getMaxDouble() throws HistoryException {
+ return maxField.getDoubleValue();
+ }
+
+ public void setMax(Object v) throws HistoryException {
+ maxField.setValue(v);
+ }
+
+ public void setMax(Binding binding, Object v) throws HistoryException
+ {
+ maxField.setValue(binding, v);
+ }
+
+
+ /// Count ///
+ public boolean hasCount() {
+ return countField.isEnabled();
+ }
+
+ public NumberBinding getCountBinding() {
+ return (NumberBinding) countField.binding;
+ }
+
+ public int getCount() throws HistoryException {
+ Integer i = (Integer) countField.getValue( Bindings.INTEGER );
+ return i == null ? 0 : i;
+ }
+
+ public Object getCount(Binding b) throws HistoryException {
+ return countField.getValue(b);
+ }
+
+ public void setCount(int v) throws HistoryException {
+ countField.setValue(Bindings.INTEGER, v);
+ }
+
+ /// Quality ///
+ public boolean hasQuality() {
+ return qualityField.isEnabled();
+ }
+
+ public Binding getQualityBinding() {
+ return qualityField.binding;
+ }
+
+ public Object getQuality() throws HistoryException {
+ return qualityField.getValue();
+ }
+
+ public Object getQuality(Binding b) throws HistoryException {
+ return qualityField.getValue(b);
+ }
+
+ public void setQuality(Object v) throws HistoryException {
+ qualityField.setValue(v);
+ }
+
+ public void setQuality(Binding binding, Object v) throws HistoryException
+ {
+ qualityField.setValue(binding, v);
+ }
+
+
+ /**
+ * Value band is a region of one or more samples.
+ * This method returns true, if value band is expressed with a single sample.
+ *
+ * If value band is expressed with two samples, there is start and end
+ * sample. The format is typicaly simple (time, value).
+ *
+ * @return true if it can represent more than one sample
+ */
+ public boolean isRanged()
+ {
+ return endTimeField.isEnabled();
+ }
+
+ public boolean isValidValue() throws HistoryException {
+ return !isNanSample() && !isNullValue();
+ }
+
+ /**
+ * Return true, if this sample
+ *
+ * @return true if the value is Not-a-number
+ */
+ public boolean isNanSample() {
+ try {
+ if (valueField.binding instanceof DoubleBinding) {
+ DoubleBinding db = (DoubleBinding) valueField.binding;
+ double d = db.getValue_( binding.getComponent(sample, valueField.index) );
+ return Double.isNaN( d );
+ }
+ if (valueField.binding instanceof FloatBinding) {
+ FloatBinding db = (FloatBinding) valueField.binding;
+ float d = db.getValue_( binding.getComponent(sample, valueField.index) );
+ return Float.isNaN( d );
+ }
+ return false;
+ } catch (BindingException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true, if this sample format supports a way to express
+ * discontinuation regions.
+ *
+ * @return true if can support discontinuation
+ */
+ public boolean supportsNullValue() {
+ return qualityField.isEnabled();
+ }
+
+ /**
+ * Marks this sample as discontinuation sample
+ * @throws HistoryException
+ */
+ public void setValueNull() throws HistoryException {
+ qualityField.setValue(Bindings.BYTE, QUALITY_NOVALUE);
+ }
+
+ /**
+ * Returns true, if the sample is discontinuation sample
+ *
+ * @return true, if the sample is discontinuation sample
+ * @throws HistoryException
+ */
+ public boolean isNullValue() throws HistoryException {
+ Byte b = (Byte) qualityField.getValue(Bindings.BYTE);
+ return b == null ? false : b.equals( QUALITY_NOVALUE );
+ }
+
+ public boolean isNumericValue() {
+ return valueField.isNumeric();
+ }
+
+ @Override
+ public String toString() {
+ try {
+ return binding.toString(sample);
+ } catch (BindingException e) {
+ return e.toString();
+ }
+ }
+
+ class FieldAdapter {
+ /** Binding of the field, with possible optionalbinding stripped */
+ Binding binding;
+
+ /// Adapter1 is cached adapter for setValue
+ Binding adapter1binding;
+ Adapter adapter1;
+
+ /// Adapter2 is cached adapter for getValue
+ Binding adapter2binding;
+ Adapter adapter2;
+
+ /** Field index in sample record */
+ int index;
+
+ /** Field name */
+ String fieldName;
+
+ public FieldAdapter(String fieldName) {
+ this.fieldName = fieldName;
+ index = ValueBand.this.binding.type().getComponentIndex2( fieldName );
+ if (index<0) return;
+
+ this.binding = ValueBand.this.binding.getComponentBinding(index);
+ }
+
+ public boolean getBooleanValue() throws HistoryException {
+ if (sample == null || index==-1) return false;
+ try {
+ Object value = ValueBand.this.binding.getComponent(sample, index);
+ if (binding instanceof BooleanBinding) {
+ return ValueBand.this.binding.getBoolean(sample, index);
+// BooleanBinding bb = (BooleanBinding) binding;
+// return bb.getValue_( value );
+ }
+ if (binding instanceof ByteBinding) {
+ ByteBinding nb = (ByteBinding) binding;
+ return nb.getValue_( value ) != 0;
+ }
+ if (binding instanceof DoubleBinding) {
+ DoubleBinding nb = (DoubleBinding) binding;
+ return nb.getValue_( value ) != 0.;
+ }
+ if (binding instanceof NumberBinding) {
+ NumberBinding nb = (NumberBinding) binding;
+ return nb.getValue( value ).doubleValue() != 0.;
+ }
+ return false;
+ } catch (BindingException e) {
+ throw new HistoryException( e );
+ }
+ }
+
+ public double getDoubleValue() throws HistoryException {
+ if (sample == null || index==-1) return Double.NaN;
+ try {
+ // Read field from record
+ if (binding != Bindings.DOUBLE) {
+ Object result = ValueBand.this.binding.getComponent(sample, index);
+ result = Bindings.adapt(result, binding, Bindings.DOUBLE);
+ return (Double) result;
+ } else {
+ return ValueBand.this.binding.getDouble(sample, index);
+ }
+ } catch (BindingException e) {
+ throw new HistoryException( e );
+ } catch (AdaptException e) {
+ throw new HistoryException( e );
+ }
+ }
+
+ public boolean isEnabled() {
+ return index>=0;
+ }
+
+ /**
+ * Get the value
+ *
+ * @return value or null, if value is not available
+ * @throws HistoryException
+ */
+ public Object getValue() throws HistoryException {
+ if (sample == null || index==-1) return null;
+ try {
+ // Read field from record
+ Object result = ValueBand.this.binding.getComponent(sample, index);
+
+ return result;
+ } catch (BindingException e) {
+ throw new HistoryException( e );
+ }
+ }
+
+ /**
+ * Get the value
+ * @param binding
+ * @return value in given binding or null, if value is not available
+ * @throws HistoryException
+ */
+ public Object getValue(Binding binding) throws HistoryException {
+ if (sample == null || index==-1) return null;
+ try {
+ // Read field from record
+ Object result = ValueBand.this.binding.getComponent(sample, index);
+
+ // Adapt value
+ if ( binding != this.binding ) {
+ if ( binding != adapter2binding ) {
+ adapter2 = Bindings.adapterFactory.getAdapter(this.binding, binding, true, false);
+ adapter2binding = binding;
+ }
+ result = adapter2.adapt( result );
+ }
+
+ return result;
+ } catch (BindingException e) {
+ throw new HistoryException( e );
+ } catch (AdaptException e) {
+ throw new HistoryException( e );
+ } catch (AdapterConstructionException e) {
+ throw new HistoryException( e );
+ }
+ }
+
+ public void setValue(Object object) throws HistoryException {
+ if (sample == null || index==-1) return;
+ setValue(binding, object);
+ }
+
+ public void setValue(Binding binding, Object object) throws HistoryException {
+ if (sample == null || index==-1) return;
+
+ try {
+ // Adapt value
+ if (this.binding != binding) {
+ // Create new adapter
+ if (binding != adapter1binding) {
+ adapter1 = Bindings.adapterFactory.getAdapter(binding, this.binding, true, !binding.isImmutable());
+ adapter1binding = binding;
+ }
+
+ // Adapt
+ object = adapter1.adapt(object);
+ }
+
+ // Write value
+ ValueBand.this.binding.setComponent(sample, index, object);
+
+ } catch (AdaptException e) {
+ throw new HistoryException( e );
+ } catch (BindingException e) {
+ throw new HistoryException( e );
+ } catch (AdapterConstructionException e) {
+ throw new HistoryException( e );
+ }
+ }
+
+ public boolean isNumeric() {
+ return binding instanceof NumberBinding;
+ }
+
+ }
+
+}