View Javadoc
1   package fr.ifremer.quadrige2.ui.swing.common.callback;
2   
3   /*-
4    * #%L
5    * Quadrige2 Core :: Quadrige2 UI Common
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (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 Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  
27  import com.google.common.base.Preconditions;
28  import com.google.common.collect.Maps;
29  import fr.ifremer.quadrige2.core.security.AuthenticationInfo;
30  import fr.ifremer.quadrige2.ui.swing.common.ApplicationUIContext;
31  import fr.ifremer.quadrige2.ui.swing.common.action.AbstractMainUIAction;
32  import fr.ifremer.quadrige2.ui.swing.common.content.AbstractMainUIHandler;
33  import fr.ifremer.quadrige2.ui.swing.common.model.ProgressionModel;
34  import org.apache.commons.io.FileUtils;
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.nuiton.jaxx.application.ApplicationTechnicalException;
38  import org.nuiton.jaxx.application.swing.action.ApplicationActionException;
39  import org.nuiton.updater.ApplicationInfo;
40  import org.nuiton.updater.ApplicationUpdaterCallback;
41  
42  import java.io.File;
43  import java.io.IOException;
44  import java.util.Map;
45  
46  import static org.nuiton.i18n.I18n.n;
47  import static org.nuiton.i18n.I18n.t;
48  
49  /**
50   * CallBack to update db.
51   *
52   * @since 2.6
53   */
54  public class DatabaseUpdaterCallBack implements ApplicationUpdaterCallback {
55  
56      /** Logger. */
57      private static final Log LOG =
58              LogFactory.getLog(DatabaseUpdaterCallBack.class);
59  
60      /** Constant <code>DB_UPDATE_NAME="db"</code> */
61      public static final String DB_UPDATE_NAME = "db";
62  
63      static {
64          n("quadrige2.update.db");
65      }
66  
67      protected final ApplicationUIContext context;
68  
69      protected final AbstractMainUIHandler handler;
70  
71      protected final ProgressionModel progressionModel;
72  
73      protected boolean dbInstalled;
74  
75      protected boolean dbUpdated;
76  
77      protected final AbstractMainUIAction action;
78  
79      /**
80       * <p>Constructor for DatabaseUpdaterCallBack.</p>
81       *
82       * @param action a {@link AbstractMainUIAction} object.
83       * @param progressionModel a {@link ProgressionModel} object.
84       */
85      public DatabaseUpdaterCallBack(AbstractMainUIAction action, ProgressionModel progressionModel) {
86          this.action = action;
87          this.handler = action.getHandler();
88          this.context = action.getContext();
89          this.progressionModel = progressionModel;
90      }
91  
92      /**
93       * <p>isDbUpdated.</p>
94       *
95       * @return a boolean.
96       */
97      public boolean isDbUpdated() {
98          return dbUpdated;
99      }
100 
101     /**
102      * <p>isDbInstalled.</p>
103      *
104      * @return a boolean.
105      */
106     public boolean isDbInstalled() {
107         return dbInstalled;
108     }
109 
110     /** {@inheritDoc} */
111     @Override
112     public Map<String, ApplicationInfo> updateToDo(Map<String, ApplicationInfo> appToUpdate) {
113         Map<String, ApplicationInfo> result = Maps.newHashMap();
114 
115         ApplicationInfo info = appToUpdate.get(DB_UPDATE_NAME);
116         if (info == null) {
117             dbInstalled = false;
118             dbUpdated = false;
119         } else {
120             result.put(info.name, info);
121 
122             if (info.needAuthentication) {
123 
124                 // ask auth
125                 AuthenticationInfo authenticationInfo = handler.askAuthenticationInfo(info.url);
126                 if (authenticationInfo != null) {
127                     info.setAuthentication(authenticationInfo.getLogin(), authenticationInfo.getPassword().toCharArray());
128                 }
129             }
130 
131             if (context.isDbExist()) {
132 
133                 // when db exists always an update
134                 dbUpdated = true;
135             } else {
136 
137                 // when no db, then always install
138                 dbInstalled = true;
139             }
140         }
141 
142         return result;
143     }
144 
145     /** {@inheritDoc} */
146     @Override
147     public void startUpdate(ApplicationInfo info) {
148 
149         if (dbInstalled) {
150             progressionModel.setMessage(t("quadrige2.applicationUpdater.startUpdate.db.installation", info.newVersion));
151         } else if (dbUpdated) {
152             progressionModel.setMessage(t("quadrige2.applicationUpdater.startUpdate.db.update", info.newVersion));
153         }
154     }
155 
156     /** {@inheritDoc} */
157     @Override
158     public void updateDone(Map<String, ApplicationInfo> appToUpdate,
159                            Map<String, Exception> appUpdateError) {
160 
161         ApplicationInfo info = appToUpdate.get(DB_UPDATE_NAME);
162         Exception error = appUpdateError.get(DB_UPDATE_NAME);
163         if (error != null) {
164 
165             // something bad while updating db
166             if (LOG.isErrorEnabled()) {
167                 LOG.error("Could not update db", error);
168             }
169             String errorMessage;
170             if (info != null && info.needAuthentication) {
171                 errorMessage = t("quadrige2.updateDb.error.with.auth");
172             } else {
173                 errorMessage = t("quadrige2.updateDb.error.with.noauth");
174             }
175             throw ApplicationActionException.propagateError(
176                     action, new ApplicationTechnicalException(errorMessage, error));
177         } else if (info != null) {
178 
179             if (LOG.isInfoEnabled()) {
180                 LOG.info(String.format(
181                         "A db update was downloaded (oldVersion: %s, newVersion: %s), will process it.",
182                         info.oldVersion, info.newVersion));
183             }
184 
185             if (dbInstalled) {
186 
187                 // first database, just copy it to correct directory
188                 prepareFirstDatabase(info);
189             } else if (dbUpdated) {
190 
191             }
192         }
193     }
194 
195     /** {@inheritDoc} */
196     @Override
197     public void aborted(String propertiesURL, Exception eee) {
198         if (LOG.isErrorEnabled()) {
199             LOG.error("Could not update from " + propertiesURL, eee);
200         }
201         throw ApplicationActionException.propagateError(action, eee);
202     }
203 
204     /**
205      * <p>getDbDirectory.</p>
206      *
207      * @param info a {@link ApplicationInfo} object.
208      * @return a {@link File} object.
209      */
210     protected File getDbDirectory(ApplicationInfo info) {
211         File[] sources = info.destDir.listFiles();
212         Preconditions.checkState(
213                 sources != null && sources.length == 1,
214                 "Downloaded db should contains one directory at " + info.destDir);
215         return sources[0];
216     }
217 
218     /**
219      * <p>prepareFirstDatabase.</p>
220      *
221      * @param info a {@link ApplicationInfo} object.
222      */
223     protected void prepareFirstDatabase(ApplicationInfo info) {
224         if (LOG.isInfoEnabled()) {
225             LOG.info("First time database was downloaded at version: " + info.newVersion);
226         }
227         File source = getDbDirectory(info);
228         File target = context.getConfiguration().getDbDirectory();
229         if (LOG.isInfoEnabled()) {
230             LOG.info(String.format("Copy from [%s] to [%s]", source , target));
231         }
232         try {
233             FileUtils.copyDirectory(source, target);
234         } catch (IOException e) {
235             throw new ApplicationTechnicalException(t("quadrige2.applicationUpdater.prepareFirstDB.copyDirectory.error", source, target), e);
236         }
237         try {
238             FileUtils.deleteDirectory(source.getParentFile());
239         } catch (IOException e) {
240             throw new ApplicationTechnicalException(t("quadrige2.applicationUpdater.prepareFirstDB.deleteDirectory.error", target), e);
241         }
242     }
243 }