]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.history/src/org/simantics/history/util/ValueBand.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / util / ValueBand.java
index 3189e8af44cbcb056d4e9f9856a84d4395478418..ce2f392c8ec8055e0de6a0cf1304b8cbe4099aed 100644 (file)
-/*******************************************************************************\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;
+               }       
+       
+       }
+       
+}