View Javadoc
1   package fr.ifremer.tutti.ui.swing.updater;
2   
3   /*
4    * #%L
5    * Tutti :: UI Updater
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2012 - 2015 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as
13   * published by the Free Software Foundation, either version 3 of the
14   * License, or (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public
22   * License along with this program.  If not, see
23   * <http://www.gnu.org/licenses/gpl-3.0.html>.
24   * #L%
25   */
26  
27  import javax.swing.JOptionPane;
28  import java.io.IOException;
29  import java.io.InputStream;
30  import java.net.URL;
31  import java.nio.charset.Charset;
32  import java.nio.file.Files;
33  import java.nio.file.Path;
34  import java.nio.file.Paths;
35  import java.nio.file.StandardCopyOption;
36  import java.text.SimpleDateFormat;
37  import java.util.Date;
38  
39  /**
40   * @author Ludovic Pecquot (ludovic.pecquot@e-is.pro)
41   * @author tony Chemit (chemit@codelutin.com)
42   * @since 3.12
43   */
44  public class Updater {
45  
46      public static final int NORMAL_EXIT_CODE = 0;
47  
48      public static final int ERROR_EXIT_CODE = 1;
49  
50      public static final int RUNTIME_UPDATE_EXIT_CODE = 90;
51  
52      private final UpdaterFileSystemPathes pathHelper;
53  
54      public static void main(String... args) {
55  
56          Updater updater = new Updater();
57          int exitCode = updater.execute();
58          System.exit(exitCode);
59  
60      }
61  
62      public Updater() {
63  
64          // Get the current directory where application has been launched
65          Path baseDir = Paths.get(System.getProperty("user.dir"));
66          if (!baseDir.isAbsolute()) {
67              baseDir = baseDir.toFile().getAbsoluteFile().toPath();
68          }
69          System.out.println(String.format("Basedir: %s", baseDir));
70          pathHelper = new UpdaterFileSystemPathes(baseDir);
71  
72      }
73  
74      public int execute() {
75  
76          System.out.println("updater started at " + new Date().toString());
77  
78          int exitCode;
79  
80          try {
81  
82              // before trying to update runtime modules
83              beforeUpdateRuntimeModules();
84  
85              // update runtime modules
86              boolean runtimeUpdate = updateRuntimeModules();
87  
88              if (runtimeUpdate) {
89  
90                  // there is some runtime updates
91                  afterUpdateRuntimeModules();
92  
93                  exitCode = RUNTIME_UPDATE_EXIT_CODE;
94  
95              } else {
96  
97                  // update application modules
98                  updateNoneRuntimeModules();
99  
100                 // clean files
101                 cleanFiles();
102 
103                 exitCode = NORMAL_EXIT_CODE;
104 
105             }
106 
107         } catch (Exception ex) {
108 
109             ex.printStackTrace();
110             exitCode = ERROR_EXIT_CODE;
111 
112         }
113 
114         System.out.println("updater ended   at " + new Date().toString() + " with exit code: " + exitCode);
115 
116         return exitCode;
117 
118     }
119 
120     protected void beforeUpdateRuntimeModules() throws IOException {
121 
122         Path runtimeUpdater = pathHelper.getUpdaterScriptPath();
123         Files.deleteIfExists(runtimeUpdater);
124 
125     }
126 
127     protected boolean updateRuntimeModules() throws Exception {
128 
129         boolean mustUpdateRuntime = false;
130 
131         for (UpdateModule updateModule : UpdateModule.values()) {
132 
133             UpdateModuleConfiguration moduleConfiguration = updateModule.getModuleConfiguration();
134             if (moduleConfiguration.isManageByUpdater() && moduleConfiguration.isRuntime()) {
135 
136                 boolean updateFound = updateRuntimeModule(updateModule);
137 
138                 if (updateFound) {
139                     mustUpdateRuntime = true;
140                 }
141 
142             }
143 
144         }
145 
146         return mustUpdateRuntime;
147 
148     }
149 
150     protected void afterUpdateRuntimeModules() throws IOException {
151 
152         Path runtimeUpdater = pathHelper.getUpdaterScriptPath();
153 
154         URL resource = getClass().getResource("/" + runtimeUpdater.getFileName());
155 
156         try (InputStream stream = resource.openStream()) {
157 
158             Path tempFile = Files.createTempFile(runtimeUpdater.getFileName().toFile().getName(), null);
159             Files.copy(stream, tempFile, StandardCopyOption.REPLACE_EXISTING);
160             tempFile.toFile().deleteOnExit();
161 
162             Charset charset = Charset.forName("UTF-8");
163             String content = new String(Files.readAllBytes(tempFile), charset);
164 
165             SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss");
166             content = content.replaceFirst("~~BACKUP_DATE~~", dateFormat.format(new Date()));
167 
168             Files.write(runtimeUpdater, content.getBytes());
169 
170         }
171 
172         pathHelper.makeExecutable(runtimeUpdater);
173 
174         String message = String.format("Une mise à jour de l'exécutable est disponible." +
175                                        "\nVous devez lancer le script '%s' en double cliquant dessus dans un explorateur de fichier." +
176                                        "\nLe script se trouve dans le dossier %s.",
177                                        runtimeUpdater.getFileName(),
178                                        runtimeUpdater.toFile().getParentFile());
179         System.out.println(message);
180         JOptionPane.showMessageDialog(null, message);
181 
182     }
183 
184     protected void updateNoneRuntimeModules() throws IOException {
185 
186         for (UpdateModule updateModule : UpdateModule.values()) {
187 
188             UpdateModuleConfiguration moduleConfiguration = updateModule.getModuleConfiguration();
189 
190             if (moduleConfiguration.isManageByUpdater() && !moduleConfiguration.isRuntime()) {
191 
192                 updateNoneRuntimeModule(updateModule);
193 
194             }
195         }
196 
197     }
198 
199     protected boolean updateRuntimeModule(UpdateModule updateModule) throws IOException {
200 
201         boolean moduleExist = pathHelper.isModuleExists(updateModule);
202         boolean updateModuleExist = pathHelper.isUpdateModuleExists(updateModule);
203 
204         String oldVersion = moduleExist ? pathHelper.getModuleVersion(updateModule) : "None";
205 
206         String moduleNameStr = updateModule.getModuleLoggerName();
207 
208         System.out.println(String.format("%s Current version: %s", moduleNameStr, oldVersion));
209 
210         if (updateModuleExist) {
211 
212             String newVersion = pathHelper.getUpdateModuleVersion(updateModule);
213 
214             System.out.println(String.format("%s New version detected %s", moduleNameStr, newVersion));
215 
216             // Remove older backup
217             pathHelper.removeOlderBackup(updateModule);
218 
219         } else {
220 
221             System.out.println(String.format("%s No update found", moduleNameStr));
222 
223         }
224 
225         return updateModuleExist;
226 
227     }
228 
229     protected void updateNoneRuntimeModule(UpdateModule updateModule) throws IOException {
230 
231         boolean moduleExist = pathHelper.isModuleExists(updateModule);
232         boolean updateModuleExist = pathHelper.isUpdateModuleExists(updateModule);
233 
234         String oldVersion = moduleExist ? pathHelper.getModuleVersion(updateModule) : "None";
235 
236         String moduleNameStr = updateModule.getModuleLoggerName();
237 
238         System.out.println(String.format("%s Current version: %s", moduleNameStr, oldVersion));
239 
240         if (updateModuleExist) {
241 
242             String newVersion = pathHelper.getUpdateModuleVersion(updateModule);
243 
244             System.out.println(String.format("%s New version detected %s", moduleNameStr, newVersion));
245 
246             pathHelper.removeOlderBackup(updateModule);
247 
248             if (moduleExist) {
249 
250                 // Backup existing module
251                 pathHelper.backupModule(updateModule, oldVersion);
252 
253             }
254 
255             // Installing new module
256             System.out.println(String.format("%s Install new version %s", moduleNameStr, newVersion));
257             Path modulePath = pathHelper.getModulePath(updateModule);
258             Path moduleNewPath = pathHelper.getUpdateModulePath(updateModule);
259 
260             try {
261 
262                 pathHelper.move(moduleNewPath, modulePath);
263 
264             } catch (IOException e) {
265 
266                 String message = String.format("La mise à jour du module '%s' a échouée.\nVeuillez contacter un administrateur.", updateModule);
267                 System.out.println(message);
268                 JOptionPane.showMessageDialog(null, message);
269 
270                 e.printStackTrace();
271 
272             }
273 
274         } else {
275 
276             System.out.println(String.format("%s No update found", moduleNameStr));
277 
278         }
279 
280     }
281 
282     protected void cleanFiles() throws IOException {
283 
284         pathHelper.cleanObsoleteFiles();
285         DeleteHelper.deleteDirectory(pathHelper.getUpdateDirectory());
286 
287     }
288 
289 }