1 /*******************************************************************************
2 * Copyright (c) 2015, 2016 Ericsson
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org
.eclipse
.tracecompass
.analysis
.timing
.core
.segmentstore
;
11 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
13 import java
.io
.IOException
;
14 import java
.io
.ObjectInputStream
;
15 import java
.io
.ObjectOutputStream
;
16 import java
.nio
.file
.Files
;
17 import java
.nio
.file
.Path
;
18 import java
.nio
.file
.Paths
;
19 import java
.util
.ArrayList
;
20 import java
.util
.Collections
;
21 import java
.util
.List
;
23 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
24 import org
.eclipse
.core
.runtime
.ListenerList
;
25 import org
.eclipse
.jdt
.annotation
.Nullable
;
26 import org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
;
27 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
28 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegmentStore
;
29 import org
.eclipse
.tracecompass
.segmentstore
.core
.SegmentStoreFactory
;
30 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.TmfAbstractAnalysisModule
;
31 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfAnalysisException
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.segment
.ISegmentAspect
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
37 * Abstract analysis module to generate a segment store. It is a base class that
38 * can be used as a shortcut by analysis who just need to build a single segment
41 * @author Bernd Hufmann
45 public abstract class AbstractSegmentStoreAnalysisModule
extends TmfAbstractAnalysisModule
implements ISegmentStoreProvider
{
47 private final ListenerList fListeners
= new ListenerList(ListenerList
.IDENTITY
);
49 private @Nullable ISegmentStore
<ISegment
> fSegmentStore
;
52 public void addListener(IAnalysisProgressListener listener
) {
53 fListeners
.add(listener
);
57 public void removeListener(IAnalysisProgressListener listener
) {
58 fListeners
.remove(listener
);
62 * Returns all the listeners
64 * @return latency listeners
66 protected Iterable
<IAnalysisProgressListener
> getListeners() {
67 List
<IAnalysisProgressListener
> listeners
= new ArrayList
<>();
68 for (Object listener
: fListeners
.getListeners()) {
69 if (listener
!= null) {
70 listeners
.add((IAnalysisProgressListener
) listener
);
77 public Iterable
<ISegmentAspect
> getSegmentAspects() {
78 return Collections
.emptyList();
82 * Returns the file name for storing segment store
84 * @return segment store fine name, or null if you don't want a file
86 protected @Nullable String
getDataFileName() {
91 * Read an object from the ObjectInputStream.
94 * the ObjectInputStream to used
95 * @return the read object
96 * @throws ClassNotFoundException
97 * - Class of a serialized object cannot be found.
99 * - Any of the usual Input/Output related exceptions.
101 protected abstract Object
[] readObject(ObjectInputStream ois
) throws ClassNotFoundException
, IOException
;
104 * Fills the segment store. This is the main method that children classes
105 * need to implement to build the segment store. For example, if the
106 * segments are found by parsing the events of a trace, the event request
107 * would be done in this method.
109 * Note: After this method, the segment store should be completed, so it
110 * should also close the segment store at the end of the analysis
112 * @param segmentStore
113 * The segment store to fill
116 * @return Whether the segments was resolved successfully or not
117 * @throws TmfAnalysisException
118 * Method may throw an analysis exception
120 protected abstract boolean buildAnalysisSegments(ISegmentStore
<ISegment
> segmentStore
, IProgressMonitor monitor
) throws TmfAnalysisException
;
123 public @Nullable ISegmentStore
<ISegment
> getSegmentStore() {
124 return fSegmentStore
;
128 public void dispose() {
130 ISegmentStore
<ISegment
> store
= fSegmentStore
;
137 protected boolean executeAnalysis(IProgressMonitor monitor
) throws TmfAnalysisException
{
138 ITmfTrace trace
= checkNotNull(getTrace());
140 final @Nullable String dataFileName
= getDataFileName();
141 if (dataFileName
!= null) {
142 /* See if the data file already exists on disk */
143 String dir
= TmfTraceManager
.getSupplementaryFileDir(trace
);
144 final Path file
= Paths
.get(dir
, dataFileName
);
146 if (Files
.exists(file
)) {
147 /* Attempt to read the existing file */
148 try (ObjectInputStream ois
= new ObjectInputStream(Files
.newInputStream(file
))) {
149 Object
[] segmentArray
= readObject(ois
);
150 ISegmentStore
<ISegment
> store
= SegmentStoreFactory
.createSegmentStore(NonNullUtils
.checkNotNullContents(segmentArray
));
151 fSegmentStore
= store
;
154 } catch (IOException
| ClassNotFoundException
| ClassCastException e
) {
156 * We did not manage to read the file successfully, we will
157 * just fall-through to rebuild a new one.
161 } catch (IOException e1
) {
167 ISegmentStore
<ISegment
> segmentStore
= SegmentStoreFactory
.createSegmentStore();
168 boolean completed
= buildAnalysisSegments(segmentStore
, monitor
);
172 fSegmentStore
= segmentStore
;
174 if (dataFileName
!= null) {
175 String dir
= TmfTraceManager
.getSupplementaryFileDir(trace
);
176 final Path file
= Paths
.get(dir
, dataFileName
);
178 /* Serialize the collections to disk for future usage */
179 try (ObjectOutputStream oos
= new ObjectOutputStream(Files
.newOutputStream(file
))) {
180 oos
.writeObject(segmentStore
.toArray());
181 } catch (IOException e
) {
183 * Didn't work, oh well. We will just re-read the trace next
189 sendUpdate(segmentStore
);
195 * Send the segment store to all its listener
198 * The segment store to broadcast
200 protected void sendUpdate(final ISegmentStore
<ISegment
> store
) {
201 for (IAnalysisProgressListener listener
: getListeners()) {
202 listener
.onComplete(this, store
);