1 package fr.ifremer.tutti.ui.swing.update.module;
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
27 import com.google.common.base.Preconditions;
28 import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroContext;
29 import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroResult;
30 import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel;
31 import fr.ifremer.tutti.service.PersistenceService;
32 import fr.ifremer.tutti.service.referential.TuttiReferentialSynchronizeService;
33 import fr.ifremer.tutti.ui.swing.TuttiUIContext;
34 import fr.ifremer.tutti.ui.swing.updater.DeleteHelper;
35 import fr.ifremer.tutti.ui.swing.updater.UpdateModule;
36 import org.apache.commons.io.FileUtils;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.nuiton.jaxx.application.ApplicationIOUtil;
40 import org.nuiton.jaxx.application.ApplicationTechnicalException;
41 import org.nuiton.jaxx.application.swing.action.ApplicationActionUI;
42 import org.nuiton.jaxx.application.type.ApplicationProgressionModel;
43 import org.nuiton.updater.ApplicationInfo;
44 import org.nuiton.updater.ApplicationUpdater;
45
46 import java.io.File;
47 import java.io.IOException;
48
49 import static org.nuiton.i18n.I18n.t;
50
51
52
53
54
55
56
57 public class DbModuleUpdater extends ModuleUpdaterSupport {
58
59
60 private static final Log log = LogFactory.getLog(DbModuleUpdater.class);
61
62 protected boolean dbInstalled;
63
64 protected boolean dbUpdated;
65
66 public DbModuleUpdater() {
67 super(UpdateModule.db);
68 }
69
70 public boolean isDbInstalled() {
71 return dbInstalled;
72 }
73
74 public boolean isDbUpdated() {
75 return dbUpdated;
76 }
77
78 @Override
79 protected void onUpdateToDo(TuttiUIContext context, ApplicationInfo info) {
80
81 if (info == null) {
82 dbInstalled = false;
83 dbUpdated = false;
84 } else {
85
86 if (log.isInfoEnabled()) {
87 log.info("Find a updatable module : " + updateModule);
88 }
89
90 if (context.isDbExist()) {
91
92
93 dbUpdated = true;
94 } else {
95
96
97 dbInstalled = true;
98 }
99 }
100
101 }
102
103 @Override
104 public void onUpdateDone(TuttiUIContext context, ApplicationInfo info) {
105
106 if (log.isInfoEnabled()) {
107 log.info(String.format(
108 "A db update was downloaded (oldVersion: %s, newVersion: %s).",
109 info.oldVersion, info.newVersion));
110 }
111
112 if (dbInstalled || dbUpdated) {
113
114 File source = getDbDirectory(info);
115
116 if (dbInstalled) {
117
118
119 prepareFirstDatabase(context, info, source);
120
121 } else if (dbUpdated) {
122
123
124 synchronizeDatabase(context, info, source);
125
126 }
127
128 if (log.isInfoEnabled()) {
129 log.info("Delete update directory: " + source);
130 }
131 try {
132 FileUtils.deleteDirectory(source);
133 } catch (IOException e) {
134 throw new ApplicationTechnicalException(t("tutti.applicationUpdater.prepareFirstDB.deleteDirectory.error", source), e);
135 }
136
137 }
138
139 }
140
141 @Override
142 public String getLabel() {
143 return t("tutti.update.db");
144 }
145
146 protected void prepareFirstDatabase(TuttiUIContext context, ApplicationInfo info, File source) {
147
148 if (log.isInfoEnabled()) {
149 log.info("First time database was downloaded at version: " + info.newVersion);
150 }
151
152 File target = context.getConfig().getDbDirectory();
153 if (log.isInfoEnabled()) {
154 log.info("Copy from " + source + " to " + target);
155 }
156
157 try {
158 FileUtils.copyDirectory(source, target);
159 } catch (IOException e) {
160 throw new ApplicationTechnicalException(t("tutti.applicationUpdater.prepareFirstDB.copyDirectory.error", source, target), e);
161 }
162
163 }
164
165 protected void synchronizeDatabase(TuttiUIContext context, ApplicationInfo info, File source) {
166
167 if (log.isInfoEnabled()) {
168 log.info(String.format("A database update was downloaded (oldVersion: %s, newVersion: %s), will launch a referential synchronize operation ", info.oldVersion, info.newVersion));
169 }
170
171 TuttiReferentialSynchronizeService service = context.getTuttiReferentialSynchronizeService();
172
173 File dbDirectory = getDbDirectoryCopy(source);
174
175 ReferentialSynchroContext synchroContext = service.createSynchroContext(dbDirectory);
176 ReferentialSynchroResult result = synchroContext.getResult();
177
178 ApplicationActionUI actionUI = context.getActionUI();
179 actionUI.getModel().setProgressionModel(new DelegateProgressionModel(result.getProgressionModel()));
180 service.prepare(synchroContext);
181
182 if (!result.isSuccess()) {
183 throw new ApplicationTechnicalException(t("tutti.applicationUpdater.synchroDB.prepare.error"), result.getError());
184 }
185
186 service.synchronize(synchroContext);
187
188 if (!result.isSuccess()) {
189 throw new ApplicationTechnicalException(t("tutti.applicationUpdater.synchroDB.synchro.error"), result.getError());
190 }
191
192
193 if (log.isInfoEnabled()) {
194 log.info("Reset all caches.");
195 }
196 PersistenceService persistence = context.getPersistenceService();
197 persistence.clearAllCaches();
198
199
200 SampleCategoryModel sampleCategoryModel = context.getConfig().getSampleCategoryModel();
201 if (log.isInfoEnabled()) {
202 log.info("SampleCategoryModel to reload: " + sampleCategoryModel);
203 }
204 if (log.isInfoEnabled()) {
205 log.info("Clean data context.");
206 }
207 context.getDataContext().clearContext();
208 if (log.isInfoEnabled()) {
209 log.info("SampleCategoryModel to reload (after clearContext): " + sampleCategoryModel);
210 }
211 context.getDataContext().setSampleCategoryModel(sampleCategoryModel);
212
213
214 File target = context.getConfig().getDbDirectory();
215 File versionFile = ApplicationUpdater.getVersionFile(target);
216 if (log.isInfoEnabled()) {
217 log.info("Replace content of file " + versionFile + " with " + info.newVersion);
218 }
219 try {
220 ApplicationUpdater.storeVersionFile(target, info.newVersion);
221 } catch (IOException e) {
222 throw new ApplicationTechnicalException(
223 t("tutti.applicationUpdater.synchroDB.writeVersion.error", versionFile));
224 }
225 }
226
227 protected File getDbDirectory(ApplicationInfo info) {
228 File[] sources = info.destDir.listFiles();
229 Preconditions.checkNotNull(sources, "Downloaded db must have at least on directory, see " + info.destDir);
230 Preconditions.checkState(sources.length == 1, "Downloaded db should contains one directory at " + info.destDir);
231 return sources[0];
232 }
233
234 protected File getDbDirectoryCopy(File source) {
235
236 File temporaryDirectory = ApplicationIOUtil.createTemporaryDirectory(this.toString());
237 File[] files = source.listFiles();
238 if (files != null) {
239
240 for (File file : files) {
241 ApplicationIOUtil.copyFileToDirectory(file, temporaryDirectory, "Can't copy file " + file + " to directory " + temporaryDirectory);
242 }
243
244 }
245
246 try {
247 DeleteHelper.deleteDirectoryOnExit(temporaryDirectory.toPath());
248 } catch (IOException e) {
249 throw new ApplicationTechnicalException("Can't mark directory " + temporaryDirectory + "to be deleted on exit", e);
250 }
251
252 return temporaryDirectory;
253
254 }
255
256 private static class DelegateProgressionModel extends ApplicationProgressionModel {
257
258 private static final long serialVersionUID = 1L;
259
260 private final fr.ifremer.adagio.core.type.ProgressionModel progressionModel;
261
262 public DelegateProgressionModel(fr.ifremer.adagio.core.type.ProgressionModel progressionModel) {
263
264 this.progressionModel = progressionModel;
265 this.progressionModel.addPropertyChangeListener(evt -> firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()));
266 }
267
268 @Override
269 public void setMessage(String message) {
270 progressionModel.setMessage(message);
271 }
272
273 @Override
274 public void increments(String message) {
275 progressionModel.increments(message);
276 }
277
278 @Override
279 public String getMessage() {
280 return progressionModel.getMessage();
281 }
282
283 @Override
284 public void setRate(float rate) {
285 progressionModel.setRate(rate);
286 }
287
288 @Override
289 public float getRate() {
290 return progressionModel.getRate();
291 }
292
293 @Override
294 public void increments(int nb) {
295 progressionModel.increments(nb);
296 }
297
298 @Override
299 public void setCurrent(int current) {
300 progressionModel.setCurrent(current);
301 }
302
303 @Override
304 public int getCurrent() {
305 return progressionModel.getCurrent();
306 }
307
308 @Override
309 public void adaptTotal(int total) {
310 progressionModel.adaptTotal(total);
311 }
312
313 @Override
314 public void setTotal(int total) {
315 progressionModel.setTotal(total);
316 }
317
318 @Override
319 public int getTotal() {
320 return progressionModel.getTotal();
321 }
322 }
323 }