Fix some null warnings
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.core / src / org / eclipse / tracecompass / analysis / timing / core / segmentstore / AbstractSegmentStoreAnalysisModule.java
1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
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;
10
11 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
12
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.Collection;
21 import java.util.List;
22
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.segmentstore.core.ISegment;
27 import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
28 import org.eclipse.tracecompass.segmentstore.core.treemap.TreeMapStore;
29 import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
30 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
31 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
32 import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
33 import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
34 import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
35 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
36 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
37
38 import com.google.common.collect.ImmutableList;
39
40 /**
41 * Abstract analysis module to generate a segment store. It is a base class that
42 * can be used as a shortcut by analysis who just need to build a single segment
43 * store.
44 *
45 * @author Bernd Hufmann
46 * @since 2.0
47 *
48 */
49 public abstract class AbstractSegmentStoreAnalysisModule extends TmfAbstractAnalysisModule {
50
51 private final ListenerList fListeners = new ListenerList(ListenerList.IDENTITY);
52
53 private @Nullable ISegmentStore<ISegment> fSegmentStore;
54
55 private @Nullable ITmfEventRequest fOngoingRequest = null;
56
57 /**
58 * Listener for the viewers
59 *
60 * @param listener
61 * listener for each type of viewer
62 */
63 public void addListener(IAnalysisProgressListener listener) {
64 fListeners.add(listener);
65 }
66
67 /**
68 * Removes a listener for the viewers
69 *
70 * @param listener
71 * listener for each type of viewer to remove
72 */
73 public void removeListener(IAnalysisProgressListener listener) {
74 fListeners.remove(listener);
75 }
76
77 /**
78 * Returns all the listeners
79 * @return latency listeners
80 */
81 protected Iterable<IAnalysisProgressListener> getListeners() {
82 List<IAnalysisProgressListener> listeners = new ArrayList<>();
83 for (Object listener : fListeners.getListeners()) {
84 if (listener != null) {
85 listeners.add((IAnalysisProgressListener) listener);
86 }
87 }
88 return listeners;
89 }
90
91 /**
92 * Return the pre-defined set of segment aspects exposed by this analysis.
93 *
94 * It should not be null, but could be empty.
95 * @return The segment aspects for this analysis
96 */
97 public Iterable<ISegmentAspect> getSegmentAspects() {
98 Collection<ISegmentAspect> coll = ImmutableList.of();
99 return checkNotNull(coll);
100 }
101
102 /**
103 * Returns the file name for storing segment store
104 * @return segment store fine name
105 */
106 protected abstract String getDataFileName();
107
108 /**
109 * Returns the analysis request for creating the segment store
110 * @param segmentStore
111 * a segment store to fill
112 * @return the segment store analysis request implementation
113 */
114 protected abstract AbstractSegmentStoreAnalysisRequest createAnalysisRequest(ISegmentStore<ISegment> segmentStore);
115
116 /**
117 * Read an object from the ObjectInputStream.
118 *
119 * @param ois
120 * the ObjectInputStream to used
121 * @return the read object
122 * @throws ClassNotFoundException
123 * - Class of a serialized object cannot be found.
124 * @throws IOException
125 * - Any of the usual Input/Output related exceptions.
126 */
127 protected abstract Object[] readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException;
128
129 /**
130 * Returns the result in a from the analysis in a ISegmentStore
131 * @return Results from the analysis in a ISegmentStore
132 */
133 public @Nullable ISegmentStore<ISegment> getResults() {
134 return fSegmentStore;
135 }
136
137 @Override
138 protected void canceling() {
139 ITmfEventRequest req = fOngoingRequest;
140 if ((req != null) && (!req.isCompleted())) {
141 req.cancel();
142 }
143 }
144
145 @Override
146 public void dispose() {
147 super.dispose();
148 ISegmentStore<ISegment> store = fSegmentStore;
149 if (store != null) {
150 store.dispose();
151 }
152 }
153
154 @Override
155 protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException {
156 ITmfTrace trace = checkNotNull(getTrace());
157
158 /* See if the data file already exists on disk */
159 String dir = TmfTraceManager.getSupplementaryFileDir(trace);
160 final Path file = Paths.get(dir, getDataFileName());
161
162 if (Files.exists(file)) {
163 /* Attempt to read the existing file */
164 try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(file))) {
165 Object[] segmentArray = readObject(ois);
166 final ISegmentStore<ISegment> store = new TreeMapStore<>();
167 for (Object element : segmentArray) {
168 if (element instanceof ISegment) {
169 ISegment segment = (ISegment) element;
170 store.add(segment);
171 }
172 }
173 fSegmentStore = store;
174 for (IAnalysisProgressListener listener : getListeners()) {
175 listener.onComplete(this, store);
176 }
177 return true;
178 } catch (IOException | ClassNotFoundException | ClassCastException e) {
179 /*
180 * We did not manage to read the file successfully, we will just
181 * fall-through to rebuild a new one.
182 */
183 try {
184 Files.delete(file);
185 } catch (IOException e1) {
186 }
187 }
188 }
189
190 ISegmentStore<ISegment> syscalls = new TreeMapStore<>();
191
192 /* Cancel an ongoing request */
193 ITmfEventRequest req = fOngoingRequest;
194 if ((req != null) && (!req.isCompleted())) {
195 req.cancel();
196 }
197
198 /* Create a new request */
199 req = createAnalysisRequest(syscalls);
200 fOngoingRequest = req;
201 trace.sendRequest(req);
202
203 try {
204 req.waitForCompletion();
205 } catch (InterruptedException e) {
206 }
207
208 /* Do not process the results if the request was cancelled */
209 if (req.isCancelled() || req.isFailed()) {
210 return false;
211 }
212
213 /* The request will fill 'syscalls' */
214 fSegmentStore = syscalls;
215
216 /* Serialize the collections to disk for future usage */
217 try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(file))) {
218 oos.writeObject(syscalls.toArray());
219 } catch (IOException e) {
220 /* Didn't work, oh well. We will just re-read the trace next time */
221 }
222
223 for (IAnalysisProgressListener listener : getListeners()) {
224 listener.onComplete(this, syscalls);
225 }
226
227 return true;
228 }
229
230 /**
231 * Abstract event request to fill a a segment store
232 */
233 protected static abstract class AbstractSegmentStoreAnalysisRequest extends TmfEventRequest {
234
235 private final ISegmentStore<ISegment> fFullLatencyStore;
236
237 /**
238 * Constructor
239 *
240 * @param latencyStore
241 * a latency segment store to fill
242 */
243 public AbstractSegmentStoreAnalysisRequest(ISegmentStore<ISegment> latencyStore) {
244 super(ITmfEvent.class, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND);
245 /*
246 * We do NOT make a copy here! We want to modify the list that was
247 * passed in parameter.
248 */
249 fFullLatencyStore = latencyStore;
250 }
251
252 /**
253 * Returns the segment store
254 * @return the segment store
255 */
256 public ISegmentStore<ISegment> getSegmentStore() {
257 return fFullLatencyStore;
258 }
259 }
260 }
This page took 0.040392 seconds and 5 git commands to generate.