1 | /** |
2 | * |
3 | */ |
4 | package de.fzi.se.accuracy.transformation; |
5 | |
6 | import org.apache.log4j.Logger; |
7 | |
8 | import de.fzi.se.quality.qualityannotation.ExactlyAsSpecifiedPrecision; |
9 | import de.fzi.se.quality.qualityannotation.LimitedDeviationPrecision; |
10 | import de.fzi.se.quality.qualityannotation.NoPrecision; |
11 | import de.fzi.se.quality.qualityannotation.Precision; |
12 | import de.fzi.se.quality.qualityannotation.util.QualityAnnotationSwitch; |
13 | import static de.fzi.se.quality.util.StoExHelper.*; |
14 | import de.uka.ipd.sdq.pcm.core.PCMRandomVariable; |
15 | |
16 | /**Modifies a given PCM Random Variable according to the minimum allowed by a precision. |
17 | * First set the random variable by {@link #setModifiedVariable(PCMRandomVariable)} then transform it by {@link PCMRandomVariableSpecificationAccuracyMinimumTrafo#doSwitch(org.eclipse.emf.ecore.EObject)}. |
18 | |
19 | * @author groenda |
20 | * |
21 | */ |
22 | public class PCMRandomVariableSpecificationAccuracyMinimumTrafo extends |
23 | QualityAnnotationSwitch<Boolean> { |
24 | /** Logger for this class. */ |
25 | private static final Logger logger = Logger.getLogger(PCMRandomVariableSpecificationAccuracyMinimumTrafo.class); |
26 | |
27 | /** The variable modified by the transformation when {@link #doSwitch(org.eclipse.emf.ecore.EObject)} is called. */ |
28 | private PCMRandomVariable modifiedVariable; |
29 | |
30 | /** Minimum value reported will not be smaller than this bound.*/ |
31 | private String lowerLimit; |
32 | |
33 | /**Sets the lower bound for the minimum. |
34 | * The transformation will not result in values below this bound. |
35 | * The bound is automatically reset after an invocation of {@link #doSwitch(org.eclipse.emf.ecore.EObject)}. |
36 | * @param lowerLimit The lower bound. |
37 | */ |
38 | public void setLowerLimit(String lowerLimit) { |
39 | this.lowerLimit = lowerLimit; |
40 | } |
41 | |
42 | /**Set the variable to modify upon invocation of {@link #doSwitch(org.eclipse.emf.ecore.EObject)}. |
43 | * @param modifiedVariable The variable. |
44 | */ |
45 | public void setModifiedVariable(PCMRandomVariable modifiedVariable) { |
46 | this.modifiedVariable = modifiedVariable; |
47 | } |
48 | |
49 | @Override |
50 | public Boolean caseNoPrecision(NoPrecision object) { |
51 | checkModifiedVariable(); |
52 | if (lowerLimit == null) { |
53 | String msg = "Dynamic type inference of specifications to determine minimal value is not implemented (yet)."; |
54 | logger.error(msg); |
55 | throw new IllegalArgumentException(msg); |
56 | } else { |
57 | modifiedVariable.setSpecification(lowerLimit); |
58 | } |
59 | reset(); |
60 | return true; |
61 | } |
62 | |
63 | @Override |
64 | public Boolean caseExactlyAsSpecifiedPrecision( |
65 | ExactlyAsSpecifiedPrecision object) { |
66 | checkModifiedVariable(); |
67 | reset(); |
68 | // nothing to do |
69 | return true; |
70 | } |
71 | |
72 | @Override |
73 | public Boolean caseLimitedDeviationPrecision( |
74 | LimitedDeviationPrecision object) { |
75 | checkModifiedVariable(); |
76 | // newSpec = max(min(noc.specification - absolute, noc.specification - noc.specification * relative, 0); |
77 | String spec = modifiedVariable.getSpecification(); |
78 | String abs = "" + object.getAbsolute(); |
79 | String rel = "" + object.getRelative(); |
80 | String min = "MinDeviation(" + spec + ", " + abs + ", " + rel + ")"; |
81 | if (lowerLimit == null) { |
82 | modifiedVariable.setSpecification(min); |
83 | } else { |
84 | modifiedVariable.setSpecification(stoExMax(min, lowerLimit)); |
85 | } |
86 | reset(); |
87 | return true; |
88 | } |
89 | |
90 | @Override |
91 | public Boolean casePrecision(Precision object) { |
92 | checkModifiedVariable(); |
93 | String msg = "The handling of the provided Precision " + object + " is not implemented."; |
94 | logger.error(msg); |
95 | reset(); |
96 | throw new IllegalArgumentException(msg); |
97 | } |
98 | |
99 | /**Checks that the modified variable is set. |
100 | * |
101 | */ |
102 | private void checkModifiedVariable() { |
103 | if (modifiedVariable == null) { |
104 | String msg = "You have to set the modified variable before invoking doSwitch(). Note: The modified variable is reset after an execution of doSwitch() to prevent accidental transformations of the same variable."; |
105 | logger.error(msg); |
106 | throw new IllegalArgumentException(msg); |
107 | } |
108 | } |
109 | |
110 | /**Prevent accidental re-transformation by resetting this classes instance variables. |
111 | */ |
112 | private void reset() { |
113 | modifiedVariable = null; |
114 | lowerLimit = null; |
115 | } |
116 | } |