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 maximum allowed by a precision. |
17 | * First set the random variable by {@link #setModifiedVariable(PCMRandomVariable)} then transform it by {@link #doSwitch(org.eclipse.emf.ecore.EObject)}. |
18 | |
19 | * @author groenda |
20 | * |
21 | */ |
22 | public class PCMRandomVariableSpecificationAccuracyMaximumTrafo extends |
23 | QualityAnnotationSwitch<Boolean> { |
24 | /** Logger for this class. */ |
25 | private static final Logger logger = Logger.getLogger(PCMRandomVariableSpecificationAccuracyMaximumTrafo.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 | /** Maximal value reported will not be greater than this bound. */ |
31 | private String upperLimit; |
32 | |
33 | /**Sets the upper bound for the maximum. |
34 | * The transformation will not result in values above 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 setUpperLimit(String upperLimit) { |
39 | this.upperLimit = upperLimit; |
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 (upperLimit == null) { |
53 | String msg = "Dynamic type inference of specificaitons to determine maximal value is not implemented (yet)."; |
54 | logger.error(msg); |
55 | throw new IllegalArgumentException(msg); |
56 | } else { |
57 | modifiedVariable.setSpecification(upperLimit); |
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 | String spec = modifiedVariable.getSpecification(); |
77 | String abs = "" + object.getAbsolute(); |
78 | String rel = "" + object.getRelative(); |
79 | String max = "MaxDeviation(" + spec + ", " + abs + ", " + rel + ")"; |
80 | if (upperLimit == null) { |
81 | modifiedVariable.setSpecification(max); |
82 | } else { |
83 | modifiedVariable.setSpecification(stoExMin(max, upperLimit)); |
84 | } |
85 | reset(); |
86 | return true; |
87 | } |
88 | |
89 | @Override |
90 | public Boolean casePrecision(Precision object) { |
91 | checkModifiedVariable(); |
92 | String msg = "The handling of the provided Precision " + object + " is not implemented."; |
93 | logger.error(msg); |
94 | reset(); |
95 | throw new IllegalArgumentException(msg); |
96 | } |
97 | |
98 | /**Checks that the modified variable is set. |
99 | * |
100 | */ |
101 | private void checkModifiedVariable() { |
102 | if (modifiedVariable == null) { |
103 | 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."; |
104 | logger.error(msg); |
105 | throw new IllegalArgumentException(msg); |
106 | } |
107 | } |
108 | |
109 | /**Prevent accidental re-transformation by resetting this classes instance variables. |
110 | */ |
111 | private void reset() { |
112 | modifiedVariable = null; |
113 | upperLimit = null; |
114 | } |
115 | } |