1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
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
8 ******************************************************************************/
9 package org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.pattern
.stateprovider
;
11 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
14 import java
.util
.Comparator
;
15 import java
.util
.List
;
16 import java
.util
.concurrent
.CountDownLatch
;
17 import java
.util
.stream
.Collectors
;
19 import org
.eclipse
.core
.runtime
.IPath
;
20 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
21 import org
.eclipse
.core
.runtime
.IStatus
;
22 import org
.eclipse
.jdt
.annotation
.NonNull
;
23 import org
.eclipse
.jdt
.annotation
.Nullable
;
24 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.segmentstore
.IAnalysisProgressListener
;
25 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.segmentstore
.ISegmentStoreProvider
;
26 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.model
.TmfXmlPatternSegmentBuilder
;
27 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.segment
.TmfXmlPatternSegment
;
28 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
29 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegmentStore
;
30 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
31 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.TmfAbstractAnalysisModule
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfAnalysisException
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.segment
.ISegmentAspect
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.ITmfAnalysisModuleWithStateSystems
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
38 import com
.google
.common
.collect
.ImmutableList
;
41 * Analysis module for pattern matching within traces. This module creates two
42 * sub-analyses : A state system analysis that will execute the pattern on the
43 * trace and a segment store analysis that will build a segment store with the
44 * segments generated by the state system analysis.
46 * @author Jean-Christian Kouame
48 public class XmlPatternAnalysis
extends TmfAbstractAnalysisModule
implements ITmfAnalysisModuleWithStateSystems
, ISegmentStoreProvider
{
51 * Segment store supplementary file extension
53 public static final @NonNull String SEGMENT_STORE_EXTENSION
= ".dat"; //$NON-NLS-1$
55 * state system supplementary file extension
57 private static final @NonNull String STATE_SYSTEM_EXTENSION
= ".ht"; //$NON-NLS-1$
58 private static final String SEGMENT_STORE_SUFFIX
= " segment store"; //$NON-NLS-1$
59 private static final String STATE_SYSTEM_SUFFIX
= " state system"; //$NON-NLS-1$
60 private final CountDownLatch fInitialized
= new CountDownLatch(1);
61 private XmlPatternStateSystemModule fStateSystemModule
;
62 private XmlPatternSegmentStoreModule fSegmentStoreModule
;
63 private boolean fInitializationSucceeded
;
68 public XmlPatternAnalysis() {
70 fSegmentStoreModule
= new XmlPatternSegmentStoreModule(this);
71 fStateSystemModule
= new XmlPatternStateSystemModule(fSegmentStoreModule
);
75 public @Nullable ISegmentStore
<@NonNull ISegment
> getSegmentStore() {
76 return fSegmentStoreModule
.getSegmentStore();
80 public @Nullable ITmfStateSystem
getStateSystem(@NonNull String id
) {
81 return fStateSystemModule
.getStateSystem(id
);
85 public @NonNull Iterable
<@NonNull ITmfStateSystem
> getStateSystems() {
86 return fStateSystemModule
.getStateSystems();
90 public boolean waitForInitialization() {
93 } catch (InterruptedException e
) {
96 return fInitializationSucceeded
;
100 protected boolean executeAnalysis(@NonNull IProgressMonitor monitor
) throws TmfAnalysisException
{
101 ITmfTrace trace
= getTrace();
103 /* This analysis was cancelled in the meantime */
104 analysisReady(false);
108 File segmentStoreFile
= getSupplementaryFile(getSegmentStoreFileName());
109 File stateSystemFile
= getSupplementaryFile(getStateSystemFileName());
110 if (segmentStoreFile
== null || stateSystemFile
== null) {
111 analysisReady(false);
115 if (!segmentStoreFile
.exists()) {
116 fStateSystemModule
.cancel();
117 stateSystemFile
.delete();
120 IStatus segmentStoreStatus
= fSegmentStoreModule
.schedule();
121 IStatus stateSystemStatus
= fStateSystemModule
.schedule();
122 if (!(segmentStoreStatus
.isOK() && stateSystemStatus
.isOK())) {
124 analysisReady(false);
128 /* Wait until the state system module is initialized */
129 if (!fStateSystemModule
.waitForInitialization()) {
130 analysisReady(false);
135 ITmfStateSystem stateSystem
= fStateSystemModule
.getStateSystem();
136 if (stateSystem
== null) {
137 analysisReady(false);
138 throw new IllegalStateException("Initialization of the state system module succeeded but the statesystem is null"); //$NON-NLS-1$
143 return fStateSystemModule
.waitForCompletion(monitor
) && fSegmentStoreModule
.waitForCompletion(monitor
);
147 protected void canceling() {
151 private void cancelSubAnalyses() {
152 fStateSystemModule
.cancel();
153 fSegmentStoreModule
.cancel();
157 public void dispose() {
159 * The sub-analyses are not registered to the trace directly, so we need
160 * to tell them when the trace is disposed.
163 fStateSystemModule
.dispose();
164 fSegmentStoreModule
.dispose();
168 public void setId(@NonNull String id
) {
170 fStateSystemModule
.setId(id
);
171 fSegmentStoreModule
.setId(id
);
175 public void setName(@NonNull String name
) {
177 fStateSystemModule
.setName(name
+ STATE_SYSTEM_SUFFIX
);
178 fSegmentStoreModule
.setName(name
+ SEGMENT_STORE_SUFFIX
);
182 public boolean setTrace(ITmfTrace trace
) throws TmfAnalysisException
{
183 if (!super.setTrace(trace
)) {
188 * Since these sub-analyzes are not built from an extension point, we
189 * have to assign the trace ourselves. Very important to do so before
190 * calling schedule()!
192 return fSegmentStoreModule
.setTrace(trace
) && fStateSystemModule
.setTrace(trace
);
196 * Sets the file path of the XML file and the id of pattern analysis in the
200 * The full path to the XML file
202 public void setXmlFile(IPath file
) {
203 fStateSystemModule
.setXmlFile(file
);
207 * Make the module available and set whether the initialization succeeded or
208 * not. If not, no state system is available and
209 * {@link #waitForInitialization()} should return false.
212 * True if the initialization went well, false otherwise
214 private void analysisReady(boolean succeeded
) {
215 fInitializationSucceeded
= succeeded
;
216 fInitialized
.countDown();
219 private @Nullable File
getSupplementaryFile(String filename
) {
220 ITmfTrace trace
= getTrace();
224 String directory
= TmfTraceManager
.getSupplementaryFileDir(trace
);
225 File file
= new File(directory
+ filename
);
229 private String
getStateSystemFileName() {
230 return fStateSystemModule
.getId() + STATE_SYSTEM_EXTENSION
;
233 private String
getSegmentStoreFileName() {
234 return fSegmentStoreModule
.getId() + SEGMENT_STORE_EXTENSION
;
238 public void addListener(@NonNull IAnalysisProgressListener listener
) {
239 fSegmentStoreModule
.addListener(listener
);
243 public void removeListener(@NonNull IAnalysisProgressListener listener
) {
244 fSegmentStoreModule
.removeListener(listener
);
248 public Iterable
<ISegmentAspect
> getSegmentAspects() {
249 return ImmutableList
.of(PatternSegmentNameAspect
.INSTANCE
, PatternSegmentContentAspect
.INSTANCE
);
252 private static class PatternSegmentNameAspect
implements ISegmentAspect
{
253 public static final @NonNull ISegmentAspect INSTANCE
= new PatternSegmentNameAspect();
255 private PatternSegmentNameAspect() {}
258 public String
getHelpText() {
259 return checkNotNull(Messages
.PatternSegmentNameAspect_HelpText
);
262 public String
getName() {
263 return checkNotNull(Messages
.PatternSegmentNameAspect_Name
);
266 public @Nullable Comparator
<?
> getComparator() {
270 public @Nullable String
resolve(ISegment segment
) {
271 if (segment
instanceof TmfXmlPatternSegment
) {
272 return ((TmfXmlPatternSegment
) segment
).getName()
273 .substring(TmfXmlPatternSegmentBuilder
.PATTERN_SEGMENT_NAME_PREFIX
.length());
279 private static class PatternSegmentContentAspect
implements ISegmentAspect
{
280 public static final @NonNull ISegmentAspect INSTANCE
= new PatternSegmentContentAspect();
282 private PatternSegmentContentAspect() {}
285 public String
getHelpText() {
286 return checkNotNull(Messages
.PatternSegmentContentAspect_HelpText
);
289 public String
getName() {
290 return checkNotNull(Messages
.PatternSegmentContentAspect_Content
);
293 public @Nullable Comparator
<?
> getComparator() {
297 public @Nullable String
resolve(ISegment segment
) {
298 if (segment
instanceof TmfXmlPatternSegment
) {
299 List
<String
> values
= ((TmfXmlPatternSegment
) segment
).getContent().entrySet().stream().map(c
-> c
.getKey() + '=' + c
.getValue()).collect(Collectors
.toList());
300 return String
.join(", ", values
); //$NON-NLS-1$