|
1 /* |
|
2 * Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 * TriggerProcessor DataProcessor |
|
17 * |
|
18 */ |
|
19 package com.nokia.traceviewer.engine.dataprocessor; |
|
20 |
|
21 import java.util.ArrayList; |
|
22 import java.util.List; |
|
23 |
|
24 import com.nokia.traceviewer.TraceViewerPlugin; |
|
25 import com.nokia.traceviewer.action.TraceViewerActionUtils; |
|
26 import com.nokia.traceviewer.dialog.TriggerDialog; |
|
27 import com.nokia.traceviewer.dialog.treeitem.TreeItem; |
|
28 import com.nokia.traceviewer.dialog.treeitem.TreeItemContentProvider; |
|
29 import com.nokia.traceviewer.dialog.treeitem.TreeItemListener; |
|
30 import com.nokia.traceviewer.dialog.treeitem.TriggerTreeBaseItem; |
|
31 import com.nokia.traceviewer.dialog.treeitem.TriggerTreeItem; |
|
32 import com.nokia.traceviewer.dialog.treeitem.TriggerTreeTextItem; |
|
33 import com.nokia.traceviewer.engine.TraceProperties; |
|
34 import com.nokia.traceviewer.engine.TraceViewerGlobals; |
|
35 import com.nokia.traceviewer.engine.TraceViewerDialogInterface.Dialog; |
|
36 import com.nokia.traceviewer.engine.activation.TraceActivationComponentItem; |
|
37 import com.nokia.traceviewer.engine.activation.TraceActivationXMLImporter; |
|
38 import com.nokia.traceviewer.engine.activation.TraceActivator; |
|
39 import com.nokia.traceviewer.engine.preferences.PreferenceConstants; |
|
40 import com.nokia.traceviewer.engine.preferences.XMLTriggerConfigurationImporter; |
|
41 |
|
42 /** |
|
43 * Trigger DataProcessor |
|
44 * |
|
45 */ |
|
46 public final class TriggerProcessor implements DataProcessor { |
|
47 |
|
48 /** |
|
49 * Dataprocessors stop delay |
|
50 */ |
|
51 private static final int DATAPROCESSOR_STOP_DELAY = 500; |
|
52 |
|
53 /** |
|
54 * State of the trigger process enumeration |
|
55 */ |
|
56 public enum TriggerState { |
|
57 |
|
58 /** |
|
59 * Searching for start trigger |
|
60 */ |
|
61 SEARCHING_FOR_STARTTRIGGER, |
|
62 |
|
63 /** |
|
64 * Searching for stop trigger |
|
65 */ |
|
66 SEARCHING_FOR_STOPTRIGGER |
|
67 } |
|
68 |
|
69 /** |
|
70 * State of the trigger process |
|
71 */ |
|
72 private TriggerState triggerState; |
|
73 |
|
74 /** |
|
75 * Trigger dialog used in setting rules |
|
76 */ |
|
77 private TriggerDialog triggerDialog; |
|
78 |
|
79 /** |
|
80 * Content provider for the dialog |
|
81 */ |
|
82 private TreeItemContentProvider contentProvider; |
|
83 |
|
84 /** |
|
85 * First visible object in the dialog tree |
|
86 */ |
|
87 private TreeItem root; |
|
88 |
|
89 /** |
|
90 * Start triggers |
|
91 */ |
|
92 private final List<TriggerTreeTextItem> startTriggers; |
|
93 |
|
94 /** |
|
95 * Stop triggers |
|
96 */ |
|
97 private final List<TriggerTreeTextItem> stopTriggers; |
|
98 |
|
99 /** |
|
100 * Activation triggers |
|
101 */ |
|
102 private final List<TriggerTreeTextItem> activationTriggers; |
|
103 |
|
104 /** |
|
105 * Constructor |
|
106 */ |
|
107 public TriggerProcessor() { |
|
108 createInitialTree(); |
|
109 startTriggers = new ArrayList<TriggerTreeTextItem>(); |
|
110 stopTriggers = new ArrayList<TriggerTreeTextItem>(); |
|
111 activationTriggers = new ArrayList<TriggerTreeTextItem>(); |
|
112 } |
|
113 |
|
114 /** |
|
115 * Creates initial tree |
|
116 */ |
|
117 public void createInitialTree() { |
|
118 contentProvider = new TreeItemContentProvider(); |
|
119 // Create root node |
|
120 TreeItem treeRoot = new TriggerTreeBaseItem(contentProvider, null, |
|
121 "root", //$NON-NLS-1$ |
|
122 TriggerTreeItem.Rule.GROUP, null); |
|
123 root = new TriggerTreeBaseItem(contentProvider, treeRoot, |
|
124 TraceViewerPlugin.getDefault().getPreferenceStore().getString( |
|
125 PreferenceConstants.CONFIGURATION_FILE), |
|
126 TriggerTreeItem.Rule.GROUP, null); |
|
127 treeRoot.addChild(root); |
|
128 } |
|
129 |
|
130 /** |
|
131 * Imports trigger rules from configuration file |
|
132 */ |
|
133 public void importTriggerRules() { |
|
134 // Import rules |
|
135 XMLTriggerConfigurationImporter importer = new XMLTriggerConfigurationImporter( |
|
136 root, TraceViewerPlugin.getDefault().getPreferenceStore() |
|
137 .getString(PreferenceConstants.CONFIGURATION_FILE), |
|
138 true); |
|
139 importer.importData(); |
|
140 } |
|
141 |
|
142 /* |
|
143 * (non-Javadoc) |
|
144 * |
|
145 * @see |
|
146 * com.nokia.traceviewer.engine.DataProcessor#processData(com.nokia.traceviewer |
|
147 * .engine.TraceProperties) |
|
148 */ |
|
149 public void processData(TraceProperties properties) { |
|
150 if (isTriggering() && !properties.traceConfiguration.isScrolledTrace()) { |
|
151 |
|
152 // Set the trigger State |
|
153 if (!startTriggers.isEmpty()) { |
|
154 triggerState = TriggerState.SEARCHING_FOR_STARTTRIGGER; |
|
155 properties.traceConfiguration.setTriggeredOut(true); |
|
156 } else if (!stopTriggers.isEmpty()) { |
|
157 triggerState = TriggerState.SEARCHING_FOR_STOPTRIGGER; |
|
158 properties.traceConfiguration.setTriggeredOut(false); |
|
159 } |
|
160 |
|
161 // Searching for activation line |
|
162 if (!activationTriggers.isEmpty()) { |
|
163 if (containsTrigger(activationTriggers, properties)) { |
|
164 generateAndSendActivationMsg(activationTriggers, properties); |
|
165 } |
|
166 } |
|
167 |
|
168 // State machine |
|
169 if (triggerState == TriggerState.SEARCHING_FOR_STARTTRIGGER) { |
|
170 |
|
171 // Start trigger is found |
|
172 if (containsTrigger(startTriggers, properties)) { |
|
173 |
|
174 // One of the start triggers has been found, remove all |
|
175 // start triggers and change the view state |
|
176 startTriggers.clear(); |
|
177 TraceViewerGlobals.getTraceViewer().getView() |
|
178 .updateViewName(); |
|
179 |
|
180 // Start using trigger file |
|
181 long posInFile = TraceViewerGlobals.getTraceViewer() |
|
182 .getDataReaderAccess().getMainDataReader() |
|
183 .getTracePositionInFile(); |
|
184 startUsingTriggerFile(posInFile); |
|
185 } |
|
186 |
|
187 } else if (triggerState == TriggerState.SEARCHING_FOR_STOPTRIGGER) { |
|
188 |
|
189 // One of the stop triggers has been found, remove all |
|
190 // stop triggers, and pause data reader. Pausing the data reader |
|
191 // will also update the view name so it's not necessary here |
|
192 if (containsTrigger(stopTriggers, properties)) { |
|
193 stopTriggers.clear(); |
|
194 TraceViewerGlobals.getTraceViewer().getView() |
|
195 .getActionFactory().getPauseAction().run(); |
|
196 } |
|
197 } |
|
198 } |
|
199 } |
|
200 |
|
201 /** |
|
202 * Sets TraceViewer to use the new trigger file as main file |
|
203 * |
|
204 * @param position |
|
205 * position of the message containing the start trigger |
|
206 */ |
|
207 private void startUsingTriggerFile(long position) { |
|
208 TraceViewerGlobals.getTraceViewer().getFileHandler().closeFile(); |
|
209 |
|
210 // Shut down data readers |
|
211 TraceViewerGlobals.getTraceViewer().getDataReaderAccess() |
|
212 .getMainDataReader().shutdown(); |
|
213 TraceViewerGlobals.getTraceViewer().getDataReaderAccess() |
|
214 .deleteScrollReader(); |
|
215 |
|
216 // Wait for a while for readers to really stop |
|
217 try { |
|
218 Thread.sleep(DATAPROCESSOR_STOP_DELAY); |
|
219 } catch (InterruptedException e) { |
|
220 } |
|
221 |
|
222 // Set the start of the trace file |
|
223 TraceViewerGlobals.getTraceViewer().getDataReaderAccess() |
|
224 .setFileStartOffset(position); |
|
225 |
|
226 // Create new main file |
|
227 TraceViewerGlobals.getTraceViewer().getFileHandler().openFile(); |
|
228 |
|
229 // Start new main data reader |
|
230 TraceViewerGlobals.getTraceViewer().getDataReaderAccess() |
|
231 .createMainDataReader(); |
|
232 |
|
233 triggerState = TriggerState.SEARCHING_FOR_STOPTRIGGER; |
|
234 } |
|
235 |
|
236 /** |
|
237 * Tells if this trace hits any of the triggers in the list |
|
238 * |
|
239 * @param triggers |
|
240 * trigger list to find from |
|
241 * @param properties |
|
242 * trace to find |
|
243 * @return true if trace is contained in the trigger array |
|
244 */ |
|
245 private boolean containsTrigger(List<TriggerTreeTextItem> triggers, |
|
246 TraceProperties properties) { |
|
247 boolean found = false; |
|
248 |
|
249 // Loop through triggers |
|
250 for (int i = 0; i < triggers.size(); i++) { |
|
251 found = containsTrigger(triggers.get(i), properties); |
|
252 |
|
253 if (found) { |
|
254 break; |
|
255 } |
|
256 } |
|
257 |
|
258 return found; |
|
259 } |
|
260 |
|
261 /** |
|
262 * Tells if this trace hits given trigger |
|
263 * |
|
264 * @param trigger |
|
265 * trigger rule |
|
266 * @param properties |
|
267 * trace |
|
268 * @return true if trace hits the given trigger |
|
269 */ |
|
270 private boolean containsTrigger(TriggerTreeTextItem trigger, |
|
271 TraceProperties properties) { |
|
272 boolean found = false; |
|
273 String triggerStr = trigger.getTextToCompare(); |
|
274 |
|
275 String traceLine = ""; //$NON-NLS-1$ |
|
276 |
|
277 // Traces missing |
|
278 if (properties.bTraceInformation.isTraceMissing()) { |
|
279 traceLine = TraceViewerActionUtils.TRACES_DROPPED_MSG; |
|
280 } |
|
281 if (properties.traceString != null) { |
|
282 traceLine += properties.traceString; |
|
283 } |
|
284 |
|
285 if (!trigger.isMatchCase()) { |
|
286 traceLine = traceLine.toLowerCase(); |
|
287 } |
|
288 if (traceLine.contains(triggerStr)) { |
|
289 found = true; |
|
290 } |
|
291 return found; |
|
292 } |
|
293 |
|
294 /** |
|
295 * Generate and send activation message |
|
296 * |
|
297 * @param triggers |
|
298 * activation triggers |
|
299 * @param trace |
|
300 * trace properties |
|
301 */ |
|
302 private void generateAndSendActivationMsg( |
|
303 List<TriggerTreeTextItem> triggers, TraceProperties trace) { |
|
304 |
|
305 // Go through the whole list as one trace can hit multiple triggers |
|
306 for (int i = 0; i < triggers.size(); i++) { |
|
307 TriggerTreeTextItem trigger = triggers.get(i); |
|
308 |
|
309 // Trigger hits |
|
310 if (containsTrigger(trigger, trace)) { |
|
311 // Generate activation list |
|
312 TraceActivationXMLImporter importer = new TraceActivationXMLImporter( |
|
313 trigger.getConfigurationFilePath()); |
|
314 |
|
315 // Create the list |
|
316 List<TraceActivationComponentItem> activationList = new ArrayList<TraceActivationComponentItem>(); |
|
317 |
|
318 // Fill the list from the importer |
|
319 importer.createComponentListFromConfigurationName( |
|
320 activationList, trigger.getConfigurationName()); |
|
321 |
|
322 // Activate |
|
323 new TraceActivator().activate(activationList); |
|
324 } |
|
325 } |
|
326 } |
|
327 |
|
328 /** |
|
329 * Tells are we start triggering |
|
330 * |
|
331 * @return true if start triggering |
|
332 */ |
|
333 public boolean isStartTriggering() { |
|
334 boolean isStartTriggering = !startTriggers.isEmpty(); |
|
335 return isStartTriggering; |
|
336 } |
|
337 |
|
338 /** |
|
339 * Tells are we stop triggering |
|
340 * |
|
341 * @return true if stop triggering |
|
342 */ |
|
343 public boolean isStopTriggering() { |
|
344 boolean isStopTriggering = !stopTriggers.isEmpty(); |
|
345 return isStopTriggering; |
|
346 } |
|
347 |
|
348 /** |
|
349 * Tells are we triggering |
|
350 * |
|
351 * @return true if triggering |
|
352 */ |
|
353 public boolean isTriggering() { |
|
354 boolean isTriggering = !startTriggers.isEmpty() |
|
355 || !stopTriggers.isEmpty() || !activationTriggers.isEmpty(); |
|
356 return isTriggering; |
|
357 } |
|
358 |
|
359 /** |
|
360 * Gets trigger dialog |
|
361 * |
|
362 * @return Trigger dialog |
|
363 */ |
|
364 public TriggerDialog getTriggerDialog() { |
|
365 if (triggerDialog == null) { |
|
366 triggerDialog = (TriggerDialog) TraceViewerGlobals.getTraceViewer() |
|
367 .getDialogs().createDialog(Dialog.TRIGGER); |
|
368 } |
|
369 return triggerDialog; |
|
370 } |
|
371 |
|
372 /** |
|
373 * Gets root node of the tree |
|
374 * |
|
375 * @return root node of the tree |
|
376 */ |
|
377 public TreeItem getRoot() { |
|
378 return root; |
|
379 } |
|
380 |
|
381 /** |
|
382 * Gets item listener |
|
383 * |
|
384 * @return the contentProvider |
|
385 */ |
|
386 public TreeItemListener getTreeItemListener() { |
|
387 return contentProvider; |
|
388 } |
|
389 |
|
390 /** |
|
391 * Removes triggers |
|
392 */ |
|
393 public void removeTriggers() { |
|
394 startTriggers.clear(); |
|
395 stopTriggers.clear(); |
|
396 } |
|
397 |
|
398 /** |
|
399 * Gets start triggers |
|
400 * |
|
401 * @return the startTriggers |
|
402 */ |
|
403 public List<TriggerTreeTextItem> getStartTriggers() { |
|
404 return startTriggers; |
|
405 } |
|
406 |
|
407 /** |
|
408 * Gets stop triggers |
|
409 * |
|
410 * @return the stopTriggers |
|
411 */ |
|
412 public List<TriggerTreeTextItem> getStopTriggers() { |
|
413 return stopTriggers; |
|
414 } |
|
415 |
|
416 /** |
|
417 * Gets activation triggers |
|
418 * |
|
419 * @return the activationTriggers |
|
420 */ |
|
421 public List<TriggerTreeTextItem> getActivationTriggers() { |
|
422 return activationTriggers; |
|
423 } |
|
424 |
|
425 /** |
|
426 * Enable variabletracing rule |
|
427 * |
|
428 * @param item |
|
429 * the rule item |
|
430 */ |
|
431 public void enableRule(TriggerTreeItem item) { |
|
432 if (item instanceof TriggerTreeTextItem) { |
|
433 TriggerTreeTextItem newItem = (TriggerTreeTextItem) item; |
|
434 activationTriggers.add(newItem); |
|
435 } |
|
436 } |
|
437 } |