Commit | Line | Data |
---|---|---|
d132bcc7 | 1 | /********************************************************************** |
94cce698 | 2 | * Copyright (c) 2012, 2013 Ericsson |
cfdb727a | 3 | * |
d132bcc7 BH |
4 | * All rights reserved. This program and the accompanying materials are |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
cfdb727a AM |
8 | * |
9 | * Contributors: | |
d132bcc7 BH |
10 | * Bernd Hufmann - Initial API and implementation |
11 | **********************************************************************/ | |
115b4a01 | 12 | package org.eclipse.linuxtools.internal.lttng2.stubs.shells; |
d132bcc7 BH |
13 | |
14 | import java.io.BufferedReader; | |
15 | import java.io.DataInputStream; | |
16 | import java.io.FileInputStream; | |
17 | import java.io.InputStreamReader; | |
18 | import java.util.ArrayList; | |
19 | import java.util.Collection; | |
20 | import java.util.HashMap; | |
21 | import java.util.Iterator; | |
22 | import java.util.List; | |
23 | import java.util.Map; | |
24 | import java.util.regex.Matcher; | |
25 | import java.util.regex.Pattern; | |
26 | ||
27 | import org.eclipse.core.commands.ExecutionException; | |
28 | import org.eclipse.core.runtime.IProgressMonitor; | |
9315aeee BH |
29 | import org.eclipse.linuxtools.internal.lttng2.ui.views.control.remote.CommandResult; |
30 | import org.eclipse.linuxtools.internal.lttng2.ui.views.control.remote.ICommandResult; | |
d132bcc7 | 31 | |
cfdb727a | 32 | @SuppressWarnings("javadoc") |
d132bcc7 BH |
33 | public class LTTngToolsFileShell extends TestCommandShell { |
34 | ||
35 | // ------------------------------------------------------------------------ | |
36 | // CONSTANTS | |
37 | // ------------------------------------------------------------------------ | |
4e0b52e0 AM |
38 | private final static String SCENARIO_KEY = "<SCENARIO>"; |
39 | private final static String SCENARIO_END_KEY = "</SCENARIO>"; | |
40 | private final static String INPUT_KEY = "<COMMAND_INPUT>"; | |
41 | private final static String INPUT_END_KEY = "</COMMAND_INPUT>"; | |
42 | private final static String RESULT_KEY = "<COMMAND_RESULT>"; | |
4e0b52e0 AM |
43 | private final static String OUTPUT_KEY = "<COMMAND_OUTPUT>"; |
44 | private final static String OUTPUT_END_KEY = "</COMMAND_OUTPUT>"; | |
45 | private final static String COMMENT_KEY = "#.*"; | |
cfdb727a | 46 | |
4e0b52e0 AM |
47 | private final static Pattern LTTNG_LIST_SESSION_PATTERN = Pattern.compile("lttng\\s+list\\s+(.+)"); |
48 | private final static String LTTNG_LIST_PROVIDER_PATTERN = "lttng\\s+list\\s+(-u|-k)"; | |
d132bcc7 BH |
49 | |
50 | // ------------------------------------------------------------------------ | |
51 | // Attributes | |
52 | // ------------------------------------------------------------------------ | |
53 | private String fScenariofile; | |
54 | private String fScenario; | |
55 | ||
e0838ca1 AM |
56 | private final Map<String, Map<String, ICommandResult>> fScenarioMap = new HashMap<>(); |
57 | private final Map<String, Integer> fSessionNameMap = new HashMap<>(); | |
d132bcc7 BH |
58 | |
59 | /** | |
60 | * Parse a scenario file with the format: | |
61 | * <SCENARIO> | |
62 | * ScenarioName | |
cfdb727a | 63 | * |
d132bcc7 BH |
64 | * <COMMAND_INPUT> |
65 | * Command | |
66 | * </COMAND_INPUT> | |
cfdb727a | 67 | * |
d132bcc7 BH |
68 | * <COMMAND_RESULT> |
69 | * CommandResult | |
70 | * </COMMAND_RESULT> | |
cfdb727a | 71 | * |
d132bcc7 BH |
72 | * <COMMAND_OUTPUT> |
73 | * CommandOutput | |
74 | * </COMMAND_OUTPUT> | |
cfdb727a | 75 | * |
d132bcc7 | 76 | * </SCENARIO> |
cfdb727a | 77 | * |
d132bcc7 BH |
78 | * Where: ScenarioName - is the scenario name |
79 | * Command - the command line string | |
80 | * CommandResult - the result integer of the command (0 for success, 1 for failure) | |
81 | * ComandOutput - the command output string (multi-line possible) | |
cfdb727a | 82 | * |
d132bcc7 BH |
83 | * Note: 1) There can be many scenarios per file |
84 | * 2) There can be many (Command-CommandResult-CommandOutput) triples per scenario | |
85 | * 3) Lines starting with # will be ignored (comments) | |
cfdb727a | 86 | * |
d132bcc7 BH |
87 | * @param scenariofile - path to scenario file |
88 | * @throws Exception | |
89 | */ | |
1f2f091b | 90 | public synchronized void loadScenarioFile(String scenariofile) throws Exception { |
d132bcc7 | 91 | fScenariofile = scenariofile; |
cfdb727a | 92 | |
d132bcc7 BH |
93 | // clean up map |
94 | Collection<Map<String, ICommandResult>> values = fScenarioMap.values(); | |
95 | for (Iterator<Map<String, ICommandResult>> iterator = values.iterator(); iterator.hasNext();) { | |
cfdb727a | 96 | Map<String, ICommandResult> map = iterator.next(); |
d132bcc7 BH |
97 | map.clear(); |
98 | } | |
99 | fScenarioMap.clear(); | |
cfdb727a | 100 | |
d132bcc7 | 101 | // load from file |
cfdb727a | 102 | |
d132bcc7 | 103 | // Open the file |
e0838ca1 AM |
104 | try (FileInputStream fstream = new FileInputStream(fScenariofile); |
105 | DataInputStream in = new DataInputStream(fstream); | |
106 | BufferedReader br = new BufferedReader(new InputStreamReader(in));) { | |
107 | String strLine; | |
cfdb727a | 108 | |
e0838ca1 | 109 | // Read File Line by Line |
cfdb727a | 110 | |
e0838ca1 AM |
111 | // Temporary map for generating instance numbers for lttng list |
112 | // <session> commands. | |
113 | // The numbers are per scenario. | |
114 | Map<String, Integer> tmpSessionNameMap = new HashMap<>(); | |
115 | while ((strLine = br.readLine()) != null) { | |
d132bcc7 BH |
116 | |
117 | // Ignore comments | |
e0838ca1 AM |
118 | if (isComment(strLine)) { |
119 | continue; | |
d132bcc7 BH |
120 | } |
121 | ||
e0838ca1 AM |
122 | if (SCENARIO_KEY.equals(strLine)) { |
123 | // scenario start | |
124 | ||
cfdb727a | 125 | // Ignore comments |
e0838ca1 AM |
126 | strLine = br.readLine(); |
127 | while (isComment(strLine)) { | |
128 | strLine = br.readLine(); | |
d132bcc7 BH |
129 | } |
130 | ||
e0838ca1 AM |
131 | String scenario = strLine; |
132 | Map<String, ICommandResult> commandMap = new HashMap<>(); | |
133 | fScenarioMap.put(scenario, commandMap); | |
134 | List<String> output = null; | |
135 | String input = null; | |
136 | boolean inOutput = false; | |
137 | int result = 0; | |
138 | tmpSessionNameMap.clear(); | |
139 | while ((strLine = br.readLine()) != null) { | |
d132bcc7 | 140 | // Ignore comments |
e0838ca1 AM |
141 | if (isComment(strLine)) { |
142 | continue; | |
d132bcc7 | 143 | } |
e0838ca1 AM |
144 | |
145 | if (SCENARIO_END_KEY.equals(strLine)) { | |
146 | // Scenario is finished | |
147 | break; | |
d132bcc7 | 148 | } |
e0838ca1 | 149 | if (INPUT_KEY.equals(strLine)) { |
d132bcc7 | 150 | strLine = br.readLine(); |
e0838ca1 AM |
151 | // Ignore comments |
152 | while (isComment(strLine)) { | |
153 | strLine = br.readLine(); | |
154 | } | |
155 | // Read command | |
156 | input = strLine; | |
157 | ||
158 | // Handle instances of 'lttng list | |
159 | // <session"-comamand | |
160 | Matcher matcher = LTTNG_LIST_SESSION_PATTERN.matcher(strLine); | |
161 | if (matcher.matches() && !input.matches(LTTNG_LIST_PROVIDER_PATTERN)) { | |
162 | String sessionName = matcher.group(1).trim(); | |
163 | Integer i = tmpSessionNameMap.get(sessionName); | |
164 | if (i != null) { | |
165 | i++; | |
166 | } else { | |
167 | i = 0; | |
168 | } | |
169 | tmpSessionNameMap.put(sessionName, i); | |
170 | input += String.valueOf(i); | |
171 | } | |
172 | } else if (INPUT_END_KEY.equals(strLine)) { | |
173 | // Initialize output array | |
174 | output = new ArrayList<>(); | |
175 | } else if (RESULT_KEY.equals(strLine)) { | |
d132bcc7 | 176 | strLine = br.readLine(); |
e0838ca1 AM |
177 | // Ignore comments |
178 | while (isComment(strLine)) { | |
179 | strLine = br.readLine(); | |
180 | } | |
181 | // Save result value | |
182 | result = Integer.parseInt(strLine); | |
183 | } else if (OUTPUT_END_KEY.equals(strLine)) { | |
184 | // Save output/result in command map | |
185 | if (output != null) { | |
186 | commandMap.put(input, new CommandResult(result, output.toArray(new String[output.size()]))); | |
187 | } | |
188 | inOutput = false; | |
189 | } else if (OUTPUT_KEY.equals(strLine)) { | |
190 | // first line of output | |
191 | inOutput = true; | |
192 | strLine = br.readLine(); | |
193 | ||
194 | // Ignore comments | |
195 | while (isComment(strLine)) { | |
196 | strLine = br.readLine(); | |
197 | } | |
198 | if (output != null) { | |
199 | output.add(strLine); | |
200 | } | |
201 | } else if (inOutput) { | |
202 | // subsequent lines of output | |
203 | if (output != null) { | |
204 | output.add(strLine); | |
205 | } | |
d132bcc7 | 206 | } |
e0838ca1 AM |
207 | // else { |
208 | // if (RESULT_END_KEY.equals(strLine)) { | |
d132bcc7 | 209 | // nothing to do |
e0838ca1 AM |
210 | // } |
211 | } | |
d132bcc7 BH |
212 | } |
213 | } | |
214 | } | |
d132bcc7 BH |
215 | } |
216 | ||
217 | // Set the scenario to consider in executeCommand() | |
218 | public synchronized void setScenario(String scenario) { | |
219 | fScenario = scenario; | |
220 | fSessionNameMap.clear(); | |
221 | if (!fScenarioMap.containsKey(fScenario)) { | |
222 | throw new IllegalArgumentException(); | |
223 | } | |
224 | } | |
225 | ||
d132bcc7 | 226 | @Override |
1f2f091b | 227 | public synchronized ICommandResult executeCommand(String command, IProgressMonitor monitor, boolean checkReturnValue) throws ExecutionException { |
d132bcc7 | 228 | Map<String, ICommandResult> commands = fScenarioMap.get(fScenario); |
41b5c37f | 229 | String fullCommand = command; |
d132bcc7 BH |
230 | |
231 | Matcher matcher = LTTNG_LIST_SESSION_PATTERN.matcher(command); | |
232 | if (matcher.matches() && !command.matches(LTTNG_LIST_PROVIDER_PATTERN)) { | |
233 | String sessionName = matcher.group(1).trim(); | |
234 | Integer i = fSessionNameMap.get(sessionName); | |
235 | if (i != null) { | |
236 | i++; | |
237 | } else { | |
238 | i = 0; | |
239 | } | |
240 | fSessionNameMap.put(sessionName, i); | |
41b5c37f | 241 | fullCommand += String.valueOf(i); |
d132bcc7 BH |
242 | } |
243 | ||
41b5c37f AM |
244 | if (commands.containsKey(fullCommand)) { |
245 | return commands.get(fullCommand); | |
cfdb727a | 246 | } |
d132bcc7 BH |
247 | |
248 | String[] output = new String[1]; | |
4e0b52e0 | 249 | output[0] = String.valueOf("Command not found"); |
4ea599a5 BH |
250 | CommandResult result = new CommandResult(0, null); |
251 | // For verification of setters of class CommandResult | |
252 | result.setOutput(output); | |
253 | result.setResult(1); | |
254 | return result; | |
d132bcc7 | 255 | } |
cfdb727a | 256 | |
d132bcc7 BH |
257 | // ------------------------------------------------------------------------ |
258 | // Helper methods | |
259 | // ------------------------------------------------------------------------ | |
11252342 | 260 | |
0a78d11a | 261 | private static boolean isComment(String line) { |
1f2f091b | 262 | if (line == null) { |
4e0b52e0 | 263 | throw new RuntimeException("line is null"); |
1f2f091b | 264 | } |
d132bcc7 BH |
265 | return line.matches(COMMENT_KEY); |
266 | } | |
267 | } |