segment store: introduce a Segment Store Factory and centralize segment stores
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.core / src / org / eclipse / tracecompass / analysis / timing / core / segmentstore / AbstractSegmentStoreAnalysisModule.java
CommitLineData
152630e0 1/*******************************************************************************
65a4afc0 2 * Copyright (c) 2015, 2016 Ericsson
152630e0
BH
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 *******************************************************************************/
9package org.eclipse.tracecompass.analysis.timing.core.segmentstore;
10
11import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
12
13import java.io.IOException;
14import java.io.ObjectInputStream;
15import java.io.ObjectOutputStream;
16import java.nio.file.Files;
17import java.nio.file.Path;
18import java.nio.file.Paths;
76be6c00 19import java.util.ArrayList;
0f769d2b 20import java.util.Collections;
76be6c00 21import java.util.List;
152630e0
BH
22
23import org.eclipse.core.runtime.IProgressMonitor;
76be6c00 24import org.eclipse.core.runtime.ListenerList;
152630e0 25import org.eclipse.jdt.annotation.Nullable;
aa9082f9 26import org.eclipse.tracecompass.common.core.NonNullUtils;
152630e0
BH
27import org.eclipse.tracecompass.segmentstore.core.ISegment;
28import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
664a3a81 29import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory;
152630e0 30import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
152630e0 31import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
18c18ee0 32import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
152630e0
BH
33import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
34import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
35
36/**
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
39 * store.
40 *
41 * @author Bernd Hufmann
42 * @since 2.0
43 *
44 */
0f769d2b 45public abstract class AbstractSegmentStoreAnalysisModule extends TmfAbstractAnalysisModule implements ISegmentStoreProvider {
152630e0 46
76be6c00 47 private final ListenerList fListeners = new ListenerList(ListenerList.IDENTITY);
152630e0
BH
48
49 private @Nullable ISegmentStore<ISegment> fSegmentStore;
50
0f769d2b 51 @Override
152630e0
BH
52 public void addListener(IAnalysisProgressListener listener) {
53 fListeners.add(listener);
54 }
55
0f769d2b 56 @Override
76be6c00
BH
57 public void removeListener(IAnalysisProgressListener listener) {
58 fListeners.remove(listener);
59 }
60
152630e0
BH
61 /**
62 * Returns all the listeners
07b705e8 63 *
76be6c00 64 * @return latency listeners
152630e0 65 */
cabc09fe 66 protected Iterable<IAnalysisProgressListener> getListeners() {
76be6c00
BH
67 List<IAnalysisProgressListener> listeners = new ArrayList<>();
68 for (Object listener : fListeners.getListeners()) {
aa353506
AM
69 if (listener != null) {
70 listeners.add((IAnalysisProgressListener) listener);
71 }
76be6c00
BH
72 }
73 return listeners;
152630e0
BH
74 }
75
0f769d2b 76 @Override
18c18ee0 77 public Iterable<ISegmentAspect> getSegmentAspects() {
0f769d2b 78 return Collections.emptyList();
18c18ee0
BH
79 }
80
152630e0
BH
81 /**
82 * Returns the file name for storing segment store
07b705e8
MK
83 *
84 * @return segment store fine name, or null if you don't want a file
152630e0 85 */
07b705e8
MK
86 protected @Nullable String getDataFileName() {
87 return null;
88 }
152630e0 89
152630e0
BH
90 /**
91 * Read an object from the ObjectInputStream.
92 *
93 * @param ois
94 * the ObjectInputStream to used
95 * @return the read object
96 * @throws ClassNotFoundException
97 * - Class of a serialized object cannot be found.
98 * @throws IOException
99 * - Any of the usual Input/Output related exceptions.
100 */
101 protected abstract Object[] readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException;
102
65a4afc0
JCK
103 /**
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.
108 *
a05d1af8
GB
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
111 *
65a4afc0
JCK
112 * @param segmentStore
113 * The segment store to fill
114 * @param monitor
115 * Progress monitor
116 * @return Whether the segments was resolved successfully or not
117 * @throws TmfAnalysisException
118 * Method may throw an analysis exception
119 */
120 protected abstract boolean buildAnalysisSegments(ISegmentStore<ISegment> segmentStore, IProgressMonitor monitor) throws TmfAnalysisException;
121
0f769d2b 122 @Override
73c74de7 123 public @Nullable ISegmentStore<ISegment> getSegmentStore() {
152630e0
BH
124 return fSegmentStore;
125 }
126
73f1f3ea
BH
127 @Override
128 public void dispose() {
129 super.dispose();
130 ISegmentStore<ISegment> store = fSegmentStore;
131 if (store != null) {
132 store.dispose();
133 }
134 }
135
152630e0
BH
136 @Override
137 protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException {
138 ITmfTrace trace = checkNotNull(getTrace());
139
07b705e8
MK
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);
145
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);
664a3a81 150 ISegmentStore<ISegment> store = SegmentStoreFactory.createSegmentStore(NonNullUtils.checkNotNullContents(segmentArray));
07b705e8 151 fSegmentStore = store;
38e2a2e9 152 sendUpdate(store);
07b705e8
MK
153 return true;
154 } catch (IOException | ClassNotFoundException | ClassCastException e) {
155 /*
156 * We did not manage to read the file successfully, we will
157 * just fall-through to rebuild a new one.
158 */
159 try {
160 Files.delete(file);
161 } catch (IOException e1) {
152630e0 162 }
152630e0
BH
163 }
164 }
165 }
152630e0 166
664a3a81 167 ISegmentStore<ISegment> segmentStore = SegmentStoreFactory.createSegmentStore();
65a4afc0
JCK
168 boolean completed = buildAnalysisSegments(segmentStore, monitor);
169 if (!completed) {
152630e0
BH
170 return false;
171 }
07b705e8
MK
172 fSegmentStore = segmentStore;
173
174 if (dataFileName != null) {
175 String dir = TmfTraceManager.getSupplementaryFileDir(trace);
176 final Path file = Paths.get(dir, dataFileName);
152630e0 177
07b705e8
MK
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) {
182 /*
183 * Didn't work, oh well. We will just re-read the trace next
184 * time
185 */
186 }
152630e0
BH
187 }
188
38e2a2e9 189 sendUpdate(segmentStore);
152630e0
BH
190
191 return true;
192 }
38e2a2e9
JCK
193
194 /**
195 * Send the segment store to all its listener
196 *
197 * @param store
198 * The segment store to broadcast
199 */
200 protected void sendUpdate(final ISegmentStore<ISegment> store) {
201 for (IAnalysisProgressListener listener : getListeners()) {
202 listener.onComplete(this, store);
203 }
204 }
152630e0 205}
This page took 0.047012 seconds and 5 git commands to generate.