1 package fr.ifremer.quadrige2.core.service.persistence;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import com.google.common.base.Preconditions;
27 import fr.ifremer.quadrige2.core.exception.Quadrige2BusinessException;
28 import fr.ifremer.quadrige2.core.exception.Quadrige2TechnicalException;
29 import fr.ifremer.quadrige2.core.config.Quadrige2Configuration;
30 import fr.ifremer.quadrige2.core.config.Quadrige2CoreConfiguration;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.commons.vfs2.AllFileSelector;
34 import org.apache.commons.vfs2.FileName;
35 import org.apache.commons.vfs2.FileObject;
36 import org.apache.commons.vfs2.FileType;
37 import org.joda.time.DateTime;
38 import org.joda.time.format.DateTimeFormat;
39 import org.joda.time.format.DateTimeFormatter;
40 import org.nuiton.jaxx.application.ApplicationIOUtil;
41
42 import java.io.File;
43
44 import static org.nuiton.i18n.I18n.t;
45
46
47
48
49
50
51 public class PersistenceServiceHelper {
52
53 private static final Log LOG = LogFactory.getLog(PersistenceServiceHelper.class);
54
55 public enum ImportStructureType {
56
57 NORMAL,
58 INLINE
59 }
60
61
62 public static final DateTimeFormatter EXPORT_DATE_FORMAT = DateTimeFormat.forPattern("yyyy-MM-dd");
63
64 public static final String EXPORT_DIRECTORY_FORMAT = "%s-%s-%s";
65
66
67
68
69
70
71
72 public static void exportDb(File file) {
73
74
75 try {
76 Thread.sleep(2000);
77 } catch (InterruptedException e) {
78 throw new Quadrige2TechnicalException(e);
79 }
80
81 Quadrige2CoreConfiguration config = Quadrige2CoreConfiguration.getInstance();
82 Preconditions.checkNotNull(config);
83
84
85 Preconditions.checkNotNull(file);
86
87
88 String directoryName = String.format(
89 EXPORT_DIRECTORY_FORMAT,
90 config.getApplicationName(),
91 config.getVersion(),
92 EXPORT_DATE_FORMAT.print(new DateTime()));
93
94 File structureDirectory = new File(config.newTempFile("exportdb"),
95 directoryName);
96
97 try {
98 ApplicationIOUtil.forceMkdir(structureDirectory,
99 t("quadrige2.error.create.directory", structureDirectory));
100
101 if (LOG.isDebugEnabled()) {
102 LOG.debug("Export directory: " + structureDirectory);
103 }
104
105 ApplicationIOUtil.copyDirectory(config.getDbDirectory(),
106 new File(structureDirectory, "db"),
107 t("quadrige2.service.persistence.copyDirectory.db.error"));
108
109 ApplicationIOUtil.copyDirectory(config.getDbAttachmentDirectory(),
110 new File(structureDirectory, "meas_files"),
111 t("quadrige2.service.persistence.copyDirectory.attachment.error"));
112
113
114 ApplicationIOUtil.zip(structureDirectory, file,
115 t("quadrige2.service.persistence.exportDb.zip.error", file));
116
117 } finally {
118
119
120 ApplicationIOUtil.forceDeleteOnExit(
121 structureDirectory,
122 t("quadrige2.service.persistence.exportDb.deleteTempDir.error", structureDirectory));
123 }
124
125 }
126
127
128
129
130
131
132
133
134 public static void importDb(ImportStructureType importStructureType, File file) {
135
136
137
138
139 Quadrige2Configuration config = Quadrige2Configuration.getInstance();
140 Preconditions.checkNotNull(config);
141
142
143 Preconditions.checkNotNull(file);
144
145 File target = config.getDataDirectory();
146
147 if (LOG.isInfoEnabled()) {
148 LOG.info("Import db to " + target);
149 }
150 FileObject fileObject = ApplicationIOUtil.resolveFile(
151 "zip:" + file.getAbsolutePath(),
152 t("quadrige2.service.persistence.getArchive.error", file));
153
154 FileObject[] children = ApplicationIOUtil.getChildren(
155 fileObject,
156 t("quadrige2.service.persistence.openArchive.error", file));
157
158 fileObject = children[0];
159
160 switch (importStructureType) {
161
162 case NORMAL:
163
164 break;
165
166 case INLINE:
167 target = new File(target, "db");
168 ApplicationIOUtil.forceMkdir(
169 target,
170 t("quadrige2.service.persistence.createDbDirectory.error", file));
171
172 break;
173
174 default:
175 break;
176 }
177
178 ApplicationIOUtil.explode(fileObject,
179 target,
180 new AllFileSelector(),
181 t("quadrige2.service.persistence.extractArchive.error", file));
182
183 }
184
185
186
187
188
189
190
191 public static ImportStructureType checkImportStructure(File file) {
192 if (!file.exists()) {
193 throw new Quadrige2BusinessException(t("quadrige2.service.persistence.checkImportStructure.fileNotExist", file));
194 }
195
196
197 FileObject fileObject = ApplicationIOUtil.resolveFile(
198 "zip:" + file.getAbsolutePath(), t("quadrige2.service.persistence.getArchive.error", file));
199
200
201 FileObject[] children = ApplicationIOUtil.getChildren(fileObject, t("quadrige2.service.persistence.openArchive.error", file));
202 if (children.length != 1) {
203 throw new Quadrige2BusinessException(t("quadrige2.service.persistence.checkImportStructure.tooManyChildren", file));
204 }
205 fileObject = children[0];
206
207 ImportStructureType result;
208 children = ApplicationIOUtil.getChildren(fileObject, t("quadrige2.service.persistence.openArchive.error", file));
209
210
211 boolean dbDirectoyDetected = false;
212 for (FileObject child : children) {
213 FileName name = child.getName();
214 if ("db".equals(name.getBaseName())) {
215 dbDirectoyDetected = true;
216 break;
217 }
218 }
219
220 if (dbDirectoyDetected) {
221
222
223 result = ImportStructureType.NORMAL;
224
225 checkArchiveDb(file, fileObject, "db", true);
226 checkArchiveDb(file, fileObject, "meas_files", false);
227 } else {
228
229
230 result = ImportStructureType.INLINE;
231
232
233 boolean hasScriptFile = false;
234 for (FileObject child : children) {
235 FileType type = ApplicationIOUtil.getType(child, "Could not get type of " + child);
236 if (FileType.FILE.equals(type)
237 && "script".equalsIgnoreCase(child.getName().getExtension())) {
238 hasScriptFile = true;
239 break;
240 }
241 }
242 if (!hasScriptFile) {
243 throw new Quadrige2BusinessException(t("quadrige2.service.persistence.checkImportStructure.inlineNoScriptFile"));
244 }
245 }
246
247 if (LOG.isDebugEnabled()) {
248 LOG.debug("Database import type: " + result);
249 }
250
251 return result;
252 }
253
254
255
256
257
258
259
260
261
262 protected static void checkArchiveDb(File file,
263 FileObject fileObject,
264 String dir,
265 boolean required) {
266 FileObject directory = ApplicationIOUtil.getChild(fileObject, dir, t("quadrige2.service.persistence.getChild.error", dir));
267 if (directory == null) {
268
269 String message = t("quadrige2.service.persistence.checkArchiveDb.error", file, dir);
270 if (required) {
271 throw new Quadrige2BusinessException(message);
272 }
273
274 if (LOG.isWarnEnabled()) {
275 LOG.warn(message);
276 }
277 }
278 }
279
280 }