0518880fdc1344f4d76a86d72d7e28fb4e097bb8
[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, 2016 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.Collections;
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.internal.analysis.timing.core.store.ArrayListStore;
27 import org.eclipse.tracecompass.segmentstore.core.ISegment;
28 import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
29 import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
30 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
31 import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
32 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
33 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
34
35 /**
36 * Abstract analysis module to generate a segment store. It is a base class that
37 * can be used as a shortcut by analysis who just need to build a single segment
38 * store.
39 *
40 * @author Bernd Hufmann
41 * @since 2.0
42 *
43 */
44 public abstract class AbstractSegmentStoreAnalysisModule extends TmfAbstractAnalysisModule implements ISegmentStoreProvider {
45
46 private final ListenerList fListeners = new ListenerList(ListenerList.IDENTITY);
47
48 private @Nullable ISegmentStore<ISegment> fSegmentStore;
49
50 @Override
51 public void addListener(IAnalysisProgressListener listener) {
52 fListeners.add(listener);
53 }
54
55 @Override
56 public void removeListener(IAnalysisProgressListener listener) {
57 fListeners.remove(listener);
58 }
59
60 /**
61 * Returns all the listeners
62 *
63 * @return latency listeners
64 */
65 protected Iterable<IAnalysisProgressListener> getListeners() {
66 List<IAnalysisProgressListener> listeners = new ArrayList<>();
67 for (Object listener : fListeners.getListeners()) {
68 if (listener != null) {
69 listeners.add((IAnalysisProgressListener) listener);
70 }
71 }
72 return listeners;
73 }
74
75 @Override
76 public Iterable<ISegmentAspect> getSegmentAspects() {
77 return Collections.emptyList();
78 }
79
80 /**
81 * Returns the file name for storing segment store
82 *
83 * @return segment store fine name, or null if you don't want a file
84 */
85 protected @Nullable String getDataFileName() {
86 return null;
87 }
88
89 /**
90 * Read an object from the ObjectInputStream.
91 *
92 * @param ois
93 * the ObjectInputStream to used
94 * @return the read object
95 * @throws ClassNotFoundException
96 * - Class of a serialized object cannot be found.
97 * @throws IOException
98 * - Any of the usual Input/Output related exceptions.
99 */
100 protected abstract Object[] readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException;
101
102 /**
103 * Fills the segment store. This is the main method that children classes
104 * need to implement to build the segment store. For example, if the
105 * segments are found by parsing the events of a trace, the event request
106 * would be done in this method.
107 *
108 * Note: After this method, the segment store should be completed, so it
109 * should also close the segment store at the end of the analysis
110 *
111 * @param segmentStore
112 * The segment store to fill
113 * @param monitor
114 * Progress monitor
115 * @return Whether the segments was resolved successfully or not
116 * @throws TmfAnalysisException
117 * Method may throw an analysis exception
118 */
119 protected abstract boolean buildAnalysisSegments(ISegmentStore<ISegment> segmentStore, IProgressMonitor monitor) throws TmfAnalysisException;
120
121 @Override
122 public @Nullable ISegmentStore<ISegment> getSegmentStore() {
123 return fSegmentStore;
124 }
125
126 @Override
127 public void dispose() {
128 super.dispose();
129 ISegmentStore<ISegment> store = fSegmentStore;
130 if (store != null) {
131 store.dispose();
132 }
133 }
134
135 @Override
136 protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException {
137 ITmfTrace trace = checkNotNull(getTrace());
138
139 final @Nullable String dataFileName = getDataFileName();
140 if (dataFileName != null) {
141 /* See if the data file already exists on disk */
142 String dir = TmfTraceManager.getSupplementaryFileDir(trace);
143 final Path file = Paths.get(dir, dataFileName);
144
145 if (Files.exists(file)) {
146 /* Attempt to read the existing file */
147 try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(file))) {
148 Object[] segmentArray = readObject(ois);
149 final ISegmentStore<ISegment> store = new ArrayListStore<>();
150 for (Object element : segmentArray) {
151 if (element instanceof ISegment) {
152 ISegment segment = (ISegment) element;
153 store.add(segment);
154 }
155 }
156 fSegmentStore = store;
157 sendUpdate(store);
158 return true;
159 } catch (IOException | ClassNotFoundException | ClassCastException e) {
160 /*
161 * We did not manage to read the file successfully, we will
162 * just fall-through to rebuild a new one.
163 */
164 try {
165 Files.delete(file);
166 } catch (IOException e1) {
167 }
168 }
169 }
170 }
171
172 ISegmentStore<ISegment> segmentStore = new ArrayListStore<>();
173 boolean completed = buildAnalysisSegments(segmentStore, monitor);
174 if (!completed) {
175 return false;
176 }
177 fSegmentStore = segmentStore;
178
179 if (dataFileName != null) {
180 String dir = TmfTraceManager.getSupplementaryFileDir(trace);
181 final Path file = Paths.get(dir, dataFileName);
182
183 /* Serialize the collections to disk for future usage */
184 try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(file))) {
185 oos.writeObject(segmentStore.toArray());
186 } catch (IOException e) {
187 /*
188 * Didn't work, oh well. We will just re-read the trace next
189 * time
190 */
191 }
192 }
193
194 sendUpdate(segmentStore);
195
196 return true;
197 }
198
199 /**
200 * Send the segment store to all its listener
201 *
202 * @param store
203 * The segment store to broadcast
204 */
205 protected void sendUpdate(final ISegmentStore<ISegment> store) {
206 for (IAnalysisProgressListener listener : getListeners()) {
207 listener.onComplete(this, store);
208 }
209 }
210 }
This page took 0.034517 seconds and 4 git commands to generate.