analysis: Move plugins to their own sub-directory
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / synchronization / SynchronizationBackend.java
1 /*******************************************************************************
2 * Copyright (c) 2013, 2014 É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.tracecompass.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.tracecompass.internal.tmf.core.Activator;
26
27 /**
28 * Class to fetch and save synchronization information between traces
29 *
30 * @author Geneviève Bastien
31 */
32 public class SynchronizationBackend {
33
34 private static final int SYNC_FILE_MAGIC_NUMBER = 0x0DECAF00;
35
36 private static final int FILE_VERSION = 1;
37
38 private static final int HEADER_SIZE = 20;
39
40 private final File fSyncFile;
41
42 /**
43 * Constructor
44 *
45 * @param syncFile
46 * The file containing synchronization information
47 * @throws IOException
48 * If the file couldn't be opened for some reason
49 */
50 public SynchronizationBackend(File syncFile) throws IOException {
51 this(syncFile, true);
52 }
53
54 /**
55 * Constructor with possibility to tell whether to throw errors on exception
56 * or not
57 *
58 * @param syncFile
59 * The file containing synchronization information
60 * @param throwErrors
61 * Whether to throw exceptions or not
62 * @throws IOException
63 * If the file couldn't be opened for some reason
64 */
65 public SynchronizationBackend(File syncFile, boolean throwErrors) throws IOException {
66 /*
67 * Open the file ourselves, get the header information we need, then
68 * pass on the descriptor.
69 */
70 int res;
71
72 fSyncFile = syncFile;
73
74 if (syncFile == null) {
75 return;
76 }
77
78 if (!syncFile.exists()) {
79 if (throwErrors) {
80 throw new IOException("Selected synchronization file does not exist"); //$NON-NLS-1$
81 }
82 return;
83 }
84 if (syncFile.length() <= 0) {
85 if (throwErrors) {
86 throw new IOException("Invalid synchronization file selected, " + //$NON-NLS-1$
87 "target file is empty"); //$NON-NLS-1$
88 }
89 return;
90 }
91
92 try (FileInputStream fis = new FileInputStream(syncFile);
93 FileChannel fc = fis.getChannel();) {
94 ByteBuffer buffer = ByteBuffer.allocate(HEADER_SIZE);
95 buffer.clear();
96 fc.read(buffer);
97 buffer.flip();
98
99 /*
100 * Check the magic number,to make sure we're opening the right type
101 * of file
102 */
103 res = buffer.getInt();
104 if (res != SYNC_FILE_MAGIC_NUMBER) {
105 throw new IOException("Selected file does not" + //$NON-NLS-1$
106 "look like a synchronization file"); //$NON-NLS-1$
107 }
108
109 res = buffer.getInt(); /* Major version number */
110 if (res != FILE_VERSION) {
111 throw new IOException("Select synchronization file is of an older " //$NON-NLS-1$
112 + "format. Synchronization will have to be computed again."); //$NON-NLS-1$
113 }
114
115 res = buffer.getInt(); /* Minor version number */
116 }
117 }
118
119 /**
120 * Opens an existing synchronization file
121 *
122 * @return The synchronization algorithm contained in the file
123 * @throws IOException
124 * Exception returned file functions
125 */
126 public SynchronizationAlgorithm openExistingSync() throws IOException {
127
128 if (fSyncFile == null) {
129 return null;
130 }
131
132 try (/* Set the position after the header */
133 FileInputStream fis = new FileInputStream(fSyncFile);
134 FileChannel fc = fis.getChannel().position(HEADER_SIZE);
135 /* Read the input stream */
136 ObjectInputStream ois = new ObjectInputStream(fis);) {
137
138 return (SynchronizationAlgorithm) ois.readObject();
139 } catch (ClassNotFoundException e) {
140 return null;
141 }
142
143
144 }
145
146 /**
147 * Saves the synchronization algorithm object to file
148 *
149 * @param syncAlgo
150 * The algorithm to save
151 * @throws FileNotFoundException
152 * propagate callee's exceptions
153 */
154 public void saveSync(SynchronizationAlgorithm syncAlgo) throws FileNotFoundException {
155
156 if (fSyncFile == null) {
157 return;
158 }
159
160 /* Save the header of the file */
161 try (FileOutputStream fos = new FileOutputStream(fSyncFile, false);
162 FileChannel fc = fos.getChannel();) {
163
164 ByteBuffer buffer = ByteBuffer.allocate(HEADER_SIZE);
165 buffer.clear();
166
167 fc.position(0);
168
169 buffer.putInt(SYNC_FILE_MAGIC_NUMBER);
170
171 buffer.putInt(FILE_VERSION);
172
173 buffer.flip();
174 int res = fc.write(buffer);
175 assert (res <= HEADER_SIZE);
176 /* done writing the file header */
177
178 fc.position(HEADER_SIZE);
179
180 try (ObjectOutputStream oos = new ObjectOutputStream(fos);) {
181 oos.writeObject(syncAlgo);
182 }
183
184 } catch (FileNotFoundException e) {
185 /* Send this upwards */
186 throw e;
187 } catch (IOException e) {
188 /* Handle other cases of IOException's */
189 Activator.logError("Error saving trace synchronization data", e); //$NON-NLS-1$
190 }
191 return;
192
193 }
194
195 }
This page took 0.033953 seconds and 5 git commands to generate.