Commit | Line | Data |
---|---|---|
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 | *******************************************************************************/ | |
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; | |
76be6c00 | 19 | import java.util.ArrayList; |
0f769d2b | 20 | import java.util.Collections; |
76be6c00 | 21 | import java.util.List; |
152630e0 BH |
22 | |
23 | import org.eclipse.core.runtime.IProgressMonitor; | |
76be6c00 | 24 | import org.eclipse.core.runtime.ListenerList; |
152630e0 | 25 | import org.eclipse.jdt.annotation.Nullable; |
aa9082f9 | 26 | import org.eclipse.tracecompass.common.core.NonNullUtils; |
152630e0 BH |
27 | import org.eclipse.tracecompass.segmentstore.core.ISegment; |
28 | import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; | |
664a3a81 | 29 | import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory; |
152630e0 | 30 | import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; |
152630e0 | 31 | import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; |
18c18ee0 | 32 | import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect; |
152630e0 BH |
33 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; |
34 | import 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 | 45 | public 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 | } |