EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.simucomframework.variables.stoexvisitor]

COVERAGE SUMMARY FOR SOURCE FILE [PCMStoExEvaluationVisitor.java]

nameclass, %method, %block, %line, %
PCMStoExEvaluationVisitor.java0%   (0/1)0%   (0/26)0%   (0/1007)0%   (0/164)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class PCMStoExEvaluationVisitor0%   (0/1)0%   (0/26)0%   (0/1007)0%   (0/164)
$SWITCH_TABLE$de$uka$ipd$sdq$stoex$BooleanOperations (): int [] 0%   (0/1)0%   (0/34)0%   (0/1)
$SWITCH_TABLE$de$uka$ipd$sdq$stoex$CompareOperations (): int [] 0%   (0/1)0%   (0/55)0%   (0/1)
$SWITCH_TABLE$de$uka$ipd$sdq$stoex$ProductOperations (): int [] 0%   (0/1)0%   (0/34)0%   (0/1)
$SWITCH_TABLE$de$uka$ipd$sdq$stoex$TermOperations (): int [] 0%   (0/1)0%   (0/27)0%   (0/1)
<static initializer> 0%   (0/1)0%   (0/9)0%   (0/4)
PCMStoExEvaluationVisitor (StoExCacheEntry, SimulatedStackframe, VariableMode... 0%   (0/1)0%   (0/28)0%   (0/7)
caseBoolLiteral (BoolLiteral): Object 0%   (0/1)0%   (0/4)0%   (0/1)
caseBooleanOperatorExpression (BooleanOperatorExpression): Object 0%   (0/1)0%   (0/50)0%   (0/7)
caseCharacterisedVariable (CharacterisedVariable): Object 0%   (0/1)0%   (0/147)0%   (0/30)
caseCompareExpression (CompareExpression): Object 0%   (0/1)0%   (0/148)0%   (0/21)
caseDoubleLiteral (DoubleLiteral): Object 0%   (0/1)0%   (0/4)0%   (0/1)
caseFunctionLiteral (FunctionLiteral): Object 0%   (0/1)0%   (0/31)0%   (0/5)
caseIfElseExpression (IfElseExpression): Object 0%   (0/1)0%   (0/19)0%   (0/4)
caseIntLiteral (IntLiteral): Object 0%   (0/1)0%   (0/4)0%   (0/1)
caseNegativeExpression (NegativeExpression): Object 0%   (0/1)0%   (0/28)0%   (0/6)
caseNotExpression (NotExpression): Object 0%   (0/1)0%   (0/14)0%   (0/2)
caseParenthesis (Parenthesis): Object 0%   (0/1)0%   (0/5)0%   (0/1)
casePowerExpression (PowerExpression): Object 0%   (0/1)0%   (0/63)0%   (0/11)
caseProbabilityFunctionLiteral (ProbabilityFunctionLiteral): Object 0%   (0/1)0%   (0/6)0%   (0/1)
caseProductExpression (ProductExpression): Object 0%   (0/1)0%   (0/121)0%   (0/23)
caseStringLiteral (StringLiteral): Object 0%   (0/1)0%   (0/3)0%   (0/1)
caseTermExpression (TermExpression): Object 0%   (0/1)0%   (0/111)0%   (0/21)
getDouble (Object): double 0%   (0/1)0%   (0/30)0%   (0/5)
getDynamicType (Object): TypeEnum 0%   (0/1)0%   (0/25)0%   (0/9)
getVariableMode (): VariableMode 0%   (0/1)0%   (0/3)0%   (0/1)
setVariableMode (VariableMode): void 0%   (0/1)0%   (0/4)0%   (0/2)

1package de.uka.ipd.sdq.simucomframework.variables.stoexvisitor;
2 
3import java.util.ArrayList;
4import java.util.Map.Entry;
5 
6import org.apache.log4j.Logger;
7 
8import de.uka.ipd.sdq.pcm.parameter.CharacterisedVariable;
9import de.uka.ipd.sdq.pcm.stochasticexpressions.PCMStoExPrettyPrintVisitor;
10import de.uka.ipd.sdq.pcm.stochasticexpressions.PCMStoExSwitch;
11 
12import de.uka.ipd.sdq.probfunction.math.IProbabilityFunctionFactory;
13 
14import de.uka.ipd.sdq.simucomframework.variables.EvaluationProxy;
15import de.uka.ipd.sdq.simucomframework.variables.StackContext;
16 
17import de.uka.ipd.sdq.simucomframework.variables.cache.StoExCacheEntry;
18import de.uka.ipd.sdq.simucomframework.variables.exceptions.TypesIncompatibleInComparisionException;
19import de.uka.ipd.sdq.simucomframework.variables.exceptions.TypesIncompatibleInProductException;
20import de.uka.ipd.sdq.simucomframework.variables.exceptions.TypesIncompatibleInTermException;
21import de.uka.ipd.sdq.simucomframework.variables.exceptions.ValueNotInFrameException;
22import de.uka.ipd.sdq.simucomframework.variables.functions.FunctionLib;
23import de.uka.ipd.sdq.simucomframework.variables.stackframe.SimulatedStackframe;
24import de.uka.ipd.sdq.stoex.BoolLiteral;
25import de.uka.ipd.sdq.stoex.BooleanOperatorExpression;
26import de.uka.ipd.sdq.stoex.CompareExpression;
27import de.uka.ipd.sdq.stoex.DoubleLiteral;
28import de.uka.ipd.sdq.stoex.Expression;
29import de.uka.ipd.sdq.stoex.FunctionLiteral;
30import de.uka.ipd.sdq.stoex.IfElseExpression;
31import de.uka.ipd.sdq.stoex.IntLiteral;
32import de.uka.ipd.sdq.stoex.NegativeExpression;
33import de.uka.ipd.sdq.stoex.NotExpression;
34import de.uka.ipd.sdq.stoex.Parenthesis;
35import de.uka.ipd.sdq.stoex.PowerExpression;
36import de.uka.ipd.sdq.stoex.ProbabilityFunctionLiteral;
37import de.uka.ipd.sdq.stoex.ProductExpression;
38import de.uka.ipd.sdq.stoex.StringLiteral;
39import de.uka.ipd.sdq.stoex.TermExpression;
40import de.uka.ipd.sdq.stoex.analyser.visitors.ExpressionInferTypeVisitor;
41import de.uka.ipd.sdq.stoex.analyser.visitors.TypeEnum;
42 
43 
44/**
45 * Visitor to evaluate stoex. It executes the corresponding Java mathematical 
46 * operations at each operator. It partially relies on the types infered
47 * to do its casts 
48 * @author Steffen Becker
49 *
50 */
51public class PCMStoExEvaluationVisitor extends PCMStoExSwitch {
52 
53        /**
54         * This class' logger
55         */
56        private static final Logger logger = 
57                Logger.getLogger(PCMStoExEvaluationVisitor.class.getName());
58 
59        /**
60         * Pretty printer. This class is stateless hence it is save to have just one object of it
61         */
62        private final static PCMStoExPrettyPrintVisitor printVisitor = new PCMStoExPrettyPrintVisitor();
63        
64        /**
65         * Subvisitor to evaluate probability functions inside the visited stoex
66         */
67        private final PCMProbfunctionEvaluationVisitor probfunctionVisitor;
68        
69        /**
70         * Stackframe against which variables will be evaluated
71         */
72        private final SimulatedStackframe<Object> myStackFrame;
73        
74        /**
75         * Type infer visitor which will be used to infer the stoex's type
76         */
77        private final ExpressionInferTypeVisitor typeInferer;
78                
79        /**
80         * Function lib contains functions like Exp, etc. This cannot be static as it depends on its respective
81         * random number generator
82         */
83        private final FunctionLib functionLib;
84        
85        /**
86         * Mode for evaluating variables. Determines when to throw Exceptions if some evaluation fails
87         */
88        private VariableMode mode;
89        
90        public PCMStoExEvaluationVisitor(StoExCacheEntry cacheEntry, SimulatedStackframe<Object> frame, VariableMode initialMode, IProbabilityFunctionFactory probFunctionFactory) {
91                this.typeInferer = cacheEntry.getTypeInferer();
92                myStackFrame = frame;
93                this.mode = initialMode;
94                probfunctionVisitor = new PCMProbfunctionEvaluationVisitor(cacheEntry);
95                functionLib = new FunctionLib(probFunctionFactory.getRandomGenerator(), probFunctionFactory.getPDFFactory());
96        }
97 
98        public void setVariableMode(VariableMode mode) {
99                this.mode = mode;
100        }
101        
102        public VariableMode getVariableMode() {
103                return this.mode;
104        }
105        
106        @Override
107        public Object caseCharacterisedVariable(CharacterisedVariable object) {
108                String variableID = (String)printVisitor.caseCharacterisedVariable(object);
109                try {
110                        Object value = this.myStackFrame.getValue(variableID); 
111                        if (value instanceof EvaluationProxy) {
112                                EvaluationProxy proxy = (EvaluationProxy)value;
113                                return StackContext.evaluateStatic(proxy.getStoEx(), proxy.getStackFrame());
114                        } else {
115                                return value;
116                        }
117                } catch (ValueNotInFrameException e) {
118                        if (mode == VariableMode.EXCEPTION_ON_NOT_FOUND) {
119                                logger.error("Value should be in stackframe, but it is not!",e);
120                                e.printStackTrace();
121                        }
122                }
123                if (mode == VariableMode.EXCEPTION_ON_NOT_FOUND) {
124                        String availableIDs = "";
125                        for (Entry<String, Object> e : this.myStackFrame.getContents()) {
126                                availableIDs += "<"+e.getKey()+"> ";
127                        }
128                        RuntimeException re = new RuntimeException("Architecture specification incomplete. Stackframe is missing id "+variableID+"\nAvailable IDs are "+availableIDs);
129                logger.error("Value not found in specification",re);
130                        throw re; 
131                } else if (mode == VariableMode.RETURN_NULL_ON_NOT_FOUND) {
132                        return null;
133                } else {
134                        if (typeInferer.getType(object) == TypeEnum.INT)
135                                return 0;
136                        if (typeInferer.getType(object) == TypeEnum.DOUBLE)
137                                return 0.0;
138                        if (typeInferer.getType(object) == TypeEnum.ENUM)
139                                return "";
140                        if (typeInferer.getType(object) == TypeEnum.BOOL)
141                                return false;
142                        RuntimeException re = new RuntimeException("Architecture specification incomplete. Stackframe is missing id "+variableID);
143                logger.error("Value not found in specification",re);
144                        throw re; 
145                }
146        }
147 
148        @SuppressWarnings("unchecked")
149        @Override
150        public Object caseCompareExpression(CompareExpression object) {
151                TypeEnum leftType = typeInferer.getType(object.getLeft());
152                TypeEnum rightType = typeInferer.getType(object.getRight());
153                Object leftExpr = doSwitch(object.getLeft());
154                Object rightExpr = doSwitch(object.getRight());
155                if (leftType == TypeEnum.ANY) leftType = getDynamicType(leftExpr);
156                if (rightType == TypeEnum.ANY) rightType = getDynamicType(rightExpr);
157                
158                if (leftType == TypeEnum.INT && rightType == TypeEnum.DOUBLE)
159                        leftExpr = Double.valueOf( (((Integer)leftExpr).intValue()));
160                if (rightType == TypeEnum.INT && leftType == TypeEnum.DOUBLE)
161                        rightExpr = Double.valueOf( (((Integer)rightExpr).intValue()));
162 
163                // If types still don't comply, give up!
164                if (leftExpr.getClass() != rightExpr.getClass()) {
165                        throw new TypesIncompatibleInComparisionException("Can not compare "+leftExpr.getClass().getName()+" to "+rightExpr.getClass().getName());
166                }
167                
168                int result = ((Comparable)leftExpr).compareTo(rightExpr);
169                switch(object.getOperation())
170                {
171                case EQUALS:
172                        return result == 0;
173                case LESS:
174                        return result < 0;
175                case LESSEQUAL:
176                        return result <= 0;
177                case GREATER:
178                        return result > 0;
179                case GREATEREQUAL:
180                        return result >= 0;
181                case NOTEQUAL:
182                        return result != 0;
183                }
184                throw new RuntimeException("Unknown Compare Operation found! Should not happen!");
185        }
186 
187        @Override
188        public Object caseDoubleLiteral(DoubleLiteral object) {
189                return object.getValue();
190        }
191 
192        @Override
193        public Object caseIntLiteral(IntLiteral object) {
194                return object.getValue();
195        }
196 
197        @Override
198        public Object caseStringLiteral(StringLiteral object) {
199                return object.getValue();
200        }
201 
202        @Override
203        public Object caseParenthesis(Parenthesis object) {
204                return doSwitch(object.getInnerExpression());
205        }
206 
207        @Override
208        public Object caseProbabilityFunctionLiteral(ProbabilityFunctionLiteral object) {
209                return probfunctionVisitor.doSwitch(object.getFunction_ProbabilityFunctionLiteral());
210        }
211 
212        @Override
213        public Object caseProductExpression(ProductExpression object) {
214                TypeEnum leftType = typeInferer.getType(object.getLeft());
215                TypeEnum rightType = typeInferer.getType(object.getRight());
216                Object left = doSwitch(object.getLeft());
217                Object right = doSwitch(object.getRight());
218                if (leftType == TypeEnum.ANY) leftType = getDynamicType(left);
219                if (rightType == TypeEnum.ANY) rightType = getDynamicType(right);
220                if (leftType == TypeEnum.INT &&        rightType == TypeEnum.INT) {
221                        if (!(left instanceof Integer) || !(right instanceof Integer)) {
222                                throw new TypesIncompatibleInProductException("Incompatible types in product expression. Expecting Integer!");
223                        }
224                        
225                        int leftInt = (Integer)left;
226                        int rightInt = (Integer)right;
227                        switch(object.getOperation())
228                        {
229                        case DIV:
230                                return leftInt / rightInt;
231                        case MULT:
232                                return leftInt * rightInt;
233                        case MOD:
234                                return leftInt % rightInt;
235                        }
236                        throw new RuntimeException("This should never happen!");
237                        
238                } else {
239                        double leftDouble = getDouble(left);
240                        double rightDouble = getDouble(right);
241                        switch(object.getOperation())
242                        {
243                        case DIV:
244                                return leftDouble / rightDouble;
245                        case MULT:
246                                return leftDouble * rightDouble;
247                        case MOD:
248                                return leftDouble % rightDouble;
249                        }
250                        throw new RuntimeException("This should never happen!");
251                }
252        }
253 
254        private double getDouble(Object o) {
255                if (o instanceof Double)
256                        return (Double)o;
257                if (o instanceof Integer)
258                        return (Integer)o;
259                throw new UnsupportedOperationException("Trying to cast a "+o.getClass().getCanonicalName()+" to a Double!");
260        }
261 
262        private TypeEnum getDynamicType(Object o) {
263                if (o instanceof Integer)
264                        return TypeEnum.INT;
265                if (o instanceof Double)
266                        return TypeEnum.DOUBLE;
267                if (o instanceof String)
268                        return TypeEnum.ENUM;
269                if (o instanceof Boolean)
270                        return TypeEnum.BOOL;
271                throw new RuntimeException("Unknown dynamic type found! Should never happen!");
272        }
273 
274        @Override
275        public Object caseTermExpression(TermExpression object) {
276                TypeEnum leftType = typeInferer.getType(object.getLeft());
277                TypeEnum rightType = typeInferer.getType(object.getRight());
278                Object left = doSwitch(object.getLeft());
279                Object right = doSwitch(object.getRight());
280                if (leftType == TypeEnum.ANY) leftType = getDynamicType(left);
281                if (rightType == TypeEnum.ANY) rightType = getDynamicType(right);
282                if (leftType == TypeEnum.INT &&        rightType == TypeEnum.INT) {
283                        if (!(left instanceof Integer) || !(right instanceof Integer)) {
284                                throw new TypesIncompatibleInTermException("Incompatible types in term expression. Expecting Integer!");
285                        }
286                        int leftInt = (Integer)left;
287                        int rightInt = (Integer)right;
288                        switch(object.getOperation())
289                        {
290                        case ADD:
291                                return leftInt + rightInt;
292                        case SUB:
293                                return leftInt - rightInt;
294                        }
295                        throw new RuntimeException("This should never happen!");
296                        
297                } else {
298                        double leftDouble = getDouble(left);
299                        double rightDouble = getDouble(right);
300                        switch(object.getOperation())
301                        {
302                        case ADD:
303                                return leftDouble + rightDouble;
304                        case SUB:
305                                return leftDouble - rightDouble;
306                        }
307                        throw new RuntimeException("This should never happen!");
308                }
309        }
310 
311        @Override
312        public Object caseBooleanOperatorExpression(BooleanOperatorExpression object) {
313                boolean b1 = (Boolean) this.doSwitch(object.getLeft());
314                boolean b2 = (Boolean) this.doSwitch(object.getRight());
315                switch(object.getOperation()) {
316                case OR:
317                        return b1 || b2;
318                case AND:
319                        return b1 && b2;
320                case XOR:
321                        return b1 ^ b2;
322                }
323                throw new RuntimeException("This should never happen!");
324        }
325 
326        @Override
327        public Object caseNegativeExpression(NegativeExpression object) {
328                Object value = this.doSwitch(object.getInner());
329                if (value instanceof Integer)
330                        return -((Integer)value);
331                if (value instanceof Double)
332                        return -((Double)value);
333                throw new RuntimeException("Type mismatch, unary minus only supported for numbers!");
334        }
335 
336        @Override
337        public Object caseBoolLiteral(BoolLiteral object) {
338                return object.isValue();
339        }
340 
341        @Override
342        public Object caseNotExpression(NotExpression object) {
343                Boolean b = (Boolean)this.doSwitch(object.getInner());
344                return !b;
345        }
346 
347        @Override
348        public Object casePowerExpression(PowerExpression object) {
349                TypeEnum leftType = typeInferer.getType(object.getBase());
350                TypeEnum rightType = typeInferer.getType(object.getExponent());
351                Object leftExpr = doSwitch(object.getBase());
352                Object rightExpr = doSwitch(object.getExponent());
353                if (leftType == TypeEnum.ANY) leftType = getDynamicType(leftExpr);
354                if (rightType == TypeEnum.ANY) rightType = getDynamicType(rightExpr);
355                
356                if (leftType == TypeEnum.INT)
357                        leftExpr = Double.valueOf( (((Integer)leftExpr).intValue()));
358                if (rightType == TypeEnum.INT)
359                        rightExpr = Double.valueOf( (((Integer)rightExpr).intValue()));
360                return Math.pow((Double)leftExpr, (Double)rightExpr);
361        }
362 
363        @Override
364        public Object caseFunctionLiteral(FunctionLiteral object) {
365                String functionID = object.getId();
366                ArrayList<Object> parameterValues = new ArrayList<Object>();
367                for (Expression e : object.getParameters_FunctionLiteral()) {
368                        parameterValues.add(this.doSwitch(e));
369                }
370                return functionLib.evaluate(functionID,parameterValues);
371        }
372 
373        @Override
374        public Object caseIfElseExpression(IfElseExpression object) {
375                boolean cond = (Boolean)this.doSwitch(object.getConditionExpression());
376                if (cond)
377                        return this.doSwitch(object.getIfExpression());
378                else
379                        return this.doSwitch(object.getElseExpression());
380        }
381        
382}

[all classes][de.uka.ipd.sdq.simucomframework.variables.stoexvisitor]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov