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.TelemetryStreamCollection; 006 007 /** 008 * If passed two numbers, returns their product, and if passed two telemetry streams, returns a 009 * new TelemetryStreamCollection containing the pairwise multiplication of the individual elements. 010 * 011 * @author (Cedric) Qin ZHANG, Philip Johnson 012 */ 013 public class MulFunction extends TelemetryFunction { 014 015 /** Thread-safe mul operator. */ 016 private MulOperator mulOperator = new MulOperator(); 017 018 /** 019 * Constructs this instance. 020 */ 021 public MulFunction() { 022 super("mul"); 023 } 024 025 /** 026 * @param parameters An array of 2 objects of type either <code>Number</code> 027 * or <code>TelemetryStreamCollection</code>. 028 * 029 * @return Either an instance of <code>Number</code> or <code>TelemetryStreamCollection</code>. 030 * @throws TelemetryFunctionException If anything is wrong. 031 */ 032 @Override 033 public Object compute(Object[] parameters) throws TelemetryFunctionException { 034 //parameter validity check 035 if (parameters.length != 2 036 || ! (parameters[0] instanceof Number || parameters[0] instanceof TelemetryStreamCollection) 037 || ! (parameters[1] instanceof Number || parameters[1] instanceof TelemetryStreamCollection) 038 ) { 039 throw new TelemetryFunctionException("Telemetry function " + this.getName() 040 + " takes 2 parameters of type 'Number' and/or 'TelemetryStreamCollection'."); 041 } 042 043 if (parameters[0] instanceof Number && parameters[1] instanceof Number) { 044 return this.mulOperator.computes((Number) parameters[0], (Number) parameters[1]); 045 } 046 else { 047 TelemetryStreamCollection tsc0 = (parameters[0] instanceof Number) 048 ? Utility.expandNumber((Number) parameters[0], (TelemetryStreamCollection) parameters[1]) 049 : (TelemetryStreamCollection) parameters[0]; 050 TelemetryStreamCollection tsc1 = (parameters[1] instanceof Number) 051 ? Utility.expandNumber((Number) parameters[1], (TelemetryStreamCollection) parameters[0]) 052 : (TelemetryStreamCollection) parameters[1]; 053 return BinaryOperationUtility.computes(this.mulOperator, tsc0, tsc1); 054 } 055 } 056 057 /** 058 * Binary operator used by the enclosing class. 059 * 060 * @author (Cedric) Qin ZHANG 061 */ 062 private static class MulOperator implements BinaryOperationUtility.BinaryOperator { 063 /** 064 * Performs binary operation. 065 * @param a Number 1. 066 * @param b Number 2. 067 * @return The result. 068 */ 069 public Number computes(Number a, Number b) { 070 if (a instanceof Integer && b instanceof Integer) { 071 return Integer.valueOf(a.intValue() * b.intValue()); 072 } 073 else { 074 return Double.valueOf(a.doubleValue() * b.doubleValue()); 075 } 076 } 077 } 078 }