1 | package de.uka.ipd.sdq.reliability.solver.pcm2markov; |
2 | |
3 | import java.io.BufferedWriter; |
4 | import java.io.File; |
5 | import java.io.FileWriter; |
6 | import java.io.IOException; |
7 | import java.net.URL; |
8 | import java.util.List; |
9 | |
10 | import org.eclipse.core.runtime.FileLocator; |
11 | import org.eclipse.swt.widgets.Display; |
12 | import org.eclipse.ui.IWorkbenchPage; |
13 | import org.eclipse.ui.PartInitException; |
14 | import org.eclipse.ui.PlatformUI; |
15 | |
16 | import de.uka.ipd.sdq.pcmsolver.models.PCMInstance; |
17 | import de.uka.ipd.sdq.pcmsolver.runconfig.PCMSolverWorkflowRunConfiguration; |
18 | import de.uka.ipd.sdq.pcmsolver.transformations.EMFHelper; |
19 | import de.uka.ipd.sdq.pcmsolver.transformations.SolverStrategy; |
20 | import de.uka.ipd.sdq.reliability.solver.reporting.MarkovReporting; |
21 | import de.uka.ipd.sdq.reliability.solver.sensitivity.MarkovSensitivity; |
22 | import de.uka.ipd.sdq.reliability.solver.sensitivity.MarkovSensitivityBuilder; |
23 | import de.uka.ipd.sdq.reliability.solver.visualisation.MarkovHtmlGenerator; |
24 | import de.uka.ipd.sdq.reliability.solver.visualisation.MarkovResultEditorInput; |
25 | |
26 | /** |
27 | * This class performs a transformation from a PCM instance to a Markov Chain |
28 | * instance, and solves the resulting Markov Chain instance. |
29 | * |
30 | * @author brosch |
31 | * |
32 | */ |
33 | public class Pcm2MarkovStrategy implements SolverStrategy { |
34 | |
35 | /** |
36 | * Configuration properties for the reliability solver workflow. |
37 | */ |
38 | private PCMSolverWorkflowRunConfiguration configuration; |
39 | |
40 | /** |
41 | * The Markov transformation results (one result object for each PCM |
42 | * UsageScenario). |
43 | */ |
44 | private List<MarkovTransformationResult> markovResults; |
45 | |
46 | /** |
47 | * Captures a configuration for sensitivity analysis (temporary). |
48 | */ |
49 | private MarkovSensitivity markovSensitivity; |
50 | |
51 | /** |
52 | * The constructor. |
53 | * |
54 | * @param configuration |
55 | * launch configuration parameters |
56 | */ |
57 | public Pcm2MarkovStrategy( |
58 | final PCMSolverWorkflowRunConfiguration configuration) { |
59 | this.configuration = configuration; |
60 | this.markovSensitivity = initSensitivityAnalysis(); |
61 | } |
62 | |
63 | /** |
64 | * Retrieves the Markov transformation results. |
65 | * |
66 | * If the PCM instance has multiple usage scenarios, only the results for |
67 | * the first usage scenario are returned. |
68 | * |
69 | * @return the Markov transformation results |
70 | */ |
71 | public MarkovTransformationResult getSolvedValue() { |
72 | return (markovResults.size() > 0) ? markovResults.get(0) : null; |
73 | } |
74 | |
75 | /** |
76 | * Initializes sensitivity analysis parameters. |
77 | * |
78 | * @return the sensitivity configuration; NULL if no sensitivity analysis |
79 | * shall be performed |
80 | */ |
81 | private MarkovSensitivity initSensitivityAnalysis() { |
82 | if (configuration.isSensitivityModelEnabled()) { |
83 | MarkovSensitivityBuilder builder = new MarkovSensitivityBuilder(); |
84 | return builder.buildSensitivity(resolveFile(configuration |
85 | .getSensitivityModelFileName()), resolveFile(configuration |
86 | .getSensitivityLogFileName())); |
87 | } |
88 | return null; |
89 | } |
90 | |
91 | /** |
92 | * Loads an already existing Markov Chain from a given XMI file. Not yet |
93 | * implemented. |
94 | * |
95 | * @param fileName |
96 | * the name of the XMI file |
97 | */ |
98 | public void loadTransformedModel(final String fileName) { |
99 | throw new UnsupportedOperationException(); |
100 | } |
101 | |
102 | /** |
103 | * Resolves a file's path in case it starts with "platform:/" and returns |
104 | * the entire absolute path to the file, including the file's name. |
105 | * |
106 | * @param fileURL |
107 | * the path to a file, including the file's name (and its |
108 | * extension) |
109 | * @return the absolute path to the file, including the file's name |
110 | */ |
111 | private String resolveFile(String fileURL) { |
112 | // if this is a platform URL, first resolve it to an absolute path |
113 | if (fileURL.startsWith("platform:")) { |
114 | try { |
115 | URL solvedURL = FileLocator.resolve(new URL(fileURL)); |
116 | fileURL = solvedURL.getPath(); |
117 | } catch (Exception e) { |
118 | e.printStackTrace(); |
119 | return ""; |
120 | } |
121 | } |
122 | return fileURL; |
123 | } |
124 | |
125 | /** |
126 | * Saves the given String (HTML code) to a file specified in the |
127 | * configuration. |
128 | * |
129 | * @param htmlCode |
130 | * the (HTML code) string to save |
131 | */ |
132 | private void saveResultsToFile(String htmlCode) { |
133 | BufferedWriter out = null; |
134 | String filePath = resolveFile(configuration.getSaveFile()); |
135 | try { |
136 | File f = new File(filePath); |
137 | // if the file exists, we will delete it and create a new, |
138 | // empty one (i.e., overwrite the existing file) once, and then |
139 | // repeatedly append to this file |
140 | if (f.exists()) { |
141 | f.delete(); // delete current (old) file |
142 | f.createNewFile(); // create a new, empty file |
143 | } |
144 | out = new BufferedWriter(new FileWriter(filePath, true)); |
145 | out.append(htmlCode.toString()); |
146 | } catch (IOException e) { |
147 | e.printStackTrace(); |
148 | } finally { |
149 | try { |
150 | if (out != null) { |
151 | out.flush(); |
152 | out.close(); |
153 | } |
154 | } catch (IOException e) { |
155 | e.printStackTrace(); |
156 | } |
157 | } |
158 | } |
159 | |
160 | /** |
161 | * Shows the Markov transformation results in the workbench editor of the |
162 | * target instance, given HTML code, represented as string. |
163 | * |
164 | * @param htmlCode |
165 | * the HTML code as string |
166 | */ |
167 | private void showResults(final String htmlCode) { |
168 | if (markovResults != null) { |
169 | Display.getDefault().asyncExec(new Runnable() { |
170 | public void run() { |
171 | IWorkbenchPage page = PlatformUI.getWorkbench() |
172 | .getActiveWorkbenchWindow().getActivePage(); |
173 | if (page != null) { |
174 | try { |
175 | page |
176 | .openEditor(new MarkovResultEditorInput( |
177 | htmlCode), |
178 | "de.uka.ipd.sdq.reliability.solver.pcm2markov.MarkovResultEditor"); |
179 | } catch (PartInitException e) { |
180 | e.printStackTrace(); |
181 | } |
182 | } |
183 | } |
184 | }); |
185 | } |
186 | } |
187 | |
188 | /** |
189 | * Solves the Markov Chain which has been created as a result of the |
190 | * transformation or has been loaded from an XMI file. |
191 | */ |
192 | public void solve() { |
193 | |
194 | // Solving of Markov Chain has already taken place during the |
195 | // transformation. |
196 | |
197 | } |
198 | |
199 | /** |
200 | * Saves the Markov Chain resulting from the transformation into an XMI |
201 | * file. |
202 | * |
203 | * If the PCM instance has multiple usage scenarios, only the results for |
204 | * the first usage scenario are written into the file. |
205 | * |
206 | * @param fileName |
207 | * the name of the XMI file to create |
208 | */ |
209 | public void storeTransformedModel(final String fileName) { |
210 | MarkovTransformationResult result = (markovResults.size() > 0) ? markovResults |
211 | .get(0) |
212 | : null; |
213 | if (result != null) { |
214 | EMFHelper.saveToXMIFile(result.getResultChain(), |
215 | resolveFile(fileName)); |
216 | } |
217 | } |
218 | |
219 | /** |
220 | * Transforms a PCM instance into a Markov Chain instance. |
221 | * |
222 | * The transformation is performed either as a single transformation, or as |
223 | * a repeated transformation to perform sensitivity analysis. |
224 | * |
225 | * @param model |
226 | * the input PCM instance |
227 | */ |
228 | public void transform(final PCMInstance model) { |
229 | markovResults = new MarkovTransformation().runTransform(model, |
230 | configuration, markovSensitivity); |
231 | if (configuration.isMarkovModelStorageEnabled()) { |
232 | storeTransformedModel(configuration.getMarkovModelFile()); |
233 | } |
234 | |
235 | // embed results in HTML page |
236 | String htmlCode = new MarkovHtmlGenerator(new MarkovReporting( |
237 | markovResults, configuration)).getHtml(); |
238 | // check whether the HTML page containing the results shall be saved to |
239 | // a file |
240 | if (configuration.isSaveResultsToFileEnabled()) { |
241 | saveResultsToFile(htmlCode); |
242 | } // else do nothing |
243 | |
244 | // show the HTML page containing the results |
245 | if (configuration.isShowHtmlResults()){ |
246 | showResults(htmlCode); |
247 | } |
248 | } |
249 | } |