View Javadoc
1   package fr.ifremer.tutti.persistence.service.referential.synchro;
2   
3   /*
4    * #%L
5    * Tutti :: Persistence
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 com.google.common.collect.Maps;
28  import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroDatabaseMetadata;
29  import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroResult;
30  import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroServiceImpl;
31  import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTableMetadata;
32  import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTableTool;
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  import org.springframework.context.annotation.Lazy;
36  import org.springframework.stereotype.Service;
37  
38  import java.sql.Connection;
39  import java.sql.PreparedStatement;
40  import java.sql.ResultSet;
41  import java.sql.SQLException;
42  import java.sql.Statement;
43  import java.sql.Timestamp;
44  import java.util.List;
45  import java.util.Map;
46  import java.util.ServiceLoader;
47  
48  /**
49   * @author Kevin Morin (Code Lutin)
50   * @since 4.2
51   */
52  @Service("referentialSynchroServiceTutti")
53  @Lazy
54  public class TuttiReferentialSynchroServiceImpl extends ReferentialSynchroServiceImpl {
55  
56      /**
57       * Logger.
58       */
59      private static final Log log = LogFactory.getLog(TuttiReferentialSynchroServiceImpl.class);
60  
61      protected Map<String, ReferentialUpdateTask> updateTasks;
62  
63      protected Map<String, ReferentialUpdateTask> getUpdateTasks() {
64          if (updateTasks == null) {
65  
66              updateTasks = Maps.newHashMap();
67  
68              ServiceLoader<ReferentialUpdateTask> loader = ServiceLoader.load(ReferentialUpdateTask.class);
69              for (ReferentialUpdateTask task : loader) {
70                  updateTasks.put(task.getTable(), task);
71              }
72  
73          }
74          return updateTasks;
75      }
76  
77      protected void synchronizeTable(ReferentialSynchroDatabaseMetadata dbMetas,
78                                      ReferentialSynchroTableMetadata table,
79                                      Connection localConnection,
80                                      Connection remoteConnection,
81                                      ReferentialSynchroResult result) throws SQLException {
82  
83          Timestamp lastUpdate;
84  
85          log.info("Synchronize table " + table);
86  
87          if (table.getName().toLowerCase().equals("transcribing_item")) {
88  
89              // Specific synchronize logic
90  
91              ReferentialSynchroTableTool localDao = new ReferentialSynchroTableTool(localConnection, table);
92              ReferentialSynchroTableTool remoteDao = new ReferentialSynchroTableTool(remoteConnection, table);
93  
94              // get all data to insert from remote db
95              ResultSet dataToUpdate = remoteDao.getDataToUpdate(null);
96  
97              String tableName = localDao.getTable().getName();
98  
99              result.addTableName(tableName);
100 
101             String tablePrefix = table.getTableLogPrefix() + " - " + result.getNbRows(tableName);
102 
103             // delete table
104             localDao.deleteAll();
105 
106             int countR = 0;
107 
108             // add all data from remote
109             while (dataToUpdate.next()) {
110 
111                 List<Object> pk = table.getPk(dataToUpdate);
112 
113                 localDao.executeInsert(pk, dataToUpdate);
114 
115                 countR++;
116 
117                 reportProgress(result, localDao, countR, tablePrefix);
118             }
119 
120             // No data in local
121             lastUpdate = new Timestamp(0);
122 
123         } else {
124 
125             lastUpdate = getLastUpdateDate(localConnection, table);
126 
127             super.synchronizeTable(dbMetas, table, localConnection, remoteConnection, result);
128 
129         }
130 
131         String tableName = table.getName();
132 
133         ReferentialUpdateTask updateTask = getUpdateTasks().get(tableName);
134 
135         if (updateTask != null) {
136             if (log.isInfoEnabled()) {
137                 log.info(table.getTableLogPrefix() + " - " + result.getNbRows(tableName) + " Will use specific update task: " + updateTask);
138             }
139             updateTask.update(localConnection, lastUpdate);
140         }
141 
142     }
143 
144     /**
145      * Gets the last updateDate for the given {@code table} using
146      * the given datasource.
147      *
148      * @param connection incoming sql connection
149      * @param table      the table to test
150      * @return the last update date of the given table, or {@code null} if table does not use a updateDate columns or if
151      * there is no data in table.
152      * @throws SQLException if any sql problem
153      */
154     protected Timestamp getLastUpdateDate(Connection connection, ReferentialSynchroTableMetadata table) throws SQLException {
155         Timestamp result = null;
156 
157         if (table.isWithUpdateDateColumn()) {
158 
159             String sql = table.getSelectMaxUpdateDateQuery();
160 
161             PreparedStatement statement = connection.prepareStatement(sql);
162             try {
163                 ResultSet resultSet = statement.executeQuery();
164                 if (resultSet.next()) {
165                     result = resultSet.getTimestamp(1);
166                 }
167                 statement.close();
168             } finally {
169                 closeSilently(statement);
170             }
171         }
172         return result;
173     }
174 
175     protected void closeSilently(Statement statement) {
176         try {
177             if (statement != null && !statement.isClosed()) {
178 
179                 statement.close();
180             }
181         } catch (AbstractMethodError e) {
182             if (log.isDebugEnabled()) {
183                 log.debug("Fix this linkage error, damned hsqlsb 1.8.0.7:(");
184             }
185         } catch (IllegalAccessError e) {
186             if (log.isDebugEnabled()) {
187                 log.debug("Fix this IllegalAccessError error, damned hsqlsb 1.8.0.7:(");
188             }
189         } catch (Exception e) {
190             if (log.isErrorEnabled()) {
191                 log.error("Could not close statement, but do not care", e);
192             }
193         }
194     }
195 }