Tutti-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
January 2014
- 8 participants
- 108 discussions
r1494 - in trunk: . tutti-persistence tutti-service tutti-ui-swing
by tchemit@users.forge.codelutin.com 16 Jan '14
by tchemit@users.forge.codelutin.com 16 Jan '14
16 Jan '14
Author: tchemit
Date: 2014-01-16 18:22:40 +0100 (Thu, 16 Jan 2014)
New Revision: 1494
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1494
Log:
[maven-release-plugin] prepare release tutti-3.0
Modified:
trunk/pom.xml
trunk/tutti-persistence/pom.xml
trunk/tutti-service/pom.xml
trunk/tutti-ui-swing/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2014-01-16 17:19:38 UTC (rev 1493)
+++ trunk/pom.xml 2014-01-16 17:22:40 UTC (rev 1494)
@@ -32,7 +32,7 @@
<groupId>fr.ifremer</groupId>
<artifactId>tutti</artifactId>
- <version>3.0-SNAPSHOT</version>
+ <version>3.0</version>
<packaging>pom</packaging>
<name>Tutti</name>
@@ -97,12 +97,12 @@
</modules>
<scm>
- <url>http://svn.forge.codelutin.com/svn/tutti/trunk</url>
+ <url>http://svn.forge.codelutin.com/svn/tutti/tags/tutti-3.0</url>
<connection>
- scm:svn:http://svn.forge.codelutin.com/svn/tutti/trunk
+ scm:svn:http://svn.forge.codelutin.com/svn/tutti/tags/tutti-3.0
</connection>
<developerConnection>
- scm:svn:http://svn.forge.codelutin.com/svn/tutti/trunk
+ scm:svn:http://svn.forge.codelutin.com/svn/tutti/tags/tutti-3.0
</developerConnection>
</scm>
<distributionManagement>
@@ -744,10 +744,7 @@
<configuration>
<tasks>
<echo message="Copy help to site" />
- <copy verbose="${maven.verbose}"
- failonerror="false"
- overwrite="true"
- todir="${project.reporting.outputDirectory}/help">
+ <copy verbose="${maven.verbose}" failonerror="false" overwrite="true" todir="${project.reporting.outputDirectory}/help">
<fileset dir="${project.basedir}/tutti-ui-swing/src/main/help">
<include name="**/*" />
</fileset>
Modified: trunk/tutti-persistence/pom.xml
===================================================================
--- trunk/tutti-persistence/pom.xml 2014-01-16 17:19:38 UTC (rev 1493)
+++ trunk/tutti-persistence/pom.xml 2014-01-16 17:22:40 UTC (rev 1494)
@@ -27,7 +27,7 @@
<parent>
<groupId>fr.ifremer</groupId>
<artifactId>tutti</artifactId>
- <version>3.0-SNAPSHOT</version>
+ <version>3.0</version>
</parent>
<groupId>fr.ifremer.tutti</groupId>
Modified: trunk/tutti-service/pom.xml
===================================================================
--- trunk/tutti-service/pom.xml 2014-01-16 17:19:38 UTC (rev 1493)
+++ trunk/tutti-service/pom.xml 2014-01-16 17:22:40 UTC (rev 1494)
@@ -27,7 +27,7 @@
<parent>
<groupId>fr.ifremer</groupId>
<artifactId>tutti</artifactId>
- <version>3.0-SNAPSHOT</version>
+ <version>3.0</version>
</parent>
<groupId>fr.ifremer.tutti</groupId>
Modified: trunk/tutti-ui-swing/pom.xml
===================================================================
--- trunk/tutti-ui-swing/pom.xml 2014-01-16 17:19:38 UTC (rev 1493)
+++ trunk/tutti-ui-swing/pom.xml 2014-01-16 17:22:40 UTC (rev 1494)
@@ -27,7 +27,7 @@
<parent>
<groupId>fr.ifremer</groupId>
<artifactId>tutti</artifactId>
- <version>3.0-SNAPSHOT</version>
+ <version>3.0</version>
</parent>
<groupId>fr.ifremer.tutti</groupId>
1
0
Author: tchemit
Date: 2014-01-16 18:19:38 +0100 (Thu, 16 Jan 2014)
New Revision: 1493
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1493
Log:
update doc
Modified:
trunk/src/site/rst/dbversions.rst
Modified: trunk/src/site/rst/dbversions.rst
===================================================================
--- trunk/src/site/rst/dbversions.rst 2014-01-16 15:08:54 UTC (rev 1492)
+++ trunk/src/site/rst/dbversions.rst 2014-01-16 17:19:38 UTC (rev 1493)
@@ -52,6 +52,8 @@
+---------------------+------------+---------------------------+
+ 3.0-rc-2 + 2013.11.29 + 3.4.1 +
+---------------------+------------+---------------------------+
++ 3.0 + 2014.01.10 + 3.4.1 +
++---------------------+------------+---------------------------+
Légende :
1
0
Author: tchemit
Date: 2014-01-16 16:08:54 +0100 (Thu, 16 Jan 2014)
New Revision: 1492
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1492
Log:
fixes #4136: [TECH] Int?\195?\169gration de l'aide en ligne dans le site g?\195?\169n?\195?\169r?\195?\169
Modified:
trunk/pom.xml
trunk/src/site/site_fr.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2014-01-16 14:36:24 UTC (rev 1491)
+++ trunk/pom.xml 2014-01-16 15:08:54 UTC (rev 1492)
@@ -159,12 +159,6 @@
<!-- Last JRE version to use -->
<jreVersion>1.7.45</jreVersion>
- <!-- Last tutti db version -->
- <dbVersion>2013.12.19</dbVersion>
-
- <!-- Last tutti report version -->
- <reportVersion>2013.12.05</reportVersion>
-
</properties>
<repositories>
@@ -499,6 +493,11 @@
<artifactId>hibernate-core</artifactId>
<version>${hibernateVersion}</version>
</dependency>
+ <dependency>
+ <groupId>fr.ifremer.shared</groupId>
+ <artifactId>application</artifactId>
+ <version>${ifremerApplicationVersion}</version>
+ </dependency>
</dependencies>
</plugin>
@@ -602,14 +601,6 @@
<property>jreVersion</property>
<message>You must set a jreVersion property!</message>
</requireProperty>
- <requireProperty>
- <property>dbVersion</property>
- <message>You must set a dbVersion property!</message>
- </requireProperty>
- <requireProperty>
- <property>reportVersion</property>
- <message>You must set a reportVersion property!</message>
- </requireProperty>
</rules>
<ignoreCache>true</ignoreCache>
<failFast>true</failFast>
@@ -733,7 +724,7 @@
</profile>
<profile>
- <id>deploy-tutti-data-update</id>
+ <id>reporting</id>
<activation>
<property>
<name>performRelease</name>
@@ -742,25 +733,23 @@
</activation>
<build>
- <defaultGoal>deploy</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
- <id>copy tutti-data.properties to site</id>
- <phase>package</phase>
+ <id>Copy help site</id>
+ <phase>pre-site</phase>
<inherited>false</inherited>
<configuration>
<tasks>
- <echo message="copy tutti-db.properties to site" />
- <copy verbose="true" failonerror="false" overwrite="true" filtering="true" todir="${project.build.directory}/update">
- <filterset>
- <filter value="${dbVersion}" token="dbVersion" />
- <filter value="${reportVersion}" token="reportVersion" />
- </filterset>
- <fileset dir="${basedir}/src/update/">
- <include name="tutti-data.properties" />
+ <echo message="Copy help to site" />
+ <copy verbose="${maven.verbose}"
+ failonerror="false"
+ overwrite="true"
+ todir="${project.reporting.outputDirectory}/help">
+ <fileset dir="${project.basedir}/tutti-ui-swing/src/main/help">
+ <include name="**/*" />
</fileset>
</copy>
</tasks>
@@ -771,46 +760,8 @@
</execution>
</executions>
</plugin>
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>wagon-maven-plugin</artifactId>
- <version>1.0-beta-4</version>
- <executions>
- <execution>
- <id>deploy tutti-db.properties</id>
- <phase>deploy</phase>
- <inherited>false</inherited>
- <goals>
- <goal>upload-single</goal>
- </goals>
- <configuration>
- <serverId>forge.codelutin.com</serverId>
- <fromFile>
- ${project.build.directory}/update/tutti-data.properties
- </fromFile>
- <url>
- scpexe://forge.codelutin.com/var/www/ApplicationUpdate/http/tutti
- </url>
- </configuration>
- </execution>
- </executions>
-
- </plugin>
</plugins>
</build>
-
- </profile>
-
- <profile>
- <id>reporting</id>
- <activation>
- <property>
- <name>performRelease</name>
- <value>true</value>
- </property>
- </activation>
-
<reporting>
<plugins>
Modified: trunk/src/site/site_fr.xml
===================================================================
--- trunk/src/site/site_fr.xml 2014-01-16 14:36:24 UTC (rev 1491)
+++ trunk/src/site/site_fr.xml 2014-01-16 15:08:54 UTC (rev 1492)
@@ -23,7 +23,10 @@
#L%
-->
-<project name="${project.name}">
+<project name="${project.name}"
+ xmlns="http://maven.apache.org/DECORATION/1.4.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd">
<skin>
<groupId>org.apache.maven.skins</groupId>
@@ -97,13 +100,20 @@
<menu name="Tutti">
<item name="Accueil" href="index.html"/>
<item name="Fonctionnalités" href="./features.html"/>
- <item name="Téléchargement"
+ <item name="Téléchargement" target="forge"
href="http://forge.codelutin.com/projects/tutti/files"/>
- <item name="Roadmap"
+ <item name="Roadmap" target="forge"
href="http://forge.codelutin.com/projects/tutti/roadmap"/>
<item name="Historique des versions" href="changes-report.html"/>
</menu>
+ <menu name="Documentation utilisateur">
+ <item name="Aide en ligne (FR)" href="./help/fr/index.html"
+ target="help"/>
+ <item name="Aide en ligne (EN)" href="./help/en/index.html"
+ target="help"/>
+ </menu>
+
<menu name="Documentation Technique">
<item name="Configuration" href="./application-config-report.html"/>
<item name="Référentiel" href="./referential.html"/>
1
0
r1491 - in trunk/tutti-ui-swing/src/main: help/fr java/fr/ifremer/tutti/ui/swing/content/operation/catches resources/i18n
by tchemit@users.forge.codelutin.com 16 Jan '14
by tchemit@users.forge.codelutin.com 16 Jan '14
16 Jan '14
Author: tchemit
Date: 2014-01-16 15:36:24 +0100 (Thu, 16 Jan 2014)
New Revision: 1491
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1491
Log:
fixes #3839: [CAPTURE] ne pas calculer les poids totaux esp?\195?\168ces ou benthos quand il y a ?\195?\169chantillonage de la capture avant trie
Modified:
trunk/tutti-ui-swing/src/main/help/fr/editFishingOperation.html
trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesUI.css
trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesUIHandler.java
trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties
trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties
Modified: trunk/tutti-ui-swing/src/main/help/fr/editFishingOperation.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/editFishingOperation.html 2014-01-16 14:35:57 UTC (rev 1490)
+++ trunk/tutti-ui-swing/src/main/help/fr/editFishingOperation.html 2014-01-16 14:36:24 UTC (rev 1491)
@@ -279,9 +279,9 @@
: si la valeur du Poids total NON TRIE est non nulle, la valeur
calculée dans ce champ n'a aucune signification car l'application va
sommer un VRAC qui doit être élevé avec un HORS VRAC qui n'est par
- définition pas élevé. Cette anomalie de la 3.0 sera corrigée dans une
- version
- ultérieure.
+ définition pas élevé.
+ <br/>
+ Dans ce cas un message remplace la valeur calculée.
</dd>
<dt>Poids total VRAC</dt>
<dd>
@@ -306,8 +306,9 @@
style="font-weight: bold;">ATTENTION</span> : si la valeur du
Poids total NON TRIE est non nulle, la valeur calculée dans ce champ
n'a aucune signification car l'application va sommer un vrac qui doit
- être élevé avec un hrs vrac qui n'est par définition pas élevé. Cette
- anomalie sera corrigée dans une version ultérieure.
+ être élevé avec un hrs vrac qui n'est par définition pas élevé.
+ <br/>
+ Dans ce cas un message remplace la valeur calculée.
</dd>
<dt>Poids total VRAC</dt>
<dd>
Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesUI.css
===================================================================
--- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesUI.css 2014-01-16 14:35:57 UTC (rev 1490)
+++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesUI.css 2014-01-16 14:36:24 UTC (rev 1491)
@@ -191,7 +191,8 @@
}
#speciesTotalWeightField {
- text: {getWeightStringValue(model.getSpeciesTotalComputedWeight())};
+ text: {handler.getWeightStringValueForTotalWeight(model.getCatchTotalRejectedWeight(), model.getSpeciesTotalComputedWeight())};
+ disabledTextColor: {handler.getWeightColorForTotalWeight(model.getCatchTotalRejectedWeight(), model.getSpeciesTotalComputedWeight())};
_computed: true;
_help: {"tutti.editCatchBatch.field.speciesTotalWeight.help"};
}
@@ -256,7 +257,8 @@
}
#benthosTotalWeightField {
- text: {getWeightStringValue(model.getBenthosTotalComputedWeight())};
+ text: {handler.getWeightStringValueForTotalWeight(model.getCatchTotalRejectedWeight(), model.getBenthosTotalComputedWeight())};
+ disabledTextColor: {handler.getWeightColorForTotalWeight(model.getCatchTotalRejectedWeight(), model.getBenthosTotalComputedWeight())};
_computed: true;
_help: {"tutti.editCatchBatch.field.benthosTotalWeight.help"};
}
Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesUIHandler.java
===================================================================
--- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesUIHandler.java 2014-01-16 14:35:57 UTC (rev 1490)
+++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/EditCatchesUIHandler.java 2014-01-16 14:36:24 UTC (rev 1491)
@@ -26,9 +26,8 @@
import com.google.common.collect.Sets;
import fr.ifremer.shared.application.swing.tab.TabHandler;
+import fr.ifremer.tutti.persistence.entities.TuttiEntities;
import fr.ifremer.tutti.persistence.entities.referential.Species;
-import fr.ifremer.tutti.ui.swing.content.operation.FishingOperationsUI;
-import fr.ifremer.tutti.ui.swing.content.operation.FishingOperationsUIHandler;
import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.BenthosBatchRowModel;
import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyCellComponent;
import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUI;
@@ -40,7 +39,6 @@
import fr.ifremer.tutti.ui.swing.util.AbstractTuttiTabContainerUIHandler;
import fr.ifremer.tutti.ui.swing.util.TuttiBeanMonitor;
import fr.ifremer.tutti.ui.swing.util.TuttiUI;
-import jaxx.runtime.SwingUtil;
import jaxx.runtime.swing.CardLayout2Ext;
import jaxx.runtime.validator.swing.SwingValidator;
import org.apache.commons.logging.Log;
@@ -51,7 +49,7 @@
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
-import java.awt.Container;
+import java.awt.Color;
import java.util.Set;
import static org.nuiton.i18n.I18n._;
@@ -589,22 +587,28 @@
}
}
-// public String buildReminderLabelTitle(Species species,
-// Iterable<SampleCategory<?>> categories,
-// String prefix,
-// String suffix) {
-// StringBuilder title = new StringBuilder(prefix);
-//
-// title.append(" - [").append(decorate(species)).append("]");
-//
-// for (SampleCategory<?> sampleCategory : categories) {
-// if (sampleCategory.getCategoryValue() != null) {
-// title.append(" - ");
-// title.append(decorate(sampleCategory.getCategoryValue()));
-// }
-// }
-//
-// title.append(" - ").append(suffix);
-// return title.toString();
-// }
+ public String getWeightStringValueForTotalWeight(Float rejectWeight, Float totalWeight) {
+ String result;
+ if (rejectWeight == null || totalWeight == null) {
+
+ // no reject weight, so can let this weight
+ result = TuttiEntities.getWeightStringValue(totalWeight);
+ } else {
+ result = _("tutti.editCatchBatch.field.speciesOrBenthosTotalWeight.not.computed");
+ }
+ return result;
+ }
+
+ public Color getWeightColorForTotalWeight(Float rejectWeight, Float totalWeight) {
+ //jTextField.setDisabledTextColor(
+ Color result;
+ if (rejectWeight == null || totalWeight == null) {
+
+ // no reject weight, so can let this weight
+ result = getConfig().getColorComputedWeights();
+ } else {
+ result = Color.RED;
+ }
+ return result;
+ }
}
\ No newline at end of file
Modified: trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties
===================================================================
--- trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties 2014-01-16 14:35:57 UTC (rev 1490)
+++ trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties 2014-01-16 14:36:24 UTC (rev 1491)
@@ -564,6 +564,7 @@
tutti.editCatchBatch.field.catchTotalWeight.tip=
tutti.editCatchBatch.field.marineLitterTotalWeight=
tutti.editCatchBatch.field.marineLitterTotalWeight.tip=
+tutti.editCatchBatch.field.speciesOrBenthosTotalWeight.not.computed=
tutti.editCatchBatch.field.speciesTotalSampleSortedWeight=
tutti.editCatchBatch.field.speciesTotalSampleSortedWeight.tip=
tutti.editCatchBatch.field.speciesTotalSortedWeight=
Modified: trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties
===================================================================
--- trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties 2014-01-16 14:35:57 UTC (rev 1490)
+++ trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties 2014-01-16 14:36:24 UTC (rev 1491)
@@ -557,6 +557,7 @@
tutti.editCatchBatch.field.catchTotalWeight.tip=Poids total de la capture (sauf macro déchets et captures accidentelles)
tutti.editCatchBatch.field.marineLitterTotalWeight=Poids TOTAL
tutti.editCatchBatch.field.marineLitterTotalWeight.tip=Poids total des macro déchets dans la capture
+tutti.editCatchBatch.field.speciesOrBenthosTotalWeight.not.computed=poids non calculable dans ce contexte
tutti.editCatchBatch.field.speciesTotalSampleSortedWeight=Poids VRAC trié
tutti.editCatchBatch.field.speciesTotalSampleSortedWeight.tip=Poids total des espèces triées (poissons, crustacés etc.)
tutti.editCatchBatch.field.speciesTotalSortedWeight=Poids total VRAC
1
0
Author: tchemit
Date: 2014-01-16 15:35:57 +0100 (Thu, 16 Jan 2014)
New Revision: 1490
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1490
Log:
add L?\195?\169o as commiter
Modified:
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2014-01-15 17:10:23 UTC (rev 1489)
+++ trunk/pom.xml 2014-01-16 14:35:57 UTC (rev 1490)
@@ -77,6 +77,17 @@
</roles>
<timezone>Europe/Paris</timezone>
</developer>
+ <developer>
+ <id>lkaufmann</id>
+ <name>Léo Kaufmann</name>
+ <email>morin at codelutin dot com</email>
+ <organization>CodeLutin</organization>
+ <organizationUrl>http://www.codelutin.com</organizationUrl>
+ <roles>
+ <role>Technical writer</role>
+ </roles>
+ <timezone>Europe/Paris</timezone>
+ </developer>
</developers>
<modules>
1
0
r1489 - in trunk: . tutti-persistence/src/main/java/fr/ifremer/tutti
by tchemit@users.forge.codelutin.com 15 Jan '14
by tchemit@users.forge.codelutin.com 15 Jan '14
15 Jan '14
Author: tchemit
Date: 2014-01-15 18:10:23 +0100 (Wed, 15 Jan 2014)
New Revision: 1489
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1489
Log:
fixes #4125: [TECH] Modification de l'url de mise ?\195?\160 jour des donn?\195?\169es
Modified:
trunk/README.txt
trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java
Modified: trunk/README.txt
===================================================================
--- trunk/README.txt 2014-01-15 16:34:18 UTC (rev 1488)
+++ trunk/README.txt 2014-01-15 17:10:23 UTC (rev 1489)
@@ -30,5 +30,5 @@
+---------------------+------------+---------------------------+
+ 3.0-rc-2 + 2013.11.29 + 3.4.1 +
+---------------------+------------+---------------------------+
-+ 3.0 + 2013.12.19 + 3.4.1 +
++ 3.0 + 2014.01.10 + 3.4.1 +
+---------------------+------------+---------------------------+
Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java 2014-01-15 16:34:18 UTC (rev 1488)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java 2014-01-15 17:10:23 UTC (rev 1489)
@@ -329,7 +329,7 @@
UPDATE_DATA_URL(
"tutti.update.data.url",
n_("tutti.config.option.update.data.url.description"),
- "http://appup.forge.codelutin.com/tutti/tutti-data.properties",
+ "https://www.ifremer.fr/sih-resource-private/tutti/tutti-data.properties",
String.class,
false
),
1
0
r1488 - in trunk/tutti-persistence/src: main/java/fr/ifremer/adagio/core/service/technical/synchro main/java/fr/ifremer/adagio/core/service/technical/synchro/specific main/java/fr/ifremer/tutti/persistence main/java/fr/ifremer/tutti/persistence/service main/resources/META-INF/services test/java/fr/ifremer/adagio/core/service/technical/synchro
by tchemit@users.forge.codelutin.com 15 Jan '14
by tchemit@users.forge.codelutin.com 15 Jan '14
15 Jan '14
Author: tchemit
Date: 2014-01-15 17:34:18 +0100 (Wed, 15 Jan 2014)
New Revision: 1488
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1488
Log:
refs #4124: [TECH] Mise ?\195?\160 jour de r?\195?\169f?\195?\169rentiel - Erreur sur les donn?\195?\169es suite ?\195?\160 la mise ?\195?\160 jour
Added:
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/ReferentialSynchroSpecificTableTask.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselFeaturesReferentialSynchroSpecificTableTaskImpl.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselRegistrationPeriodReferentialSynchroSpecificTableTaskImpl.java
trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceService.java
trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceServiceImpl.java
trunk/tutti-persistence/src/main/resources/META-INF/services/fr.ifremer.adagio.core.service.technical.synchro.specific.ReferentialSynchroSpecificTableTask
Modified:
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroServiceImpl.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadata.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableTool.java
trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java
trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadataTest.java
Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroServiceImpl.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroServiceImpl.java 2014-01-15 12:45:59 UTC (rev 1487)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroServiceImpl.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -27,6 +27,7 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.io.Closeables;
+import fr.ifremer.adagio.core.service.technical.synchro.specific.ReferentialSynchroSpecificTableTask;
import fr.ifremer.tutti.persistence.ProgressionModel;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.logging.Log;
@@ -50,9 +51,11 @@
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
+import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.ServiceLoader;
import java.util.Set;
import static org.nuiton.i18n.I18n._;
@@ -83,6 +86,8 @@
protected Properties dbconnexionProperties;
+ protected EnumMap<ReferentialSynchroTable, ReferentialSynchroSpecificTableTask> extraTasks;
+
@Override
public Properties getLocalConnectionProperties() {
if (dbconnexionProperties == null) {
@@ -103,6 +108,20 @@
return localDialect;
}
+ public EnumMap<ReferentialSynchroTable, ReferentialSynchroSpecificTableTask> getExtraTasks() {
+ if (extraTasks == null) {
+
+ extraTasks = Maps.newEnumMap(ReferentialSynchroTable.class);
+
+ ServiceLoader<ReferentialSynchroSpecificTableTask> loader = ServiceLoader.load(ReferentialSynchroSpecificTableTask.class);
+ for (ReferentialSynchroSpecificTableTask task : loader) {
+ extraTasks.put(task.getTable(), task);
+ }
+
+ }
+ return extraTasks;
+ }
+
@Override
public void prepare(Properties remoteConnectionProperties, ReferentialSynchroResult result) {
Preconditions.checkNotNull(result);
@@ -114,6 +133,7 @@
dbconnexionProperties = null;
localDialect = null;
+ extraTasks = null;
Connection localConnection = null;
Connection remoteConnection = null;
@@ -209,7 +229,7 @@
remoteConnection = createConnection(remoteConnectionProperties);
// load metas
- ReferentialSynchroDatabaseMetadata remoteMeta =
+ ReferentialSynchroDatabaseMetadata dbMetas =
ReferentialSynchroDatabaseMetadata.loadDatabaseMetadata(remoteConnection, getLocalDialect());
// set total in progression model
@@ -229,7 +249,7 @@
progressionModel.setMessage(_("tutti.persistence.synchronizeReferential.synchronize.step1", tableName));
- ReferentialSynchroTableMetadata table = remoteMeta.getTable(tableName);
+ ReferentialSynchroTableMetadata table = dbMetas.getTable(tableName);
if (log.isInfoEnabled()) {
log.info("Synchronize table: " + tableName);
@@ -238,9 +258,13 @@
if (countToUpdate > 0) {
- synchronizeTable(table,
+ ReferentialSynchroSpecificTableTask extraTask = getExtraTasks().get(tuttiTable);
+
+ synchronizeTable(dbMetas,
+ table,
localConnection,
remoteConnection,
+ extraTask,
result);
}
@@ -346,7 +370,7 @@
ReferentialSynchroTableTool remoteDao = new ReferentialSynchroTableTool(remoteConnection, table);
- long countToUpdate = remoteDao.getCountDataToUpdate(updateDate);
+ long countToUpdate = remoteDao.countDataToUpdate(updateDate);
if (log.isInfoEnabled()) {
log.info(String.format("%s nb rows to update: %s", tablePrefix, countToUpdate));
@@ -356,9 +380,11 @@
result.addRows(tableName, (int) countToUpdate);
}
- protected void synchronizeTable(ReferentialSynchroTableMetadata table,
+ protected void synchronizeTable(ReferentialSynchroDatabaseMetadata dbMetas,
+ ReferentialSynchroTableMetadata table,
Connection localConnection,
Connection remoteConnection,
+ ReferentialSynchroSpecificTableTask extraTask,
ReferentialSynchroResult result) throws SQLException {
String tableName = table.getName();
@@ -367,6 +393,9 @@
String tablePrefix = table.getTableLogPrefix();
+ if (extraTask != null && log.isInfoEnabled()) {
+ log.info(tablePrefix + " Will use specific task: " + extraTask);
+ }
ReferentialSynchroTableTool localDao = new ReferentialSynchroTableTool(localConnection, table);
ReferentialSynchroTableTool remoteDao = new ReferentialSynchroTableTool(remoteConnection, table);
@@ -394,16 +423,16 @@
if (bigTable) {
// big table update strategy
- updateBigTable(localDao,
+ updateBigTable(dbMetas,
+ localDao,
remoteDao,
- table,
dataToUpdate,
+ extraTask,
result);
} else {
// small table update strategy
updateTable(localDao,
- table,
dataToUpdate,
result);
}
@@ -428,16 +457,16 @@
* method instead.
*
* @param localDao connection on the local db
- * @param table table to update
* @param incomingData data to update from the remote db
* @param result where to store operation results
* @throws SQLException if any sql errors
*/
protected void updateTable(ReferentialSynchroTableTool localDao,
- ReferentialSynchroTableMetadata table,
ResultSet incomingData,
ReferentialSynchroResult result) throws SQLException {
+ ReferentialSynchroTableMetadata table = localDao.getTable();
+
// get existing ids in the local db
Set<String> existingIds = localDao.getExistingPrimaryKeys();
@@ -504,20 +533,22 @@
* </ul>
* In that way we will only perform some insert queries.
*
+ * @param dbMetas
* @param localDao connection on the local db
* @param remoteDao connection on the local db
- * @param table table to update
* @param incomingData data to update from the remote db
- * @param result where to store operation results
- * @throws SQLException if any sql errors
+ * @param extraTask
+ * @param result where to store operation results @throws SQLException if any sql errors
*/
- protected void updateBigTable(ReferentialSynchroTableTool localDao,
+ protected void updateBigTable(ReferentialSynchroDatabaseMetadata dbMetas,
+ ReferentialSynchroTableTool localDao,
ReferentialSynchroTableTool remoteDao,
- ReferentialSynchroTableMetadata table,
ResultSet incomingData,
+ ReferentialSynchroSpecificTableTask extraTask,
ReferentialSynchroResult result) throws SQLException {
- String tableName = table.getName();
+ ReferentialSynchroTableMetadata table = localDao.getTable();
+ String tableName = localDao.table.getName();
result.addTableName(tableName);
@@ -539,10 +570,14 @@
existingIds.removeAll(remoteExistingIds);
if (log.isDebugEnabled()) {
- log.debug(tablePrefix + " local data existingIds not in remote: " + existingIds);
+ log.debug(tablePrefix + " local data existingIds not in remote: " + existingIds.size());
}
+ if (log.isTraceEnabled()) {
+ for (String existingId : existingIds) {
+ log.trace("- " + existingId);
+ }
+ }
-
// copy extra rows from local
Map<List<Object>, Object[]> extraRows = Maps.newLinkedHashMap();
@@ -556,6 +591,20 @@
extraRows.put(pk, extraRow);
}
+ // remove obsolete extra rows
+
+ if (extraTask != null) {
+ extraRows = extraTask.transformExtraLocalData(dbMetas,
+ localDao,
+ remoteDao,
+ extraRows);
+
+ if (log.isDebugEnabled()) {
+ log.debug(tablePrefix + " local data existingIds not in remote (after apply task): " + extraRows.size());
+ }
+ }
+
+
// delete table
localDao.deleteAll();
Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadata.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadata.java 2014-01-15 12:45:59 UTC (rev 1487)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadata.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -24,10 +24,10 @@
* #L%
*/
-import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import fr.ifremer.shared.application.ApplicationTechnicalException;
import fr.ifremer.tutti.persistence.entities.TuttiEntities;
@@ -41,10 +41,11 @@
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.Collections;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.SortedSet;
import static org.nuiton.i18n.I18n._;
@@ -72,28 +73,20 @@
*/
public class ReferentialSynchroTableMetadata {
- protected static final String QUERY_SELECT_MAX_UPDATE = "SELECT max(update_date) FROM %s";
+ public static final String PK_SEPARATOR = "~~";
- protected static final String QUERY_INSERT = "INSERT INTO %s (%s) VALUES (%s)";
+ protected final String selectPrimaryKeysQuery;
- protected static final String QUERY_UPDATE = "UPDATE %s SET %s WHERE %s";
+ protected final String selectMaxUpdateDateQuery;
- protected static final String QUERY_SELECT = "SELECT %s FROM %s WHERE %s";
-
- protected static final String QUERY_SELECT_PRIMARY_KEYS = "SELECT %s FROM %s";
-
- protected static final String QUERY_SELECT_COUNT = "SELECT count(*) FROM %s";
-
- protected final String existingPrimaryKeysQuery;
-
- protected final String maxUpdateDateQuery;
-
protected final String countQuery;
protected final TableMetadata delegate;
protected final Map<String, ColumnMetadata> columns;
+ protected final List<String> columnNames;
+
protected final Set<String> pkNames;
protected final int[] pkIndexs;
@@ -106,16 +99,12 @@
protected final String countDataToUpdateQuery;
- protected final String countDataToUpdateQueryWithNull;
+ protected final String selectDataToUpdateQuery;
- protected final String dataToUpdateQuery;
+ protected final String selectAllQuery;
- protected final String dataToUpdateQueryWithNull;
-
protected final String selectDataQueryFromPk;
- protected final boolean simpleKey;
-
public ReferentialSynchroTableMetadata(TableMetadata delegate,
DatabaseMetaData meta) {
@@ -125,73 +114,46 @@
try {
Field field = TableMetadata.class.getDeclaredField("columns");
field.setAccessible(true);
- this.columns = (Map) field.get(delegate);
+ this.columns = Maps.<String, ColumnMetadata>newLinkedHashMap((Map) field.get(delegate));
this.withUpdateDateColumn = columns.containsKey("update_date");
+ this.columnNames = initColumnNames(columns);
this.pkNames = initPrimaryKeys(meta);
Preconditions.checkNotNull(pkNames);
- this.pkIndexs = createPkIndex();
- this.simpleKey = this.pkIndexs.length == 1;
-
- this.insertQuery = createInsertQuery();
- this.updateQuery = createUpdateQuery();
- this.maxUpdateDateQuery = String.format(QUERY_SELECT_MAX_UPDATE, getName());
- this.existingPrimaryKeysQuery = String.format(QUERY_SELECT_PRIMARY_KEYS, Joiner.on(',').join(pkNames), getName());
- this.countQuery = String.format(QUERY_SELECT_COUNT, getName());
} catch (Exception e) {
throw new ApplicationTechnicalException(_("tutti.persistence.tableMetadata.instanciation.error", this), e);
}
- dataToUpdateQueryWithNull = "SELECT " + createSelectParams() + " FROM " + getName();
- countDataToUpdateQueryWithNull = "SELECT count(*) FROM " + getName();
-
- this.selectDataQueryFromPk = createSelectQuery();
- String whereClause;
-
- if (isWithUpdateDateColumn()) {
-
- // add a filter
- whereClause = " WHERE (update_date IS NULL OR update_date > ?)";
- } else {
- whereClause = "";
- }
- dataToUpdateQuery = dataToUpdateQueryWithNull + whereClause;
- countDataToUpdateQuery = countDataToUpdateQueryWithNull + whereClause;
+ this.pkIndexs = createPkIndex();
+ this.insertQuery = createInsertQuery();
+ this.updateQuery = createUpdateQuery();
+ this.selectMaxUpdateDateQuery = createSelectMaxUpdateDateQuery();
+ this.selectPrimaryKeysQuery = createSelectPrimaryKeysQuery();
+ this.selectAllQuery = createSelectAllQuery();
+ this.selectDataQueryFromPk = createSelectDataFromPkQuery();
+ this.selectDataToUpdateQuery = createSelectDataToUpdateQuery();
+ this.countQuery = createCountQuery();
+ this.countDataToUpdateQuery = createCountDataToUpdateQuery();
}
// for tests purposes
ReferentialSynchroTableMetadata() {
- existingPrimaryKeysQuery = null;
-
- maxUpdateDateQuery = null;
-
- countQuery = null;
-
delegate = null;
-
columns = null;
-
+ columnNames = null;
pkNames = null;
-
pkIndexs = null;
-
+ withUpdateDateColumn = false;
insertQuery = null;
-
updateQuery = null;
-
- withUpdateDateColumn = false;
-
+ countQuery = null;
countDataToUpdateQuery = null;
-
- countDataToUpdateQueryWithNull = null;
-
- dataToUpdateQuery = null;
-
- dataToUpdateQueryWithNull = null;
-
+ selectPrimaryKeysQuery = null;
+ selectMaxUpdateDateQuery = null;
+ selectDataToUpdateQuery = null;
+ selectAllQuery = null;
selectDataQueryFromPk = null;
- simpleKey = false;
}
public Set<String> getPkNames() {
@@ -206,10 +168,15 @@
return columns.size();
}
- public SortedSet<String> getColumnNames() {
- return Sets.newTreeSet(columns.keySet());
+ public Set<String> getColumnNames() {
+ return ImmutableSet.copyOf(columnNames);
}
+ public int getColumnIndex(String name) {
+ int result = columnNames.indexOf(name);
+ return result;
+ }
+
public String getName() {
return delegate.getName();
}
@@ -238,6 +205,10 @@
return delegate.getIndexMetadata(indexName);
}
+ //------------------------------------------------------------------------//
+ //-- queries methods --//
+ //------------------------------------------------------------------------//
+
public String getInsertQuery() {
return insertQuery;
}
@@ -246,44 +217,46 @@
return updateQuery;
}
- public String getExistingPrimaryKeysQuery() {
- return existingPrimaryKeysQuery;
+ public String getSelectPrimaryKeysQuery() {
+ return selectPrimaryKeysQuery;
}
- public String getMaxUpdateDateQuery() {
- return maxUpdateDateQuery;
+ public String getSelectMaxUpdateDateQuery() {
+ return selectMaxUpdateDateQuery;
}
- public String getCountQuery() {
- return countQuery;
- }
-
public String getSelectDataQueryFromPk() {
return selectDataQueryFromPk;
}
- public int[] getPkIndexs() {
- return pkIndexs;
+ public String getSelectDataToUpdateQuery(Date fromDate) {
+ String sql = fromDate == null ?
+ selectAllQuery :
+ selectDataToUpdateQuery;
+ return sql;
}
- public String getDataToUpdateQuery() {
- return dataToUpdateQuery;
+ public String getCountQuery() {
+ return countQuery;
}
- public String getDataToUpdateQueryWithNull() {
- return dataToUpdateQueryWithNull;
+ public String getCountDataToUpdateQuery(Date fromDate) {
+ String sql = fromDate == null ?
+ countQuery :
+ countDataToUpdateQuery;
+ return sql;
}
- public String getCountDataToUpdateQuery() {
- return countDataToUpdateQuery;
- }
+ //------------------------------------------------------------------------//
+ //-- PK methods --//
+ //------------------------------------------------------------------------//
- public String getCountDataToUpdateQueryWithNull() {
- return countDataToUpdateQueryWithNull;
+ public int[] getPkIndexs() {
+ return pkIndexs;
}
public boolean isSimpleKey() {
- return simpleKey;
+ return pkIndexs.length == 1;
}
public List<Object> getPk(ResultSet incomingData) throws SQLException {
@@ -298,27 +271,38 @@
public String toPkStr(List<Object> pkList) {
StringBuilder sb = new StringBuilder();
for (Object pk : pkList) {
- sb.append("~|").append(pk);
+ sb.append(PK_SEPARATOR).append(pk);
}
- return sb.toString();
+ return sb.substring(PK_SEPARATOR.length());
}
public List<Object> fromPkStr(String pk) {
List<Object> pkList = Lists.newArrayList();
- String[] split = pk.split("~\\|");
+ String[] split = pk.split(PK_SEPARATOR);
for (String s : split) {
if ("null".equals(s)) {
s = null;
}
pkList.add(s);
}
- pkList.remove(0);
return pkList;
}
+ //------------------------------------------------------------------------//
+ //-- Protected methods --//
+ //------------------------------------------------------------------------//
+
+ protected List<String> initColumnNames(Map<String, ColumnMetadata> columns) {
+ List<String> result = Lists.newArrayListWithCapacity(columns.size());
+ for (String name : columns.keySet()) {
+ result.add(name);
+ }
+ return Collections.unmodifiableList(result);
+ }
+
protected Set<String> initPrimaryKeys(DatabaseMetaData meta) throws SQLException {
- Set<String> result = Sets.newHashSet();
+ Set<String> result = Sets.newLinkedHashSet();
ResultSet rs = meta.getPrimaryKeys(getCatalog(), getSchema(), getName());
try {
@@ -343,7 +327,7 @@
int i = 1;
int index = -1;
- for (String columnName : getColumnNames()) {
+ for (String columnName : columnNames) {
if (pkColumnName.equals(columnName)) {
index = i;
} else {
@@ -355,18 +339,17 @@
return result;
}
-
protected String createInsertQuery() {
StringBuilder queryParams = new StringBuilder();
StringBuilder valueParams = new StringBuilder();
- for (String columnName : getColumnNames()) {
+ for (String columnName : columnNames) {
queryParams.append(", ").append(columnName);
valueParams.append(", ?");
}
- String result = String.format(QUERY_INSERT,
+ String result = String.format("INSERT INTO %s (%s) VALUES (%s)",
getName(),
queryParams.substring(2),
valueParams.substring(2));
@@ -377,42 +360,89 @@
StringBuilder updateParams = new StringBuilder();
- for (String columnName : getColumnNames()) {
+ for (String columnName : columnNames) {
updateParams.append(", ").append(columnName).append(" = ?");
}
- String result = String.format(QUERY_UPDATE,
+ String result = String.format("UPDATE %s SET %s WHERE %s",
getName(),
updateParams.substring(2),
createPkWhereClause());
return result;
}
- protected String createSelectQuery() {
+ protected String createSelectDataFromPkQuery() {
- String result = String.format(QUERY_SELECT,
+ String result = String.format("SELECT %s FROM %s WHERE %s",
createSelectParams(),
getName(),
createPkWhereClause());
return result;
}
+ protected String createSelectPrimaryKeysQuery() {
+
+ String prefix = " || '" + PK_SEPARATOR + "' || ";
+ StringBuilder pkParams = new StringBuilder();
+ for (String columnName : pkNames) {
+ pkParams.append(prefix).append(columnName);
+ }
+ return String.format("SELECT %s FROM %s",
+ pkParams.substring(prefix.length()),
+ getName());
+ }
+
+ protected String createSelectAllQuery() {
+ return "SELECT " + createSelectParams() + " FROM " + getName();
+ }
+
+ protected String createSelectMaxUpdateDateQuery() {
+ return String.format("SELECT max(update_date) FROM %s", getName());
+ }
+
+ protected String createSelectDataToUpdateQuery() {
+ String whereClause = createWithUpdateDateWhereClause();
+ return "SELECT " + createSelectParams() + " FROM " + getName() + whereClause;
+ }
+
+ protected String createCountQuery() {
+ return String.format("SELECT count(*) FROM %s", getName());
+ }
+
+ protected String createCountDataToUpdateQuery() {
+ String whereClause = createWithUpdateDateWhereClause();
+ return "SELECT count(*) FROM " + getName() + whereClause;
+ }
+
protected String createPkWhereClause() {
StringBuilder pkParams = new StringBuilder();
- for (String columnName : getPkNames()) {
+ for (String columnName : pkNames) {
pkParams.append("AND ").append(columnName).append(" = ?");
}
return pkParams.substring(4);
}
+ protected String createWithUpdateDateWhereClause() {
+ String whereClause;
+
+ if (isWithUpdateDateColumn()) {
+
+ // add a filter
+ whereClause = " WHERE (update_date IS NULL OR update_date > ?)";
+ } else {
+ whereClause = "";
+ }
+ return whereClause;
+ }
+
protected String createSelectParams() {
StringBuilder queryParams = new StringBuilder();
- for (String columnName : getColumnNames()) {
+ for (String columnName : columnNames) {
queryParams.append(", ").append(columnName);
}
Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableTool.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableTool.java 2014-01-15 12:45:59 UTC (rev 1487)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableTool.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -72,6 +72,11 @@
protected boolean debug;
+ public ReferentialSynchroTableTool(ReferentialSynchroTableTool tool,
+ ReferentialSynchroTableMetadata table) throws SQLException {
+ this(tool.connection, table);
+ }
+
public ReferentialSynchroTableTool(Connection connection,
ReferentialSynchroTableMetadata table) throws SQLException {
this.connection = connection;
@@ -123,24 +128,15 @@
public Set<String> getExistingPrimaryKeys() throws SQLException {
- Set<String> pkNames = table.getPkNames();
- int pkCount = pkNames.size();
- String sql = table.getExistingPrimaryKeysQuery();
+ String sql = table.getSelectPrimaryKeysQuery();
PreparedStatement statement = connection.prepareStatement(sql);
Set<String> result = Sets.newHashSet();
try {
ResultSet resultSet = statement.executeQuery();
-
-
while (resultSet.next()) {
- List<Object> pkList = Lists.newArrayListWithCapacity(pkNames.size());
- for (int i = 1; i <= pkCount; i++) {
- Object pk = resultSet.getObject(i);
- pkList.add(pk);
- }
- String pk = table.toPkStr(pkList);
+ String pk = resultSet.getString(1);
result.add(pk);
}
statement.close();
@@ -152,9 +148,7 @@
public ResultSet getDataToUpdate(Date fromDate) throws SQLException {
- String sql = fromDate == null ?
- table.getDataToUpdateQueryWithNull() :
- table.getDataToUpdateQuery();
+ String sql = table.getSelectDataToUpdateQuery(fromDate);
PreparedStatement statement = connection.prepareStatement(sql);
if (table.isWithUpdateDateColumn() &&
@@ -164,8 +158,6 @@
statement.setFetchSize(1000);
ResultSet result = statement.executeQuery();
-// // to be able to reward on resultSet
-// ((RowSet)result).setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
return result;
}
@@ -291,7 +283,7 @@
if (table.isWithUpdateDateColumn()) {
- String sql = table.getMaxUpdateDateQuery();
+ String sql = table.getSelectMaxUpdateDateQuery();
PreparedStatement statement = connection.prepareStatement(sql);
try {
@@ -307,11 +299,9 @@
return result;
}
- public long getCountDataToUpdate(Date fromDate) throws SQLException {
+ public long countDataToUpdate(Date fromDate) throws SQLException {
- String sql = fromDate == null ?
- table.getCountDataToUpdateQueryWithNull() :
- table.getCountDataToUpdateQuery();
+ String sql = table.getCountDataToUpdateQuery(fromDate);
PreparedStatement statement = connection.prepareStatement(sql);
if (table.isWithUpdateDateColumn() &&
@@ -362,4 +352,8 @@
}
}
}
+
+ public ReferentialSynchroTableMetadata getTable() {
+ return table;
+ }
}
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/ReferentialSynchroSpecificTableTask.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/ReferentialSynchroSpecificTableTask.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/ReferentialSynchroSpecificTableTask.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -0,0 +1,63 @@
+package fr.ifremer.adagio.core.service.technical.synchro.specific;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroDatabaseMetadata;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTable;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTableTool;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created on 1/15/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+public interface ReferentialSynchroSpecificTableTask {
+
+ /**
+ * @return the table on which the task can be apply.
+ */
+ ReferentialSynchroTable getTable();
+
+ /**
+ * Given the extra rows of the local db, transform them to reinject them
+ * after in the current table.
+ *
+ * @param dbMetas
+ * @param localDao dao of the local db
+ * @param remoteDao dao of the remote db
+ * @param extraRows extra rows of the local db to transform
+ * @return transformed extra rows of the local db
+ */
+ Map<List<Object>, Object[]> transformExtraLocalData(ReferentialSynchroDatabaseMetadata dbMetas,
+ ReferentialSynchroTableTool localDao,
+ ReferentialSynchroTableTool remoteDao,
+ Map<List<Object>, Object[]> extraRows) throws SQLException;
+
+}
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/ReferentialSynchroSpecificTableTask.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselFeaturesReferentialSynchroSpecificTableTaskImpl.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselFeaturesReferentialSynchroSpecificTableTaskImpl.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselFeaturesReferentialSynchroSpecificTableTaskImpl.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -0,0 +1,83 @@
+package fr.ifremer.adagio.core.service.technical.synchro.specific;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.collect.Maps;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroDatabaseMetadata;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTable;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTableMetadata;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTableTool;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created on 1/15/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+public class VesselFeaturesReferentialSynchroSpecificTableTaskImpl implements ReferentialSynchroSpecificTableTask {
+ @Override
+ public ReferentialSynchroTable getTable() {
+ return ReferentialSynchroTable.VESSEL_FEATURES;
+ }
+
+ @Override
+ public Map<List<Object>, Object[]> transformExtraLocalData(ReferentialSynchroDatabaseMetadata dbMetas,
+ ReferentialSynchroTableTool localDao,
+ ReferentialSynchroTableTool remoteDao,
+ Map<List<Object>, Object[]> extraRows) throws SQLException {
+
+ // get all vessel codes already existing in remove db
+
+ ReferentialSynchroTableMetadata vesselTable =
+ dbMetas.getTable(ReferentialSynchroTable.VESSEL.name());
+
+ ReferentialSynchroTableTool remoteVesselDao =
+ new ReferentialSynchroTableTool(remoteDao, vesselTable);
+
+ Set<String> existingVesselCodes = remoteVesselDao.getExistingPrimaryKeys();
+
+ ReferentialSynchroTableMetadata table = localDao.getTable();
+
+ int columnIndex = table.getColumnIndex("vessel_fk");
+
+ Map<List<Object>, Object[]> result = Maps.newHashMap();
+
+ for (Map.Entry<List<Object>, Object[]> entry : extraRows.entrySet()) {
+ Object[] row = entry.getValue();
+ Object vesselCode = row[columnIndex];
+ if (!existingVesselCodes.contains(String.valueOf(vesselCode))) {
+
+ // really a features from a the local db (temporary data for example, keep it)
+ result.put(entry.getKey(), entry.getValue());
+ }
+ }
+ return result;
+ }
+}
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselFeaturesReferentialSynchroSpecificTableTaskImpl.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselRegistrationPeriodReferentialSynchroSpecificTableTaskImpl.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselRegistrationPeriodReferentialSynchroSpecificTableTaskImpl.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselRegistrationPeriodReferentialSynchroSpecificTableTaskImpl.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -0,0 +1,83 @@
+package fr.ifremer.adagio.core.service.technical.synchro.specific;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.collect.Maps;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroDatabaseMetadata;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTable;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTableMetadata;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroTableTool;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created on 1/15/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+public class VesselRegistrationPeriodReferentialSynchroSpecificTableTaskImpl implements ReferentialSynchroSpecificTableTask {
+ @Override
+ public ReferentialSynchroTable getTable() {
+ return ReferentialSynchroTable.VESSEL_REGISTRATION_PERIOD;
+ }
+
+ @Override
+ public Map<List<Object>, Object[]> transformExtraLocalData(ReferentialSynchroDatabaseMetadata dbMetas,
+ ReferentialSynchroTableTool localDao,
+ ReferentialSynchroTableTool remoteDao,
+ Map<List<Object>, Object[]> extraRows) throws SQLException {
+
+ // get all vessel codes already existing in remove db
+
+ ReferentialSynchroTableMetadata vesselTable =
+ dbMetas.getTable(ReferentialSynchroTable.VESSEL.name());
+
+ ReferentialSynchroTableTool remoteVesselDao =
+ new ReferentialSynchroTableTool(remoteDao, vesselTable);
+
+ Set<String> existingVesselCodes = remoteVesselDao.getExistingPrimaryKeys();
+
+ ReferentialSynchroTableMetadata table = localDao.getTable();
+
+ int columnIndex = table.getColumnIndex("vessel_fk");
+
+ Map<List<Object>, Object[]> result = Maps.newHashMap();
+
+ for (Map.Entry<List<Object>, Object[]> entry : extraRows.entrySet()) {
+ Object[] row = entry.getValue();
+ Object vesselCode = row[columnIndex];
+ if (!existingVesselCodes.contains(String.valueOf(vesselCode))) {
+
+ // really a features from a the local db (temporary data for example, keep it)
+ result.put(entry.getKey(), entry.getValue());
+ }
+ }
+ return result;
+ }
+}
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/specific/VesselRegistrationPeriodReferentialSynchroSpecificTableTaskImpl.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java 2014-01-15 12:45:59 UTC (rev 1487)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -64,6 +64,7 @@
import fr.ifremer.tutti.persistence.service.BenthosBatchPersistenceService;
import fr.ifremer.tutti.persistence.service.CatchBatchPersistenceService;
import fr.ifremer.tutti.persistence.service.CruisePersistenceService;
+import fr.ifremer.tutti.persistence.service.DatabaseCheckPersistenceService;
import fr.ifremer.tutti.persistence.service.FishingOperationPersistenceService;
import fr.ifremer.tutti.persistence.service.IndividualObservationBatchPersistenceService;
import fr.ifremer.tutti.persistence.service.MarineLitterBatchPersistenceService;
@@ -134,6 +135,9 @@
protected AttachmentPersistenceService attachmentService;
@Autowired
+ protected DatabaseCheckPersistenceService databaseCheckPersistenceService;
+
+ @Autowired
protected CacheService cacheService;
@Autowired
@@ -222,10 +226,14 @@
individualObservationBatchService.init();
protocolService.init();
attachmentService.init();
+ databaseCheckPersistenceService.init();
TuttiEnumerationFile enumerationFile = getEnumerationFile();
batchVracPredicate = TuttiEntities.newSpeciesAbleBatchCategoryPredicate(enumerationFile.PMFM_ID_SORTED_UNSORTED, enumerationFile.QUALITATIVE_VRAC_ID);
+
+ // check database is sane
+ databaseCheckPersistenceService.check();
}
protected boolean close;
@@ -252,6 +260,7 @@
individualObservationBatchService.close();
protocolService.close();
attachmentService.close();
+ databaseCheckPersistenceService.close();
TuttiPersistenceServiceLocator.close();
}
}
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceService.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceService.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceService.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -0,0 +1,44 @@
+package fr.ifremer.tutti.persistence.service;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import fr.ifremer.tutti.persistence.TuttiPersistenceServiceImplementor;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * To fix some errors in db.
+ *
+ * Created on 1/15/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+@Transactional(readOnly = true)
+public interface DatabaseCheckPersistenceService extends TuttiPersistenceServiceImplementor {
+
+ @Transactional(readOnly = false)
+ public void check();
+
+}
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceService.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceServiceImpl.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceServiceImpl.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceServiceImpl.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -0,0 +1,98 @@
+package fr.ifremer.tutti.persistence.service;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.collect.Lists;
+import fr.ifremer.adagio.core.dao.data.vessel.feature.physical.VesselFeaturesImpl;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.FlushMode;
+import org.hibernate.Query;
+import org.hibernate.classic.Session;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * To fix some errors in db.
+ * <p/>
+ * Created on 1/15/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+@Service("databaseCheckPersistenceService")
+public class DatabaseCheckPersistenceServiceImpl extends AbstractPersistenceService
+ implements DatabaseCheckPersistenceService {
+
+ /** Logger. */
+ private static final Log log =
+ LogFactory.getLog(DatabaseCheckPersistenceServiceImpl.class);
+
+ @Override
+ public void check() {
+ checkVesselFeatures();
+ }
+
+ public void checkVesselFeatures() {
+
+ // get all VESSEL_FEATURES with more than one unclosed period
+ Session currentSession = getCurrentSession();
+
+ Query query = currentSession.createQuery("SELECT vessel.code FROM " + VesselFeaturesImpl.class.getName() + " WHERE endDateTime IS NULL GROUP BY vessel.code HAVING COUNT(id)>1");
+ List<String> vesselCodes = query.list();
+
+ if (CollectionUtils.isEmpty(vesselCodes)) {
+ if (log.isInfoEnabled()) {
+ log.info("vesselFeatures are sane");
+ }
+ return;
+ }
+
+ for (String vesselCode : vesselCodes) {
+
+ // Get all features having a null endDatetime
+ Query query1 = currentSession.createQuery("SELECT id FROM " + VesselFeaturesImpl.class.getName() + " WHERE endDateTime IS NULL AND vessel.code = :vesselCode ORDER BY startDateTime DESC");
+ query1.setString("vesselCode", vesselCode);
+
+ List<Integer> vesselFeaturesIds = Lists.<Integer>newArrayList(query1.list());
+
+ // remove first id (this one will stay on db)
+ vesselFeaturesIds.remove(0);
+
+ // remove all others ids
+ if (log.isInfoEnabled()) {
+ log.info("Remove vesselFeature with id: " + vesselFeaturesIds);
+ }
+ currentSession.createQuery("DELETE FROM " + VesselFeaturesImpl.class.getName() + " WHERE id in :id").
+ setParameterList("id", vesselFeaturesIds).executeUpdate();
+ }
+
+ getCurrentSession().setFlushMode(FlushMode.COMMIT);
+ getCurrentSession().flush();
+ }
+
+}
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/DatabaseCheckPersistenceServiceImpl.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Added: trunk/tutti-persistence/src/main/resources/META-INF/services/fr.ifremer.adagio.core.service.technical.synchro.specific.ReferentialSynchroSpecificTableTask
===================================================================
--- trunk/tutti-persistence/src/main/resources/META-INF/services/fr.ifremer.adagio.core.service.technical.synchro.specific.ReferentialSynchroSpecificTableTask (rev 0)
+++ trunk/tutti-persistence/src/main/resources/META-INF/services/fr.ifremer.adagio.core.service.technical.synchro.specific.ReferentialSynchroSpecificTableTask 2014-01-15 16:34:18 UTC (rev 1488)
@@ -0,0 +1,2 @@
+fr.ifremer.adagio.core.service.technical.synchro.specific.VesselFeaturesReferentialSynchroSpecificTableTaskImpl
+fr.ifremer.adagio.core.service.technical.synchro.specific.VesselRegistrationPeriodReferentialSynchroSpecificTableTaskImpl
\ No newline at end of file
Modified: trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadataTest.java
===================================================================
--- trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadataTest.java 2014-01-15 12:45:59 UTC (rev 1487)
+++ trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadataTest.java 2014-01-15 16:34:18 UTC (rev 1488)
@@ -46,7 +46,7 @@
ReferentialSynchroTableMetadata table = new ReferentialSynchroTableMetadata();
String pkStr = table.toPkStr(pk);
- Assert.assertEquals("~|a~|null~|3", pkStr);
+ Assert.assertEquals("a~~null~~3", pkStr);
List<Object> fromPkStr = table.fromPkStr(pkStr);
1
0
r1487 - in trunk/tutti-ui-swing/src/main/help: en fr
by lkaufmann@users.forge.codelutin.com 15 Jan '14
by lkaufmann@users.forge.codelutin.com 15 Jan '14
15 Jan '14
Author: lkaufmann
Date: 2014-01-15 13:45:59 +0100 (Wed, 15 Jan 2014)
New Revision: 1487
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1487
Log:
Replace tutti by allegro campagne in help pages
Modified:
trunk/tutti-ui-swing/src/main/help/en/config.html
trunk/tutti-ui-swing/src/main/help/en/dbManager.html
trunk/tutti-ui-swing/src/main/help/en/editCruise.html
trunk/tutti-ui-swing/src/main/help/en/editFishingOperation.html
trunk/tutti-ui-swing/src/main/help/en/editProgram.html
trunk/tutti-ui-swing/src/main/help/en/editProtocol.html
trunk/tutti-ui-swing/src/main/help/en/editSampleCategory.html
trunk/tutti-ui-swing/src/main/help/en/faq.html
trunk/tutti-ui-swing/src/main/help/en/index.html
trunk/tutti-ui-swing/src/main/help/en/manageTemporaryReferential.html
trunk/tutti-ui-swing/src/main/help/en/report.html
trunk/tutti-ui-swing/src/main/help/en/selectCruise.html
trunk/tutti-ui-swing/src/main/help/fr/config.html
trunk/tutti-ui-swing/src/main/help/fr/dbManager.html
trunk/tutti-ui-swing/src/main/help/fr/editCruise.html
trunk/tutti-ui-swing/src/main/help/fr/editProgram.html
trunk/tutti-ui-swing/src/main/help/fr/editProtocol.html
trunk/tutti-ui-swing/src/main/help/fr/editSampleCategory.html
trunk/tutti-ui-swing/src/main/help/fr/faq.html
trunk/tutti-ui-swing/src/main/help/fr/fonctionnalites_transversales.html
trunk/tutti-ui-swing/src/main/help/fr/index.html
trunk/tutti-ui-swing/src/main/help/fr/manageTemporaryReferential.html
trunk/tutti-ui-swing/src/main/help/fr/menu.html
trunk/tutti-ui-swing/src/main/help/fr/report.html
trunk/tutti-ui-swing/src/main/help/fr/selectCruise.html
Modified: trunk/tutti-ui-swing/src/main/help/en/config.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/config.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/config.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Configuration</title>
+ <title>Allegro Campagne - Configuration</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/dbManager.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/dbManager.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/dbManager.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -26,7 +26,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Gérer la base de données</title>
+ <title>Allegro Campagne - Gérer la base de données</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/editCruise.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/editCruise.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/editCruise.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Créer / Éditer une campagne</title>
+ <title>Allegro Campagne - Créer / Éditer une campagne</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/editFishingOperation.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/editFishingOperation.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/editFishingOperation.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Saisie du trait et de la capture</title>
+ <title>Allegro Campagne - Saisie du trait et de la capture</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/editProgram.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/editProgram.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/editProgram.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -26,7 +26,7 @@
<head>
<meta charset="utf-8"/>
- <title>Tutti - Éditer une série de campagne</title>
+ <title>Allegro Campagne - Éditer une série de campagne</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/editProtocol.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/editProtocol.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/editProtocol.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Éditer un protocole</title>
+ <title>Allegro Campagne - Éditer un protocole</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/editSampleCategory.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/editSampleCategory.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/editSampleCategory.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Configurer les catégories</title>
+ <title>Allegro Campagne - Configurer les catégories</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/faq.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/faq.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/faq.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Aide en ligne (Foire aux questions)</title>
+ <title>Allegro Campagne - Aide en ligne (Foire aux questions)</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/index.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/index.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/index.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -26,7 +26,7 @@
<head>
<meta charset="utf-8">
- <title>Tutti - Aide en ligne</title>
+ <title>Allegro Campagne - Aide en ligne</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/manageTemporaryReferential.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/manageTemporaryReferential.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/manageTemporaryReferential.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Gérer les référentiels temporaires</title>
+ <title>Allegro Campagne - Gérer les référentiels temporaires</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/report.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/report.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/report.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -26,7 +26,7 @@
<head>
<meta charset="utf-8"/>
- <title>Tutti - Générer des rapports</title>
+ <title>Allegro Campagne - Générer des rapports</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/en/selectCruise.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/en/selectCruise.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/en/selectCruise.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Choisir la campagne</title>
+ <title>Allegro Campagne - Choisir la campagne</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/config.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/config.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/config.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Configuration</title>
+ <title>Allegro Campagne - Configuration</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/dbManager.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/dbManager.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/dbManager.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -26,7 +26,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Gérer la base de données</title>
+ <title>Allegro Campagne - Gérer la base de données</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/editCruise.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/editCruise.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/editCruise.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Créer / Éditer une campagne</title>
+ <title>Allegro Campagne - Créer / Éditer une campagne</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/editProgram.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/editProgram.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/editProgram.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -26,7 +26,7 @@
<head>
<meta charset="utf-8"/>
- <title>Tutti - Éditer une série de campagne</title>
+ <title>Allegro Campagne - Éditer une série de campagne</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/editProtocol.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/editProtocol.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/editProtocol.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Éditer un protocole</title>
+ <title>Allegro Campagne - Éditer un protocole</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/editSampleCategory.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/editSampleCategory.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/editSampleCategory.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Configurer les catégories</title>
+ <title>Allegro Campagne - Configurer les catégories</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/faq.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/faq.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/faq.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Aide en ligne (Foire aux questions)</title>
+ <title>Allegro Campagne - Aide en ligne (Foire aux questions)</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/fonctionnalites_transversales.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/fonctionnalites_transversales.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/fonctionnalites_transversales.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Aide en ligne (Fonctionnalités transversales)</title>
+ <title>Allegro Campagne - Aide en ligne (Fonctionnalités transversales)</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/index.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/index.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/index.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -26,7 +26,7 @@
<head>
<meta charset="utf-8">
- <title>Tutti - Aide en ligne</title>
+ <title>Allegro Campagne - Aide en ligne</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/manageTemporaryReferential.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/manageTemporaryReferential.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/manageTemporaryReferential.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Gérer les référentiels temporaires</title>
+ <title>Allegro Campagne - Gérer les référentiels temporaires</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/menu.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/menu.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/menu.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Aide en ligne (Menu)</title>
+ <title>Allegro Campagne - Aide en ligne (Menu)</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
@@ -249,7 +249,7 @@
<h3>Aide<a name="menu_aide_aide"></a></h3>
Permet d'accéder à l'aide sur l'application.
<h3>Site<a name="menu_aide_site"></a></h3>
-En mode connecté, permet d'accéder au site du projet Tutti qui coordonne le
+En mode connecté, permet d'accéder au site du projet Allegro Campagne qui coordonne le
développement de cette application.
<h3>À propos<a name="menu_aide_about"></a></h3>
Permet d'accéder aux informations légales sur l’application, à des
Modified: trunk/tutti-ui-swing/src/main/help/fr/report.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/report.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/report.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -26,7 +26,7 @@
<head>
<meta charset="utf-8"/>
- <title>Tutti - Générer des rapports</title>
+ <title>Allegro Campagne - Générer des rapports</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
Modified: trunk/tutti-ui-swing/src/main/help/fr/selectCruise.html
===================================================================
--- trunk/tutti-ui-swing/src/main/help/fr/selectCruise.html 2014-01-15 08:43:26 UTC (rev 1486)
+++ trunk/tutti-ui-swing/src/main/help/fr/selectCruise.html 2014-01-15 12:45:59 UTC (rev 1487)
@@ -25,7 +25,7 @@
-->
<meta charset="utf-8">
- <title>Tutti - Choisir la campagne</title>
+ <title>Allegro Campagne - Choisir la campagne</title>
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/style.css" rel="stylesheet">
<script type="text/javascript" src="../js/jquery-2.0.3.min.js"></script>
1
0
15 Jan '14
Author: tchemit
Date: 2014-01-15 09:43:26 +0100 (Wed, 15 Jan 2014)
New Revision: 1486
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1486
Log:
refs #4124: [TECH] Mise ?\195?\160 jour de r?\195?\169f?\195?\169rentiel - Erreur sur les donn?\195?\169es suite ?\195?\160 la mise ?\195?\160 jour (rewrite synchro service)
Added:
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroDatabaseMetadata.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroResult.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroService.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroServiceImpl.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTable.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadata.java
trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableTool.java
trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/
trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/
trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/
trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/
trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/
trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadataTest.java
Removed:
trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/
trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/
Modified:
trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java
trunk/tutti-service/src/license/THIRD-PARTY.properties
trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/TuttiDataContext.java
trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/referential/TuttiReferentialSynchronizeService.java
trunk/tutti-ui-swing/src/license/THIRD-PARTY.properties
trunk/tutti-ui-swing/src/main/filtered-resources/log4j.properties
trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiApplicationUpdaterCallBack.java
trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiDbUpdaterCallBack.java
trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroDatabaseMetadata.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroDatabaseMetadata.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroDatabaseMetadata.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -0,0 +1,136 @@
+package fr.ifremer.adagio.core.service.technical.synchro;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import fr.ifremer.shared.application.ApplicationTechnicalException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.mapping.Table;
+import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
+import org.hibernate.tool.hbm2ddl.TableMetadata;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Set;
+
+import static org.nuiton.i18n.I18n._;
+
+/**
+ * Created on 1/14/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+public class ReferentialSynchroDatabaseMetadata {
+
+ /** Logger. */
+ private static final Log log =
+ LogFactory.getLog(ReferentialSynchroDatabaseMetadata.class);
+
+ /**
+ * Load the datasource schema for the given connection and dialect.
+ *
+ * @param connection connection of the data source
+ * @param dialect dialect to use
+ * @return the datasource schema
+ */
+ public static ReferentialSynchroDatabaseMetadata loadDatabaseMetadata(Connection connection,
+ Dialect dialect) {
+ ReferentialSynchroDatabaseMetadata result = new ReferentialSynchroDatabaseMetadata(connection, dialect);
+ for (ReferentialSynchroTable tuttiTable : ReferentialSynchroTable.values()) {
+
+ String tableName = tuttiTable.name();
+ if (log.isDebugEnabled()) {
+ log.debug("Load metas of table: " + tableName);
+ }
+ result.getTable(tableName);
+ }
+ return result;
+ }
+
+ protected final DatabaseMetadata delegate;
+
+ protected final Map<String, ReferentialSynchroTableMetadata> tables;
+
+ protected final DatabaseMetaData meta;
+
+ public ReferentialSynchroDatabaseMetadata(Connection connection, Dialect dialect) {
+ Preconditions.checkNotNull(connection);
+ Preconditions.checkNotNull(dialect);
+ try {
+ this.delegate = new DatabaseMetadata(connection, dialect, true);
+ this.meta = connection.getMetaData();
+ } catch (SQLException e) {
+ throw new ApplicationTechnicalException(_("tutti.persistence.dbMetadata.instanciation.error", connection), e);
+ }
+ tables = Maps.newTreeMap();
+ }
+
+ public ReferentialSynchroTableMetadata getTable(String name) throws HibernateException {
+ return getTable(name, "PUBLIC", null, false);
+ }
+
+ public int getTableCount() {
+ return tables.size();
+ }
+
+ public Set<String> getTableNames() {
+ Set<String> result = Sets.newHashSet();
+ for (ReferentialSynchroTableMetadata tableMetadata : tables.values()) {
+ result.add(tableMetadata.getName());
+ }
+ return result;
+ }
+
+ protected ReferentialSynchroTableMetadata getTable(String name,
+ String schema,
+ String catalog,
+ boolean isQuoted) throws HibernateException {
+ String key = Table.qualify(catalog, schema, name);
+ ReferentialSynchroTableMetadata tuttiTableMetadata = tables.get(key);
+ if (tuttiTableMetadata == null) {
+
+ TableMetadata tableMetadata = delegate.getTableMetadata(
+ name, schema, catalog, isQuoted);
+ Preconditions.checkNotNull(tableMetadata,
+ "Could not find db table " + name);
+ ReferentialSynchroTable tuttiTable = ReferentialSynchroTable.valueOf(name);
+ Preconditions.checkNotNull(tuttiTable,
+ "Could not find db table " + tuttiTable);
+ tuttiTableMetadata = new ReferentialSynchroTableMetadata(tableMetadata, meta);
+ Preconditions.checkNotNull(tuttiTableMetadata,
+ "Could not find db table " + name);
+ tables.put(key, tuttiTableMetadata);
+ }
+ return tuttiTableMetadata;
+ }
+}
\ No newline at end of file
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroDatabaseMetadata.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroResult.java (from rev 1477, trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeResult.java)
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroResult.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroResult.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -0,0 +1,208 @@
+package fr.ifremer.adagio.core.service.technical.synchro;
+
+/*
+ * #%L
+ * Tutti :: Persistence API
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2012 - 2013 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import fr.ifremer.tutti.persistence.ProgressionModel;
+
+import java.sql.Timestamp;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Result of a referential synchronize operation.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 1.0
+ */
+public class ReferentialSynchroResult {
+
+ protected Exception error;
+
+ /**
+ * Number of rows detected to update (per table).
+ *
+ * @since 1.0
+ */
+ protected final Map<String, Integer> rowHits = Maps.newTreeMap();
+
+ /**
+ * Number of insert done (per table).
+ *
+ * @since 1.0
+ */
+ protected final Map<String, Integer> insertHits = Maps.newTreeMap();
+
+ /**
+ * Number of update done (per table).
+ *
+ * @since 1.0
+ */
+ protected final Map<String, Integer> updateHits = Maps.newTreeMap();
+
+ /**
+ * timestamp of last update date (per table).
+ *
+ * @since 1.0
+ */
+ protected final Map<String, Timestamp> updateDateHits = Maps.newTreeMap();
+
+ /**
+ * All table treated.
+ *
+ * @since 1.0
+ */
+ protected final Set<String> tableNames = Sets.newHashSet();
+
+ protected String localUrl;
+
+ protected String remoteUrl;
+
+ protected final ProgressionModel progressionModel = new ProgressionModel();
+
+ public ReferentialSynchroResult() {
+ }
+
+ public ReferentialSynchroResult(String localUrl, String remoteUrl) {
+ this.localUrl = localUrl;
+ this.remoteUrl = remoteUrl;
+ }
+
+ public void setLocalUrl(String localUrl) {
+ this.localUrl = localUrl;
+ }
+
+ public void setRemoteUrl(String remoteUrl) {
+ this.remoteUrl = remoteUrl;
+ }
+
+ public boolean isSuccess() {
+ return error == null;
+ }
+
+ public Exception getError() {
+ return error;
+ }
+
+ public void setError(Exception error) {
+ this.error = error;
+ }
+
+ public ProgressionModel getProgressionModel() {
+ return progressionModel;
+ }
+
+ public Set<String> getTableNames() {
+ return ImmutableSet.copyOf(tableNames);
+ }
+
+ public int getTotalRows() {
+ int result = 0;
+ for (Integer nb : rowHits.values()) {
+ result += nb;
+ }
+ return result;
+ }
+
+ public int getTotalInserts() {
+ int result = 0;
+ for (Integer nb : insertHits.values()) {
+ result += nb;
+ }
+ return result;
+ }
+
+ public int getTotalUpdates() {
+ int result = 0;
+ for (Integer nb : updateHits.values()) {
+ result += nb;
+ }
+ return result;
+ }
+
+ public int getNbRows(String tableName) {
+ Integer result = rowHits.get(tableName);
+ if (result == null) {
+ result = 0;
+ }
+ return result;
+ }
+
+ public int getNbInserts(String tableName) {
+ Integer result = insertHits.get(tableName);
+ if (result == null) {
+ result = 0;
+ }
+ return result;
+ }
+
+ public int getNbUpdates(String tableName) {
+ Integer result = updateHits.get(tableName);
+ if (result == null) {
+ result = 0;
+ }
+ return result;
+ }
+
+ public void addRows(String tableName, int nb) {
+ if (nb > 0) {
+ rowHits.put(tableName, getNbRows(tableName) + nb);
+ }
+ }
+
+ public void addUpdates(String tableName, int nb) {
+ if (nb > 0) {
+ updateHits.put(tableName, getNbUpdates(tableName) + nb);
+ }
+ }
+
+ public void addInserts(String tableName, int nb) {
+ if (nb > 0) {
+ insertHits.put(tableName, getNbInserts(tableName) + nb);
+ }
+ }
+
+ public Timestamp getUpdateDate(String tableName) {
+ return updateDateHits.get(tableName);
+ }
+
+ public void setUpdateDate(String tableName, Timestamp t) {
+ updateDateHits.put(tableName, t);
+ }
+
+ public void addTableName(String tableName) {
+ tableNames.add(tableName);
+ }
+
+ public String getLocalUrl() {
+ return localUrl;
+ }
+
+ public String getRemoteUrl() {
+ return remoteUrl;
+ }
+}
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroService.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroService.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroService.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -0,0 +1,78 @@
+package fr.ifremer.adagio.core.service.technical.synchro;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.hibernate.dialect.Dialect;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Properties;
+
+/**
+ * Created on 1/14/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
+public interface ReferentialSynchroService {
+
+ /**
+ * Get the db connexion informations for the internal data source.
+ *
+ * @return the db connexion for the internal data source
+ */
+ Properties getLocalConnectionProperties();
+
+ /**
+ * Gets the dialect used by the local database.
+ *
+ * @return the dialect used by the local database.
+ */
+ Dialect getLocalDialect();
+
+ /**
+ * Prepare the synchronize operation from the local data database supported
+ * by this service, says just compute nb rows to update for each table and
+ * update the result model.
+ *
+ * @param remoteConnectionProperties connection properties of the remote
+ * database used to synchronize referential
+ * @param result result of the operation
+ */
+ void prepare(Properties remoteConnectionProperties,
+ ReferentialSynchroResult result);
+
+ /**
+ * Launch the synchronize operation from the local data database supported
+ * by this service.
+ *
+ * @param remoteConnectionProperties connection properties of the remote
+ * database used to synchronize referential
+ * @param result model
+ */
+ void synchronize(Properties remoteConnectionProperties,
+ ReferentialSynchroResult result);
+}
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroService.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroServiceImpl.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroServiceImpl.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroServiceImpl.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -0,0 +1,646 @@
+package fr.ifremer.adagio.core.service.technical.synchro;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.io.Closeables;
+import fr.ifremer.tutti.persistence.ProgressionModel;
+import org.apache.commons.lang3.time.DateUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.tool.hbm2ddl.ColumnMetadata;
+import org.nuiton.util.TimeLog;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataRetrievalFailureException;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+import org.springframework.jdbc.support.JdbcUtils;
+import org.springframework.stereotype.Service;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import static org.nuiton.i18n.I18n._;
+
+/**
+ * Created on 1/14/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+@Service("referentialSynchroService")
+public class ReferentialSynchroServiceImpl implements ReferentialSynchroService {
+
+ /** Logger. */
+ private static final Log log =
+ LogFactory.getLog(ReferentialSynchroServiceImpl.class);
+
+ private static final TimeLog TIME =
+ new TimeLog(ReferentialSynchroServiceImpl.class);
+
+ @Autowired
+ protected DriverManagerDataSource dataSource;
+
+ @Autowired
+ protected SessionFactory sessionFactory;
+
+ protected Dialect localDialect;
+
+ protected Properties dbconnexionProperties;
+
+ @Override
+ public Properties getLocalConnectionProperties() {
+ if (dbconnexionProperties == null) {
+ dbconnexionProperties = new Properties();
+
+ dbconnexionProperties.put(Environment.URL, dataSource.getUrl());
+ dbconnexionProperties.put(Environment.USER, dataSource.getUsername());
+ dbconnexionProperties.put(Environment.PASS, dataSource.getPassword());
+ }
+ return dbconnexionProperties;
+ }
+
+ @Override
+ public Dialect getLocalDialect() {
+ if (localDialect == null) {
+ localDialect = ((SessionFactoryImplementor) sessionFactory).getSettings().getDialect();
+ }
+ return localDialect;
+ }
+
+ @Override
+ public void prepare(Properties remoteConnectionProperties, ReferentialSynchroResult result) {
+ Preconditions.checkNotNull(result);
+ Preconditions.checkNotNull(remoteConnectionProperties);
+
+
+ result.setLocalUrl(getUrl(getLocalConnectionProperties()));
+ result.setRemoteUrl(getUrl(remoteConnectionProperties));
+
+ dbconnexionProperties = null;
+ localDialect = null;
+
+ Connection localConnection = null;
+ Connection remoteConnection = null;
+ try {
+
+ ProgressionModel progressionModel = result.getProgressionModel();
+ progressionModel.setMessage(_("tutti.persistence.synchronizeReferential.prepare.step1"));
+
+ // create local connection
+ localConnection = createConnection(getLocalConnectionProperties());
+
+ progressionModel.setMessage(_("tutti.persistence.synchronizeReferential.prepare.step2"));
+
+ // create remote Connection
+ remoteConnection = createConnection(remoteConnectionProperties);
+
+ // load metas
+ ReferentialSynchroDatabaseMetadata localMeta =
+ ReferentialSynchroDatabaseMetadata.loadDatabaseMetadata(localConnection, getLocalDialect());
+
+ ReferentialSynchroDatabaseMetadata remoteMeta =
+ ReferentialSynchroDatabaseMetadata.loadDatabaseMetadata(remoteConnection, getLocalDialect());
+
+ progressionModel.setMessage(_("tutti.persistence.synchronizeReferential.prepare.step3"));
+
+ // check schema
+ try {
+ checkSchemas(localMeta, remoteMeta);
+ } catch (DataRetrievalFailureException e) {
+ result.setError(e);
+ }
+
+ if (result.isSuccess()) {
+
+ // prepare model (compute update date, count rows to update,...)
+
+ for (ReferentialSynchroTable tuttiTable : ReferentialSynchroTable.values()) {
+
+ long t0 = TimeLog.getTime();
+
+ String tableName = tuttiTable.name();
+
+ progressionModel.setMessage(_("tutti.persistence.synchronizeReferential.prepare.step4", tableName));
+
+ ReferentialSynchroTableMetadata table = remoteMeta.getTable(tableName);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Prepare table: " + tableName);
+ }
+ prepareTable(table,
+ localConnection,
+ remoteConnection,
+ result);
+
+ TIME.log(t0, "prepare table " + tableName);
+ }
+
+ long totalRows = result.getTotalRows();
+ if (log.isInfoEnabled()) {
+ log.info("Total rows to update: " + totalRows);
+ }
+ localConnection.rollback();
+ }
+ } catch (SQLException e) {
+ try {
+ if (localConnection != null) {
+ localConnection.rollback();
+ }
+ } catch (SQLException e1) {
+
+ // ignore the rolback error
+ }
+ result.setError(e);
+ } finally {
+ JdbcUtils.closeConnection(remoteConnection);
+ JdbcUtils.closeConnection(localConnection);
+ }
+ }
+
+ @Override
+ public void synchronize(Properties remoteConnectionProperties, ReferentialSynchroResult result) {
+ Preconditions.checkNotNull(result);
+ Preconditions.checkNotNull(remoteConnectionProperties);
+
+ Connection localConnection = null;
+ Connection remoteConnection = null;
+ try {
+
+ // create local connection
+ localConnection = createConnection(getLocalConnectionProperties());
+
+ // create remote Connection
+ remoteConnection = createConnection(remoteConnectionProperties);
+
+ // load metas
+ ReferentialSynchroDatabaseMetadata remoteMeta =
+ ReferentialSynchroDatabaseMetadata.loadDatabaseMetadata(remoteConnection, getLocalDialect());
+
+ // set total in progression model
+ ProgressionModel progressionModel = result.getProgressionModel();
+ progressionModel.setTotal(result.getTotalRows());
+
+ // prepare target (desactivate constraints)
+ prepareSynch(localConnection);
+
+ try {
+
+ for (ReferentialSynchroTable tuttiTable : ReferentialSynchroTable.values()) {
+
+ long t0 = TimeLog.getTime();
+
+ String tableName = tuttiTable.name();
+
+ progressionModel.setMessage(_("tutti.persistence.synchronizeReferential.synchronize.step1", tableName));
+
+ ReferentialSynchroTableMetadata table = remoteMeta.getTable(tableName);
+
+ if (log.isInfoEnabled()) {
+ log.info("Synchronize table: " + tableName);
+ }
+ long countToUpdate = result.getNbRows(tableName);
+
+ if (countToUpdate > 0) {
+
+ synchronizeTable(table,
+ localConnection,
+ remoteConnection,
+ result);
+ }
+
+ TIME.log(t0, "synchronize table " + tableName);
+ }
+ if (log.isInfoEnabled()) {
+ long totalInserts = result.getTotalInserts();
+ long totalUpdates = result.getTotalUpdates();
+ log.info("Total rows to treat: " + result.getTotalRows());
+ log.info("Total rows inserted: " + totalInserts);
+ log.info("Total rows updated: " + totalUpdates);
+ log.info("Total rows treated: " + (totalInserts + totalUpdates));
+ }
+ } finally {
+ releaseSynch(localConnection);
+ }
+
+ progressionModel.setMessage(_("tutti.persistence.synchronizeReferential.synchronize.step2"));
+
+ localConnection.commit();
+
+ } catch (SQLException e) {
+ try {
+ if (localConnection != null) {
+ localConnection.rollback();
+ }
+ } catch (SQLException e1) {
+
+ // ignore the rolback error
+ }
+ result.setError(e);
+ } finally {
+ JdbcUtils.closeConnection(remoteConnection);
+ JdbcUtils.closeConnection(localConnection);
+ }
+ }
+
+ /**
+ * Check that the tow given datasource shemas are compatible for a
+ * synchronize operation (same tables with same columns).
+ * <p/>
+ * If schemas are incompatible, then a
+ * {@link DataRetrievalFailureException} exception will be thrown.
+ *
+ * @param schema1 schema 1 to check
+ * @param schema2 schema 2 to check
+ */
+ protected void checkSchemas(ReferentialSynchroDatabaseMetadata schema1,
+ ReferentialSynchroDatabaseMetadata schema2) {
+ Set<String> internalSchemaTableNames = schema1.getTableNames();
+ Set<String> externalSchemaTableNames = schema2.getTableNames();
+ if (!internalSchemaTableNames.equals(externalSchemaTableNames)) {
+ throw new DataRetrievalFailureException("Incompatible schemas");
+ }
+ for (String tableName : internalSchemaTableNames) {
+ ReferentialSynchroTableMetadata internalTable = schema1.getTable(tableName);
+ ReferentialSynchroTableMetadata externalTable = schema2.getTable(tableName);
+ Set<String> internalColumnNames = internalTable.getColumnNames();
+ Set<String> externalColumnNames = externalTable.getColumnNames();
+ if (!internalColumnNames.equals(externalColumnNames)) {
+ throw new DataRetrievalFailureException("Incompatible schema of table: " + tableName);
+ }
+ for (String columnName : internalColumnNames) {
+ ColumnMetadata internalColumn = internalTable.getColumnMetadata(columnName);
+ ColumnMetadata externalColumn = externalTable.getColumnMetadata(columnName);
+ String internalColumnTypeName = internalColumn.getTypeName();
+ String externalColumnTypeName = externalColumn.getTypeName();
+ if (!internalColumnTypeName.equals(externalColumnTypeName)) {
+ throw new DataRetrievalFailureException("Incompatible column type of table / column: " + tableName + " / " + columnName);
+ }
+ }
+ }
+ }
+
+ protected void prepareTable(ReferentialSynchroTableMetadata table,
+ Connection localConnection,
+ Connection remoteConnection,
+ ReferentialSynchroResult result) throws SQLException {
+
+ String tablePrefix = table.getTableLogPrefix();
+
+ String tableName = table.getName();
+
+ ReferentialSynchroTableTool localDao = new ReferentialSynchroTableTool(localConnection, table);
+
+ long localCount = localDao.count();
+
+ // get last updateDate used by local db
+ Timestamp updateDate = null;
+
+ if (localCount < 50000) {
+
+ // only use the update date on small table, for big table we will re-insert all the table content
+ updateDate = localDao.getLastUpdateDate();
+
+ if (updateDate != null) {
+
+ // just inscrements of 1 milisecond to not having same
+ updateDate = new Timestamp(DateUtils.setMilliseconds(updateDate, 0).getTime());
+ updateDate = new Timestamp(DateUtils.addSeconds(updateDate, 1).getTime());
+ }
+ }
+
+ ReferentialSynchroTableTool remoteDao = new ReferentialSynchroTableTool(remoteConnection, table);
+
+ long countToUpdate = remoteDao.getCountDataToUpdate(updateDate);
+
+ if (log.isInfoEnabled()) {
+ log.info(String.format("%s nb rows to update: %s", tablePrefix, countToUpdate));
+ }
+
+ result.setUpdateDate(tableName, updateDate);
+ result.addRows(tableName, (int) countToUpdate);
+ }
+
+ protected void synchronizeTable(ReferentialSynchroTableMetadata table,
+ Connection localConnection,
+ Connection remoteConnection,
+ ReferentialSynchroResult result) throws SQLException {
+
+ String tableName = table.getName();
+
+ result.getProgressionModel().setMessage(_("tutti.persistence.synchronizeReferential.synchronizeTable", tableName));
+
+ String tablePrefix = table.getTableLogPrefix();
+
+ ReferentialSynchroTableTool localDao = new ReferentialSynchroTableTool(localConnection, table);
+ ReferentialSynchroTableTool remoteDao = new ReferentialSynchroTableTool(remoteConnection, table);
+
+ // get last updateDate used by local db
+ Date updateDate = result.getUpdateDate(tableName);
+
+ // get table count
+ long count = localDao.count();
+
+ // get existing ids in the local db
+ Set<String> existingIds = localDao.getExistingPrimaryKeys();
+
+ if (log.isDebugEnabled()) {
+ log.debug(tablePrefix + " existingIds: " + existingIds.size());
+ }
+
+ boolean bigTable = count > 50000;
+
+ // get data to update from remote db
+ ResultSet dataToUpdate = remoteDao.getDataToUpdate(
+ bigTable ? null : updateDate);
+
+ try {
+
+ if (bigTable) {
+
+ // big table update strategy
+ updateBigTable(localDao,
+ remoteDao,
+ table,
+ dataToUpdate,
+ result);
+ } else {
+
+ // small table update strategy
+ updateTable(localDao,
+ table,
+ dataToUpdate,
+ result);
+ }
+ dataToUpdate.close();
+ } finally {
+
+ Closeables.closeQuietly(localDao);
+ Closeables.closeQuietly(remoteDao);
+ JdbcUtils.closeResultSet(dataToUpdate);
+ }
+ }
+
+ /**
+ * To update the content of the given {@code table} on the local db,
+ * from the given {@code incomingData} of the remote db.
+ * <p/>
+ * The algorithm is pretty simple, for each row of the {@code incomingData},
+ * if exists on local table, then do an update, otherwise do a insert.
+ * <p/>
+ * As an update query is more expensive, we won't use this method for table
+ * with a lot of rows, we will prefer to use the {@code updateBigTable}
+ * method instead.
+ *
+ * @param localDao connection on the local db
+ * @param table table to update
+ * @param incomingData data to update from the remote db
+ * @param result where to store operation results
+ * @throws SQLException if any sql errors
+ */
+ protected void updateTable(ReferentialSynchroTableTool localDao,
+ ReferentialSynchroTableMetadata table,
+ ResultSet incomingData,
+ ReferentialSynchroResult result) throws SQLException {
+
+ // get existing ids in the local db
+ Set<String> existingIds = localDao.getExistingPrimaryKeys();
+
+ String tableName = table.getName();
+ String tablePrefix = table.getTableLogPrefix() + " - " + result.getNbRows(tableName);
+
+ result.addTableName(tableName);
+
+ int countR = 0;
+
+ while (incomingData.next()) {
+
+ List<Object> pk = table.getPk(incomingData);
+ String pkStr = table.toPkStr(pk);
+
+ boolean doUpdate = existingIds.contains(pkStr);
+
+ if (doUpdate) {
+
+ localDao.executeUpdate(pk, incomingData);
+
+ } else {
+
+ localDao.executeInsert(pk, incomingData);
+ }
+
+ countR++;
+
+ reportProgress(result, localDao, countR, tablePrefix);
+ }
+
+ localDao.flushQueries();
+
+ int insertCount = localDao.getInsertCount();
+ int updateCount = localDao.getUpdateCount();
+
+ result.addInserts(tableName, insertCount);
+ result.addUpdates(tableName, updateCount);
+ if (log.isInfoEnabled()) {
+ log.info(String.format("%s done: %s (inserts: %s, updates: %s)", tablePrefix, countR, insertCount, updateCount));
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("%s INSERT count: %s", tablePrefix, result.getNbInserts(tableName)));
+ log.debug(String.format("%s UPDATE count: %s", tablePrefix, result.getNbUpdates(tableName)));
+ }
+
+ result.getProgressionModel().increments(countR % 1000);
+ }
+
+ /**
+ * To update the content of the given {@code table} (with a lot of rows) on
+ * the local db, from the given {@code incomingData} of the remote db.
+ * <p/>
+ * We can't use the simple algorithm, since update queries cost too much
+ * and is not acceptable when talking on huge numbers of rows.
+ * <p/>
+ * Here is what to do :
+ * <ul>
+ * <li>Get form the local db the data which are not in remote db, keep them</li>
+ * <li>Delete local table content</li>
+ * <li>Insert remote table in local table</li>
+ * <li>Insert the saved extra rows from original table</li>
+ * </ul>
+ * In that way we will only perform some insert queries.
+ *
+ * @param localDao connection on the local db
+ * @param remoteDao connection on the local db
+ * @param table table to update
+ * @param incomingData data to update from the remote db
+ * @param result where to store operation results
+ * @throws SQLException if any sql errors
+ */
+ protected void updateBigTable(ReferentialSynchroTableTool localDao,
+ ReferentialSynchroTableTool remoteDao,
+ ReferentialSynchroTableMetadata table,
+ ResultSet incomingData,
+ ReferentialSynchroResult result) throws SQLException {
+
+ String tableName = table.getName();
+
+ result.addTableName(tableName);
+
+ String tablePrefix = table.getTableLogPrefix() + " - " + result.getNbRows(tableName);
+
+ // get existing ids in the local db
+ Set<String> existingIds = localDao.getExistingPrimaryKeys();
+
+ if (log.isDebugEnabled()) {
+ log.debug(tablePrefix + " local existingIds: " + existingIds.size());
+ }
+
+ Set<String> remoteExistingIds = remoteDao.getExistingPrimaryKeys();
+
+ if (log.isDebugEnabled()) {
+ log.debug(tablePrefix + " remote existingIds: " + existingIds.size());
+ }
+
+ existingIds.removeAll(remoteExistingIds);
+
+ if (log.isDebugEnabled()) {
+ log.debug(tablePrefix + " local data existingIds not in remote: " + existingIds);
+ }
+
+
+ // copy extra rows from local
+
+ Map<List<Object>, Object[]> extraRows = Maps.newLinkedHashMap();
+
+ for (String pkStr : existingIds) {
+
+ List<Object> pk = table.fromPkStr(pkStr);
+
+ Object[] extraRow = localDao.findByPk(pk);
+
+ extraRows.put(pk, extraRow);
+ }
+
+ // delete table
+ localDao.deleteAll();
+
+ int countR = 0;
+
+ // add all data from remote
+ while (incomingData.next()) {
+
+ List<Object> pk = table.getPk(incomingData);
+
+ localDao.executeInsert(pk, incomingData);
+
+ countR++;
+
+ reportProgress(result, localDao, countR, tablePrefix);
+ }
+
+ // re-add extra local rows
+ for (Map.Entry<List<Object>, Object[]> entry : extraRows.entrySet()) {
+
+ List<Object> pk = entry.getKey();
+ Object[] row = entry.getValue();
+ localDao.executeInsert(pk, row);
+
+ countR++;
+
+ reportProgress(result, localDao, countR, tablePrefix);
+ }
+
+ localDao.flushQueries();
+
+ int insertCount = localDao.getInsertCount();
+ result.addInserts(tableName, insertCount);
+ if (log.isInfoEnabled()) {
+ log.info(String.format("%s done: %s (inserts: %s)", tablePrefix, countR, insertCount));
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("%s INSERT count: %s", tablePrefix, result.getNbInserts(tableName)));
+ }
+
+ result.getProgressionModel().increments(countR % 1000);
+ }
+
+ protected void reportProgress(ReferentialSynchroResult result, ReferentialSynchroTableTool dao, int countR, String tablePrefix) {
+ if (countR % 1000 == 0) {
+ result.getProgressionModel().increments(1000);
+ }
+
+ if (countR % 10000 == 0) {
+ if (log.isInfoEnabled()) {
+ log.info(String.format("%s Done: %s (inserts: %s, updates: %s)", tablePrefix, countR, dao.getInsertCount(), dao.getUpdateCount()));
+ }
+ }
+ }
+
+ Connection createConnection(Properties connectionProperties) throws SQLException {
+ return createConnection(
+ connectionProperties.getProperty(Environment.URL),
+ connectionProperties.getProperty(Environment.USER),
+ connectionProperties.getProperty(Environment.PASS)
+ );
+ }
+
+ String getUrl(Properties connectionProperties) {
+ return connectionProperties.getProperty(Environment.URL);
+ }
+
+ Connection createConnection(String jdbcUrl,
+ String user,
+ String password) throws SQLException {
+ Connection connection = DriverManager.getConnection(jdbcUrl,
+ user,
+ password);
+ connection.setAutoCommit(false);
+ return connection;
+ }
+
+ void prepareSynch(Connection connection) throws SQLException {
+ PreparedStatement statement = connection.prepareStatement("SET REFERENTIAL_INTEGRITY FALSE;");
+ statement.executeUpdate();
+ }
+
+ void releaseSynch(Connection connection) throws SQLException {
+ PreparedStatement statement = connection.prepareStatement("SET REFERENTIAL_INTEGRITY TRUE;");
+ statement.executeUpdate();
+ }
+}
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroServiceImpl.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTable.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTable.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTable.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -0,0 +1,116 @@
+package fr.ifremer.adagio.core.service.technical.synchro;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+/**
+ * List of all tables we want to synchronize.
+ * <p/>
+ * Created on 1/14/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+public enum ReferentialSynchroTable {
+
+ STATUS,
+ QUALITY_FLAG,
+
+ // PMFM
+ UNIT,
+ AGGREGATION_LEVEL,
+ PARAMETER_GROUP,
+ QUALITATIVE_VALUE,
+ PARAMETER,
+ MATRIX,
+ FRACTION,
+ FRACTION2MATRIX,
+ METHOD,
+ PMFM,
+ PMFM2QUALITATIVE_VALUE,
+
+ // GEAR
+ GEAR_CLASSIFICATION,
+ GEAR_CLASSIFICATION_ASSOCIATIO,
+ GEAR,
+ GEAR_ASSOCIATION,
+
+ // LOCATION
+ LOCATION_CLASSIFICATION,
+ LOCATION_LEVEL,
+ LOCATION_ASSOCIATION,
+ LOCATION,
+ LOCATION_HIERARCHY,
+ LOCATION_HIERARCHY_EXCEPTION,
+
+ // TAXON
+ TAXONOMIC_LEVEL,
+ REFERENCE_TAXON,
+ TAXON_NAME,
+ TAXON_INFORMATION,
+ TAXON_INFORMATION_HISTORY,
+ VIRTUAL_COMPONENT,
+ TAXON_NAME_HISTORY,
+ REFERENCE_DOCUMENT,
+ AUTHOR,
+ CITATION,
+
+ // TAXON GROUP
+ TAXON_GROUP_TYPE,
+ TAXON_GROUP,
+ TAXON_GROUP_HISTORICAL_RECORD,
+ TAXON_GROUP_INFORMATION,
+
+ // CONVERSION
+ ROUND_WEIGHT_CONVERSION,
+ WEIGHT_LENGTH_CONVERSION,
+ UNIT_CONVERSION,
+
+ // VESSEL
+ VESSEL_TYPE,
+ VESSEL_REGISTRATION_PERIOD,
+ VESSEL_FEATURES,
+ VESSEL,
+
+ // PERSON
+ USER_PROFIL,
+ DEPARTMENT,
+ PERSON,
+ PERSON2USER_PROFIL,
+
+ // VESSEL_PERSON_ROLE
+ VESSEL_PERSON_ROLE,
+ VESSEL_PERSON,
+
+ //ORDER
+ ORDER_ITEM,
+
+ //OTHER
+ PRECISION_TYPE,
+ NUMERICAL_PRECISION,
+ PHOTO_TYPE,
+ OBJECT_TYPE,
+ ORDER_TYPE,
+ ANALYSIS_INSTRUMENT
+}
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTable.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadata.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadata.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadata.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -0,0 +1,425 @@
+package fr.ifremer.adagio.core.service.technical.synchro;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import fr.ifremer.shared.application.ApplicationTechnicalException;
+import fr.ifremer.tutti.persistence.entities.TuttiEntities;
+import org.hibernate.mapping.ForeignKey;
+import org.hibernate.tool.hbm2ddl.ColumnMetadata;
+import org.hibernate.tool.hbm2ddl.ForeignKeyMetadata;
+import org.hibernate.tool.hbm2ddl.IndexMetadata;
+import org.hibernate.tool.hbm2ddl.TableMetadata;
+
+import java.lang.reflect.Field;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+
+import static org.nuiton.i18n.I18n._;
+
+/**
+ * Overrides of the {@link TableMetadata} with some improvements:
+ * <ul>
+ * <li>Obtains number of columns via {@link #getColumnsCount()}</li>
+ * <li>Obtains all columns names available via {@link #getColumnNames()}</li>
+ * <li>Obtains primary key column names via {@link #getPkNames()}</li>
+ * </ul>
+ * <p/>
+ * And others methods used to synchronize referentials:
+ * <ul>
+ * <li>Obtains query to update a row of the table (column names order is the
+ * one introduced by method {@link #getColumnNames()}: {@link #getUpdateQuery()}
+ * </li>
+ * <li>Obtains query to insert a row in the table (column names order is the
+ * one introduced by method {@link #getColumnNames()}: {@link #getInsertQuery()}
+ * </li>
+ * </ul>
+ * Created on 1/14/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+public class ReferentialSynchroTableMetadata {
+
+ protected static final String QUERY_SELECT_MAX_UPDATE = "SELECT max(update_date) FROM %s";
+
+ protected static final String QUERY_INSERT = "INSERT INTO %s (%s) VALUES (%s)";
+
+ protected static final String QUERY_UPDATE = "UPDATE %s SET %s WHERE %s";
+
+ protected static final String QUERY_SELECT = "SELECT %s FROM %s WHERE %s";
+
+ protected static final String QUERY_SELECT_PRIMARY_KEYS = "SELECT %s FROM %s";
+
+ protected static final String QUERY_SELECT_COUNT = "SELECT count(*) FROM %s";
+
+ protected final String existingPrimaryKeysQuery;
+
+ protected final String maxUpdateDateQuery;
+
+ protected final String countQuery;
+
+ protected final TableMetadata delegate;
+
+ protected final Map<String, ColumnMetadata> columns;
+
+ protected final Set<String> pkNames;
+
+ protected final int[] pkIndexs;
+
+ protected final String insertQuery;
+
+ protected final String updateQuery;
+
+ protected final boolean withUpdateDateColumn;
+
+ protected final String countDataToUpdateQuery;
+
+ protected final String countDataToUpdateQueryWithNull;
+
+ protected final String dataToUpdateQuery;
+
+ protected final String dataToUpdateQueryWithNull;
+
+ protected final String selectDataQueryFromPk;
+
+ protected final boolean simpleKey;
+
+ public ReferentialSynchroTableMetadata(TableMetadata delegate,
+ DatabaseMetaData meta) {
+
+ Preconditions.checkNotNull(delegate);
+ this.delegate = delegate;
+
+ try {
+ Field field = TableMetadata.class.getDeclaredField("columns");
+ field.setAccessible(true);
+ this.columns = (Map) field.get(delegate);
+ this.withUpdateDateColumn = columns.containsKey("update_date");
+ this.pkNames = initPrimaryKeys(meta);
+ Preconditions.checkNotNull(pkNames);
+ this.pkIndexs = createPkIndex();
+
+ this.simpleKey = this.pkIndexs.length == 1;
+
+ this.insertQuery = createInsertQuery();
+ this.updateQuery = createUpdateQuery();
+ this.maxUpdateDateQuery = String.format(QUERY_SELECT_MAX_UPDATE, getName());
+ this.existingPrimaryKeysQuery = String.format(QUERY_SELECT_PRIMARY_KEYS, Joiner.on(',').join(pkNames), getName());
+ this.countQuery = String.format(QUERY_SELECT_COUNT, getName());
+ } catch (Exception e) {
+ throw new ApplicationTechnicalException(_("tutti.persistence.tableMetadata.instanciation.error", this), e);
+ }
+
+ dataToUpdateQueryWithNull = "SELECT " + createSelectParams() + " FROM " + getName();
+ countDataToUpdateQueryWithNull = "SELECT count(*) FROM " + getName();
+
+ this.selectDataQueryFromPk = createSelectQuery();
+ String whereClause;
+
+ if (isWithUpdateDateColumn()) {
+
+ // add a filter
+ whereClause = " WHERE (update_date IS NULL OR update_date > ?)";
+ } else {
+ whereClause = "";
+ }
+ dataToUpdateQuery = dataToUpdateQueryWithNull + whereClause;
+ countDataToUpdateQuery = countDataToUpdateQueryWithNull + whereClause;
+ }
+
+ // for tests purposes
+ ReferentialSynchroTableMetadata() {
+
+ existingPrimaryKeysQuery = null;
+
+ maxUpdateDateQuery = null;
+
+ countQuery = null;
+
+ delegate = null;
+
+ columns = null;
+
+ pkNames = null;
+
+ pkIndexs = null;
+
+ insertQuery = null;
+
+ updateQuery = null;
+
+ withUpdateDateColumn = false;
+
+ countDataToUpdateQuery = null;
+
+ countDataToUpdateQueryWithNull = null;
+
+ dataToUpdateQuery = null;
+
+ dataToUpdateQueryWithNull = null;
+
+ selectDataQueryFromPk = null;
+ simpleKey = false;
+ }
+
+ public Set<String> getPkNames() {
+ return pkNames;
+ }
+
+ public boolean isWithUpdateDateColumn() {
+ return withUpdateDateColumn;
+ }
+
+ public int getColumnsCount() {
+ return columns.size();
+ }
+
+ public SortedSet<String> getColumnNames() {
+ return Sets.newTreeSet(columns.keySet());
+ }
+
+ public String getName() {
+ return delegate.getName();
+ }
+
+ public ForeignKeyMetadata getForeignKeyMetadata(ForeignKey fk) {
+ return delegate.getForeignKeyMetadata(fk);
+ }
+
+ public ColumnMetadata getColumnMetadata(String columnName) {
+ return delegate.getColumnMetadata(columnName);
+ }
+
+ public String getSchema() {
+ return delegate.getSchema();
+ }
+
+ public String getCatalog() {
+ return delegate.getCatalog();
+ }
+
+ public ForeignKeyMetadata getForeignKeyMetadata(String keyName) {
+ return delegate.getForeignKeyMetadata(keyName);
+ }
+
+ public IndexMetadata getIndexMetadata(String indexName) {
+ return delegate.getIndexMetadata(indexName);
+ }
+
+ public String getInsertQuery() {
+ return insertQuery;
+ }
+
+ public String getUpdateQuery() {
+ return updateQuery;
+ }
+
+ public String getExistingPrimaryKeysQuery() {
+ return existingPrimaryKeysQuery;
+ }
+
+ public String getMaxUpdateDateQuery() {
+ return maxUpdateDateQuery;
+ }
+
+ public String getCountQuery() {
+ return countQuery;
+ }
+
+ public String getSelectDataQueryFromPk() {
+ return selectDataQueryFromPk;
+ }
+
+ public int[] getPkIndexs() {
+ return pkIndexs;
+ }
+
+ public String getDataToUpdateQuery() {
+ return dataToUpdateQuery;
+ }
+
+ public String getDataToUpdateQueryWithNull() {
+ return dataToUpdateQueryWithNull;
+ }
+
+ public String getCountDataToUpdateQuery() {
+ return countDataToUpdateQuery;
+ }
+
+ public String getCountDataToUpdateQueryWithNull() {
+ return countDataToUpdateQueryWithNull;
+ }
+
+ public boolean isSimpleKey() {
+ return simpleKey;
+ }
+
+ public List<Object> getPk(ResultSet incomingData) throws SQLException {
+ List<Object> result = Lists.newArrayListWithCapacity(pkIndexs.length);
+ for (int pkIndex : pkIndexs) {
+ Object pk = incomingData.getObject(pkIndex);
+ result.add(pk);
+ }
+ return result;
+ }
+
+ public String toPkStr(List<Object> pkList) {
+ StringBuilder sb = new StringBuilder();
+ for (Object pk : pkList) {
+ sb.append("~|").append(pk);
+ }
+ return sb.toString();
+ }
+
+ public List<Object> fromPkStr(String pk) {
+ List<Object> pkList = Lists.newArrayList();
+ String[] split = pk.split("~\\|");
+ for (String s : split) {
+ if ("null".equals(s)) {
+ s = null;
+ }
+ pkList.add(s);
+ }
+ pkList.remove(0);
+ return pkList;
+ }
+
+ protected Set<String> initPrimaryKeys(DatabaseMetaData meta) throws SQLException {
+
+ Set<String> result = Sets.newHashSet();
+ ResultSet rs = meta.getPrimaryKeys(getCatalog(), getSchema(), getName());
+ try {
+
+ while (rs.next()) {
+ result.add(rs.getString("COLUMN_NAME"));
+ }
+ rs.close();
+ return ImmutableSet.copyOf(result);
+ } finally {
+ TuttiEntities.closeSilently(rs);
+ }
+ }
+
+ protected int[] createPkIndex() {
+
+ int[] result = new int[pkNames.size()];
+
+ int pkI = 0;
+ for (String pkName : pkNames) {
+ String pkColumnName = pkName.toLowerCase();
+
+ int i = 1;
+
+ int index = -1;
+ for (String columnName : getColumnNames()) {
+ if (pkColumnName.equals(columnName)) {
+ index = i;
+ } else {
+ i++;
+ }
+ }
+ result[pkI++] = index;
+ }
+ return result;
+ }
+
+
+ protected String createInsertQuery() {
+
+ StringBuilder queryParams = new StringBuilder();
+ StringBuilder valueParams = new StringBuilder();
+
+ for (String columnName : getColumnNames()) {
+ queryParams.append(", ").append(columnName);
+ valueParams.append(", ?");
+ }
+
+ String result = String.format(QUERY_INSERT,
+ getName(),
+ queryParams.substring(2),
+ valueParams.substring(2));
+ return result;
+ }
+
+ protected String createUpdateQuery() {
+
+ StringBuilder updateParams = new StringBuilder();
+
+ for (String columnName : getColumnNames()) {
+ updateParams.append(", ").append(columnName).append(" = ?");
+ }
+
+ String result = String.format(QUERY_UPDATE,
+ getName(),
+ updateParams.substring(2),
+ createPkWhereClause());
+ return result;
+ }
+
+ protected String createSelectQuery() {
+
+ String result = String.format(QUERY_SELECT,
+ createSelectParams(),
+ getName(),
+ createPkWhereClause());
+ return result;
+ }
+
+ protected String createPkWhereClause() {
+
+ StringBuilder pkParams = new StringBuilder();
+
+ for (String columnName : getPkNames()) {
+ pkParams.append("AND ").append(columnName).append(" = ?");
+ }
+
+ return pkParams.substring(4);
+ }
+
+ protected String createSelectParams() {
+
+ StringBuilder queryParams = new StringBuilder();
+
+ for (String columnName : getColumnNames()) {
+ queryParams.append(", ").append(columnName);
+ }
+
+ return queryParams.substring(2);
+ }
+
+ public String getTableLogPrefix() {
+ return "[" + getName() + "]";
+ }
+}
\ No newline at end of file
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadata.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Added: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableTool.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableTool.java (rev 0)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableTool.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -0,0 +1,365 @@
+package fr.ifremer.adagio.core.service.technical.synchro;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Created on 1/14/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+public class ReferentialSynchroTableTool implements Closeable {
+
+ /** Logger. */
+ private static final Log log =
+ LogFactory.getLog(ReferentialSynchroTableTool.class);
+
+ protected final Connection connection;
+
+ protected final ReferentialSynchroTableMetadata table;
+
+ protected final PreparedStatement insertStatement;
+
+ protected final PreparedStatement updateStatement;
+
+ protected final int columnCount;
+
+ protected final String tableName;
+
+ protected int insertCount = 0;
+
+ protected int updateCount = 0;
+
+ protected boolean debug;
+
+ public ReferentialSynchroTableTool(Connection connection,
+ ReferentialSynchroTableMetadata table) throws SQLException {
+ this.connection = connection;
+ this.table = table;
+ this.columnCount = table.getColumnsCount();
+ this.tableName = table.getName();
+
+ String insertSql = table.getInsertQuery();
+ String updateSql = table.getUpdateQuery();
+
+ insertStatement = connection.prepareStatement(insertSql);
+ updateStatement = connection.prepareStatement(updateSql);
+
+ debug = log.isTraceEnabled();
+ }
+
+
+ public void deleteAll() throws SQLException {
+ PreparedStatement deleteStatement =
+ connection.prepareStatement(
+ "DELETE FROM " + table.getName());
+ deleteStatement.execute();
+ }
+
+ public Object[] findByPk(List<Object> pk) throws SQLException {
+ String selectDataSql = table.getSelectDataQueryFromPk();
+
+ PreparedStatement selectStatement =
+ connection.prepareStatement(selectDataSql);
+
+ int columnCountIndex = 1;
+
+ for (Object pkColumn : pk) {
+ selectStatement.setObject(columnCountIndex++, pkColumn);
+ }
+
+ int columnsCount = table.getColumnsCount();
+ ResultSet resultSet = selectStatement.executeQuery();
+ resultSet.next();
+
+ Object[] result = new Object[columnsCount];
+
+ for (int i = 1; i <= columnsCount; i++) {
+
+ result[i - 1] = resultSet.getObject(i);
+ }
+ return result;
+ }
+
+ public Set<String> getExistingPrimaryKeys() throws SQLException {
+
+ Set<String> pkNames = table.getPkNames();
+ int pkCount = pkNames.size();
+ String sql = table.getExistingPrimaryKeysQuery();
+
+ PreparedStatement statement = connection.prepareStatement(sql);
+
+ Set<String> result = Sets.newHashSet();
+ try {
+ ResultSet resultSet = statement.executeQuery();
+
+
+ while (resultSet.next()) {
+ List<Object> pkList = Lists.newArrayListWithCapacity(pkNames.size());
+ for (int i = 1; i <= pkCount; i++) {
+ Object pk = resultSet.getObject(i);
+ pkList.add(pk);
+ }
+ String pk = table.toPkStr(pkList);
+ result.add(pk);
+ }
+ statement.close();
+ return result;
+ } finally {
+ closeSilently(statement);
+ }
+ }
+
+ public ResultSet getDataToUpdate(Date fromDate) throws SQLException {
+
+ String sql = fromDate == null ?
+ table.getDataToUpdateQueryWithNull() :
+ table.getDataToUpdateQuery();
+
+ PreparedStatement statement = connection.prepareStatement(sql);
+ if (table.isWithUpdateDateColumn() &&
+ fromDate != null) {
+ statement.setTimestamp(1, new Timestamp(fromDate.getTime()));
+ }
+ statement.setFetchSize(1000);
+
+ ResultSet result = statement.executeQuery();
+// // to be able to reward on resultSet
+// ((RowSet)result).setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
+ return result;
+ }
+
+ @Override
+ public void close() throws IOException {
+ closeSilently(insertStatement);
+ closeSilently(updateStatement);
+ }
+
+ public void executeInsert(List<Object> pk, ResultSet incomingData) throws SQLException {
+
+ List<Object> params = null;
+
+ if (debug) {
+ params = Lists.newArrayList();
+ }
+
+ for (int c = 1; c <= columnCount; c++) {
+ Object object = incomingData.getObject(c);
+ insertStatement.setObject(c, object);
+ if (debug) {
+ params.add(object);
+ }
+ }
+ insertCount++;
+
+ insertStatement.addBatch();
+
+ if (debug) {
+ log.debug(String.format("%s Execute insert query (pk:%s), params: %s", tableName, pk, params));
+ }
+
+ if (insertCount > 0 && insertCount % 1000 == 0) {
+ insertStatement.executeBatch();
+ insertStatement.clearBatch();
+ }
+ }
+
+ public void executeInsert(List<Object> pk, Object[] incomingData) throws SQLException {
+
+ for (int c = 1; c <= columnCount; c++) {
+ Object object = incomingData[c - 1];
+ insertStatement.setObject(c, object);
+ }
+ insertCount++;
+
+ insertStatement.addBatch();
+
+ if (debug) {
+ log.debug(String.format("%s Execute insert query (pk:%s), params: %s", tableName, pk, Arrays.toString(incomingData)));
+ }
+
+ if (insertCount > 0 && insertCount % 1000 == 0) {
+ insertStatement.executeBatch();
+ insertStatement.clearBatch();
+ }
+ }
+
+ public void executeUpdate(List<Object> pk, ResultSet incomingData) throws SQLException {
+
+ List<Object> params = null;
+
+ if (debug) {
+ params = Lists.newArrayList();
+ }
+
+ for (int c = 1; c <= columnCount; c++) {
+ Object object = incomingData.getObject(c);
+ updateStatement.setObject(c, object);
+ if (debug) {
+ params.add(object);
+ }
+ }
+
+ int columnCountIndex = columnCount + 1;
+
+ for (Object pkColumn : pk) {
+ updateStatement.setObject(columnCountIndex++, pkColumn);
+ }
+
+ updateCount++;
+
+ updateStatement.addBatch();
+
+ if (debug) {
+ log.debug(String.format("%s Execute update query (pk:%s), params: %s", tableName, pk, params));
+ }
+
+ if (updateCount > 0 && updateCount % 1000 == 0) {
+ updateStatement.executeBatch();
+ updateStatement.clearBatch();
+ }
+ }
+
+ public int getInsertCount() {
+ return insertCount;
+ }
+
+ public int getUpdateCount() {
+ return updateCount;
+ }
+
+ public void flushQueries() throws SQLException {
+
+ if (insertCount > 0 && insertCount % 1000 != 0) {
+ insertStatement.executeBatch();
+ }
+ if (updateCount > 0 && updateCount % 1000 != 0) {
+ updateStatement.executeBatch();
+ }
+ }
+
+ /**
+ * Gets the last updateDate for the given {@code table} using
+ * the given datasource.
+ *
+ * @return the last update date of the given table, or {@code null}
+ * if table does not use a updateDate columns or if there
+ * is no data in table.
+ */
+ public Timestamp getLastUpdateDate() throws SQLException {
+ Timestamp result = null;
+
+ if (table.isWithUpdateDateColumn()) {
+
+ String sql = table.getMaxUpdateDateQuery();
+
+ PreparedStatement statement = connection.prepareStatement(sql);
+ try {
+ ResultSet resultSet = statement.executeQuery();
+ if (resultSet.next()) {
+ result = resultSet.getTimestamp(1);
+ }
+ statement.close();
+ } finally {
+ closeSilently(statement);
+ }
+ }
+ return result;
+ }
+
+ public long getCountDataToUpdate(Date fromDate) throws SQLException {
+
+ String sql = fromDate == null ?
+ table.getCountDataToUpdateQueryWithNull() :
+ table.getCountDataToUpdateQuery();
+
+ PreparedStatement statement = connection.prepareStatement(sql);
+ if (table.isWithUpdateDateColumn() &&
+ fromDate != null) {
+ statement.setTimestamp(1, new Timestamp(fromDate.getTime()));
+ }
+
+ ResultSet queryResult = statement.executeQuery();
+ queryResult.next();
+ long result = queryResult.getLong(1);
+ return result;
+ }
+
+ public long count() throws SQLException {
+
+ String sql = table.getCountQuery();
+
+ PreparedStatement statement = connection.prepareStatement(sql);
+
+ try {
+ ResultSet resultSet = statement.executeQuery();
+ resultSet.next();
+ long result = resultSet.getLong(1);
+ statement.close();
+ return result;
+ } finally {
+ closeSilently(statement);
+ }
+ }
+
+ void closeSilently(Statement statement) {
+ try {
+ if (statement != null && !statement.isClosed()) {
+
+ statement.close();
+ }
+ } catch (AbstractMethodError e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Fix this linkage error, damned hsqlsb 1.8.0.7:(");
+ }
+ } catch (IllegalAccessError e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Fix this IllegalAccessError error, damned hsqlsb 1.8.0.7:(");
+ }
+ } catch (Exception e) {
+ if (log.isErrorEnabled()) {
+ log.error("Could not close statement, but do not care", e);
+ }
+ }
+ }
+}
Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableTool.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java
===================================================================
--- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java 2014-01-13 15:19:06 UTC (rev 1485)
+++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -25,9 +25,9 @@
*/
import fr.ifremer.adagio.core.service.ServiceLocator;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroService;
import fr.ifremer.tutti.persistence.TuttiPersistence;
import fr.ifremer.tutti.persistence.TuttiPersistenceServiceImplementor;
-import fr.ifremer.tutti.persistence.service.synchro.ReferentialSynchronizeService;
/**
* To obtain services from spring context.
@@ -115,9 +115,11 @@
ProtocolPersistenceService.class);
}
- public static ReferentialSynchronizeService getReferentialSynchronizeService() {
- return getPersistenceService("referentialSynchronizeService",
- ReferentialSynchronizeService.class);
+ //TODO Move this to adagio
+ public static ReferentialSynchroService getReferentialSynchroService() {
+ ReferentialSynchroService service = instance().getService(
+ "referentialSynchroService", ReferentialSynchroService.class);
+ return service;
}
public static AttachmentPersistenceService getAttachmentPersistenceService() {
Added: trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadataTest.java
===================================================================
--- trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadataTest.java (rev 0)
+++ trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadataTest.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -0,0 +1,56 @@
+package fr.ifremer.adagio.core.service.technical.synchro;
+
+/*
+ * #%L
+ * Tutti :: Persistence
+ * $Id$
+ * $HeadURL:$
+ * %%
+ * Copyright (C) 2012 - 2014 Ifremer
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.collect.Lists;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+/**
+ * Created on 1/14/14.
+ *
+ * @author Tony Chemit <chemit(a)codelutin.com>
+ * @since 3.0
+ */
+public class ReferentialSynchroTableMetadataTest {
+
+ @Test
+ public void getPkStr() {
+
+ List<Object> pk = Lists.<Object>newArrayList("a", null, 3);
+
+ ReferentialSynchroTableMetadata table = new ReferentialSynchroTableMetadata();
+
+ String pkStr = table.toPkStr(pk);
+ Assert.assertEquals("~|a~|null~|3", pkStr);
+
+ List<Object> fromPkStr = table.fromPkStr(pkStr);
+
+ Assert.assertEquals(Lists.<Object>newArrayList("a", null, "3"), fromPkStr);
+ }
+
+}
Property changes on: trunk/tutti-persistence/src/test/java/fr/ifremer/adagio/core/service/technical/synchro/ReferentialSynchroTableMetadataTest.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:eol-style
+ native
Modified: trunk/tutti-service/src/license/THIRD-PARTY.properties
===================================================================
--- trunk/tutti-service/src/license/THIRD-PARTY.properties 2014-01-13 15:19:06 UTC (rev 1485)
+++ trunk/tutti-service/src/license/THIRD-PARTY.properties 2014-01-15 08:43:26 UTC (rev 1486)
@@ -20,7 +20,6 @@
# - Lesser General Public License (LPGL)
# - Lesser General Public License (LPGL) v 2.1
# - MIT License
-# - MPL 1.1
# - Mozilla Public License
# - New BSD License
# - Public Domain
@@ -31,7 +30,7 @@
# Please fill the missing licenses for dependencies :
#
#
-#Sun Dec 08 20:03:42 CET 2013
+#Wed Jan 15 09:00:37 CET 2014
antlr--antlr--2.7.6=BSD License
batik--batik-awt-util--1.6=The Apache Software License, Version 2.0
batik--batik-bridge--1.6=The Apache Software License, Version 2.0
@@ -48,4 +47,5 @@
batik--batik-xml--1.6=The Apache Software License, Version 2.0
commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0
dom4j--dom4j--1.6.1=BSD License
+javassist--javassist--3.11.0.GA=The Apache Software License, Version 2.0
javax.transaction--jta--1.1=COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
Modified: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/TuttiDataContext.java
===================================================================
--- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/TuttiDataContext.java 2014-01-13 15:19:06 UTC (rev 1485)
+++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/TuttiDataContext.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -120,8 +120,6 @@
protected Cruise cruise;
-// protected TuttiProtocol protocol;
-
protected FishingOperation fishingOperation;
protected List<Caracteristic> caracteristics;
@@ -211,6 +209,7 @@
resetPersons();
resetSpecies();
resetValidationDataContext();
+ resetCaracteristics();
}
public void checkDbContext() {
@@ -777,10 +776,14 @@
referentSpecies = null;
referentSpeciesWithSurveyCode = null;
referentBenthosWithSurveyCode = null;
+
}
public void resetCaracteristics() {
caracteristics = null;
+ caracteristicsWithProtected = null;
+ genderValues = null;
+ deadOrAliveValues = null;
}
public void loadSampleCategoryModel(SampleCategoryModel sampleCategoryModel) {
Modified: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/referential/TuttiReferentialSynchronizeService.java
===================================================================
--- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/referential/TuttiReferentialSynchronizeService.java 2014-01-13 15:19:06 UTC (rev 1485)
+++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/referential/TuttiReferentialSynchronizeService.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -24,11 +24,11 @@
* #L%
*/
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroResult;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroService;
import fr.ifremer.tutti.TuttiConfiguration;
import fr.ifremer.tutti.persistence.entities.TuttiEntities;
import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator;
-import fr.ifremer.tutti.persistence.service.synchro.ReferentialSynchronizeResult;
-import fr.ifremer.tutti.persistence.service.synchro.ReferentialSynchronizeService;
import fr.ifremer.tutti.service.AbstractTuttiService;
import fr.ifremer.tutti.service.PersistenceService;
import fr.ifremer.tutti.service.TuttiServiceContext;
@@ -44,22 +44,22 @@
protected PersistenceService persistenceService;
- protected ReferentialSynchronizeService synchroService;
+ protected ReferentialSynchroService synchroService;
@Override
public void setServiceContext(TuttiServiceContext context) {
super.setServiceContext(context);
- synchroService = TuttiPersistenceServiceLocator.getReferentialSynchronizeService();
+ synchroService = TuttiPersistenceServiceLocator.getReferentialSynchroService();
persistenceService = getService(PersistenceService.class);
}
- public void prepare(File dbDirectory, ReferentialSynchronizeResult result) {
+ public void prepare(File dbDirectory, ReferentialSynchroResult result) {
Properties remoteConnectionProperties = getRemoteProperties(dbDirectory);
synchroService.prepare(remoteConnectionProperties, result);
}
public void synchronize(File dbDirectory,
- ReferentialSynchronizeResult result) {
+ ReferentialSynchroResult result) {
Properties remoteConnectionProperties = getRemoteProperties(dbDirectory);
synchroService.synchronize(remoteConnectionProperties, result);
}
Modified: trunk/tutti-ui-swing/src/license/THIRD-PARTY.properties
===================================================================
--- trunk/tutti-ui-swing/src/license/THIRD-PARTY.properties 2014-01-13 15:19:06 UTC (rev 1485)
+++ trunk/tutti-ui-swing/src/license/THIRD-PARTY.properties 2014-01-15 08:43:26 UTC (rev 1486)
@@ -30,7 +30,7 @@
# Please fill the missing licenses for dependencies :
#
#
-#Mon Dec 09 13:48:21 CET 2013
+#Wed Jan 15 09:38:43 CET 2014
antlr--antlr--2.7.6=BSD License
batik--batik-awt-util--1.6=The Apache Software License, Version 2.0
batik--batik-bridge--1.6=The Apache Software License, Version 2.0
Modified: trunk/tutti-ui-swing/src/main/filtered-resources/log4j.properties
===================================================================
--- trunk/tutti-ui-swing/src/main/filtered-resources/log4j.properties 2014-01-13 15:19:06 UTC (rev 1485)
+++ trunk/tutti-ui-swing/src/main/filtered-resources/log4j.properties 2014-01-15 08:43:26 UTC (rev 1486)
@@ -34,6 +34,7 @@
#See https://forum.hibernate.org/viewtopic.php?p=2404391
log4j.logger.org.hibernate.engine.StatefulPersistenceContext.ProxyWarnLog=ERROR
+log4j.logger.fr.ifremer.adagio.core.service.technical.synchro=DEBUG
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.file=${tutti.log.file}
Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiApplicationUpdaterCallBack.java
===================================================================
--- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiApplicationUpdaterCallBack.java 2014-01-13 15:19:06 UTC (rev 1485)
+++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiApplicationUpdaterCallBack.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -230,7 +230,7 @@
File cacheDirectory = config.getCacheDirectory();
ApplicationIOUtil.forceDeleteOnExit(
cacheDirectory,
- _("tutti.applicationUpdater.updateDone.deleteDirectory.caches.error", i18nDirectory)
+ _("tutti.applicationUpdater.updateDone.deleteDirectory.caches.error", cacheDirectory)
);
}
}
Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiDbUpdaterCallBack.java
===================================================================
--- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiDbUpdaterCallBack.java 2014-01-13 15:19:06 UTC (rev 1485)
+++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiDbUpdaterCallBack.java 2014-01-15 08:43:26 UTC (rev 1486)
@@ -26,12 +26,13 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
+import fr.ifremer.adagio.core.service.technical.synchro.ReferentialSynchroResult;
import fr.ifremer.shared.application.ApplicationTechnicalException;
import fr.ifremer.shared.application.swing.action.ApplicationActionException;
import fr.ifremer.shared.application.swing.action.ApplicationActionUI;
import fr.ifremer.tutti.TuttiConfiguration;
import fr.ifremer.tutti.persistence.ProgressionModel;
-import fr.ifremer.tutti.persistence.service.synchro.ReferentialSynchronizeResult;
+import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel;
import fr.ifremer.tutti.service.PersistenceService;
import fr.ifremer.tutti.service.referential.TuttiReferentialSynchronizeService;
import fr.ifremer.tutti.ui.swing.action.AbstractTuttiAction;
@@ -227,7 +228,7 @@
log.info(String.format("A database update was downloaded (oldVersion: %s, newVersion: %s), will launch a referential synchronize operation ", info.oldVersion, info.newVersion));
}
TuttiReferentialSynchronizeService service = context.getTuttiReferentialSynchronizeService();
- ReferentialSynchronizeResult result = new ReferentialSynchronizeResult();
+ ReferentialSynchroResult result = new ReferentialSynchroResult();
File dbDirectory = getDbDirectory(info);
ApplicationActionUI actionUI = context.getActionUI();
@@ -251,6 +252,15 @@
PersistenceService persistence = context.getPersistenceService();
persistence.clearAllCaches();
+ // clean data context
+ if (log.isInfoEnabled()) {
+ log.info("Clean data context.");
+ }
+ SampleCategoryModel sampleCategoryModel =
+ context.getDataContext().getSampleCategoryModel();
+ context.getDataContext().clearContext();
+ context.getDataContext().loadSampleCategoryModel(sampleCategoryModel);
+
// replace the version.appup file content
File target = context.getConfig().getDbDirectory();
File versionFile = ApplicationUpdater.getVersionFile(target);
@@ -260,7 +270,8 @@
try {
ApplicationUpdater.storeVersionFile(target, info.newVersion);
} catch (IOException e) {
- throw new ApplicationTechnicalException(_("tutti.applicationUpdater.synchroDB.writeVersion.error", versionFile));
+ throw new ApplicationTechnicalException(
+ _("tutti.applicationUpdater.synchroDB.writeVersion.error", versionFile));
}
}
}
Modified: trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties
===================================================================
--- trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties 2014-01-13 15:19:06 UTC (rev 1485)
+++ trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties 2014-01-15 08:43:26 UTC (rev 1486)
@@ -301,7 +301,7 @@
tutti.dbManager.action.upgradeDb=Mettre à jour les référentiels
tutti.dbManager.action.upgradeDb.check=Recherche des mises à jour de la base
tutti.dbManager.action.upgradeDb.done=La mise à jour des référentiel en version <strong>%s</strong> est terminée.
-tutti.dbManager.action.upgradeDb.mnemonic=V
+tutti.dbManager.action.upgradeDb.mnemonic=M
tutti.dbManager.action.upgradeDb.no.backup.db.choosen=La base ne sera pas migrée (vous avez annulé la sauvegarde avant migration).
tutti.dbManager.action.upgradeDb.opening=Ouverture de la base de données
tutti.dbManager.action.upgradeDb.reloading=Rechargement de la base de données
@@ -313,7 +313,7 @@
tutti.dbManager.action.upgradeDb.schema.version.not.found=L'application n'a pas pu déterminer la version de la base de données à importer. L'import ne peut pas être réalisé, veuillez contacter les administrateurs de l'application.
tutti.dbManager.action.upgradeDb.tip=Mettre à jour les référentiels
tutti.dbManager.action.upgradeDb.upToDate=<strong>Aucune mise à jour de base détectée</strong>
-tutti.dbManager.caracteristic.lastReferentialVersion=Version du référentiel disponible en mis à jour
+tutti.dbManager.caracteristic.lastReferentialVersion=Version du référentiel disponible en mise à jour
tutti.dbManager.caracteristic.referentialVersion=Version du référentiel utilisé
tutti.dbManager.caracteristic.schemaVersion=Version du schema
tutti.dbManager.caracteristic.url=Url de connexion
@@ -1472,6 +1472,8 @@
tutti.updateReport.message.success=La mise à jour des rapports nécessite le redémarrage de l'application
tutti.updateReport.noUpdate=<strong>Aucune mise à jour de rapports détectée.</strong>
tutti.updateReport.title.success=Redémarrage de l'application nécessaire...
+tutti.upgradeDb.message.success=La mise à jour des référentiels nécessite le redémarrage de l'application
+tutti.upgradeDb.title.success=Redémarrage de l'application nécessaire...
tutti.validateCruise.action.export.all.chooseFile.label=Choisir le fichier d'export
tutti.validateCruise.action.export.all.chooseFile.title=Exporter les messages de validation de la campagne
tutti.validateCruise.action.export.all.success=Les messages de validation des captures ont correctement été exporté dans le fichier %s
1
0
r1485 - in trunk: tutti-service/src/main/java/fr/ifremer/tutti/service/export/sumatra tutti-service/src/main/resources/i18n tutti-service/src/test/java/fr/ifremer/tutti/service/export/sumatra tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action
by tchemit@users.forge.codelutin.com 13 Jan '14
by tchemit@users.forge.codelutin.com 13 Jan '14
13 Jan '14
Author: tchemit
Date: 2014-01-13 16:19:06 +0100 (Mon, 13 Jan 2014)
New Revision: 1485
Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1485
Log:
fixes #3880: Erreur lors d'un export Sumatra
Modified:
trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/export/sumatra/CatchesSumatraExportService.java
trunk/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties
trunk/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties
trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/export/sumatra/CatchesSumatraExportServiceTest.java
trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ExportCruiseForSumatraAction.java
trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ExportFishingOperationForSumatraAction.java
Modified: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/export/sumatra/CatchesSumatraExportService.java
===================================================================
--- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/export/sumatra/CatchesSumatraExportService.java 2014-01-13 15:18:31 UTC (rev 1484)
+++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/export/sumatra/CatchesSumatraExportService.java 2014-01-13 15:19:06 UTC (rev 1485)
@@ -29,6 +29,7 @@
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import fr.ifremer.shared.application.ApplicationTechnicalException;
+import fr.ifremer.tutti.persistence.ProgressionModel;
import fr.ifremer.tutti.persistence.entities.data.Cruise;
import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
import fr.ifremer.tutti.service.AbstractTuttiService;
@@ -76,7 +77,8 @@
* @since 2.0
*/
public void exportCruiseForSumatra(File file,
- String cruiseId) {
+ String cruiseId,
+ ProgressionModel progressionModel) {
Preconditions.checkNotNull(cruiseId, "Cannot export a null cruise");
Preconditions.checkNotNull(file, "Cannot export to a null file");
@@ -85,13 +87,23 @@
log.info("Will export cruise " + cruiseId + " to file: " + file);
}
+ progressionModel.increments(_("tutti.service.sumatra.export.step.load.cruise", cruiseId));
+
Cruise cruise = persistenceService.getCruise(cruiseId);
Preconditions.checkNotNull(cruise, "Cruise [" + cruiseId + "] not found");
+ progressionModel.increments(_("tutti.service.sumatra.export.step.load.fishingOperationIds"));
+
List<String> operations =
persistenceService.getAllFishingOperationIds(cruiseId);
- prepareOperationsAndExport(file, operations);
+ if (log.isInfoEnabled()) {
+ log.info(operations.size() + " operations found for cruise: " + cruiseId);
+ }
+
+ progressionModel.adaptTotal(operations.size() + 3);
+
+ prepareOperationsAndExport(file, operations, progressionModel);
}
/**
@@ -104,7 +116,8 @@
*/
public void exportFishingOperationForSumatra(File file,
String cruiseId,
- String fishingOperationId) {
+ String fishingOperationId,
+ ProgressionModel progressionModel) {
Preconditions.checkNotNull(file, "Cannot export to a null file");
Preconditions.checkNotNull(cruiseId, "Cannot export a null cruise");
@@ -115,26 +128,39 @@
fishingOperationId + " to file: " + file);
}
+ progressionModel.increments(_("tutti.service.sumatra.export.step.load.cruise", cruiseId));
+
Cruise cruise = persistenceService.getCruise(cruiseId);
Preconditions.checkNotNull(cruise, "Cruise [" + cruiseId + "] not found");
List<String> operations = Lists.newArrayList(fishingOperationId);
- prepareOperationsAndExport(file, operations);
+ prepareOperationsAndExport(file, operations, progressionModel);
}
protected void prepareOperationsAndExport(File file,
- List<String> operations) {
+ List<String> operations,
+ ProgressionModel progressionModel) {
List<CatchRow> rows = Lists.newArrayList();
if (operations != null) {
for (String operationId : operations) {
+ progressionModel.increments(_("tutti.service.sumatra.export.step.load.fishingOperation", operationId));
+ if (!persistenceService.isFishingOperationWithCatchBatch(operationId)) {
+
+ if (log.isWarnEnabled()) {
+ log.warn("No catch for operation with id: " + operationId);
+ }
+ break;
+ }
+
prepareFishingOperation(rows, operationId);
}
}
+ progressionModel.increments(_("tutti.service.sumatra.export.step.export", file));
CatchRowModel csvModel =
new CatchRowModel(context.getConfig().getCsvSeparator());
Modified: trunk/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties
===================================================================
--- trunk/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties 2014-01-13 15:18:31 UTC (rev 1484)
+++ trunk/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties 2014-01-13 15:19:06 UTC (rev 1485)
@@ -161,6 +161,10 @@
tutti.service.referential.import.vessels.error=
tutti.service.referential.import.vessels.existingValue.error=
tutti.service.sumatra.export.error=
+tutti.service.sumatra.export.step.export=
+tutti.service.sumatra.export.step.load.cruise=
+tutti.service.sumatra.export.step.load.fishingOperation=
+tutti.service.sumatra.export.step.load.fishingOperationIds=
tutti.service.validateCruise.exportResult.error=
tutti.service.validateCruise.operations.progress=
tutti.validator.error.accidental.species.required=
Modified: trunk/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties
===================================================================
--- trunk/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties 2014-01-13 15:18:31 UTC (rev 1484)
+++ trunk/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties 2014-01-13 15:19:06 UTC (rev 1485)
@@ -161,6 +161,10 @@
tutti.service.referential.import.vessels.error=Erreur lors de l'import des navires du fichier %s
tutti.service.referential.import.vessels.existingValue.error=Un navire avec le nom %1s et l'immatriculation %2s existe déjà dans le référentiel
tutti.service.sumatra.export.error=Erreur lors de l'export Sumatra dans le fichier %s
+tutti.service.sumatra.export.step.export=Export dans le fichier %s
+tutti.service.sumatra.export.step.load.cruise=Chargement de la campagne %s
+tutti.service.sumatra.export.step.load.fishingOperation=Chargement du trait %s
+tutti.service.sumatra.export.step.load.fishingOperationIds=Recherche des opérations
tutti.service.validateCruise.exportResult.error=Erreur lors de l'export des résultats de validation de la campagne dans le fichier %s
tutti.service.validateCruise.operations.progress=Vérification du trait %s
tutti.validator.error.accidental.species.required=L'espèce est obligatoire
Modified: trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/export/sumatra/CatchesSumatraExportServiceTest.java
===================================================================
--- trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/export/sumatra/CatchesSumatraExportServiceTest.java 2014-01-13 15:18:31 UTC (rev 1484)
+++ trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/export/sumatra/CatchesSumatraExportServiceTest.java 2014-01-13 15:19:06 UTC (rev 1485)
@@ -24,6 +24,7 @@
* #L%
*/
+import fr.ifremer.tutti.persistence.ProgressionModel;
import fr.ifremer.tutti.service.ServiceDbResource;
import fr.ifremer.tutti.service.TuttiServiceContext;
import fr.ifremer.tutti.service.catches.TuttiWeightComputingException;
@@ -91,7 +92,9 @@
File exportFile = new File(dataDirectory, "exportSumatra.csv");
- service.exportCruiseForSumatra(exportFile, CRUISE_BAD_ID);
+ ProgressionModel progressionModel = new ProgressionModel();
+ progressionModel.setTotal(3);
+ service.exportCruiseForSumatra(exportFile, CRUISE_BAD_ID, progressionModel);
}
@Test
@@ -102,7 +105,9 @@
File exportFile = new File(dataDirectory, "exportSumatra.csv");
- service.exportCruiseForSumatra(exportFile, CRUISE_ID);
+ ProgressionModel progressionModel = new ProgressionModel();
+ progressionModel.setTotal(3);
+ service.exportCruiseForSumatra(exportFile, CRUISE_ID, progressionModel);
ServiceDbResource.assertFileContent("Sumatra export file:\n",
exportFile,
Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ExportCruiseForSumatraAction.java
===================================================================
--- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ExportCruiseForSumatraAction.java 2014-01-13 15:18:31 UTC (rev 1484)
+++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ExportCruiseForSumatraAction.java 2014-01-13 15:19:06 UTC (rev 1485)
@@ -25,6 +25,7 @@
*/
import com.google.common.base.Preconditions;
+import fr.ifremer.tutti.persistence.ProgressionModel;
import fr.ifremer.tutti.persistence.entities.data.Cruise;
import fr.ifremer.tutti.service.export.sumatra.CatchesSumatraExportService;
import fr.ifremer.tutti.ui.swing.content.MainUIHandler;
@@ -92,11 +93,14 @@
log.info("Will export cruise " + cruise.getId() +
" to file: " + file);
}
+ ProgressionModel pm = new ProgressionModel();
+ pm.setTotal(3); // loading cruise + loading fishing operationIds + export
+ setProgressionModel(pm);
// export catches
CatchesSumatraExportService service =
getContext().getCatchesSumatraExportService();
- service.exportCruiseForSumatra(file, cruise.getId());
+ service.exportCruiseForSumatra(file, cruise.getId(), pm);
}
Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ExportFishingOperationForSumatraAction.java
===================================================================
--- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ExportFishingOperationForSumatraAction.java 2014-01-13 15:18:31 UTC (rev 1484)
+++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ExportFishingOperationForSumatraAction.java 2014-01-13 15:19:06 UTC (rev 1485)
@@ -25,6 +25,7 @@
*/
import com.google.common.base.Preconditions;
+import fr.ifremer.tutti.persistence.ProgressionModel;
import fr.ifremer.tutti.persistence.entities.data.Cruise;
import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
import fr.ifremer.tutti.service.export.sumatra.CatchesSumatraExportService;
@@ -100,12 +101,17 @@
" to file: " + file);
}
+ ProgressionModel pm = new ProgressionModel();
+ pm.setTotal(3); // loading cruise + loading fishing operationIds + export
+ setProgressionModel(pm);
+
// export catches
CatchesSumatraExportService service =
getContext().getCatchesSumatraExportService();
service.exportFishingOperationForSumatra(file,
cruise.getId(),
- fishingOperation.getId());
+ fishingOperation.getId(),
+ pm);
}
1
0