Merge branch 'master' into lttng-luna
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / synchronization / SynchronizationBackend.java
1 /*******************************************************************************
2 * Copyright (c) 2013 École Polytechnique de Montréal
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Geneviève Bastien - Initial implementation and API
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.core.synchronization;
14
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.FileNotFoundException;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.io.ObjectOutputStream;
22 import java.nio.ByteBuffer;
23 import java.nio.channels.FileChannel;
24
25 import org.eclipse.linuxtools.internal.tmf.core.Activator;
26
27 /**
28 * Class to fetch and save synchronization information between traces
29 *
30 * @author Geneviève Bastien
31 * @since 3.0
32 */
33 public class SynchronizationBackend {
34
35 private static final int SYNC_FILE_MAGIC_NUMBER = 0x0DECAF00;
36
37 private static final int FILE_VERSION = 1;
38
39 private static final int HEADER_SIZE = 20;
40
41 private final File fSyncFile;
42
43 /**
44 * Constructor
45 *
46 * @param syncFile
47 * The file containing synchronization information
48 * @throws IOException
49 * If the file couldn't be opened for some reason
50 */
51 public SynchronizationBackend(File syncFile) throws IOException {
52 this(syncFile, true);
53 }
54
55 /**
56 * Constructor with possibility to tell whether to throw errors on exception
57 * or not
58 *
59 * @param syncFile
60 * The file containing synchronization information
61 * @param throwErrors
62 * Whether to throw exceptions or not
63 * @throws IOException
64 * If the file couldn't be opened for some reason
65 */
66 public SynchronizationBackend(File syncFile, boolean throwErrors) throws IOException {
67 /*
68 * Open the file ourselves, get the header information we need, then
69 * pass on the descriptor.
70 */
71 int res;
72
73 fSyncFile = syncFile;
74
75 if (syncFile == null) {
76 return;
77 }
78
79 if (!syncFile.exists()) {
80 if (throwErrors) {
81 throw new IOException("Selected synchronization file does not exist"); //$NON-NLS-1$
82 }
83 return;
84 }
85 if (syncFile.length() <= 0) {
86 if (throwErrors) {
87 throw new IOException("Invalid synchronization file selected, " + //$NON-NLS-1$
88 "target file is empty"); //$NON-NLS-1$
89 }
90 return;
91 }
92
93 FileInputStream fis = new FileInputStream(syncFile);
94 ByteBuffer buffer = ByteBuffer.allocate(HEADER_SIZE);
95 FileChannel fc = fis.getChannel();
96 buffer.clear();
97 fc.read(buffer);
98 buffer.flip();
99
100 /*
101 * Check the magic number,to make sure we're opening the right type of
102 * file
103 */
104 res = buffer.getInt();
105 if (res != SYNC_FILE_MAGIC_NUMBER) {
106 fc.close();
107 fis.close();
108 throw new IOException("Selected file does not" + //$NON-NLS-1$
109 "look like a synchronization file"); //$NON-NLS-1$
110 }
111
112 res = buffer.getInt(); /* Major version number */
113 if (res != FILE_VERSION) {
114 fc.close();
115 fis.close();
116 throw new IOException("Select synchronization file is of an older " //$NON-NLS-1$
117 + "format. Synchronization will have to be computed again."); //$NON-NLS-1$
118 }
119
120 res = buffer.getInt(); /* Minor version number */
121
122 fc.close();
123 fis.close();
124 }
125
126 /**
127 * Opens an existing synchronization file
128 *
129 * @return The synchronization algorithm contained in the file
130 * @throws IOException
131 * Exception returned file functions
132 */
133 public SynchronizationAlgorithm openExistingSync() throws IOException {
134
135 if (fSyncFile == null) {
136 return null;
137 }
138
139 /* Set the position after the header */
140 FileInputStream fis = new FileInputStream(fSyncFile);
141 FileChannel fc = fis.getChannel().position(HEADER_SIZE);
142
143 /* Read the input stream */
144 ObjectInputStream ois = new ObjectInputStream(fis);
145 SyncAlgorithmFullyIncremental syncAlgo = null;
146 try {
147 syncAlgo = (SyncAlgorithmFullyIncremental) ois.readObject();
148 } catch (ClassNotFoundException e) {
149
150 }
151 ois.close();
152 fc.close();
153
154 fis.close();
155
156 return syncAlgo;
157 }
158
159 /**
160 * Saves the synchronization algorithm object to file
161 *
162 * @param syncAlgo
163 * The algorithm to save
164 * @throws FileNotFoundException
165 * propagate callee's exceptions
166 */
167 public void saveSync(SynchronizationAlgorithm syncAlgo) throws FileNotFoundException {
168
169 if (fSyncFile == null) {
170 return;
171 }
172
173 FileChannel fc;
174 FileOutputStream fos;
175 ObjectOutputStream oos;
176 ByteBuffer buffer;
177 int res;
178
179 fos = new FileOutputStream(fSyncFile, false);
180 fc = fos.getChannel();
181
182 buffer = ByteBuffer.allocate(HEADER_SIZE);
183 buffer.clear();
184
185 /* Save the header of the file */
186 try {
187 fc.position(0);
188
189 buffer.putInt(SYNC_FILE_MAGIC_NUMBER);
190
191 buffer.putInt(FILE_VERSION);
192
193 buffer.flip();
194 res = fc.write(buffer);
195 assert (res <= HEADER_SIZE);
196 /* done writing the file header */
197
198 fc.position(HEADER_SIZE);
199
200 oos = new ObjectOutputStream(fos);
201 oos.writeObject(syncAlgo);
202 oos.close();
203
204 } catch (IOException e) {
205 /* We should not have any problems at this point... */
206 Activator.logError("Error saving trace synchronization data", e); //$NON-NLS-1$
207 } finally {
208 try {
209 fc.close();
210 fos.close();
211 } catch (IOException e) {
212 Activator.logError("Error closing synchronization file", e); //$NON-NLS-1$
213 }
214 }
215 return;
216
217 }
218
219 }
This page took 0.035057 seconds and 5 git commands to generate.