001    package org.hackystat.telemetry.analyzer.function.impl;
002    
003    import org.hackystat.telemetry.analyzer.function.TelemetryFunction;
004    import org.hackystat.telemetry.analyzer.function.TelemetryFunctionException;
005    import org.hackystat.telemetry.analyzer.model.TelemetryDataModelException;
006    import org.hackystat.telemetry.analyzer.model.TelemetryDataPoint;
007    import org.hackystat.telemetry.analyzer.model.TelemetryStream;
008    import org.hackystat.telemetry.analyzer.model.TelemetryStreamCollection;
009    
010    /**
011     * Filters out telemetry streams with zero values or no value in a 
012     * <code>TelemetryStreamCollection</code> object. 
013     * 
014     * @author (Cedric) Qin ZHANG
015     */
016    public class FilterZeroFunction extends TelemetryFunction {
017    
018      /**
019       * Constructs this instance.
020       */
021      public FilterZeroFunction() {
022        super("FilterZero");
023      }
024      
025     /**
026      * Performs filter operation.
027      * @param parameters An array of 1 objects of <code>TelemetryStreamCollection</code> type.
028      * @return A new <code>TelemetryStreamCollection</code> instance after filtering.
029      * @throws TelemetryFunctionException If anything is wrong.
030      */
031      @Override
032      public Object compute(Object[] parameters) throws TelemetryFunctionException {
033        if (parameters.length != 1 || ! (parameters[0] instanceof TelemetryStreamCollection)) { //NOPMD
034          throw new TelemetryFunctionException("Telemetry function " + this.getName()
035              + " takes 1 TelemetryStreamCollection object.");
036        }
037        else {
038          try {
039            TelemetryStreamCollection source = (TelemetryStreamCollection) parameters[0];
040            TelemetryStreamCollection target = new TelemetryStreamCollection(
041                source.getName(), source.getProject(), source.getInterval());
042            for (TelemetryStream stream : source.getTelemetryStreams()) {
043              if (! this.isAllZero(stream)) {
044                target.add(stream);
045              }
046            }
047            return target;
048          }
049          catch (TelemetryDataModelException ex) {
050            throw new TelemetryFunctionException(ex);
051          }
052        }
053      }
054      
055      /**
056       * Checks whether a telemetry stream contains all zeros or no value at all.
057       * 
058       * @param stream The telemetry stream to be checked.
059       * @return True if it contains all zero or no value.
060       */
061      private boolean isAllZero(TelemetryStream stream) {
062        for (TelemetryDataPoint dp : stream.getDataPoints()) {
063          Number value = dp.getValue();
064          if (value != null) {
065            if ((value instanceof Double || value instanceof Float)
066                && value.doubleValue() != 0.0) {
067              return false;
068            }
069            else if (value.longValue() != 0L) {
070              return false;
071            }
072          }
073        }
074        return true;
075      }
076      
077    }