r300 - in trunk: . tutti-persistence tutti-persistence/src/license tutti-persistence/src/main/java/fr/ifremer/tutti/persistence tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial tutti-pe
Author: tchemit Date: 2013-02-02 15:11:58 +0100 (Sat, 02 Feb 2013) New Revision: 300 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/300 Log: refs #1920: [TECH] - Persistence - Sauvegarde des donn?\195?\169es th?\195?\169matiques dans la DB Allegro - reunification en un seul module - nettoyage code, formatage, ... Added: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfig.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfigOption.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfigProvider.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/AbstractPersistenceService.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceImpl.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFile.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure/ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure/MeasurementPersistenceHelper.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelper.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java trunk/tutti-persistence/src/main/resources/META-INF/services/org.nuiton.util.ApplicationConfigProvider trunk/tutti-persistence/src/main/resources/applicationContext-service-tutti.xml trunk/tutti-persistence/src/main/resources/beanRefFactory.xml trunk/tutti-persistence/src/main/resources/queries-override.hbm.xml trunk/tutti-persistence/src/main/resources/tutti-db-conf.properties trunk/tutti-persistence/src/main/resources/tutti-db-enumerations.properties trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/DatabaseFixtures.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/DatabaseResource.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImplTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFileTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelperTest.java trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java trunk/tutti-persistence/src/test/resources/applicationContext-service-resources.xml trunk/tutti-persistence/src/test/resources/beanRefFactoryWitNoDb.xml trunk/tutti-persistence/src/test/resources/log4j.properties trunk/tutti-persistence/src/test/resources/tutti-test.properties trunk/tutti-persistence/src/test/server.properties trunk/tutti-persistence/src/test/startServer.sh trunk/tutti-persistence/src/test/startServerNew.sh Removed: trunk/tutti-persistence-adagio/ Modified: trunk/pom.xml trunk/tutti-persistence/README.txt trunk/tutti-persistence/pom.xml trunk/tutti-persistence/src/license/THIRD-PARTY.properties trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceServiceImplementor.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceService.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceService.java trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/SexagecimalPosition.java trunk/tutti-persistence/src/test/ trunk/tutti-service/pom.xml trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/config/TuttiServiceConfig.java trunk/tutti-ui-swing/pom.xml Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/pom.xml 2013-02-02 14:11:58 UTC (rev 300) @@ -37,7 +37,6 @@ <modules> <module>tutti-persistence</module> - <module>tutti-persistence-adagio</module> <module>tutti-service</module> <module>tutti-ui-swing</module> </modules> Modified: trunk/tutti-persistence/README.txt =================================================================== --- trunk/tutti-persistence/README.txt 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-persistence/README.txt 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,18 @@ + +Pour se connecter à la base +--------------------------- + +java -jar ~/.m2/repository/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar --inlineRC URL=jdbc:hsqldb:file:src/test/db/allegro,USER=sa + + +Pour lancer la base en mode serveur +----------------------------------- + +(cd src/test ; ./startServer.sh) + +On peut ensuite accéder à la base via l'url jdbc:hsqldb://localhost/allegro + +Se connecter à une superbe ui swing de requétage +------------------------------------------------ + +java -classpath ~/.m2/repository/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar org.hsqldb.util.DatabaseManager \ No newline at end of file Modified: trunk/tutti-persistence/pom.xml =================================================================== --- trunk/tutti-persistence/pom.xml 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-persistence/pom.xml 2013-02-02 14:11:58 UTC (rev 300) @@ -41,6 +41,14 @@ <dependencies> <dependency> + <groupId>fr.ifremer.adagio</groupId> + <artifactId>adagio-core</artifactId> + <classifier>allegro</classifier> + </dependency> + + <!-- commons --> + + <dependency> <groupId>org.nuiton</groupId> <artifactId>nuiton-utils</artifactId> </dependency> @@ -59,7 +67,7 @@ <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> - + <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> @@ -71,12 +79,51 @@ </dependency> <dependency> + <groupId>commons-dbcp</groupId> + <artifactId>commons-dbcp</artifactId> + </dependency> + + <!-- Yaml --> + + <dependency> <groupId>com.esotericsoftware.yamlbeans</groupId> <artifactId>yamlbeans</artifactId> </dependency> + <!-- jdbc drivers --> + + <!--dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + </dependency--> + <dependency> + <groupId>hsqldb</groupId> + <artifactId>hsqldb</artifactId> + </dependency> + + <!-- SPRING --> + + <dependency> <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-jdbc</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <scope>provided</scope> </dependency> @@ -87,10 +134,32 @@ <scope>provided</scope> </dependency> + <!-- Logging --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-jcl</artifactId> + <scope>runtime</scope> + </dependency> + + <!-- Test --> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-test</artifactId> + </dependency> + + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + </dependencies> <build> Modified: trunk/tutti-persistence/src/license/THIRD-PARTY.properties =================================================================== --- trunk/tutti-persistence/src/license/THIRD-PARTY.properties 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-persistence/src/license/THIRD-PARTY.properties 2013-02-02 14:11:58 UTC (rev 300) @@ -21,4 +21,4 @@ antlr--antlr--2.7.6=BSD License commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0 dom4j--dom4j--1.6.1=BSD License -javax.transaction--jta--1.1=COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 +javax.transaction--jta--1.1=COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 \ No newline at end of file Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceAdagioImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,580 @@ +package fr.ifremer.tutti.persistence; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 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.entities.data.AccidentalBatch; +import fr.ifremer.tutti.persistence.entities.data.BenthosBatch; +import fr.ifremer.tutti.persistence.entities.data.CatchBatch; +import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.data.MacroWasteBatch; +import fr.ifremer.tutti.persistence.entities.data.PlanktonBatch; +import fr.ifremer.tutti.persistence.entities.data.Program; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.Country; +import fr.ifremer.tutti.persistence.entities.referential.FishingOperationLocation; +import fr.ifremer.tutti.persistence.entities.referential.Gear; +import fr.ifremer.tutti.persistence.entities.referential.Person; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.persistence.entities.referential.Vessel; +import fr.ifremer.tutti.persistence.entities.referential.Zone; +import fr.ifremer.tutti.persistence.service.AccidentalBatchPersistenceService; +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.FishingOperationPersistenceService; +import fr.ifremer.tutti.persistence.service.MacroWasteBatchPersistenceService; +import fr.ifremer.tutti.persistence.service.PlanktonBatchPersistenceService; +import fr.ifremer.tutti.persistence.service.ProgramPersistenceService; +import fr.ifremer.tutti.persistence.service.ProtocolPersistenceService; +import fr.ifremer.tutti.persistence.service.ReferentialPersistenceService; +import fr.ifremer.tutti.persistence.service.SpeciesBatchPersistenceService; +import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.IOException; +import java.util.List; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.2 + */ +public class TuttiPersistenceImpl implements TuttiPersistence { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(TuttiPersistenceImpl.class); + + @Autowired + protected ReferentialPersistenceService referentialService; + + @Autowired + protected ProgramPersistenceService programService; + + @Autowired + protected CruisePersistenceService cruiseService; + + @Autowired + protected FishingOperationPersistenceService fishingOperationService; + + @Autowired + protected CatchBatchPersistenceService catchBatchService; + + @Autowired + protected SpeciesBatchPersistenceService speciesBatchService; + + @Autowired + protected BenthosBatchPersistenceService benthosBatchService; + + @Autowired + protected PlanktonBatchPersistenceService planktonBatchService; + + @Autowired + protected MacroWasteBatchPersistenceService macroWasteBatchService; + + @Autowired + protected AccidentalBatchPersistenceService accidentalBatchService; + + @Autowired + protected ProtocolPersistenceService protocolService; + + @Override + public String getImplementationName() { + return "Persistence Adagio implementation"; + } + + @Override + public void init() { + if (log.isInfoEnabled()) { + log.info("Open persistence driver " + getImplementationName()); + } + referentialService.init(); + programService.init(); + cruiseService.init(); + fishingOperationService.init(); + catchBatchService.init(); + speciesBatchService.init(); + benthosBatchService.init(); + benthosBatchService.init(); + planktonBatchService.init(); + macroWasteBatchService.init(); + accidentalBatchService.init(); + protocolService.init(); + } + + @Override + public void close() throws IOException { + + if (log.isInfoEnabled()) { + log.info("Close persistence driver " + getImplementationName()); + } + referentialService.close(); + programService.close(); + cruiseService.close(); + fishingOperationService.close(); + catchBatchService.close(); + speciesBatchService.close(); + benthosBatchService.close(); + benthosBatchService.close(); + planktonBatchService.close(); + macroWasteBatchService.close(); + accidentalBatchService.close(); + protocolService.close(); + TuttiPersistenceServiceLocator.close(); + } + + //------------------------------------------------------------------------// + //-- Referential methods --// + //------------------------------------------------------------------------// + + @Override + public List<Zone> getAllProgramZone() { + return referentialService.getAllProgramZone(); + } + + @Override + public List<Country> getAllCountry() { + return referentialService.getAllCountry(); + } + + @Override + public List<FishingOperationLocation> getAllFishingOperationStrata(String zoneId) { + return referentialService.getAllFishingOperationStrata(zoneId); + } + + @Override + public List<FishingOperationLocation> getAllFishingOperationSubStrata(String zoneId, + String strataId) { + return referentialService.getAllFishingOperationSubStrata(zoneId, + strataId); + } + + @Override + public List<FishingOperationLocation> getAllFishingOperationLocation(String zoneId, + String strataId, + String subStrataId) { + return referentialService.getAllFishingOperationLocation(zoneId, + strataId, + subStrataId); + } + + @Override + public List<Vessel> getAllScientificVessel() { + return referentialService.getAllScientificVessel(); + } + + @Override + public List<Vessel> getAllFishingVessel() { + return referentialService.getAllFishingVessel(); + } + + @Override + public List<Species> getAllSpecies() { + return referentialService.getAllSpecies(); + } + + @Override + public Species getSpecies(String speciesId) { + return referentialService.getSpecies(speciesId); + } + + @Override + public List<Caracteristic> getAllCaracteristic() { + return referentialService.getAllCaracteristic(); + } + + @Override + public Caracteristic getSizeCategoryCaracteristic() { + return referentialService.getSizeCategoryCaracteristic(); + } + + @Override + public Caracteristic getSexCaracteristic() { + return referentialService.getSexCaracteristic(); + } + + @Override + public Caracteristic getSortedUnsortedCaracteristic() { + return referentialService.getSortedUnsortedCaracteristic(); + } + + @Override + public Caracteristic getMaturityCaracteristic() { + return referentialService.getMaturityCaracteristic(); + } + + @Override + public Caracteristic getMacroWasteCategoryCaracteristic() { + return referentialService.getMacroWasteCategoryCaracteristic(); + } + + @Override + public Caracteristic getMacroWasteSizeCategoryCaracteristic() { + return referentialService.getMacroWasteSizeCategoryCaracteristic(); + } + + @Override + public List<Gear> getAllScientificGear() { + return referentialService.getAllScientificGear(); + } + + @Override + public List<Gear> getAllFishingGear() { + return referentialService.getAllFishingGear(); + } + + @Override + public List<Person> getAllPerson() { + return referentialService.getAllPerson(); + } + + @Override + public Vessel getVessel(String vesselCode) { + return referentialService.getVessel(vesselCode); + } + + @Override + public boolean isSortedQualitativeValue(CaracteristicQualitativeValue value) { + return referentialService.isSortedQualitativeValue(value); + } + + @Override + public Person getPerson(Integer personId) { + return referentialService.getPerson(personId); + } + + @Override + public Gear getGear(Integer gearId) { + return referentialService.getGear(gearId); + } + + //------------------------------------------------------------------------// + //-- Program methods --// + //------------------------------------------------------------------------// + + @Override + public List<Program> getAllProgram() { + return programService.getAllProgram(); + } + + @Override + public Program getProgram(String id) { + return programService.getProgram(id); + } + + @Override + public Program createProgram(Program bean) { + return programService.createProgram(bean); + } + + @Override + public Program saveProgram(Program bean) { + return programService.saveProgram(bean); + } + + //------------------------------------------------------------------------// + //-- Cruise methods --// + //------------------------------------------------------------------------// + + @Override + public List<Cruise> getAllCruise(String programId) { + return cruiseService.getAllCruise(programId); + } + + @Override + public Cruise getCruise(String id) { + return cruiseService.getCruise(id); + } + + @Override + public Cruise createCruise(Cruise bean) { + return cruiseService.createCruise(bean); + } + + @Override + public Cruise saveCruise(Cruise bean) { + return cruiseService.saveCruise(bean); + } + + //------------------------------------------------------------------------// + //-- Protocol methods --// + //------------------------------------------------------------------------// + + @Override + public boolean isProtocolExist(String id) { + return protocolService.isProtocolExist(id); + } + + @Override + public List<String> getAllProtocolNames() { + return protocolService.getAllProtocolId(); + } + + @Override + public List<TuttiProtocol> getAllProtocol() { + return protocolService.getAllProtocol(); + } + + @Override + public TuttiProtocol saveProtocol(TuttiProtocol bean) { + return protocolService.saveProtocol(bean); + } + + @Override + public void deleteProtocol(String id) { + protocolService.deleteProtocol(id); + } + + @Override + public TuttiProtocol createProtocol(TuttiProtocol bean) { + return protocolService.createProtocol(bean); + } + + @Override + public TuttiProtocol getProtocol(String id) { + return protocolService.getProtocol(id); + } + + + //------------------------------------------------------------------------// + //-- Fishing operation methods --// + //------------------------------------------------------------------------// + + @Override + public List<FishingOperation> getAllFishingOperation(String cruiseId) { + return fishingOperationService.getAllFishingOperation(cruiseId); + } + + @Override + public FishingOperation getFishingOperation(String id) { + return fishingOperationService.getFishingOperation(id); + } + + @Override + public FishingOperation createFishingOperation(FishingOperation bean) { + return fishingOperationService.createFishingOperation(bean); + } + + @Override + public FishingOperation saveFishingOperation(FishingOperation bean) { + return fishingOperationService.saveFishingOperation(bean); + } + + //------------------------------------------------------------------------// + //-- CatchBatch methods --// + //------------------------------------------------------------------------// + + @Override + public CatchBatch getCatchBatchFromFishingOperation(String id) { + return catchBatchService.getCatchBatchFromFishingOperation(id); + } + + @Override + public CatchBatch createCatchBatch(CatchBatch bean) { + return catchBatchService.createCatchBatch(bean); + } + + @Override + public CatchBatch saveCatchBatch(CatchBatch bean) { + return catchBatchService.saveCatchBatch(bean); + } + + //------------------------------------------------------------------------// + //-- Species Batch methods --// + //------------------------------------------------------------------------// + + @Override + public List<SpeciesBatch> getAllRootSpeciesBatch(String fishingOperationId) { + return speciesBatchService.getAllRootSpeciesBatch(fishingOperationId); + } + + @Override + public List<SpeciesBatch> getAllSpeciesBatch(String fishingOperationId) { + return speciesBatchService.getAllSpeciesBatch(fishingOperationId); + } + + @Override + public SpeciesBatch getSpeciesBatch(String id) { + return speciesBatchService.getSpeciesBatch(id); + } + + @Override + public SpeciesBatch createSpeciesBatch(SpeciesBatch bean, String parentBatchId) { + return speciesBatchService.createSpeciesBatch(bean, parentBatchId); + } + + @Override + public SpeciesBatch saveSpeciesBatch(SpeciesBatch bean) { + return speciesBatchService.saveSpeciesBatch(bean); + } + + @Override + public void deleteSpeciesBatch(String id) { + speciesBatchService.deleteSpeciesBatch(id); + } + + @Override + public void deleteSpeciesSubBatch(String id) { + speciesBatchService.deleteSpeciesSubBatch(id); + } + + @Override + public List<SpeciesBatchFrequency> getAllSpeciesBatchFrequency(String speciesBatchId) { + return speciesBatchService.getAllSpeciesBatchFrequency(speciesBatchId); + } + + @Override + public List<SpeciesBatchFrequency> saveSpeciesBatchFrequency(String speciesBatchId, List<SpeciesBatchFrequency> frequencies) { + return speciesBatchService.saveSpeciesBatchFrequency(speciesBatchId, frequencies); + } + + //------------------------------------------------------------------------// + //-- Benthos Batch methods --// + //------------------------------------------------------------------------// + + @Override + public List<BenthosBatch> getAllBenthosBatch(String fishingOperationId) { + return benthosBatchService.getAllBenthosBatch(fishingOperationId); + } + + @Override + public BenthosBatch getBenthosBatch(String id) { + return benthosBatchService.getBenthosBatch(id); + } + + @Override + public BenthosBatch createBenthosBatch(BenthosBatch bean) { + return benthosBatchService.createBenthosBatch(bean); + } + + @Override + public BenthosBatch saveBenthosBatch(BenthosBatch bean) { + return benthosBatchService.saveBenthosBatch(bean); + } + + @Override + public void deleteBenthosBatch(String id) { + benthosBatchService.deleteBenthosBatch(id); + } + + //------------------------------------------------------------------------// + //-- Plancton Batch methods --// + //------------------------------------------------------------------------// + + @Override + public List<PlanktonBatch> getAllPlanktonBatch(String fishingOperationId) { + return planktonBatchService.getAllPlanktonBatch(fishingOperationId); + } + + @Override + public PlanktonBatch getPlanktonBatch(String id) { + return planktonBatchService.getPlanktonBatch(id); + } + + @Override + public PlanktonBatch createPlanktonBatch(PlanktonBatch bean) { + return planktonBatchService.createPlanktonBatch(bean); + } + + @Override + public PlanktonBatch savePlanktonBatch(PlanktonBatch bean) { + return planktonBatchService.savePlanktonBatch(bean); + } + + @Override + public void deletePlanktonBatch(String id) { + planktonBatchService.deletePlanktonBatch(id); + } + + //------------------------------------------------------------------------// + //-- Macrodechet Batch methods --// + //------------------------------------------------------------------------// + + @Override + public List<MacroWasteBatch> getAllMacroWasteBatch(String fishingOperationId) { + return macroWasteBatchService.getAllMacroWasteBatch(fishingOperationId); + } + + @Override + public MacroWasteBatch getMacroWasteBatch(String id) { + return macroWasteBatchService.getMacroWasteBatch(id); + } + + @Override + public MacroWasteBatch createMacroWasteBatch(MacroWasteBatch bean) { + return macroWasteBatchService.createMacroWasteBatch(bean); + } + + @Override + public MacroWasteBatch saveMacroWasteBatch(MacroWasteBatch bean) { + return macroWasteBatchService.saveMacroWasteBatch(bean); + } + + @Override + public void deleteMacroWasteBatch(String id) { + macroWasteBatchService.deleteMacroWasteBatch(id); + } + + //------------------------------------------------------------------------// + //-- Accidental Batch methods --// + //------------------------------------------------------------------------// + + @Override + public List<AccidentalBatch> getAllAccidentalBatch(String fishingOperationId) { + return accidentalBatchService.getAllAccidentalBatch(fishingOperationId); + } + + @Override + public AccidentalBatch getAccidentalBatch(String id) { + return accidentalBatchService.getAccidentalBatch(id); + } + + @Override + public AccidentalBatch createAccidentalBatch(AccidentalBatch bean) { + return accidentalBatchService.createAccidentalBatch(bean); + } + + @Override + public AccidentalBatch saveAccidentalBatch(AccidentalBatch bean) { + return accidentalBatchService.saveAccidentalBatch(bean); + } + + @Override + public void deleteAccidentalBatch(String id) { + accidentalBatchService.deleteAccidentalBatch(id); + } + + //------------------------------------------------------------------------// + //-- Internal methods --// + //------------------------------------------------------------------------// + + +} Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceServiceImplementor.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceServiceImplementor.java 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceServiceImplementor.java 2013-02-02 14:11:58 UTC (rev 300) @@ -1,5 +1,29 @@ package fr.ifremer.tutti.persistence; +/* + * #%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 java.io.Closeable; import java.io.IOException; Property changes on: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/TuttiPersistenceServiceImplementor.java ___________________________________________________________________ Modified: svn:keywords - Author Date Id Revision + Author Date Id Revision HeadURL Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfig.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceAdagioConfig.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfig.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfig.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,264 @@ +package fr.ifremer.tutti.persistence.config; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 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.Charsets; +import com.google.common.base.Predicate; +import com.google.common.collect.Sets; +import com.google.common.io.Files; +import fr.ifremer.tutti.persistence.RessourceClassLoader; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.ApplicationConfig; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.Set; + +/** + * Configuration for the persistence driver. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.2 + */ +public class TuttiPersistenceConfig { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(TuttiPersistenceConfig.class); + + private static TuttiPersistenceConfig instance; + + public static TuttiPersistenceConfig getInstance() { + return instance; + } + + public static void setInstance(TuttiPersistenceConfig instance) { + TuttiPersistenceConfig.instance = instance; + } + + protected final ApplicationConfig config; + + public TuttiPersistenceConfig(ApplicationConfig config) { + this.config = config; + } + + public void initConfig(RessourceClassLoader resourceLoader) throws IOException { + try { + FileUtils.forceMkdir(getDbDirectory()); + FileUtils.forceMkdir(getProtocolDirectory()); + } catch (Exception e) { + throw new RuntimeException("Could not create directory", e); + } + + // add a predicate to search the configuration file from his directory instead of the class-path + resourceLoader.addSearchInDirectoriesPredicate(new Predicate<String>() { + + Set<String> matchingNames = Sets.newHashSet( + getDbConfigurationPath().getName(), + getDbEnumerationPath().getName()); + + @Override + public boolean apply(String input) { + return matchingNames.contains(input); + } + }); + + // get configuration file path + File configurationPath = getDbConfigurationPath(); + + // add his directory in path to search + resourceLoader.addDirectory(configurationPath.getParentFile()); + + // generate configuration file if required + generateDbConfiguration(configurationPath); + + // get enumeration file path + File enumerationPath = getDbEnumerationPath(); + + // add his directory in path to search + resourceLoader.addDirectory(enumerationPath.getParentFile()); + + generateDbEnumerationConfiguration(enumerationPath); + } + + public File getDbConfigurationPath() { + return config.getOptionAsFile(TuttiPersistenceConfigOption.DB_CONFIGURATION_PATH.getKey()); + } + + public File getDbDirectory() { + return config.getOptionAsFile(TuttiPersistenceConfigOption.DB_DIRECTORY.getKey()); + } + + public File getProtocolDirectory() { + return config.getOptionAsFile(TuttiPersistenceConfigOption.PROTOCOL_DIRECTORY.getKey()); + } + + public File getDbName() { + return config.getOptionAsFile(TuttiPersistenceConfigOption.DB_NAME.getKey()); + } + + public boolean isDbExists() { + File f = new File(getDbDirectory(), getDbName() + ".data"); + return f.exists(); + } + + public File getDbEnumerationPath() { + return config.getOptionAsFile(TuttiPersistenceConfigOption.DB_ENUMERATION_PATH.getKey()); + } + + public String getJdbcUrl() { + return config.getOption(TuttiPersistenceConfigOption.JDBC_URL.getKey()); + } + + public Class getJdbcDriver() { + return config.getOptionAsClass(TuttiPersistenceConfigOption.JDBC_DRIVER.getKey()); + } + + public String getJdbcUsername() { + return config.getOption(TuttiPersistenceConfigOption.JDBC_USERNAME.getKey()); + } + + public String getJdbcPassword() { + return config.getOption(TuttiPersistenceConfigOption.JDBC_PASSWORD.getKey()); + } + + public Class getHibernateDialect() { + return config.getOptionAsClass(TuttiPersistenceConfigOption.HIBERNATE_DIALECT.getKey()); + } + + public boolean isHibernateShowSql() { + Boolean result = config.getOptionAsBoolean(TuttiPersistenceConfigOption.HIBERNATE_SHOW_SQL.getKey()); + return result != null && result; + } + + public boolean isHibernateUseSqlComment() { + Boolean result = config.getOptionAsBoolean(TuttiPersistenceConfigOption.HIBERNATE_USE_SQL_COMMENT.getKey()); + return result != null && result; + } + + public boolean isHibernateFormatSql() { + Boolean result = config.getOptionAsBoolean(TuttiPersistenceConfigOption.HIBERNATE_FORMAT_SQL.getKey()); + return result != null && result; + } + + public ApplicationConfig getConfig() { + return config; + } + + public void generateDbConfiguration(File destination) throws IOException { + + if (!destination.exists()) { + + // load db configuration template (tutti-db.properties) + + if (log.isInfoEnabled()) { + log.info("Generate " + destination + " from classpath."); + } + Properties result = new Properties(); + InputStream in = getClass().getResourceAsStream("/tutti-db-conf.properties"); + try { + result.load(in); + in.close(); + } finally { + IOUtils.closeQuietly(in); + } + + // replace some values from ApplicationConfig + + result.put("dataSource.jdbc.driver", getJdbcDriver().getName()); + result.put("dataSource.jdbc.username", getJdbcUsername()); + result.put("dataSource.jdbc.password", getJdbcPassword()); + result.put("dataSource.jdbc.url", getJdbcUrl()); + result.put("hibernate.dialect", getHibernateDialect().getName()); + result.put("hibernate.show_sql", isHibernateShowSql() + ""); + result.put("hibernate.format_sql", isHibernateFormatSql() + ""); + result.put("hibernate.use_sql_comments", isHibernateUseSqlComment() + ""); + + // write result file at destination + + BufferedWriter writer = Files.newWriter(destination, Charsets.UTF_8); + try { + result.store(writer, "Generated by " + getClass().getName()); + writer.close(); + } finally { + IOUtils.closeQuietly(writer); + } + } + } + + public void generateDbEnumerationConfiguration(File destination) throws IOException { + + if (!destination.exists()) { + + // load enumeration mapping from classpath (enumerations.properties) + + if (log.isInfoEnabled()) { + log.info("Generate " + destination + " from classpath."); + } + + Properties result = new Properties(); + InputStream in = getClass().getResourceAsStream("/tutti-db-enumerations.properties"); + try { + result.load(in); + in.close(); + } finally { + IOUtils.closeQuietly(in); + } + + // replace some values from ApplicationConfig + + + // write result file at destination + + BufferedWriter writer = + Files.newWriter(destination, Charsets.UTF_8); + try { + result.store(writer, "Generated by " + getClass().getName()); + writer.close(); + } finally { + IOUtils.closeQuietly(writer); + } + } + } + + public Properties getDbEnumerations() throws IOException { + Properties result = new Properties(); + BufferedReader in = Files.newReader(getDbEnumerationPath(), Charsets.UTF_8); + try { + result.load(in); + in.close(); + } finally { + IOUtils.closeQuietly(in); + } + return result; + } +} \ No newline at end of file Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfigOption.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceAdagioConfigOption.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfigOption.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfigOption.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,214 @@ +package fr.ifremer.tutti.persistence.config; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 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.HSQLDialect; +import org.hsqldb.jdbcDriver; +import org.nuiton.util.ApplicationConfig; + +import java.io.File; + +/** + * Persistence configuration options. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.2 + */ +public enum TuttiPersistenceConfigOption implements ApplicationConfig.OptionDef { + + DB_DIRECTORY( + "tutti.persistence.db.directory", + "Répertoire où est la base de données", + "${tutti.data.directory}/db", + File.class, + true, + true), + + PROTOCOL_DIRECTORY( + "tutti.persistence.protocol.directory", + "Répertoire où sont conservés les protocoles", + "${tutti.data.directory}/protocol", + File.class, + true, + true), + + DB_CONFIGURATION_PATH( + "tutti.persistence.db.configurationPath", + "Chemin du fichier de configuration d'Adagio", + "${tutti.data.directory}/resources/conf.properties", + File.class, + true, + true), + + DB_ENUMERATION_PATH( + "tutti.persistence.db.enumerationPath", + "Chemin du fichier de correspondance des constantes", + "${tutti.data.directory}/resources/enumerations-v3.properties", + File.class, + true, + true), + + DB_NAME( + "tutti.persistence.db.name", + "Nom du fichier de la base de données", + "allegro", + String.class, + true, + true), + + JDBC_USERNAME( + "tutti.persistence.jdbc.username", + "Login de l'utilisateur pour se connecter à la base de données", + "sa", + String.class, + true, + true), + JDBC_PASSWORD( + "tutti.persistence.jdbc.password", + "Mot de passe de l'utilisateur pour se connecter à la base de données", + "", + String.class, + true, + true), + JDBC_URL( + "tutti.persistence.jdbc.url", + "URL de connexion à la base de données", + "jdbc:hsqldb:file:${tutti.persistence.db.directory}/${tutti.persistence.db.name}", + String.class, + true, + true), + JDBC_DRIVER( + "tutti.persistence.jdbc.driver", + "Le pilote JDBC utilisé pour communiquer avec la base de données", + jdbcDriver.class.getName(), + Class.class, + true, + true), + HIBERNATE_DIALECT( + "tutti.persistence.hibernate.dialect", + "Le dialect hibernate utilisée pour communiquer avec la base de données", + HSQLDialect.class.getName(), + Class.class, + true, + true), + HIBERNATE_SHOW_SQL( + "tutti.persistence.hibernate.showSql", + "Option pour afficher ou non les requète sql dans les logs", + Boolean.FALSE.toString(), + boolean.class, + true, + true), + HIBERNATE_USE_SQL_COMMENT( + "tutti.persistence.hibernate.useSqlComment", + "Option pour ajouter les commentaires dans les requètes sql générées", + Boolean.FALSE.toString(), + boolean.class, + true, + true), + HIBERNATE_FORMAT_SQL( + "tutti.persistence.hibernate.formatSql", + "Option pour ajouter les commentaires dans les requètes sql générées", + Boolean.FALSE.toString(), + boolean.class, + true, + true); + + /** Configuration key. */ + private final String key; + + /** I18n key of option description */ + private final String description; + + /** Type of option */ + private final Class<?> type; + + /** Default value of option. */ + private String defaultValue; + + /** Flag to not keep option value on disk */ + private boolean isTransient; + + /** Flag to not allow option value modification */ + private boolean isFinal; + + TuttiPersistenceConfigOption(String key, + String description, + String defaultValue, + Class<?> type, + boolean isTransient, + boolean isFinal) { + this.key = key; + this.description = description; + this.defaultValue = defaultValue; + this.type = type; + this.isTransient = isTransient; + this.isFinal = isFinal; + } + + @Override + public String getKey() { + return key; + } + + @Override + public Class<?> getType() { + return type; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getDefaultValue() { + return defaultValue; + } + + @Override + public boolean isTransient() { + return isTransient; + } + + @Override + public boolean isFinal() { + return isFinal; + } + + @Override + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + @Override + public void setTransient(boolean newValue) { + // not used + } + + @Override + public void setFinal(boolean newValue) { + // not used + } +} \ No newline at end of file Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfigProvider.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceAdagioProvider.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfigProvider.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/config/TuttiPersistenceConfigProvider.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,59 @@ +package fr.ifremer.tutti.persistence.config; + +/* + * #%L + * Tutti :: Persistence API + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 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.nuiton.util.ApplicationConfig; +import org.nuiton.util.ApplicationConfigProvider; + +import java.util.Locale; + +/** + * Persistence config provider (for site generation). + * + * @author tchemit <chemit@codelutin.com> + * @since 0.2 + */ +public class TuttiPersistenceConfigProvider implements ApplicationConfigProvider { + + @Override + public String getName() { + return "tutti-persistence"; + } + + @Override + public String getDescription(Locale locale) { + return "Configuration de la persistence de Tutti."; + } + + @Override + public ApplicationConfig.OptionDef[] getOptions() { + return TuttiPersistenceConfigOption.values(); + } + + @Override + public ApplicationConfig.ActionDef[] getActions() { + return new ApplicationConfig.ActionDef[0]; + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/AbstractPersistenceService.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/AbstractPersistenceService.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/AbstractPersistenceService.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/AbstractPersistenceService.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,166 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.base.Preconditions; +import fr.ifremer.adagio.core.dao.administration.programStrategy.ProgramDao; +import fr.ifremer.tutti.persistence.TuttiPersistenceServiceImplementor; +import fr.ifremer.tutti.persistence.config.TuttiPersistenceConfig; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.Query; +import org.hibernate.SessionFactory; +import org.hibernate.classic.Session; +import org.hibernate.type.Type; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.util.Iterator; + +/** + * TODO + * + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public abstract class AbstractPersistenceService implements TuttiPersistenceServiceImplementor { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(AbstractPersistenceService.class); + + /** + * Session factory. + * + * @since 0.3 + */ + @Autowired(required = true) + protected SessionFactory sessionFactory; + + @Autowired(required = true) + protected TuttiEnumerationFile enumeration; + + @Resource(name = "programDao") + protected ProgramDao programDao; + + protected TuttiPersistenceConfig config; + + @Override + public void init() { + if (config == null) { + + config = TuttiPersistenceConfig.getInstance(); + + Preconditions.checkNotNull( + config, "No config found in " + + TuttiPersistenceConfig.class.getName()); + } + } + + @Override + public void close() { + // do nohting by default + } + + public void setConfig(TuttiPersistenceConfig config) { + this.config = config; + } + + protected final SessionFactory getSessionFactory() { + return sessionFactory; + } + + protected final Session getCurrentSession() { + return getSessionFactory().getCurrentSession(); + } + + protected Object[] queryUnique(String queryName, Object... params) { + + Query query = createQuery(queryName, params); + Object result = query.uniqueResult(); + return (Object[]) result; + } + + protected <T> T queryUniqueTyped(String queryName, Object... params) { + + Query query = createQuery(queryName, params); + Object result = query.uniqueResult(); + return (T) result; + } + + protected Iterator<Object[]> queryList(String queryName, Object... params) { + + Query query = createQuery(queryName, params); + Iterator result = query.iterate(); + return result; + } + + protected <T> Iterator<T> queryListTyped(String queryName, Object... params) { + + Query query = createQuery(queryName, params); + Iterator result = query.iterate(); + return result; + } + + protected Query createQuery(String queryName, Object... params) { + Query query = getCurrentSession().getNamedQuery(queryName); + + if (params.length > 0) { + + Preconditions.checkArgument( + params.length % 3 == 0, + "Params must be tuple (paramName, paramType, paramValue)"); + + int nbParams = params.length / 3; + + for (int i = 0; i < nbParams; i++) { + String paramName = (String) params[3 * i]; + Type paramType = (Type) params[3 * i + 1]; + Object paramValue = params[3 * i + 2]; + query.setParameter(paramName, paramValue, paramType); + if (log.isDebugEnabled()) { + log.debug("query [" + queryName + "] (param " + i + + " [" + paramName + '=' + paramValue + "])"); + } + } + } + return query; + } + + protected <T extends Serializable> T load(Class<? extends T> clazz, Serializable id) { + T load = (T) getCurrentSession().load(clazz, id); + return load; + } + + protected int queryUpdate(String queryName, Object... params) { + + Query query = createQuery(queryName, params); + + int result = query.executeUpdate(); + return result; + } + +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,72 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.Lists; +import fr.ifremer.tutti.persistence.entities.data.AccidentalBatch; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("accidentalBatchPersistenceService") +public class AccidentalBatchPersistenceServiceImpl extends AbstractPersistenceService implements AccidentalBatchPersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(AccidentalBatchPersistenceServiceImpl.class); + + @Override + public List<AccidentalBatch> getAllAccidentalBatch(String fishingOperationId) { + List<AccidentalBatch> result = Lists.newArrayList(); + + // TODO + return result; + } + + @Override + public AccidentalBatch getAccidentalBatch(String id) { + return null; + } + + @Override + public AccidentalBatch createAccidentalBatch(AccidentalBatch bean) { + return null; + } + + @Override + public AccidentalBatch saveAccidentalBatch(AccidentalBatch bean) { + return null; + } + + @Override + public void deleteAccidentalBatch(String id) { + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,72 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.Lists; +import fr.ifremer.tutti.persistence.entities.data.BenthosBatch; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("benthosBatchPersistenceService") +public class BenthosBatchPersistenceServiceImpl extends AbstractPersistenceService implements BenthosBatchPersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(BenthosBatchPersistenceServiceImpl.class); + + @Override + public List<BenthosBatch> getAllBenthosBatch(String fishingOperationId) { + List<BenthosBatch> result = Lists.newArrayList(); + + // TODO + return result; + } + + @Override + public BenthosBatch getBenthosBatch(String id) { + return null; + } + + @Override + public BenthosBatch createBenthosBatch(BenthosBatch bean) { + return null; + } + + @Override + public BenthosBatch saveBenthosBatch(BenthosBatch bean) { + return null; + } + + @Override + public void deleteBenthosBatch(String id) { + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,439 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.base.Preconditions; +import com.google.common.collect.Lists; +import fr.ifremer.adagio.core.dao.data.batch.Batch; +import fr.ifremer.adagio.core.dao.data.batch.CatchBatchDao; +import fr.ifremer.adagio.core.dao.data.batch.SortingBatch; +import fr.ifremer.adagio.core.dao.data.batch.SortingBatchDao; +import fr.ifremer.adagio.core.dao.data.batch.denormalized.DenormalizedBatchDao; +import fr.ifremer.adagio.core.dao.data.measure.QuantificationMeasurement; +import fr.ifremer.adagio.core.dao.data.measure.SortingMeasurement; +import fr.ifremer.adagio.core.dao.data.operation.FishingOperationImpl; +import fr.ifremer.adagio.core.dao.referential.QualityFlagImpl; +import fr.ifremer.adagio.core.dao.technical.synchronization.SynchronizationStatus; +import fr.ifremer.tutti.persistence.entities.data.CatchBatch; +import fr.ifremer.tutti.persistence.service.measure.MeasurementPersistenceHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.FlushMode; +import org.hibernate.type.IntegerType; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +@Service("catchBatchPersistenceService") +public class CatchBatchPersistenceServiceImpl extends AbstractPersistenceService implements CatchBatchPersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(CatchBatchPersistenceServiceImpl.class); + + @Resource(name = "referentialPersistenceService") + protected ReferentialPersistenceService referentialService; + + @Resource(name = "denormalizedBatchDao") + protected DenormalizedBatchDao denormalizedBatchDao; + + @Resource(name = "sortingBatchDao") + protected SortingBatchDao sortingBatchDao; + + @Resource(name = "catchBatchDao") + protected CatchBatchDao catchBatchDao; + + @Resource(name = "measurementPersistenceHelper") + protected MeasurementPersistenceHelper measurementHelper; + + + @Override + public CatchBatch getCatchBatchFromFishingOperation(String id) { + Preconditions.checkNotNull(id); + + Iterator<Object[]> list = queryList("catchBatch", + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(id), + "pmfmIdSorted", IntegerType.INSTANCE, enumeration.PMFM_ID_SORTED_UNSORTED, + "pmfmIdSortingType", IntegerType.INSTANCE, enumeration.PMFM_ID_SORTING_TYPE); + + int rowCount = 0; + CatchBatch result = new CatchBatch(); + Integer previousSortedBatchId = null; + while (list.hasNext()) { + Object[] source = list.next(); + rowCount++; + + if (rowCount == 1) { + // Id + result.setId(source[0].toString()); + + // Total weight + Float totalWeight = (Float) source[1]; + result.setCatchTotalWeight(totalWeight); + } + + Integer sortedBatchId = (Integer) source[2]; + Integer sortedQualitativeValueId = (Integer) source[5]; + if (sortedBatchId != null && !sortedBatchId.equals(previousSortedBatchId)) { + // TODO BL : retrieve QV + String samplingRatioText = (String) source[3]; + Float weight = (Float) source[4]; + if (weight != null && enumeration.QUALITATIVE_VRAC_ID.equals(sortedQualitativeValueId)) { + result.setCatchTotalSortedCarousselWeight(weight); + result.setCatchTotalSortedTremisWeight(getTotalWeight(weight, samplingRatioText)); + } else if (weight != null && enumeration.QUALITATIVE_HORS_VRAC_ID.equals(sortedQualitativeValueId)) { + result.setCatchTotalUnsortedWeight(weight); + if (samplingRatioText != null && !samplingRatioText.isEmpty()) { + // TODO BL : throw error because baths are not compatible with tutti ?? + } + } else if (weight != null && enumeration.QUALITATIVE_UNSORTED_ID.equals(sortedQualitativeValueId)) { + result.setCatchTotalRejectedWeight(weight); + if (samplingRatioText != null && !samplingRatioText.isEmpty()) { + // TODO BL : throw error because baths are not compatible with tutti ?? + } + } + } + + Integer sortingTypeBatchId = (Integer) source[6]; + { + String samplingRatioText = (String) source[7]; + Float weight = (Float) source[8]; + Integer qualitativeValueId = (Integer) source[9]; + if (weight != null) { + if (enumeration.QUALITATIVE_VRAC_ID.equals(sortedQualitativeValueId) + && enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES.equals(qualitativeValueId)) { + result.setSpeciesTotalSampleSortedWeight(weight); + result.setSpeciesTotalSortedWeight(getTotalWeight(weight, samplingRatioText)); + } else if (enumeration.QUALITATIVE_HORS_VRAC_ID.equals(sortedQualitativeValueId) + && enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES.equals(qualitativeValueId)) { + result.setSpeciesTotalUnsortedWeight(weight); + // TODO error si samplingRatio not null + } + // TOBO BL : add benthos, plancton, etc. + } + } + + + previousSortedBatchId = sortedBatchId; + } + + return result; + } + + @Override + public CatchBatch createCatchBatch(CatchBatch bean) { + Preconditions.checkNotNull(bean); + Preconditions.checkArgument(bean.getId() == null); + Preconditions.checkNotNull(bean.getFishingOperation()); + Preconditions.checkNotNull(bean.getFishingOperation().getId()); + + fr.ifremer.adagio.core.dao.data.batch.CatchBatch catchBatch = fr.ifremer.adagio.core.dao.data.batch.CatchBatch.Factory.newInstance(); + beanToEntity(bean, catchBatch, true); + catchBatch = catchBatchDao.create(catchBatch); + bean.setId(String.valueOf(catchBatch.getId())); + + // Link to fishing operation + getCurrentSession().flush(); + Integer fishingOperationId = Integer.valueOf(bean.getFishingOperation().getId()); + int rowUpdated = queryUpdate("updateFishingOperationCatchBatch", + "fishingOperationId", IntegerType.INSTANCE, fishingOperationId, + "catchBatchId", IntegerType.INSTANCE, catchBatch.getId()); + if (rowUpdated == 0) { + throw new DataIntegrityViolationException("Could not attach catch batch to the given operation : operation was not found."); + } + + return bean; + } + + @Override + public CatchBatch saveCatchBatch(CatchBatch bean) { + + Preconditions.checkNotNull(bean); + Preconditions.checkNotNull(bean.getId()); + + getCurrentSession().enableFetchProfile("batch-with-childs"); + getCurrentSession().setFlushMode(FlushMode.COMMIT); + fr.ifremer.adagio.core.dao.data.batch.CatchBatch catchBatch = catchBatchDao.load(Integer.valueOf(bean.getId())); + if (catchBatch == null) { + throw new DataRetrievalFailureException("Could not retrieve catch batch with id=" + bean.getId()); + } + + beanToEntity(bean, catchBatch, true); + catchBatchDao.update(catchBatch); + getCurrentSession().flush(); + return bean; + } + + // ------------------------------------------------------------------------// + // -- Internal methods --// + // ------------------------------------------------------------------------// + protected void beanToEntity(CatchBatch source, + fr.ifremer.adagio.core.dao.data.batch.CatchBatch target, + boolean copyIfNull) { + Preconditions.checkNotNull(source.getFishingOperation()); + Preconditions.checkNotNull(source.getFishingOperation().getId()); + + // Retrieve recorder department + // TODO BLA : prendre le service du 1er saisisseur sur l'OP ? + Integer recorderDepartmentId = enumeration.DEPARTMENT_ID_UNKNOWN_RECORDER_DEPARTMENT; + + // First initialization (when created) + Integer fishingOperationId = Integer.valueOf(source.getFishingOperation().getId()); + target.setFishingOperation(load(FishingOperationImpl.class, fishingOperationId)); + + target.setQualityFlag(load(QualityFlagImpl.class, enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + target.setRankOrder((short) 1); + target.setSynchronizationStatus(SynchronizationStatus.DIRTY.getValue()); + + // Create lists to store all updates, then remove not updated items + Set<QuantificationMeasurement> notChangedQuantificationMeasurements = new HashSet<QuantificationMeasurement>(); + if (target.getQuantificationMeasurements() != null) { + notChangedQuantificationMeasurements.addAll(target.getQuantificationMeasurements()); + } + + // Total Weight + if (copyIfNull && source.getCatchTotalWeight() == null) { + // Nothing to do : will be removed later, using notChangedQuantificationMeasurements + } else if (source.getCatchTotalWeight() != null) { + QuantificationMeasurement quantificationMeasurement = measurementHelper.setQuantificationMeasurement(target, enumeration.PMFM_ID_WEIGHT_MEASURED, recorderDepartmentId, source.getCatchTotalWeight(), true); + notChangedQuantificationMeasurements.remove(quantificationMeasurement); + } + + // Removed not changed measurements (in sorting and quantification measurement lists) + if (target.getQuantificationMeasurements() != null && notChangedQuantificationMeasurements.size() > 0) { + for (QuantificationMeasurement qm : notChangedQuantificationMeasurements) { + target.getQuantificationMeasurements().remove(qm); + } + } + Map<Integer, SortingBatch> catchBatchChilds = getChildsMap(target, enumeration.PMFM_ID_SORTED_UNSORTED); + + // ----------------------------------------------------------------------------- + // Sorted Vrac + // ----------------------------------------------------------------------------- + { + SortingBatch batch = catchBatchChilds.get(enumeration.QUALITATIVE_VRAC_ID); + if (batch == null) { + batch = SortingBatch.Factory.newInstance(); + target.getChildBatchs().add(batch); + } + beanToEntitySortingBatch(target, target, batch, recorderDepartmentId, + enumeration.PMFM_ID_SORTED_UNSORTED, enumeration.QUALITATIVE_VRAC_ID, + source.getCatchTotalSortedTremisWeight(), source.getCatchTotalSortedCarousselWeight(), + copyIfNull); + batch.setRankOrder((short) 1); + + // Manage childs : + { + Map<Integer, SortingBatch> batchChilds = getChildsMap(batch, enumeration.PMFM_ID_SORTING_TYPE); + + // Species : + SortingBatch speciesBatch = batchChilds.get(enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); + if (speciesBatch == null) { + speciesBatch = SortingBatch.Factory.newInstance(); + if (batch.getChildBatchs() == null) { + batch.setChildBatchs(Lists.newArrayList((Batch) speciesBatch)); + } else { + batch.getChildBatchs().add(speciesBatch); + } + } + beanToEntitySortingBatch(target, batch, speciesBatch, recorderDepartmentId, + enumeration.PMFM_ID_SORTING_TYPE, enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES, + source.getSpeciesTotalSortedWeight(), source.getSpeciesTotalSampleSortedWeight(), + copyIfNull); + speciesBatch.setRankOrder((short) 1); + } + // TODO BL : benthos, plancton, macro déchet... + } + + // ----------------------------------------------------------------------------- + // Sorted Hors Vrac + // ----------------------------------------------------------------------------- + { + SortingBatch batch = catchBatchChilds.get(enumeration.QUALITATIVE_HORS_VRAC_ID); + if (batch == null) { + batch = SortingBatch.Factory.newInstance(); + target.getChildBatchs().add(batch); + } + beanToEntitySortingBatch(target, target, batch, recorderDepartmentId, + enumeration.PMFM_ID_SORTED_UNSORTED, enumeration.QUALITATIVE_HORS_VRAC_ID, + source.getCatchTotalUnsortedWeight(), null, + copyIfNull); + batch.setRankOrder((short) 2); + + // Manage childs : + { + Map<Integer, SortingBatch> batchChilds = getChildsMap(batch, enumeration.PMFM_ID_SORTING_TYPE); + + // Species : + SortingBatch speciesBatch = batchChilds.get(enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); + if (speciesBatch == null) { + speciesBatch = SortingBatch.Factory.newInstance(); + if (batch.getChildBatchs() == null) { + batch.setChildBatchs(Lists.newArrayList((Batch) speciesBatch)); + } else { + batch.getChildBatchs().add(speciesBatch); + } + } + beanToEntitySortingBatch(target, batch, speciesBatch, recorderDepartmentId, + enumeration.PMFM_ID_SORTING_TYPE, enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES, + source.getSpeciesTotalUnsortedWeight(), null, + copyIfNull); + speciesBatch.setRankOrder((short) 1); + } + + // TODO BL : benthos, plancton, macro déchet... + } + + // ----------------------------------------------------------------------------- + // Unsorted (=rejected) + // ----------------------------------------------------------------------------- + // Unsorted : + SortingBatch unsortedBatch = catchBatchChilds.get(enumeration.QUALITATIVE_UNSORTED_ID); + if (unsortedBatch == null) { + unsortedBatch = SortingBatch.Factory.newInstance(); + target.getChildBatchs().add(unsortedBatch); + } + beanToEntitySortingBatch(target, target, unsortedBatch, recorderDepartmentId, + enumeration.PMFM_ID_SORTED_UNSORTED, enumeration.QUALITATIVE_UNSORTED_ID, + source.getCatchTotalRejectedWeight(), null, + copyIfNull); + unsortedBatch.setRankOrder((short) 3); + + + } + + protected Map<Integer, SortingBatch> getChildsMap(Batch parentBatch, Integer pmfmId) { + Map<Integer, SortingBatch> batchByQualitativeValueId = new HashMap<Integer, SortingBatch>(); + if (parentBatch.getChildBatchs() == null) { + return batchByQualitativeValueId; + } + for (Iterator iterator = parentBatch.getChildBatchs() + .iterator(); iterator.hasNext(); ) { + Batch childBatch = (Batch) iterator.next(); + SortingMeasurement sm = measurementHelper.getSortingMeasurement((SortingBatch) childBatch, pmfmId, null, false); + if (sm != null && sm.getQualitativeValue() != null && sm.getQualitativeValue().getId() != null) { + batchByQualitativeValueId.put(sm.getQualitativeValue().getId(), (SortingBatch) childBatch); + } + } + return batchByQualitativeValueId; + } + + protected void beanToEntitySortingBatch( + fr.ifremer.adagio.core.dao.data.batch.CatchBatch rootBatch, + fr.ifremer.adagio.core.dao.data.batch.Batch parentBatch, + fr.ifremer.adagio.core.dao.data.batch.SortingBatch target, + Integer recorderDepartmentId, + Integer sortingPmfmId, + Integer sortingQualitativeValueId, + Float weight, + Float sampleWeight, + boolean copyIfNull) { + + // Create lists to store all updates, then remove not updated items + Set<QuantificationMeasurement> notChangedQuantificationMeasurements = new HashSet<QuantificationMeasurement>(); + if (target.getQuantificationMeasurements() != null) { + notChangedQuantificationMeasurements.addAll(target.getQuantificationMeasurements()); + } + Set<SortingMeasurement> notChangedSortingMeasurements = new HashSet<SortingMeasurement>(); + if (target.getSortingMeasurements() != null) { + notChangedSortingMeasurements.addAll(target.getSortingMeasurements()); + } + + // Some mandatory properties : + target.setQualityFlag(load(QualityFlagImpl.class, enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + target.setRootBatch(rootBatch); + target.setParentBatch(parentBatch); + + // Sorting measurement + if (copyIfNull && (sortingPmfmId == null || sortingQualitativeValueId == null)) { + // Nothing to do : will be removed later, using notChangedSortingMeasurements + } else if (sortingPmfmId != null && sortingQualitativeValueId != null) { + SortingMeasurement sm = measurementHelper.setSortingMeasurement(target, recorderDepartmentId, sortingPmfmId, sortingQualitativeValueId); + notChangedSortingMeasurements.remove(sm); + } + + // Sampling Ratio + if (copyIfNull && (sampleWeight == null || weight == null)) { + target.setSamplingRatio(null); + target.setSamplingRatioText(null); + } else if (sampleWeight != null && weight != null) { + String samplingRatioText = sampleWeight + "/" + weight; + samplingRatioText = samplingRatioText.replaceAll(",", "."); + target.setSamplingRatioText(samplingRatioText); + target.setSamplingRatio(sampleWeight.floatValue() / weight.floatValue()); + } + + // Weight + if (copyIfNull && (sampleWeight == null && weight == null)) { + // Nothing to do : will be removed later, using notChangedQuantificationMeasurements + } else if (sampleWeight != null || weight != null) { + Float batchReferenceWeight = sampleWeight; + if (batchReferenceWeight == null) { + batchReferenceWeight = weight; + } + QuantificationMeasurement quantificationMeasurement = measurementHelper.setQuantificationMeasurement(target, enumeration.PMFM_ID_WEIGHT_MEASURED, recorderDepartmentId, batchReferenceWeight, true); + notChangedQuantificationMeasurements.remove(quantificationMeasurement); + } + + // Removed not changed measurements (in sorting and quantification measurement lists) + if (target.getQuantificationMeasurements() != null && notChangedQuantificationMeasurements.size() > 0) { + for (QuantificationMeasurement qm : notChangedQuantificationMeasurements) { + target.getQuantificationMeasurements().remove(qm); + } + } + if (target.getSortingMeasurements() != null && notChangedSortingMeasurements.size() > 0) { + for (SortingMeasurement sm : notChangedSortingMeasurements) { + target.getSortingMeasurements().remove(sm); + } + } + } + + protected Float getTotalWeight(Float weight, String samplingRatioText) { + if (weight == null) { + return null; + } + String startStr = weight.toString().replace(',', '.') + "/"; + if (samplingRatioText != null && samplingRatioText.startsWith(startStr)) { + String weightStr = samplingRatioText.substring(startStr.length()); + if (weightStr != null && !weightStr.isEmpty()) { + return Float.parseFloat(weightStr); + } + } + // TODO BL : attention au saise "1/2" qui ne seront pas pris (mais "1.0/2.0" oui) + return null; + } + +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,552 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.base.Preconditions; +import com.google.common.collect.Lists; +import fr.ifremer.adagio.core.dao.administration.user.PersonDao; +import fr.ifremer.adagio.core.dao.data.survey.fishingTrip.FishingTrip; +import fr.ifremer.adagio.core.dao.data.survey.fishingTrip.ObservedFishingTrip; +import fr.ifremer.adagio.core.dao.data.survey.scientificCruise.ScientificCruise; +import fr.ifremer.adagio.core.dao.data.survey.scientificCruise.ScientificCruiseDao; +import fr.ifremer.adagio.core.dao.data.vessel.feature.physical.GearPhysicalFeatures; +import fr.ifremer.adagio.core.dao.referential.QualityFlag; +import fr.ifremer.adagio.core.dao.referential.QualityFlagDao; +import fr.ifremer.adagio.core.dao.referential.gear.GearDao; +import fr.ifremer.adagio.core.dao.referential.location.Location; +import fr.ifremer.adagio.core.dao.referential.location.LocationDao; +import fr.ifremer.adagio.core.dao.referential.pmfm.PmfmDao; +import fr.ifremer.adagio.core.dao.referential.pmfm.QualitativeValueDao; +import fr.ifremer.adagio.core.dao.referential.vessel.VesselDao; +import fr.ifremer.adagio.core.dao.technical.synchronization.SynchronizationStatus; +import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.tutti.persistence.entities.data.Program; +import fr.ifremer.tutti.persistence.entities.referential.Country; +import fr.ifremer.tutti.persistence.entities.referential.Gear; +import fr.ifremer.tutti.persistence.entities.referential.Person; +import fr.ifremer.tutti.persistence.entities.referential.Vessel; +import fr.ifremer.tutti.persistence.service.measure.MeasurementPersistenceHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.type.IntegerType; +import org.hibernate.type.StringType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.sql.Timestamp; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("cruisePersistenceService") +public class CruisePersistenceServiceImpl extends AbstractPersistenceService implements CruisePersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(CruisePersistenceServiceImpl.class); + + protected static String CRUISE_MISC_DATA_VESSELS_TAG = "#VESSELS="; + + protected static String CRUISE_MISC_DATA_MANAGERS_TAG = "#MANAGERS="; + + protected static String CRUISE_MISC_DATA_SORT_MANAGERS_TAG = "#SORT_MANAGERS="; + + @Autowired(required = true) + protected ReferentialPersistenceService referentialService; + + @Autowired(required = true) + protected ProgramPersistenceService programService; + + @Resource(name = "scientificCruiseDao") + protected ScientificCruiseDao scientificCruiseDao; + + @Resource(name = "personDao") + protected PersonDao personDao; + + @Resource(name = "vesselDao") + protected VesselDao vesselDao; + + @Resource(name = "locationDao") + protected LocationDao locationDao; + + @Resource(name = "qualityFlagDao") + protected QualityFlagDao qualityFlagDao; + + @Resource(name = "pmfmDao") + protected PmfmDao pmfmDao; + + @Resource(name = "qualitativeValueDao") + protected QualitativeValueDao qualitativeValueDao; + + @Resource(name = "gearDao") + protected GearDao gearDao; + + @Resource(name = "measurementPersistenceHelper") + protected MeasurementPersistenceHelper measurementHelper; + + protected Calendar calendar = new GregorianCalendar(); + + @Override + public List<Cruise> getAllCruise(String programId) { + Iterator<Object[]> list = queryList( + "allCruises", + "programCode", StringType.INSTANCE, programId); + + List<Cruise> result = Lists.newArrayList(); + while (list.hasNext()) { + Object[] source = list.next(); + Cruise target = new Cruise(); + target.setId(String.valueOf(source[0])); + target.setName((String) source[1]); + target.setBeginDate((Date) source[2]); + result.add(target); + } + return result; + } + + @Override + public Cruise getCruise(String id) { + Object[] source = queryUnique( + "cruise", + "cruiseId", IntegerType.INSTANCE, Integer.valueOf(id), + "countryLocationLevelId", IntegerType.INSTANCE, enumeration.LOCATION_LEVEL_ID_COUNTRY); + + if (source == null) { + return null; + // TODo TC : manage exception in the UI ? + //throw new DataRetrievalFailureException("Could not retrieve cruise with id=" + id); + } + Cruise result = new Cruise(); + result.setId(id); + + String programCode = (String) source[0]; + Program program = programService.getProgram(programCode); + result.setProgram(program); + + result.setYear((Integer) source[1]); + result.setName((String) source[2]); + + String countryId = String.valueOf(source[3]); + String countryLabel = (String) source[4]; + String countryName = (String) source[5]; + Country c = new Country(); + c.setId(countryId); + c.setName(countryName); + c.setLabel(countryLabel); + result.setCountry(c); + + Timestamp beginDate = (Timestamp) source[6]; + if (beginDate != null && result.getYear() != null) { + calendar.setTimeInMillis(0); + calendar.set(Calendar.YEAR, result.getYear()); + calendar.add(Calendar.MILLISECOND, 1); + // Comparison with getTime() is need, to keep millisecond precision + if (beginDate.getTime() == calendar.getTimeInMillis()) { + // if BeginDate is fake : set to null (see createCruise for details) + result.setBeginDate(null); + } else { + result.setBeginDate(new Date(beginDate.getTime())); + } + } + + result.setEndDate((Date) source[7]); + + String vesselCode = (String) source[8]; + Vessel vessel = referentialService.getVessel(vesselCode); + result.setVessel(Lists.newArrayList(vessel)); + + Integer managerId = (Integer) source[9]; + if (managerId != null && managerId.equals(enumeration.PERSON_ID_UNKNOWN_RECORDER_PERSON)) { + result.setHeadOfMission(null); + } else { + Person manager = referentialService.getPerson(managerId); + result.setHeadOfMission(Lists.newArrayList(manager)); + } + + result.setComment((String) source[10]); + + String miscData = (String) source[11]; + if (miscData != null && miscData.length() > 0) { + // Retrieve secondary vessels : + int vesselTagIndex = miscData.indexOf(CRUISE_MISC_DATA_VESSELS_TAG); + if (vesselTagIndex != -1) { + String vesselCodesStr = miscData.substring(vesselTagIndex + CRUISE_MISC_DATA_VESSELS_TAG.length()).trim(); + miscData = miscData.substring(0, vesselTagIndex); + if (!vesselCodesStr.isEmpty()) { + String[] vesselCodes = vesselCodesStr.split(","); + for (int i = 0; i < vesselCodes.length; i++) { + vesselCode = vesselCodes[i]; + result.addVessel(referentialService.getVessel(vesselCode)); + } + } + } + + // Retrieve cruise managers + int managersIndex = miscData.indexOf(CRUISE_MISC_DATA_MANAGERS_TAG); + if (managersIndex != -1) { + String managersStr = miscData.substring(managersIndex + CRUISE_MISC_DATA_MANAGERS_TAG.length()).trim(); + miscData = miscData.substring(0, managersIndex); + if (!managersStr.isEmpty()) { + String[] managersArray = managersStr.split(","); + for (int i = 0; i < managersArray.length; i++) { + String personId = managersArray[i]; + Person person = referentialService.getPerson(Integer.valueOf(personId)); + result.getHeadOfMission().add(person); + } + } + } + + // Retrieve sort room managers + int sortManagersIndex = miscData.indexOf(CRUISE_MISC_DATA_SORT_MANAGERS_TAG); + if (sortManagersIndex != -1) { + String sortManagersStr = miscData.substring(sortManagersIndex + CRUISE_MISC_DATA_SORT_MANAGERS_TAG.length()).trim(); + miscData = miscData.substring(0, sortManagersIndex); + if (!sortManagersStr.isEmpty()) { + String[] managersArray = sortManagersStr.split(","); + List<Person> persons = new ArrayList<Person>(); + for (int i = 0; i < managersArray.length; i++) { + String personId = managersArray[i]; + Person person = referentialService.getPerson(Integer.valueOf(personId)); + persons.add(person); + } + result.setHeadOfSortRoom(persons); + } + } + } + + // get secondary gears from fishingOperation (first load from Allegro DB only) + if (result.getGear() == null) { + Iterator<Object[]> list = queryList( + "allCruiseGears", + "cruiseId", IntegerType.INSTANCE, Integer.valueOf(id), + "pmfmIdTrawlNet", IntegerType.INSTANCE, enumeration.PMFM_ID_MULTIRIG_NUMBER); + + List<Gear> gears = Lists.newArrayList(); + int maxMultirigNumberFound = 0; + while (list.hasNext()) { + Object[] gearRow = list.next(); + Gear target = referentialService.getGear((Integer) gearRow[0]); + Float multirigNumber = (Float) gearRow[1]; + if (multirigNumber != null && multirigNumber.intValue() > maxMultirigNumberFound) { + maxMultirigNumberFound = multirigNumber.intValue(); + } + gears.add(target); + } + result.setGear(gears); + if (maxMultirigNumberFound > 0) { + result.setMultirigNumber(maxMultirigNumberFound); + } + } + // Force initialization of multirigNumber to 1 initialization (need for UI) + if (result.getMultirigNumber() == null) { + log.warn(MessageFormat.format("Cruise with id={0} has been load with a default multirigNumber=1, beacause not multirigNumber were found in database.", new Object[]{id})); + result.setMultirigNumber(1); + } + return result; + } + + @Override + public Cruise createCruise(Cruise bean) { + Preconditions.checkNotNull(bean); + Preconditions.checkArgument(bean.getId() == null, "Cruise 'id' must be null to call createCruise()."); + + ScientificCruise scientificCruise = ScientificCruise.Factory.newInstance(); + cruiseToEntity(bean, scientificCruise, true); + scientificCruiseDao.create(scientificCruise); + + bean.setId(String.valueOf(scientificCruise.getId())); + return bean; + } + + @Override + public Cruise saveCruise(Cruise bean) { + Preconditions.checkNotNull(bean); + Preconditions.checkNotNull(bean.getId(), "Cruise 'id' must not be null or empty to be saved."); + + ScientificCruise scientificCruise = scientificCruiseDao.load(Integer.valueOf(bean.getId())); + if (scientificCruise == null) { + throw new DataRetrievalFailureException("Could not retrieve cruise with id=" + bean.getId()); + } + + cruiseToEntity(bean, scientificCruise, true); + scientificCruiseDao.update(scientificCruise); + + return bean; + } + + protected void cruiseToEntity(Cruise source, ScientificCruise target, boolean copyIfNull) { + StringBuffer miscDataBuffer = new StringBuffer(); + QualityFlag qualityFlagNotQualified = qualityFlagDao.load(enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED); + + // Retrieve entities : FishingTrip + ObservedFishingTrip fishingTrip = null; + if (target.getFishingTrips() == null || target.getFishingTrips().size() == 0) { + fishingTrip = ObservedFishingTrip.Factory.newInstance(); + if (target.getFishingTrips() == null) { + target.setFishingTrips(Lists.newArrayList((FishingTrip) fishingTrip)); + fishingTrip.setScientificCruise(target); + } else { + target.getFishingTrips().add(fishingTrip); + fishingTrip.setScientificCruise(target); + } + } else { + fishingTrip = (ObservedFishingTrip) target.getFishingTrips().iterator().next(); + } + + // Name + if (copyIfNull && source.getName() == null) { + target.setName(null); + } else if (source.getName() != null) { + target.setName(source.getName()); + } + + // Program + if (copyIfNull && (source.getProgram() == null || source.getProgram().getId() == null)) { + target.setProgram(null); + } else if (source.getName() != null && source.getProgram().getId() != null) { + target.setProgram(programDao.load(source.getProgram().getId())); + } + + // Sort Room Managers + if (copyIfNull && (source.getHeadOfSortRoom() == null || source.getHeadOfSortRoom().size() == 0)) { + target.setManagerPerson(null); + } else if (source.getHeadOfSortRoom() != null && source.getHeadOfSortRoom().size() > 0) { + List<Person> persons = source.getHeadOfSortRoom(); + miscDataBuffer.append(CRUISE_MISC_DATA_SORT_MANAGERS_TAG); + for (int i = 0; i < persons.size(); i++) { + if (i > 0) miscDataBuffer.append(','); + miscDataBuffer.append(persons.get(i).getId()); + } + } + + // Managers + if (copyIfNull && (source.getHeadOfMission() == null || source.getHeadOfMission().size() == 0)) { + target.setManagerPerson(null); + } else if (source.getHeadOfMission() != null && source.getHeadOfMission().size() > 0) { + List<Person> persons = source.getHeadOfMission(); + target.setManagerPerson(personDao.load(Integer.valueOf(persons.get(0).getId()))); + + if (persons.size() > 1) { + //throw new UnsupportedOperationException("Cruise could not yet support more than one vessel."); + miscDataBuffer.append(CRUISE_MISC_DATA_MANAGERS_TAG); + for (int i = 1; i < persons.size(); i++) { + if (i > 1) miscDataBuffer.append(','); + miscDataBuffer.append(persons.get(i).getId()); + } + } + } + + // Vessel + if (copyIfNull && (source.getVessel() == null || source.getVessel().size() == 0)) { + target.setProgram(null); + } else if (source.getVessel() != null && source.getVessel().size() > 0) { + List<Vessel> vessels = source.getVessel(); + target.setVessel(vesselDao.load(vessels.get(0).getId())); + + if (vessels.size() > 1) { + //throw new UnsupportedOperationException("Cruise could not yet support more than one vessel."); + miscDataBuffer.append(CRUISE_MISC_DATA_VESSELS_TAG); + for (int i = 1; i < vessels.size(); i++) { + if (i > 1) miscDataBuffer.append(','); + miscDataBuffer.append(vessels.get(i).getId()); + } + } + } + + // Year + if (copyIfNull && source.getYear() == null && source.getBeginDate() == null) { + target.setDepartureDateTime(null); + } else if (source.getYear() != null && source.getBeginDate() == null) { + // Set year into departure date time only if no departure date time has been set + calendar.setTimeInMillis(0); + calendar.set(Calendar.YEAR, source.getYear()); + // Add one millisecond to retrieve a 'year saved but no departure date' + calendar.set(Calendar.MILLISECOND, 1); + target.setDepartureDateTime(calendar.getTime()); + } + + // BeginDate + if (copyIfNull && source.getYear() == null && source.getBeginDate() == null) { + target.setDepartureDateTime(null); + } else if (source.getBeginDate() != null) { + calendar.setTime(source.getBeginDate()); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + target.setDepartureDateTime(calendar.getTime()); + } + + // EndDate + if (copyIfNull && source.getEndDate() == null) { + target.setReturnDateTime(null); + } else if (source.getEndDate() != null) { + calendar.setTime(source.getEndDate()); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + target.setReturnDateTime(calendar.getTime()); + } + + // Comment + if (copyIfNull && source.getComment() == null) { + target.setComments(null); + } else if (source.getComment() != null) { + target.setComments(source.getComment()); + } + + // Manager + if (copyIfNull && (source.getHeadOfMission() == null || source.getHeadOfMission().size() == 0)) { + target.setComments(null); + } else if (source.getHeadOfMission() != null && source.getHeadOfMission().size() > 0) { + if (source.getHeadOfMission().size() > 0) { + Person managerPerson = source.getHeadOfMission().get(0); + if (managerPerson.getId() != null) { + target.setManagerPerson(personDao.load(Integer.valueOf(managerPerson.getId()))); + } + } + } + + // Optional values in UI, but mandatory in DB + if (target.getManagerPerson() == null) { + target.setManagerPerson(personDao.load(enumeration.PERSON_ID_UNKNOWN_RECORDER_PERSON)); + } + + // Default values : + target.setSynchronizationStatus(SynchronizationStatus.DIRTY.getValue()); + if (target.getCreationDate() == null) { + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + target.setCreationDate(calendar.getTime()); + } + if (target.getManagerPerson() != null) { + target.setRecorderPerson(target.getManagerPerson()); + target.setRecorderDepartment(target.getManagerPerson().getDepartment()); + } + + // Fill fishing trip with scientificCruise info: + fishingTrip.setDepartureDateTime(target.getDepartureDateTime()); + fishingTrip.setReturnDateTime(target.getReturnDateTime()); + fishingTrip.setVessel(target.getVessel()); + fishingTrip.setProgram(target.getProgram()); + fishingTrip.setRecorderPerson(target.getRecorderPerson()); + fishingTrip.setRecorderDepartment(target.getRecorderDepartment()); + fishingTrip.setCreationDate(target.getCreationDate()); + fishingTrip.setSynchronizationStatus(target.getSynchronizationStatus()); + fishingTrip.setQualityFlag(qualityFlagNotQualified); + + if (fishingTrip.getReturnDateTime() == null && fishingTrip.getDepartureDateTime() != null) { + calendar.setTime(fishingTrip.getDepartureDateTime()); + calendar.add(Calendar.MILLISECOND, 1); // = departureDateTime + 1ms + fishingTrip.setReturnDateTime(calendar.getTime()); + } + + // Country + if (copyIfNull && source.getCountry() == null || source.getCountry().getId() == null) { + fishingTrip.setDepartureLocation(null); + fishingTrip.setReturnLocation(null); + } else if (source.getCountry() != null && source.getCountry().getId() != null) { + Location locationCountry = locationDao.load(Integer.valueOf(source.getCountry().getId())); + fishingTrip.setDepartureLocation(locationCountry); + fishingTrip.setReturnLocation(locationCountry); + } + + // Gear + if (copyIfNull && source.isGearEmpty() && fishingTrip.getGearPhysicalFeatures() != null) { + fishingTrip.getGearPhysicalFeatures().clear(); + } else if (!source.isGearEmpty()) { + // Create a list to trace not updated items, to be able to remove them later + Set<GearPhysicalFeatures> notChangedGearPhysicalFeatures = new HashSet<GearPhysicalFeatures>(); + if (fishingTrip.getGearPhysicalFeatures() != null) { + notChangedGearPhysicalFeatures.addAll(fishingTrip.getGearPhysicalFeatures()); + } + + // Create or update a geaPhysicalFeatures for each gears in the cruise + for (int i = 0; i < source.getGear().size(); i++) { + Gear gear = source.getGear().get(i); + GearPhysicalFeatures guf = measurementHelper.getGearPhysicalfeatures(fishingTrip, Integer.valueOf(gear.getId()), true); + notChangedGearPhysicalFeatures.remove(guf); + + guf.setStartDate(fishingTrip.getDepartureDateTime()); + guf.setEndDate(fishingTrip.getReturnDateTime()); + guf.setVessel(fishingTrip.getVessel()); + guf.setProgram(fishingTrip.getProgram()); + guf.setCreationDate(target.getCreationDate()); + guf.setQualityFlag(qualityFlagNotQualified); + guf.setRankOrder((short) 1); + + // Trawl net (store in Gear Physical features) + if (copyIfNull && source.getMultirigNumber() == null) { + measurementHelper.removeGearPhysicalMeasurement(guf, enumeration.PMFM_ID_MULTIRIG_NUMBER); + } else { + measurementHelper.setGearPhysicalMeasurement(target, guf, enumeration.PMFM_ID_MULTIRIG_NUMBER, Float.valueOf(source.getMultirigNumber()), null, null); + } + } + + // Remove deleted gear physical features + if (fishingTrip.getGearPhysicalFeatures() != null && notChangedGearPhysicalFeatures.size() > 0) { + for (GearPhysicalFeatures guf : notChangedGearPhysicalFeatures) { + if (guf.getGearPhysicalMeasurements() != null) { + guf.getGearPhysicalMeasurements().clear(); + } + fishingTrip.getGearPhysicalFeatures().remove(guf); + } + } + } + + // Save miscDataBuffer into fishing trip comments, because it's not used in Allegro + fishingTrip.setComments(miscDataBuffer.toString()); + } + + protected List<Person> getCruisePersonsByRole(String cruiseId, Integer vesselPersonRole) { + Iterator<Object[]> list = queryList( + "allCruiseManagers", + "cruiseId", IntegerType.INSTANCE, Integer.valueOf(cruiseId), + "vesselPersonRoleId", IntegerType.INSTANCE, vesselPersonRole); + + List<Person> persons = Lists.newArrayList(); + int maxTrawlNetFound = 0; + while (list.hasNext()) { + Object[] source = list.next(); + Person target = new Person(); + + persons.add(target); + } + + return persons; + } +} Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceService.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceService.java 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceService.java 2013-02-02 14:11:58 UTC (rev 300) @@ -37,7 +37,7 @@ * @since 0.3 */ @Transactional(readOnly = true) -public interface FishingOperationPersistenceService extends TuttiPersistenceServiceImplementor { +public interface FishingOperationPersistenceService extends TuttiPersistenceServiceImplementor { List<FishingOperation> getAllFishingOperation(String cruiseId); Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,1188 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.base.Preconditions; +import com.google.common.collect.Sets; +import fr.ifremer.adagio.core.dao.data.batch.denormalized.DenormalizedBatch; +import fr.ifremer.adagio.core.dao.data.fishingArea.FishingArea; +import fr.ifremer.adagio.core.dao.data.fishingArea.FishingArea2RegulationLocation; +import fr.ifremer.adagio.core.dao.data.fishingArea.FishingArea2RegulationLocationPK; +import fr.ifremer.adagio.core.dao.data.measure.GearPhysicalMeasurement; +import fr.ifremer.adagio.core.dao.data.measure.GearUseMeasurement; +import fr.ifremer.adagio.core.dao.data.measure.Measurement; +import fr.ifremer.adagio.core.dao.data.measure.VesselUseMeasurement; +import fr.ifremer.adagio.core.dao.data.operation.FishingOperationDao; +import fr.ifremer.adagio.core.dao.data.operation.Operation; +import fr.ifremer.adagio.core.dao.data.survey.fishingTrip.FishingTrip; +import fr.ifremer.adagio.core.dao.data.survey.scientificCruise.ScientificCruise; +import fr.ifremer.adagio.core.dao.data.survey.scientificCruise.ScientificCruiseDao; +import fr.ifremer.adagio.core.dao.data.vessel.feature.physical.GearPhysicalFeatures; +import fr.ifremer.adagio.core.dao.data.vessel.feature.use.GearUseFeatures; +import fr.ifremer.adagio.core.dao.data.vessel.feature.use.VesselUseFeatures; +import fr.ifremer.adagio.core.dao.data.vessel.feature.use.isActive; +import fr.ifremer.adagio.core.dao.data.vessel.position.VesselPosition; +import fr.ifremer.adagio.core.dao.referential.QualityFlagImpl; +import fr.ifremer.adagio.core.dao.referential.gear.GearImpl; +import fr.ifremer.adagio.core.dao.referential.location.LocationExtendDao; +import fr.ifremer.adagio.core.dao.referential.location.LocationImpl; +import fr.ifremer.adagio.core.dao.referential.pmfm.Pmfm; +import fr.ifremer.adagio.core.dao.referential.pmfm.PmfmImpl; +import fr.ifremer.adagio.core.dao.referential.pmfm.QualitativeValue; +import fr.ifremer.adagio.core.dao.referential.pmfm.QualitativeValueImpl; +import fr.ifremer.adagio.core.service.referential.location.LocationService; +import fr.ifremer.tutti.persistence.entities.CaracteristicMap; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicType; +import fr.ifremer.tutti.persistence.entities.referential.FishingOperationLocation; +import fr.ifremer.tutti.persistence.entities.referential.Person; +import fr.ifremer.tutti.persistence.service.measure.MeasurementPersistenceHelper; +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.type.IntegerType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.sql.Timestamp; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("fishingOperationPersistenceService") +public class FishingOperationPersistenceServiceImpl extends AbstractPersistenceService implements FishingOperationPersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(FishingOperationPersistenceServiceImpl.class); + + + @Resource(name = "measurementPersistenceHelper") + protected MeasurementPersistenceHelper measurementHelper; + + @Autowired(required = true) + protected ReferentialPersistenceService referentialService; + + @Resource(name = "scientificCruiseDao") + protected ScientificCruiseDao scientificCruiseDao; + + @Resource(name = "fishingOperationDao") + protected FishingOperationDao fishingOperationDao; + + @Resource(name = "locationService") + protected LocationService locationService; + + @Resource(name = "locationDao") + protected LocationExtendDao locationDao; + + protected static Float DEFAULT_EMPTY_LATITUDE = 0.0001f; + + protected static Float DEFAULT_EMPTY_LONGITUDE = 0.0001f; + + protected static String MISC_DATA_RECORDER_PERSONS_TAG = "#REC_PERSONS="; + + protected Calendar calendar = new GregorianCalendar(); + + @Override + public List<FishingOperation> getAllFishingOperation(String cruiseId) { + Preconditions.checkNotNull(cruiseId); + + Iterator<Object[]> list = queryList( + "allFishingOperations", + "cruiseId", IntegerType.INSTANCE, Integer.valueOf(cruiseId), + "pmfmIdStationNumber", IntegerType.INSTANCE, enumeration.PMFM_ID_STATION_NUMBER, + "pmfmIdMultirigAggregation", IntegerType.INSTANCE, enumeration.PMFM_ID_MULTIRIG_AGGREGATION + ); + + List<FishingOperation> fishingOperations = new ArrayList<FishingOperation>(); + int fishingOperationRankOrder = 0; + while (list.hasNext()) { + Object[] source = list.next(); + fishingOperationRankOrder++; + + FishingOperation fishingOperation = new FishingOperation(); + int colIndex = 0; + + // Id + fishingOperation.setId(source[colIndex++].toString()); + + // Fishing operation number : trying to retrieve from name + String name = (String) source[colIndex++]; + String gearLabel = (String) source[colIndex++]; + String fishingOperationNumberStr; + if (name != null && !name.isEmpty()) { + if (gearLabel != null && !gearLabel.isEmpty() + && name.startsWith(gearLabel)) { + fishingOperationNumberStr = name.substring(gearLabel.length()); + } else { + fishingOperationNumberStr = name; + } + if (fishingOperationNumberStr.matches("\\d+")) { + fishingOperation.setFishingOperationNumber(Integer.valueOf(fishingOperationNumberStr)); + } else { + // TODO BL : invalid op.name format : log ? + } + } + + // If not found, compute it using a counter (see "order by startDateTime" in HQL query) + if (fishingOperation.getFishingOperationNumber() == null) { + fishingOperation.setFishingOperationNumber(fishingOperationRankOrder); + } + + // Start date time + Timestamp startDateTime = (Timestamp) source[colIndex++]; + fishingOperation.setGearShootingStartDate(convertDatabase2UI(startDateTime)); + + // Station number + String stationNumber = (String) source[colIndex++]; + if (stationNumber != null) { + fishingOperation.setStationNumber(stationNumber); + } + + // Multirig Aggregation + String multirigAggregation = (String) source[colIndex++]; + if (multirigAggregation != null) { + fishingOperation.setMultirigAggregation(multirigAggregation); + } + // Force initialization to 1 initialization (need for UI) + else { + log.warn(MessageFormat.format("FishingOperation with id={0} has been load with a default multirigAggregation={1}, because no multirigAggregation were found in database.", new Object[]{fishingOperation.getId(), fishingOperation.getMultirigAggregation()})); + fishingOperation.setMultirigAggregation("1"); + } + + + fishingOperations.add(fishingOperation); + } + return fishingOperations; + } + + @Override + public FishingOperation getFishingOperation(String id) { + Preconditions.checkNotNull(id); + Object[] source = queryUnique( + "fishingOperation", + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(id), + "locationLevelIdStrata", IntegerType.INSTANCE, enumeration.LOCATION_LEVEL_ID_STRATA, + "locationLevelIdSubStrata", IntegerType.INSTANCE, enumeration.LOCATION_LEVEL_ID_SUB_STRATA, + "locationLevelIdLocalite", IntegerType.INSTANCE, enumeration.LOCATION_LEVEL_ID_LOCALITE + ); + + if (source == null) { + throw new DataRetrievalFailureException("Could not retrieve fishingOperation with id=" + id); + } + FishingOperation result = new FishingOperation(); + result.setId(id); + + // Cruise : + // do load load Cruise here, because it will be attach upper in the call stack + + int colIndex = 0; + + // Name = <GearLabel><FishingOperationNumber> + String name = (String) source[colIndex++]; + String gearLabel = (String) source[colIndex++]; + + String fishingOperationNumberStr; + if (name != null && !name.isEmpty()) { + if (gearLabel != null && !gearLabel.isEmpty() + && name.startsWith(gearLabel)) { + fishingOperationNumberStr = name.substring(gearLabel.length()); + } else { + fishingOperationNumberStr = name; + } + if (fishingOperationNumberStr.matches("\\d+")) { + result.setFishingOperationNumber(Integer.valueOf(fishingOperationNumberStr)); + } + } + + // If not found, compute it using a counter (see "order by startDateTime" in HQL query) + if (result.getFishingOperationNumber() == null) { + Integer fishingOperationRankOrder = queryUniqueTyped( + "fishingOperationRankOrder", + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(id) + ); + result.setFishingOperationNumber(fishingOperationRankOrder); + } + + // Start date + result.setGearShootingStartDate(convertDatabase2UI((Timestamp) source[colIndex++])); + + // End date + result.setGearShootingEndDate(convertDatabase2UI((Timestamp) source[colIndex++])); + + // Misc data + String miscData = (String) source[colIndex++]; + + // Retrieve recorder persons + if (miscData != null && !miscData.isEmpty()) { + int recorderPersonsIndex = miscData.indexOf(MISC_DATA_RECORDER_PERSONS_TAG); + if (recorderPersonsIndex != -1) { + String recorderPersonsStr = miscData.substring(recorderPersonsIndex + MISC_DATA_RECORDER_PERSONS_TAG.length()).trim(); + miscData = miscData.substring(0, recorderPersonsIndex); + if (!recorderPersonsStr.isEmpty()) { + String[] recorderPersonsArray = recorderPersonsStr.split(","); + List<Person> persons = new ArrayList<Person>(); + for (String personId : recorderPersonsArray) { + Person person = referentialService.getPerson(Integer.valueOf(personId)); + persons.add(person); + } + result.setSaisisseur(persons); + } + } + } + + // Comment : + if (miscData != null && !miscData.isEmpty()) { + result.setComment(miscData); + } + + // Gear : + Integer gearId = (Integer) source[colIndex++]; + if (gearId != null) { + // TODO TC : activer un cache sur getGear() + fr.ifremer.tutti.persistence.entities.referential.Gear gear = referentialService.getGear(gearId); + result.setGear(gear); + } + + // Start position + VesselPosition startVesselPosition = (VesselPosition) source[colIndex++]; + if (startVesselPosition == null) { + result.setGearShootingStartLatitude(null); + result.setGearShootingStartLongitude(null); + } else { + result.setGearShootingStartLatitude(convertLatitude2UI(startVesselPosition.getLatitude())); + result.setGearShootingStartLongitude(convertLongitude2UI(startVesselPosition.getLongitude())); + } + + // End position + VesselPosition endVesselPosition = (VesselPosition) source[colIndex++]; + if (endVesselPosition == null) { + result.setGearShootingEndLatitude(null); + result.setGearShootingEndLongitude(null); + } else { + result.setGearShootingEndLatitude(DEFAULT_EMPTY_LATITUDE.equals(endVesselPosition.getLatitude()) ? null : endVesselPosition.getLatitude()); + result.setGearShootingEndLongitude(DEFAULT_EMPTY_LONGITUDE.equals(endVesselPosition.getLongitude()) ? null : endVesselPosition.getLongitude()); + } + + // Strata : + Integer strataId = (Integer) source[colIndex++]; + if (strataId != null) { + FishingOperationLocation strata = new FishingOperationLocation(); + strata.setId(strataId.toString()); + result.setStrata(strata); + } + + // Sub Strata : + Integer subStrataId = (Integer) source[colIndex++]; + if (subStrataId != null) { + FishingOperationLocation subStrata = new FishingOperationLocation(); + subStrata.setId(subStrataId.toString()); + result.setSubStrata(subStrata); + } + + // Localite : + Integer localiteId = (Integer) source[colIndex++]; + if (localiteId != null) { + FishingOperationLocation localite = new FishingOperationLocation(); + localite.setId(localiteId.toString()); + result.setLocation(localite); + } + + // Retrieve environment caracteristics : + getEnvironmentCaracteristics(id, result); + + // Retrieve gear shooting caracteristics : + getGearShootingCaracteristics(id, result); + + return result; + } + + + @Override + public FishingOperation createFishingOperation(FishingOperation bean) { + Preconditions.checkNotNull(bean); + Preconditions.checkNotNull(bean.getCruise()); + Preconditions.checkNotNull(bean.getCruise().getId()); + + getCurrentSession().setFlushMode(FlushMode.COMMIT); + fr.ifremer.adagio.core.dao.data.operation.FishingOperation fishingOperation = fr.ifremer.adagio.core.dao.data.operation.FishingOperation.Factory.newInstance(); + beanToEntity(bean, fishingOperation, true); + fishingOperationDao.create(fishingOperation); + bean.setId(String.valueOf(fishingOperation.getId())); + getCurrentSession().flush(); + return bean; + } + + @Override + public FishingOperation saveFishingOperation(FishingOperation bean) { + Preconditions.checkNotNull(bean); + Preconditions.checkNotNull(bean.getId()); + Preconditions.checkNotNull(bean.getCruise()); + Preconditions.checkNotNull(bean.getCruise().getId()); + + getCurrentSession().clear(); + getCurrentSession().setFlushMode(FlushMode.COMMIT); + fr.ifremer.adagio.core.dao.data.operation.FishingOperation fishingOperation = fishingOperationDao.load(Integer.valueOf(bean.getId())); + if (fishingOperation == null) { + throw new DataRetrievalFailureException("Could not retrieve fishing operation with id=" + bean.getId()); + } + beanToEntity(bean, fishingOperation, true); + fishingOperationDao.update(fishingOperation); + getCurrentSession().flush(); + return bean; + } + + //------------------------------------------------------------------------// + //-- Internal methods --// + //------------------------------------------------------------------------// + + protected void getEnvironmentCaracteristics(String fishingOperationId, FishingOperation result) { + // retrieve fishing operation caracteristics + Iterator<Object[]> list = queryList( + "fishingOperationEnvironment", + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(fishingOperationId) + ); + + CaracteristicMap environmentCaracteristics = new CaracteristicMap(); + while (list.hasNext()) { + int colIndex = 0; + Object[] source = list.next(); + Integer pmfmId = (Integer) source[colIndex++]; + Float numericalValue = (Float) source[colIndex++]; + String alphanumericalValue = (String) source[colIndex++]; + Integer qualitativeValueId = (Integer) source[colIndex++]; + + // Trawl distance + if (enumeration.PMFM_ID_TRAWL_DISTANCE.equals(pmfmId)) { + result.setTrawlDistance(numericalValue); + } + + // Rectilinear operation ? + else if (enumeration.PMFM_ID_RECTILINEAR_OPERATION.equals(pmfmId)) { + result.setFishingOperationRectiligne(enumeration.QUALITATIVE_RECTILINEAR_OPERATION_YES.equals(qualitativeValueId)); + } + + // Haul valid ? + else if (enumeration.PMFM_ID_HAUL_VALID.equals(pmfmId)) { + result.setFishingOperationValid(enumeration.QUALITATIVE_HAUL_VALID_YES.equals(qualitativeValueId)); + } + + // Station Number : + else if (enumeration.PMFM_ID_STATION_NUMBER.equals(pmfmId)) { + result.setStationNumber(alphanumericalValue); + } + + // Environment caracteristic + else { + Caracteristic environmentCaracteristic = referentialService.getCaracteristic(pmfmId); + Serializable value = null; + if (environmentCaracteristic.getCaracteristicType() == CaracteristicType.NUMBER) { + value = numericalValue; + } else if (environmentCaracteristic.getCaracteristicType() == CaracteristicType.TEXT) { + value = alphanumericalValue; + } else if (environmentCaracteristic.getCaracteristicType() == CaracteristicType.QUALITATIVE) { + value = qualitativeValueId; + } + environmentCaracteristics.put(environmentCaracteristic, value); + } + } + + if (environmentCaracteristics.size() > 0) { + result.setEnvironmentCaracteristics(environmentCaracteristics); + } + } + + protected void getGearShootingCaracteristics(String fishingOperationId, FishingOperation result) { + // retrieve fishing operation caracteristics + Iterator<Object[]> list = queryList( + "fishingOperationGearShooting", + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(fishingOperationId) + ); + + CaracteristicMap gearShootingCaracteristics = new CaracteristicMap(); + while (list.hasNext()) { + int colIndex = 0; + Object[] source = list.next(); + Integer pmfmId = (Integer) source[colIndex++]; + Float numericalValue = (Float) source[colIndex++]; + String alphanumericalValue = (String) source[colIndex++]; + Integer qualitativeValueId = (Integer) source[colIndex++]; + + // Trawl net number + if (enumeration.PMFM_ID_MULTIRIG_AGGREGATION.equals(pmfmId) + && alphanumericalValue != null + && alphanumericalValue.matches("\\d+")) { + result.setMultirigAggregation(alphanumericalValue); + } + + // Gear Shooting Caracteristics + else { + Caracteristic gearShootingCaracteristic = referentialService.getCaracteristic(pmfmId); + Serializable value = null; + if (gearShootingCaracteristic.getCaracteristicType() == CaracteristicType.NUMBER) { + value = numericalValue; + } else if (gearShootingCaracteristic.getCaracteristicType() == CaracteristicType.TEXT) { + value = alphanumericalValue; + } else if (gearShootingCaracteristic.getCaracteristicType() == CaracteristicType.QUALITATIVE) { + value = qualitativeValueId; + } + gearShootingCaracteristics.put(gearShootingCaracteristic, value); + } + } + + if (gearShootingCaracteristics.size() > 0) { + result.setGearShootingCaracteristics(gearShootingCaracteristics); + } + } + + protected void beanToEntity(FishingOperation source, fr.ifremer.adagio.core.dao.data.operation.FishingOperation target, boolean copyIfNull) { + StringBuffer nameBuffer = new StringBuffer(); + + // Retrieve entities : FishingTrip and ScientificCruise + ScientificCruise scientificCruise; + FishingTrip fishingTrip = target.getFishingTrip(); + if (fishingTrip == null) { + scientificCruise = scientificCruiseDao.load(Integer.valueOf(source.getCruise().getId())); + fishingTrip = scientificCruise.getFishingTrips().iterator().next(); + fishingTrip.getOperations().add(target); // Inverse link + } else { + scientificCruise = fishingTrip.getScientificCruise(); + } + // Link to parent fishing trip + target.setFishingTrip(fishingTrip); + + // Retrieve entities : VesselPosition (start and end) + VesselPosition startPosition = null; + VesselPosition endPosition = null; + if (target.getVesselPositions() != null) { + for (VesselPosition position : target.getVesselPositions()) { + if (position.getDateTime() != null && position.getDateTime().getTime() == target.getStartDateTime().getTime()) { + startPosition = position; + } else if (position.getDateTime() == null || (target.getEndDateTime() != null && position.getDateTime().getTime() == target.getEndDateTime().getTime())) { + endPosition = position; + } + } + } + + // Retrieve entities : Gear Use Features + GearUseFeatures gearUseFeatures; + if (CollectionUtils.isEmpty(target.getGearUseFeatures())) { + gearUseFeatures = GearUseFeatures.Factory.newInstance(); + gearUseFeatures.setOperation(target); + if (target.getGearUseFeatures() == null) { + target.setGearUseFeatures(Sets.newHashSet(gearUseFeatures)); + } else { + target.getGearUseFeatures().add(gearUseFeatures); + } + } else { + gearUseFeatures = target.getGearUseFeatures().iterator().next(); + } + + // Create a list to store all updates, then remove not updated items + Set<GearUseMeasurement> notChangedGearUseMeasurements = new HashSet<GearUseMeasurement>(); + if (gearUseFeatures.getGearUseMeasurements() != null) { + notChangedGearUseMeasurements.addAll(gearUseFeatures.getGearUseMeasurements()); + } + + // Retrieve entities : Vessel Use Features + VesselUseFeatures vesselUseFeatures; + if (CollectionUtils.isEmpty(target.getVesselUseFeatures())) { + vesselUseFeatures = VesselUseFeatures.Factory.newInstance(); + if (target.getVesselUseFeatures() == null) { + target.setVesselUseFeatures(Sets.newHashSet(vesselUseFeatures)); + vesselUseFeatures.setOperation(target); + } else { + target.getVesselUseFeatures().add(vesselUseFeatures); + vesselUseFeatures.setOperation(target); + } + } else { + vesselUseFeatures = target.getVesselUseFeatures().iterator().next(); + } + + // Create a list to trace not updated items, to be able to remove them later + Set<VesselUseMeasurement> notChangedVesselUseMeasurements = new HashSet<VesselUseMeasurement>(); + if (vesselUseFeatures.getVesselUseMeasurements() != null) { + notChangedVesselUseMeasurements.addAll(vesselUseFeatures.getVesselUseMeasurements()); + } + + // Retrieve entities : Gear Physical Features + GearPhysicalFeatures gearPhysicalFeatures = target.getGearPhysicalFeatures(); + if (gearPhysicalFeatures == null && source.getGear() != null && source.getGear().getId() != null) { + gearPhysicalFeatures = measurementHelper.getGearPhysicalfeatures(fishingTrip, Integer.valueOf(source.getGear().getId())); + if (gearPhysicalFeatures == null) { + throw new DataIntegrityViolationException("An operation could not use a gear that is not declared in the cruise."); + } + target.setGearPhysicalFeatures(gearPhysicalFeatures); + if (gearPhysicalFeatures.getOperations() == null) { + gearPhysicalFeatures.setOperations(Sets.newHashSet((Operation) target)); + } else { + gearPhysicalFeatures.getOperations().add(target); + } + nameBuffer.append(source.getGear().getLabel()); + } + + // Retrieve entities : Fishing Area + FishingArea fishingArea; + if (CollectionUtils.isEmpty(gearUseFeatures.getFishingAreas())) { + fishingArea = FishingArea.Factory.newInstance(); + if (gearUseFeatures.getFishingAreas() == null) { + gearUseFeatures.setFishingAreas(Sets.newHashSet(fishingArea)); + fishingArea.setGearUseFeatures(gearUseFeatures); + } else { + gearUseFeatures.getFishingAreas().add(fishingArea); + fishingArea.setGearUseFeatures(gearUseFeatures); + } + } else { + fishingArea = gearUseFeatures.getFishingAreas().iterator().next(); + // Reset all other fishing areas + } + + // Retrieve entities : CatchBatch + /*CatchBatch catchBatch = target.getCatchBatch(); + if (catchBatch == null) { + catchBatch = CatchBatch.Factory.newInstance(); + catchBatch.setFishingOperation(target); + target.setCatchBatch(catchBatch); + }*/ + + // Retrieve multirig number, from Gear physical features + int cruiseMultirigCount = 1; // default value + GearPhysicalMeasurement gpmMultirigCount = measurementHelper.getGearPhysicalMeasurement(gearPhysicalFeatures, enumeration.PMFM_ID_MULTIRIG_NUMBER); + if (gpmMultirigCount != null && gpmMultirigCount.getNumericalValue() != null) { + cruiseMultirigCount = gpmMultirigCount.getNumericalValue().intValue(); + } + + // StationNumber + if (copyIfNull && source.getStationNumber() == null) { + // Nothing to do : will be removed using the list notChangedVesselUseMeasurements + } else if (source.getStationNumber() != null) { + VesselUseMeasurement vum = setVesselUseMeasurement(scientificCruise, vesselUseFeatures, enumeration.PMFM_ID_STATION_NUMBER, null, source.getStationNumber(), null); + notChangedVesselUseMeasurements.remove(vum); + } + + // OP N° + if (copyIfNull && source.getFishingOperationNumber() == null) { + // Leave empty in the name buffer + } else if (source.getFishingOperationNumber() != null) { + nameBuffer.append(source.getFishingOperationNumber()); + } + target.setName(nameBuffer.toString()); + + // Multirig Aggregation + if (copyIfNull && source.getMultirigAggregation() == null) { + // Nothing to do : will be removed later, using notChangedGearUseMeasurements + } else if (source.getMultirigAggregation() != null) { + if (source.getMultirigAggregation().matches("\\d+")) { + int mutlirigNumber = Integer.valueOf(source.getMultirigAggregation()); + if (mutlirigNumber > cruiseMultirigCount) { + throw new DataIntegrityViolationException("An operation could not have a 'multirig number' greater than 'multirig count' defined in the cruise."); + } + } else { + // TODO BLA : Then parse the String when more than one number (ie "1,3") + // then and validate content + } + + // Store into Gear Use Features + GearUseMeasurement gum = setGearUseMeasurement(scientificCruise, gearUseFeatures, enumeration.PMFM_ID_MULTIRIG_AGGREGATION, null, source.getMultirigAggregation(), null); + notChangedGearUseMeasurements.remove(gum); + } + + // Start date : + if (copyIfNull && source.getGearShootingStartDate() == null) { + target.setStartDateTime(null); + target.setFishingStartDateTime(null); + } else if (source.getGearShootingStartDate() != null) { + calendar.setTime(source.getGearShootingStartDate()); + // Reset millisecond (as need for Allegro) + calendar.set(Calendar.MILLISECOND, 0); + target.setStartDateTime(calendar.getTime()); + target.setFishingStartDateTime(calendar.getTime()); + } + + // End date : + if (copyIfNull && source.getGearShootingEndDate() == null) { + target.setEndDateTime(null); + target.setFishingEndDateTime(null); + } else if (source.getGearShootingEndDate() != null) { + calendar.setTime(source.getGearShootingEndDate()); + // Reset millisecond (as need for Allegro) + calendar.set(Calendar.MILLISECOND, 0); + target.setEndDateTime(calendar.getTime()); + target.setFishingEndDateTime(calendar.getTime()); + } + + // Trawl distance + if (copyIfNull && source.getTrawlDistance() == null) { + // Nothing to do : will be removed later, using notChangedVesselUseMeasurements + } else if (source.getTrawlDistance() != null) { + VesselUseMeasurement vum = setVesselUseMeasurement(scientificCruise, vesselUseFeatures, enumeration.PMFM_ID_TRAWL_DISTANCE, source.getTrawlDistance(), null, null); + notChangedVesselUseMeasurements.remove(vum); + } + + // Rectilinear operation + { + VesselUseMeasurement vum = setVesselUseMeasurement(scientificCruise, vesselUseFeatures, enumeration.PMFM_ID_RECTILINEAR_OPERATION, null, null, source.isFishingOperationRectiligne() ? enumeration.QUALITATIVE_RECTILINEAR_OPERATION_YES : enumeration.QUALITATIVE_RECTILINEAR_OPERATION_NO); + notChangedVesselUseMeasurements.remove(vum); + } + + // Operation is valid ? + if (copyIfNull && source.getFishingOperationValid() == null) { + // Nothing to do : will be removed later, using notChangedVesselUseMeasurements + } else if (source.getFishingOperationValid() != null) { + VesselUseMeasurement vum = setVesselUseMeasurement(scientificCruise, vesselUseFeatures, enumeration.PMFM_ID_HAUL_VALID, null, null, source.getFishingOperationValid().booleanValue() ? enumeration.QUALITATIVE_HAUL_VALID_YES : enumeration.QUALITATIVE_HAUL_VALID_NO); + notChangedVesselUseMeasurements.remove(vum); + } + + // Vessel + target.setVessel(fishingTrip.getVessel()); + + // Quality Flag : + if (target.getQualityFlag() == null) { + target.setQualityFlag(load(QualityFlagImpl.class, enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + } + + // Settings not null properties : + if (target.getStartDateTime() == null) { + // Generate a fake departureDate (precision=minute) then add 1 millisecond + calendar.setTime(scientificCruise.getDepartureDateTime()); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 1); + target.setStartDateTime(calendar.getTime()); + target.setFishingStartDateTime(calendar.getTime()); + } + + // VesselUseFeatures : + vesselUseFeatures.setStartDate(target.getStartDateTime()); + if (vesselUseFeatures.getStartDate() == null) { + vesselUseFeatures.setStartDate(scientificCruise.getDepartureDateTime()); + } + vesselUseFeatures.setEndDate(target.getEndDateTime()); + vesselUseFeatures.setVessel(target.getVessel()); + vesselUseFeatures.setProgram(scientificCruise.getProgram()); + vesselUseFeatures.setIsActive(isActive.ACTIVE.getValue()); + if (vesselUseFeatures.getCreationDate() == null) { + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + vesselUseFeatures.setCreationDate(calendar.getTime()); + } + if (vesselUseFeatures.getQualityFlag() == null) { + vesselUseFeatures.setQualityFlag(load(QualityFlagImpl.class, enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + } + + // GearUseFeatures : + gearUseFeatures.setStartDate(target.getStartDateTime()); + if (gearUseFeatures.getStartDate() == null) { + gearUseFeatures.setStartDate(scientificCruise.getDepartureDateTime()); + } + gearUseFeatures.setEndDate(target.getEndDateTime()); + gearUseFeatures.setVessel(target.getVessel()); + gearUseFeatures.setProgram(scientificCruise.getProgram()); + if (gearUseFeatures.getCreationDate() == null) { + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + gearUseFeatures.setCreationDate(calendar.getTime()); + } + if (gearUseFeatures.getQualityFlag() == null) { + gearUseFeatures.setQualityFlag(load(QualityFlagImpl.class, enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + } + + // GearUseFeatures.Gear + if (copyIfNull && source.getGear() == null) { + gearUseFeatures.setGear(null); + } else if (source.getGear() != null && source.getGear().getId() != null) { + gearUseFeatures.setGear(load(GearImpl.class, Integer.valueOf(source.getGear().getId()))); + } + + // Start position : + // If need to be store + if (source.getGearShootingEndLatitude() != null + || source.getGearShootingEndDate() != null + || source.getGearShootingEndLongitude() != null) { + + if (startPosition == null) { + startPosition = VesselPosition.Factory.newInstance(); + startPosition.setOperation(target); + if (target.getVesselPositions() == null) { + target.setVesselPositions(Sets.newHashSet(startPosition)); + } + target.getVesselPositions().add(startPosition); + } + startPosition.setDateTime(target.getStartDateTime()); + startPosition.setLatitude(source.getGearShootingStartLatitude() != null ? source.getGearShootingStartLatitude() : DEFAULT_EMPTY_LATITUDE); + startPosition.setLongitude(source.getGearShootingStartLongitude() != null ? source.getGearShootingStartLongitude() : DEFAULT_EMPTY_LONGITUDE); + startPosition.setVessel(target.getVessel()); + startPosition.setProgram(scientificCruise.getProgram()); + startPosition.setRecorderDepartment(scientificCruise.getRecorderDepartment()); + startPosition.setQualityFlag(target.getQualityFlag()); + } + + // If not need to be store, delete start position from list + else if (startPosition != null && target.getVesselPositions() != null) { + target.getVesselPositions().remove(startPosition); + } + + // End position : + // If need to be store + if (source.getGearShootingEndLatitude() != null + || source.getGearShootingEndDate() != null + || source.getGearShootingEndLongitude() != null) { + + if (endPosition == null) { + endPosition = VesselPosition.Factory.newInstance(); + endPosition.setOperation(target); + target.getVesselPositions().add(endPosition); + } + Date endDateTime = convertUI2DatabaseMandatoryDate(target.getEndDateTime(), startPosition.getDateTime(), true); + endPosition.setDateTime(endDateTime); + if (!endDateTime.equals(target.getEndDateTime())) { + // To link position with the operation end, Allegro need to have exactly the same dates + target.setEndDateTime(endDateTime); + target.setFishingEndDateTime(endDateTime); + } + endPosition.setLatitude(convertUI2DatabaseMandatoryLatitude(source.getGearShootingEndLatitude())); + endPosition.setLongitude(convertUI2DatabaseMandatoryLatitude(source.getGearShootingEndLongitude())); + endPosition.setVessel(target.getVessel()); + endPosition.setProgram(scientificCruise.getProgram()); + endPosition.setRecorderDepartment(scientificCruise.getRecorderDepartment()); + endPosition.setQualityFlag(target.getQualityFlag()); + } + + // If not need to be store, delete end position from list + else if (endPosition != null && target.getVesselPositions() != null) { + target.getVesselPositions().remove(endPosition); + } + + // Environment Caracteristics + CaracteristicMap environmentCaracteristics = source.getEnvironmentCaracteristics(); + if (copyIfNull && environmentCaracteristics == null || environmentCaracteristics.size() == 0) { + // Nothing to do : will be removed later, using notChangedVesselUseMeasurements + } else if (environmentCaracteristics != null && environmentCaracteristics.size() > 0) { + for (Caracteristic caracteristic : environmentCaracteristics.keySet()) { + VesselUseMeasurement vum = setVesselUseMeasurement(scientificCruise, vesselUseFeatures, caracteristic, environmentCaracteristics.get(caracteristic)); + notChangedVesselUseMeasurements.remove(vum); + } + } + + // Recorder persons + StringBuilder miscDataBuffer = new StringBuilder(); + if (copyIfNull && (source.getSaisisseur() == null || source.getSaisisseur().size() == 0)) { + miscDataBuffer.append(MISC_DATA_RECORDER_PERSONS_TAG); + } else if (source.getSaisisseur() != null && source.getSaisisseur().size() > 0) { + List<Person> persons = source.getSaisisseur(); + miscDataBuffer.append(MISC_DATA_RECORDER_PERSONS_TAG); + for (int i = 0; i < persons.size(); i++) { + if (i > 0) miscDataBuffer.append(','); + miscDataBuffer.append(persons.get(i).getId()); + } + } + + // Store misc data into comments + if (copyIfNull && source.getComment() == null) { + // Store only misc data : + target.setComments(miscDataBuffer.toString()); + } else if (source.getComment() != null) { + // Store comment + misc data + target.setComments(source.getComment() + miscDataBuffer.toString()); + } + + // ---------------------------------------------------------------- + // Removed unecessary *UseMeasurement : --- + // ---------------------------------------------------------------- + + // Gear shooting Caracteristics + CaracteristicMap gearShootingCaracteristics = source.getGearShootingCaracteristics(); + if (copyIfNull && gearShootingCaracteristics == null || gearShootingCaracteristics.size() == 0) { + // Nothing to do : will be removed later, using notChangedGearUseMeasurements + } else if (gearShootingCaracteristics != null && gearShootingCaracteristics.size() > 0) { + for (Caracteristic caracteristic : gearShootingCaracteristics.keySet()) { + GearUseMeasurement gum = setGearUseMeasurement(scientificCruise, gearUseFeatures, caracteristic, environmentCaracteristics.get(caracteristic)); + notChangedGearUseMeasurements.remove(gum); + } + } + + // Removed not changed measurements (in Vessel & Gear Use Measurement lists) + if (vesselUseFeatures.getVesselUseMeasurements() != null && notChangedVesselUseMeasurements.size() > 0) { + for (VesselUseMeasurement vum : notChangedVesselUseMeasurements) { + vesselUseFeatures.getVesselUseMeasurements().remove(vum); + } + } + if (gearUseFeatures.getGearUseMeasurements() != null && notChangedGearUseMeasurements.size() > 0) { + for (GearUseMeasurement gum : notChangedGearUseMeasurements) { + gearUseFeatures.getGearUseMeasurements().remove(gum); + } + } + + // ---------------------------------------------------------------- + // Fishing Area : Strata, substrata, localite --- + // ---------------------------------------------------------------- + + // Fishing Area : + Integer statisticalLocationId = null; + if (source.getGearShootingStartLatitude() != null && source.getGearShootingStartLongitude() != null) { + statisticalLocationId = locationService.getLocationIdByLatLong(source.getGearShootingStartLatitude(), source.getGearShootingStartLongitude()); + } + if (statisticalLocationId == null && source.getGearShootingEndLatitude() != null && source.getGearShootingEndLongitude() != null) { + statisticalLocationId = locationService.getLocationIdByLatLong(source.getGearShootingEndLatitude(), source.getGearShootingEndLongitude()); + } + + // Strata : + if (copyIfNull && (source.getStrata() == null || source.getStrata().getId() == null)) { + // TODO remove from fishing Area ? + } else if (source.getStrata() != null && source.getStrata().getId() != null) { + FishingArea2RegulationLocation fa2rl = FishingArea2RegulationLocation.Factory.newInstance(); + FishingArea2RegulationLocationPK fa2rlPK = new FishingArea2RegulationLocationPK(); + fa2rl.setFishingArea2RegulationLocationPk(fa2rlPK); + fa2rlPK.setFishingArea(fishingArea); + fa2rlPK.setLocation(load(LocationImpl.class, Integer.valueOf(source.getStrata().getId()))); + if (fishingArea.getRegulationLocation() == null) { + fishingArea.setRegulationLocation(Sets.newHashSet(fa2rl)); + } else { + fishingArea.getRegulationLocation().add(fa2rl); + } + if (statisticalLocationId == null) { + statisticalLocationId = Integer.valueOf(source.getStrata().getId()); + } + } + + // Sub-Strata : + if (copyIfNull && (source.getSubStrata() == null || source.getSubStrata().getId() == null)) { + // TODO remove from fishing Area ? + } else if (source.getSubStrata() != null && source.getSubStrata().getId() != null) { + FishingArea2RegulationLocation fa2rl = FishingArea2RegulationLocation.Factory.newInstance(); + FishingArea2RegulationLocationPK fa2rlPK = new FishingArea2RegulationLocationPK(); + fa2rl.setFishingArea2RegulationLocationPk(fa2rlPK); + fa2rlPK.setFishingArea(fishingArea); + fa2rlPK.setLocation(load(LocationImpl.class, Integer.valueOf(source.getSubStrata().getId()))); + if (fishingArea.getRegulationLocation() == null) { + fishingArea.setRegulationLocation(Sets.newHashSet(fa2rl)); + } else { + fishingArea.getRegulationLocation().add(fa2rl); + } + if (statisticalLocationId == null) { + statisticalLocationId = Integer.valueOf(source.getSubStrata().getId()); + } + } + + // Localite : + if (copyIfNull && (source.getLocation() == null || source.getLocation().getId() == null)) { + // TODO remove from fishing Area ? + } else if (source.getLocation() != null && source.getLocation().getId() != null) { + FishingArea2RegulationLocation fa2rl = FishingArea2RegulationLocation.Factory.newInstance(); + FishingArea2RegulationLocationPK fa2rlPK = new FishingArea2RegulationLocationPK(); + fa2rl.setFishingArea2RegulationLocationPk(fa2rlPK); + fa2rlPK.setFishingArea(fishingArea); + fa2rlPK.setLocation(load(LocationImpl.class, Integer.valueOf(source.getLocation().getId()))); + if (fishingArea.getRegulationLocation() == null) { + fishingArea.setRegulationLocation(Sets.newHashSet(fa2rl)); + } else { + fishingArea.getRegulationLocation().add(fa2rl); + } + if (statisticalLocationId == null) { + statisticalLocationId = Integer.valueOf(source.getLocation().getId()); + } + } + + // Fishing Area location (should be a statistical location) + if (copyIfNull && statisticalLocationId == null) { + gearUseFeatures.getFishingAreas().remove(fishingArea); + //Nothing to do : a gearUseFeatures.getFishingAreas().clear() has been done before + if (fishingArea.getRegulationLocation() != null) { + fishingArea.getRegulationLocation().clear(); + } + } else if (statisticalLocationId != null) { + fishingArea.setLocation(load(LocationImpl.class, statisticalLocationId)); + //gearUseFeatures.getFishingAreas().add(fishingArea); + } + } + + + /** + * Test if the date has millisecond set. This yes, return null, then return the date itself. + * + * @param databaseValue the date stored in the database (could be fake date, not null only because of database constraints) + * @return null if the date is a fake date + */ + protected Date convertDatabase2UI(Timestamp databaseValue) { + if (databaseValue == null) { + return null; + } + calendar.setTimeInMillis(databaseValue.getTime()); + if (calendar.get(Calendar.MILLISECOND) != 0) { + return null; + } + return calendar.getTime(); + } + + /** + * Convert a UI date, when the database value is mandatory. + * If the given value is null, use the default date, then set millisecond to '1', to be able to retrieve the null value later. + * + * @param uiValue the date used in the UI + * @return null if the date is a fake date + */ + protected Date convertUI2DatabaseMandatoryDate(Date uiValue, Date defaultNotEmptyDate, boolean addOneSecondToDefaultDate) { + // if ui date is not empty, then use it (but reset millisecond) + if (uiValue != null) { + calendar.setTime(uiValue); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTime(); + } + if (defaultNotEmptyDate == null) { + throw new IllegalArgumentException("'defaultNotEmptyDate' could not be null."); + } + + calendar.setTime(defaultNotEmptyDate); + if (addOneSecondToDefaultDate) { + calendar.add(Calendar.SECOND, 1); + } + calendar.set(Calendar.MILLISECOND, 1); + return calendar.getTime(); + } + + /** + * Test if the latitude is null, and return a default value if yes + * + * @param databaseValue the latitude used in UI (could be null) + * @return null the latitude to store in database (could not be null) + */ + protected Float convertUI2DatabaseMandatoryLatitude(Float databaseValue) { + return (databaseValue != null) ? databaseValue : DEFAULT_EMPTY_LATITUDE; + } + + /** + * Test if the latitude is a fake value. This yes, return null, then return the given value. + * + * @param databaseValue the latitude stored in the database (could be fake date, not null only because of database constraints) + * @return null if the latitude is fake + */ + protected Float convertLatitude2UI(Float databaseValue) { + return DEFAULT_EMPTY_LATITUDE.equals(databaseValue) ? null : databaseValue; + } + + /** + * Test if the latitude is null, and return a default value if yes + * + * @param databaseValue the latitude used in UI (could be null) + * @return null the latitude to store in database (could not be null) + */ + protected Float convertUI2DatabaseMandatoryLongitude(Float databaseValue) { + return (databaseValue != null) ? databaseValue : DEFAULT_EMPTY_LONGITUDE; + } + + /** + * Test if the longitude is a fake value. This yes, return null, then return the given value. + * + * @param databaseValue the longitude stored in the database (could be fake date, not null only because of database constraints) + * @return null if the longitude is fake + */ + protected Float convertLongitude2UI(Float databaseValue) { + return DEFAULT_EMPTY_LONGITUDE.equals(databaseValue) ? null : databaseValue; + } + + + protected VesselUseMeasurement getVesselUseMeasurement(ScientificCruise scientificCruise, VesselUseFeatures vesselUseFeatures, + Integer pmfmId, boolean createIfNotExists) { + VesselUseMeasurement vesselUseMeasurement = null; + if (vesselUseFeatures.getVesselUseMeasurements() != null) { + for (VesselUseMeasurement vum : vesselUseFeatures.getVesselUseMeasurements()) { + if (pmfmId.equals(vum.getPmfm().getId())) { + vesselUseMeasurement = vum; + break; + } + } + } + if (vesselUseMeasurement == null) { + if (!createIfNotExists) { + return null; + } + vesselUseMeasurement = VesselUseMeasurement.Factory.newInstance(); + vesselUseMeasurement.setVesselUseFeatures(vesselUseFeatures); + if (vesselUseFeatures.getVesselUseMeasurements() == null) { + vesselUseFeatures.setVesselUseMeasurements(Sets.newHashSet(vesselUseMeasurement)); + } else { + vesselUseFeatures.getVesselUseMeasurements().add(vesselUseMeasurement); + } + vesselUseMeasurement.setQualityFlag(load(QualityFlagImpl.class, enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + vesselUseMeasurement.setDepartment(scientificCruise.getRecorderDepartment()); + vesselUseMeasurement.setPmfm(load(PmfmImpl.class, pmfmId)); + } + + return vesselUseMeasurement; + } + + protected VesselUseMeasurement setVesselUseMeasurement(ScientificCruise scientificCruise, VesselUseFeatures vesselUseFeatures, + Integer pmfmId, + Float numericalValue, + String alphanumericalValue, + Integer qualitativevalueId) { + VesselUseMeasurement vesselUseMeasurement = getVesselUseMeasurement(scientificCruise, vesselUseFeatures, pmfmId, true); + + if (alphanumericalValue != null) { + vesselUseMeasurement.setAlphanumericalValue(alphanumericalValue); + } else if (numericalValue != null) { + vesselUseMeasurement.setNumericalValue(numericalValue); + } else if (qualitativevalueId != null) { + vesselUseMeasurement.setQualitativeValue(load(QualitativeValueImpl.class, qualitativevalueId)); + } + + return vesselUseMeasurement; + } + + protected VesselUseMeasurement setVesselUseMeasurement(ScientificCruise scientificCruise, VesselUseFeatures vesselUseFeatures, + Integer pmfmId, + Serializable value) { + VesselUseMeasurement vesselUseMeasurement = getVesselUseMeasurement(scientificCruise, vesselUseFeatures, pmfmId, true); + + if (value instanceof String) { + vesselUseMeasurement.setAlphanumericalValue((String) value); + } else if (value instanceof Float) { + vesselUseMeasurement.setNumericalValue((Float) value); + } else if (value instanceof Integer) { + vesselUseMeasurement.setQualitativeValue(load(QualitativeValueImpl.class, (Integer) value)); + } + + return vesselUseMeasurement; + } + + protected VesselUseMeasurement setVesselUseMeasurement(ScientificCruise scientificCruise, VesselUseFeatures vesselUseFeatures, + Caracteristic caracteristic, Serializable value) { + VesselUseMeasurement vesselUseMeasurement = getVesselUseMeasurement(scientificCruise, vesselUseFeatures, Integer.valueOf(caracteristic.getId()), true); + setMeasurement(vesselUseMeasurement, caracteristic, value); + return vesselUseMeasurement; + } + + protected void setMeasurement(Measurement measurement, Caracteristic caracteristic, Serializable value) { + if (value == null) { + return; + } + if (caracteristic.getCaracteristicType() == CaracteristicType.TEXT) { + measurement.setAlphanumericalValue((String) value); + } else if (caracteristic.getCaracteristicType() == CaracteristicType.NUMBER) { + measurement.setNumericalValue((Float) value); + } else if (caracteristic.getCaracteristicType() == CaracteristicType.QUALITATIVE) { + Integer qvId; + if (value instanceof Integer) { + qvId = (Integer) value; + } else { + qvId = Integer.valueOf(value.toString()); + } + QualitativeValue qv = load(QualitativeValueImpl.class, qvId); + measurement.setQualitativeValue(qv); + } + } + + protected GearUseMeasurement setGearUseMeasurement(ScientificCruise scientificCruise, GearUseFeatures gearUseFeatures, + Integer pmfmId, + Float numericalValue, + String alphanumericalValue, + Integer qualitativevalueId) { + GearUseMeasurement gearUseMeasurement = getGearUseMeasurement(scientificCruise, gearUseFeatures, pmfmId, true); + + if (alphanumericalValue != null) { + gearUseMeasurement.setAlphanumericalValue(alphanumericalValue); + } else if (numericalValue != null) { + gearUseMeasurement.setNumericalValue(numericalValue); + } else if (qualitativevalueId != null) { + QualitativeValue qv = (QualitativeValue) getCurrentSession().load(QualitativeValueImpl.class, qualitativevalueId); + gearUseMeasurement.setQualitativeValue(qv); + } + + return gearUseMeasurement; + } + + protected GearUseMeasurement setGearUseMeasurement(ScientificCruise scientificCruise, GearUseFeatures gearUseFeatures, + Caracteristic caracteristic, Serializable value) { + GearUseMeasurement gearUseMeasurement = getGearUseMeasurement(scientificCruise, gearUseFeatures, Integer.valueOf(caracteristic.getId()), true); + setMeasurement(gearUseMeasurement, caracteristic, value); + return gearUseMeasurement; + } + + protected GearUseMeasurement getGearUseMeasurement(ScientificCruise scientificCruise, GearUseFeatures gearUseFeatures, + Integer pmfmId, boolean createIfNotExists) { + GearUseMeasurement gearUseMeasurement = null; + if (gearUseFeatures.getGearUseMeasurements() != null) { + for (GearUseMeasurement vum : gearUseFeatures.getGearUseMeasurements()) { + if (pmfmId.equals(vum.getPmfm().getId())) { + gearUseMeasurement = vum; + break; + } + } + } + if (gearUseMeasurement == null) { + if (!createIfNotExists) { + return null; + } + gearUseMeasurement = GearUseMeasurement.Factory.newInstance(); + gearUseMeasurement.setGearUseFeatures(gearUseFeatures); + if (gearUseFeatures.getGearUseMeasurements() == null) { + gearUseFeatures.setGearUseMeasurements(Sets.newHashSet(gearUseMeasurement)); + } else { + gearUseFeatures.getGearUseMeasurements().add(gearUseMeasurement); + } + gearUseMeasurement.setQualityFlag(load(QualityFlagImpl.class, enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + gearUseMeasurement.setDepartment(scientificCruise.getRecorderDepartment()); + Pmfm pmfm = (Pmfm) getCurrentSession().load(PmfmImpl.class, pmfmId); + gearUseMeasurement.setPmfm(pmfm); + } + + return gearUseMeasurement; + } + + protected DenormalizedBatch getDenormalizedBatch(Integer fishingOperationId) { + Iterator<DenormalizedBatch> list = queryListTyped( + "fishingOperationBatchs", + "fishingOperationId", IntegerType.INSTANCE, fishingOperationId + ); + + CaracteristicMap environmentCaracteristics = new CaracteristicMap(); + while (list.hasNext()) { + DenormalizedBatch batch = list.next(); + System.out.println(batch.getTreeIndent() + batch.getSortingValuesText()); + } + return null; + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,73 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.Lists; +import fr.ifremer.tutti.persistence.entities.data.MacroWasteBatch; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("macroWasteBatchPersistenceService") +public class MacroWasteBatchPersistenceServiceImpl extends AbstractPersistenceService implements MacroWasteBatchPersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(MacroWasteBatchPersistenceServiceImpl.class); + + @Override + public List<MacroWasteBatch> getAllMacroWasteBatch(String fishingOperationId) { + List<MacroWasteBatch> result = Lists.newArrayList(); + + // TODO BL + + return result; + } + + @Override + public MacroWasteBatch getMacroWasteBatch(String id) { + return null; + } + + @Override + public MacroWasteBatch createMacroWasteBatch(MacroWasteBatch bean) { + return null; + } + + @Override + public MacroWasteBatch saveMacroWasteBatch(MacroWasteBatch bean) { + return null; + } + + @Override + public void deleteMacroWasteBatch(String id) { + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,73 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.Lists; +import fr.ifremer.tutti.persistence.entities.data.PlanktonBatch; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("planktonBatchPersistenceService") +public class PlanktonBatchPersistenceServiceImpl extends AbstractPersistenceService implements PlanktonBatchPersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(PlanktonBatchPersistenceServiceImpl.class); + + @Override + public List<PlanktonBatch> getAllPlanktonBatch(String fishingOperationId) { + List<PlanktonBatch> result = Lists.newArrayList(); + + // TODO BL + + return result; + } + + @Override + public PlanktonBatch getPlanktonBatch(String id) { + return null; + } + + @Override + public PlanktonBatch createPlanktonBatch(PlanktonBatch bean) { + return null; + } + + @Override + public PlanktonBatch savePlanktonBatch(PlanktonBatch bean) { + return null; + } + + @Override + public void deletePlanktonBatch(String id) { + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,245 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.base.Preconditions; +import com.google.common.collect.Lists; +import fr.ifremer.adagio.core.dao.administration.programStrategy.ProgramDao; +import fr.ifremer.adagio.core.dao.referential.gear.GearClassificationImpl; +import fr.ifremer.adagio.core.dao.referential.location.Location; +import fr.ifremer.adagio.core.dao.referential.location.LocationDao; +import fr.ifremer.adagio.core.dao.referential.taxon.TaxonGroupTypeImpl; +import fr.ifremer.tutti.persistence.entities.data.Program; +import fr.ifremer.tutti.persistence.entities.referential.Zone; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.type.IntegerType; +import org.hibernate.type.StringType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("programPersistenceService") +public class ProgramPersistenceServiceImpl extends AbstractPersistenceService implements ProgramPersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ProgramPersistenceServiceImpl.class); + + @Autowired(required = true) + protected ReferentialPersistenceService referentialService; + + @Resource(name = "programDao") + protected ProgramDao programDao; + + @Resource(name = "locationDao") + protected LocationDao locationDao; + + protected final int maxCodeLengthInDatabase = 40; + + @Override + public List<Program> getAllProgram() { + String codePattern = "%"; + if (enumeration.PROGRAM_CODE_SCIENTIFIC_CRUISE_PREFIX != null) { + codePattern = enumeration.PROGRAM_CODE_SCIENTIFIC_CRUISE_PREFIX + codePattern; + } + Iterator<Object[]> list = queryList("allPrograms", + "codePattern", StringType.INSTANCE, codePattern + ); + + List<Program> result = Lists.newArrayList(); + while (list.hasNext()) { + Object[] source = list.next(); + Program target = new Program(); + target.setId((String) source[0]); + target.setName((String) source[1]); + target.setComment((String) source[2]); + result.add(target); + } + return result; + } + + @Override + public Program getProgram(String id) { + Iterator<Object[]> list = queryList( + "program", + "programCode", StringType.INSTANCE, id, + "locationLevelId", IntegerType.INSTANCE, enumeration.LOCATION_LEVEL_ID_PROGRAM, + "locationClassificationId", IntegerType.INSTANCE, enumeration.LOCATION_CLASSIFICATION_ID_SECTOR); + + if (list.hasNext() == false) return null; + + // Keep only the first row (=the first location, if many found) + Object[] source = list.next(); + + Program result = new Program(); + result.setId((String) source[0]); + result.setName((String) source[1]); + result.setComment((String) source[2]); + + if (source[3] != null) { + Zone zone = new Zone(); + zone.setId(String.valueOf(source[3])); + zone.setLabel((String) source[4]); + zone.setName((String) source[5]); + + result.setZone(zone); + } + + return result; + } + + @Override + public Program createProgram(Program bean) { + Preconditions.checkNotNull(bean); + Preconditions.checkNotNull(bean.getName()); + Preconditions.checkArgument(bean.getId() == null); + + fr.ifremer.adagio.core.dao.administration.programStrategy.Program program = fr.ifremer.adagio.core.dao.administration.programStrategy.Program.Factory.newInstance(); + beanToEntity(bean, program, true); + program = programDao.create(program); + bean.setId(String.valueOf(program.getCode())); + + return bean; + } + + @Override + public Program saveProgram(Program bean) { + Preconditions.checkNotNull(bean); + Preconditions.checkNotNull(bean.getName()); + Preconditions.checkNotNull(bean.getId()); + + fr.ifremer.adagio.core.dao.administration.programStrategy.Program program = programDao.load(bean.getId()); + if (program == null) { + throw new DataRetrievalFailureException("Could not retrieve program with code=" + bean.getId()); + } + + beanToEntity(bean, program, true); + programDao.update(program); + + return bean; + } + + // ------------------------------------------------------------------------// + // -- Internal methods --// + // ------------------------------------------------------------------------// + protected void beanToEntity(Program source, + fr.ifremer.adagio.core.dao.administration.programStrategy.Program target, + boolean copyIfNull) { + + // Code : compute with : <prefixe><name> + if (target.getCode() == null && source.getName() != null) { + // Compute a program code (remove spaces, and capitalize the name) + String programCode = source.getName().toUpperCase().replaceAll(" ", "_"); + // Add a prefix + if (enumeration.PROGRAM_CODE_SCIENTIFIC_CRUISE_PREFIX != null) { + programCode = enumeration.PROGRAM_CODE_SCIENTIFIC_CRUISE_PREFIX + programCode; + } + // Trunc the code if too long + if (programCode.length() > maxCodeLengthInDatabase) { + programCode = programCode.substring(0, maxCodeLengthInDatabase - 1); + } + target.setCode(programCode); + + // Mandatory properties : + // Gear classification : + target.setGearClassification(load(GearClassificationImpl.class, enumeration.GEAR_CLASSIFICIATION_ID_SCIENTIFIC)); + + // taxon group type + target.setTaxonGroupType(load(TaxonGroupTypeImpl.class, enumeration.TAXON_GROUP_TYPE_ID_COMMERCIAL_SPECIES)); + + // Creation date + Calendar calendar = new GregorianCalendar(); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + target.setCreationDate(calendar.getTime()); + } + + // Name + if (copyIfNull && source.getName() == null) { + target.setName(null); + } else if (source.getName() != null) { + target.setName(source.getName()); + } + + // Description (=source.comment) + if (copyIfNull && source.getComment() == null) { + target.setDescription(null); + } else if (source.getComment() != null) { + target.setDescription(source.getComment()); + } + + // Zone + if (copyIfNull && source.getZone() == null) { + // Remove program location classifications : + if (target.getLocationClassifications() != null) { + target.getLocationClassifications().clear(); + } + // Remove program locations : + if (target.getLocations() != null) { + target.getLocations().clear(); + } + } else if (source.getZone() != null && source.getZone().getId() != null) { + Location location = locationDao.load(Integer.valueOf(source.getZone().getId())); + + // Program location classifications : + if (target.getLocationClassifications() == null) { + target.setLocationClassifications(Lists.newArrayList(location.getLocationClassification())); + } else { + target.getLocationClassifications().clear(); + target.getLocationClassifications().add(location.getLocationClassification()); + } + + // Program locations : + if (target.getLocations() == null) { + target.setLocations(Lists.newArrayList(location)); + } else { + target.getLocations().clear(); + target.getLocations().add(location); + } + } + } + + public int getProgramNameMaxLength() { + int maxCodeLengthInDatabase = 40; + if (enumeration.PROGRAM_CODE_SCIENTIFIC_CRUISE_PREFIX == null + || enumeration.PROGRAM_CODE_SCIENTIFIC_CRUISE_PREFIX.trim().isEmpty()) { + return maxCodeLengthInDatabase; + } + return (maxCodeLengthInDatabase - enumeration.PROGRAM_CODE_SCIENTIFIC_CRUISE_PREFIX.length()); + } +} Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceService.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceService.java 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceService.java 2013-02-02 14:11:58 UTC (rev 300) @@ -36,7 +36,7 @@ * @since 0.3 */ //@Transactional(readOnly = true) -public interface ProtocolPersistenceService extends TuttiPersistenceServiceImplementor { +public interface ProtocolPersistenceService extends TuttiPersistenceServiceImplementor { boolean isProtocolExist(String id); Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,185 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.Lists; +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocols; +import org.apache.commons.io.FileUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.beans.Binder; +import org.nuiton.util.beans.BinderFactory; +import org.springframework.stereotype.Service; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.UUID; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("protocolPersistenceService") +public class ProtocolPersistenceServiceImpl extends AbstractPersistenceService implements ProtocolPersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ProtocolPersistenceServiceImpl.class); + + public static final String TUTTI_PROTOCOL_EXTENSION = "tuttiProtocol"; + + @Override + public boolean isProtocolExist(String id) { + return getAllProtocolId().contains(id); + } + + @Override + public List<String> getAllProtocolId() { + + File protocolDirectory = config.getProtocolDirectory(); + Collection<File> files = FileUtils.listFiles( + protocolDirectory, + new String[]{TUTTI_PROTOCOL_EXTENSION}, false); + List<String> result = Lists.newArrayListWithCapacity(files.size()); + if (log.isDebugEnabled()) { + log.debug("Found " + files.size() + " protocol(s)."); + } + int suffixLength = TUTTI_PROTOCOL_EXTENSION.length() + 1; + for (File file : files) { + String fileName = file.getName(); + result.add(fileName.substring(0, + fileName.length() - suffixLength)); + } + return result; + } + + @Override + public List<String> getAllProtocolNames() { + + List<String> result = Lists.newArrayList(); + for (TuttiProtocol protocol : getAllProtocol()) { + result.add(protocol.getName()); + } + return result; + } + + @Override + public List<TuttiProtocol> getAllProtocol() { + List<TuttiProtocol> result = Lists.newArrayList(); + for (String id : getAllProtocolId()) { + TuttiProtocol protocol = getProtocol(id); + result.add(protocol); + } + return result; + } + + @Override + public TuttiProtocol getProtocol(String id) { + File file = getProtocolFile(id); + try { + TuttiProtocol result = TuttiProtocols.fromFile(file); + return result; + } catch (IOException e) { + throw new RuntimeException("Could not read protocol " + id + " from file " + file, e); + } + } + + @Override + public TuttiProtocol createProtocol(TuttiProtocol bean) { + Binder<TuttiProtocol, TuttiProtocol> protocolBinder = + BinderFactory.newBinder(TuttiProtocol.class); + + TuttiProtocol result = new TuttiProtocol(); + protocolBinder.copy(bean, result); + result.setId(UUID.randomUUID().toString()); + + result.setLengthClassesPmfmId(TuttiEntities.getList(bean.getLengthClassesPmfmId())); + result.setEnvironmentPmfmId(TuttiEntities.getList(bean.getEnvironmentPmfmId())); + result.setGearPmfmId(TuttiEntities.getList(bean.getGearPmfmId())); + result.setHydrologyPmfmId(TuttiEntities.getList(bean.getHydrologyPmfmId())); + Binder<SpeciesProtocol, SpeciesProtocol> speciesProtocolBinder = + BinderFactory.newBinder(SpeciesProtocol.class); + List<SpeciesProtocol> species = Lists.newArrayList(); + if (!bean.isSpeciesEmpty()) { + for (SpeciesProtocol speciesProtocol : bean.getSpecies()) { + SpeciesProtocol s = new SpeciesProtocol(); + speciesProtocolBinder.copy(speciesProtocol, s); + s.setId(UUID.randomUUID().toString()); + species.add(s); + } + } + result.setSpecies(species); + + String id = result.getId(); + + File file = getProtocolFile(id); + try { + TuttiProtocols.toFile(result, file); + return result; + } catch (IOException e) { + throw new RuntimeException( + "Could not write protocol " + id + " to file " + file, e); + } + } + + @Override + public TuttiProtocol saveProtocol(TuttiProtocol bean) { + String id = bean.getId(); + + File file = getProtocolFile(id); + try { + TuttiProtocols.toFile(bean, file); + return bean; + } catch (IOException e) { + throw new RuntimeException( + "Could not write protocol " + id + " to file " + file, e); + } + } + + @Override + public void deleteProtocol(String protocolId) { + File file = getProtocolFile(protocolId); + + try { + if (file.exists()) { + FileUtils.forceDelete(file); + } + } catch (IOException e) { + throw new RuntimeException( + "Could not delete protocol " + protocolId + " (file " + file + ")"); + } + } + + protected File getProtocolFile(String id) { + File protocolDirectory = config.getProtocolDirectory(); + File result = new File(protocolDirectory, id + "." + TUTTI_PROTOCOL_EXTENSION); + return result; + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,638 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import fr.ifremer.adagio.core.dao.referential.StatusDao; +import fr.ifremer.adagio.core.dao.referential.taxon.TaxonNameExtendDao; +import fr.ifremer.adagio.core.dao.referential.taxon.TaxonRefTaxVO; +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.entities.referential.AbstractTuttiReferentialEntity; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicType; +import fr.ifremer.tutti.persistence.entities.referential.Country; +import fr.ifremer.tutti.persistence.entities.referential.FishingOperationLocation; +import fr.ifremer.tutti.persistence.entities.referential.Gear; +import fr.ifremer.tutti.persistence.entities.referential.Person; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.persistence.entities.referential.Status; +import fr.ifremer.tutti.persistence.entities.referential.Vessel; +import fr.ifremer.tutti.persistence.entities.referential.Zone; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.Query; +import org.hibernate.type.DateType; +import org.hibernate.type.IntegerType; +import org.hibernate.type.StringType; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * Implementation of the {@link ReferentialPersistenceService} using a adagio + * data-source. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("referentialPersistenceService") +public class ReferentialPersistenceServiceImpl extends AbstractPersistenceService implements ReferentialPersistenceService { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ReferentialPersistenceServiceImpl.class); + + @Resource(name = "taxonNameDao") + protected TaxonNameExtendDao taxonNameDao; + + @Resource(name = "statusDao") + protected StatusDao statusDao; + + //------------------------------------------------------------------------// + //-- ReferentialPersistenceService implentation --// + //------------------------------------------------------------------------// + + @Override + public List<Zone> getAllProgramZone() { + Iterator<Object[]> list = queryListWithStatus( + "allProgramZones", + "locationClassificationId", IntegerType.INSTANCE, enumeration.LOCATION_CLASSIFICATION_ID_SECTOR, + "locationLevelId", IntegerType.INSTANCE, enumeration.LOCATION_LEVEL_ID_PROGRAM); + + List<Zone> result = Lists.newArrayList(); + while (list.hasNext()) { + Object[] source = list.next(); + Zone target = new Zone(); + target.setId(String.valueOf(source[0])); + target.setLabel((String) source[1]); + target.setName((String) source[2]); + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source[3], target); + result.add(target); + } + return result; + } + + @Override + public List<Country> getAllCountry() { + Iterator<Object[]> list = queryListWithStatus( + "allCountries", + "locationLevelId", IntegerType.INSTANCE, enumeration.LOCATION_LEVEL_ID_COUNTRY); + + List<Country> result = Lists.newArrayList(); + while (list.hasNext()) { + Object[] source = list.next(); + Country target = new Country(); + target.setId(String.valueOf(source[0])); + target.setLabel((String) source[1]); + target.setName((String) source[2]); + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source[3], target); + result.add(target); + } + return result; + } + + @Override + public List<FishingOperationLocation> getAllFishingOperationStrata(String zoneId) { + Preconditions.checkNotNull(zoneId); + List<FishingOperationLocation> result = getFishingOperationLocationsByParent( + enumeration.LOCATION_LEVEL_ID_STRATA, + Integer.valueOf(zoneId), + enumeration.LOCATION_LEVEL_ID_PROGRAM); + return result; + } + + @Override + public List<FishingOperationLocation> getAllFishingOperationSubStrata(String zoneId, + String strataId) { + + String parentId; + Integer parentLocationLevelId; + + if (strataId != null) { + + // use strata as parent + parentId = strataId; + parentLocationLevelId = enumeration.LOCATION_LEVEL_ID_STRATA; + + } else { + + // use zoneId as parent + parentId = zoneId; + parentLocationLevelId = enumeration.LOCATION_LEVEL_ID_PROGRAM; + } + + Preconditions.checkNotNull(parentId); + List<FishingOperationLocation> result = getFishingOperationLocationsByParent( + enumeration.LOCATION_LEVEL_ID_SUB_STRATA, + Integer.valueOf(parentId), + parentLocationLevelId); + return result; + } + + @Override + public List<FishingOperationLocation> getAllFishingOperationLocation(String zoneId, + String strataId, + String subStrataId) { + + String parentId; + Integer parentLocationLevelId; + + if (subStrataId != null) { + + // use substrata as parent + parentId = subStrataId; + parentLocationLevelId = enumeration.LOCATION_LEVEL_ID_SUB_STRATA; + + } else if (strataId != null) { + + // use strata as parent + parentId = strataId; + parentLocationLevelId = enumeration.LOCATION_LEVEL_ID_STRATA; + + } else { + + // use zoneId as parent + parentId = zoneId; + parentLocationLevelId = enumeration.LOCATION_LEVEL_ID_PROGRAM; + } + + Preconditions.checkNotNull(parentId); + List<FishingOperationLocation> result = getFishingOperationLocationsByParent( + enumeration.LOCATION_LEVEL_ID_LOCALITE, + Integer.valueOf(parentId), + parentLocationLevelId); + return result; + } + + @Override + public List<Vessel> getAllScientificVessel() { + + Iterator<Object[]> list = queryListWithStatus( + "allVessels", + "refDate", DateType.INSTANCE, new Date(), + "vesselTypeId", IntegerType.INSTANCE, enumeration.VESSEL_TYPE_ID_SCIENTIFIC); + + List<Vessel> result = Lists.newArrayList(); + while (list.hasNext()) { + Object[] source = list.next(); + Vessel target = loadVessel(source); + result.add(target); + } + return result; + } + + @Override + @Cacheable(value = "tuttiAllFishingVessel") + public List<Vessel> getAllFishingVessel() { + Iterator<Object[]> list = queryListWithStatus( + "allVessels", + "refDate", DateType.INSTANCE, new Date(), + "vesselTypeId", IntegerType.INSTANCE, enumeration.VESSEL_TYPE_ID_FISHING + ); + + List<Vessel> result = Lists.newArrayList(); + while (list.hasNext()) { + Object[] source = list.next(); + Vessel target = loadVessel(source); + result.add(target); + } + return result; + } + + // @Override + public List<Vessel> getAllFishingVessel2() { + Iterator<Object[]> list = queryListWithStatus( + "allSimpleVessels", + + "vesselTypeId", IntegerType.INSTANCE, enumeration.VESSEL_TYPE_ID_FISHING); + + Set<String> codes = Sets.newHashSet(); + List<Vessel> result = Lists.newArrayList(); + while (list.hasNext()) { + Object[] source = list.next(); + String vesselCode = (String) source[0]; + if (codes.add(vesselCode)) { + + if (log.isInfoEnabled()) { + log.info("VesselCode: " + vesselCode); + } + Vessel target = new Vessel(); + target.setId(vesselCode); + target.setName((String) source[1]); + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source[2], target); + result.add(target); + } + + +// Iterator<Object[]> source2 = queryList( +// "vessel2", +// "vesselCode", StringType.INSTANCE, vesselCode, +// "refDate", DateType.INSTANCE, new Date() +// ); +// +// if (source2.hasNext()) { +// Object[] next = source2.next(); +// +// target.setRegistrationCode((String) next[0]); +// target.setInternalRegistrationCode((String) next[1]); +// } + + } + return result; + } + + @Override + public Vessel getVessel(String vesselCode) { + if (log.isInfoEnabled()) { + log.info("get vessel: " + vesselCode); + } + // Warning : return a list because more than one line could be found, + // but 'order by' assume that the first one in the good row + Iterator<Object[]> source = queryListWithStatus( + "vessel", + "vesselCode", StringType.INSTANCE, vesselCode, + "refDate", DateType.INSTANCE, new Date() + ); + Vessel result; + if (source.hasNext()) + result = loadVessel(source.next()); + else + result = null; + return result; + } + + @Override + public List<Gear> getAllScientificGear() { + + Iterator<Object[]> sources = queryListWithStatus( + "allGears", + "gearClassificiationId", IntegerType.INSTANCE, enumeration.GEAR_CLASSIFICIATION_ID_SCIENTIFIC); + List<Gear> result = Lists.newArrayList(); + while (sources.hasNext()) { + Object[] source = sources.next(); + Gear target = loadGear(source); + result.add(target); + } + return result; + } + + @Override + public List<Gear> getAllFishingGear() { + Iterator<Object[]> sources = queryListWithStatus( + "allGears", + "gearClassificiationId", IntegerType.INSTANCE, enumeration.GEAR_CLASSIFICIATION_ID_FISHING); + List<Gear> result = Lists.newArrayList(); + while (sources.hasNext()) { + Object[] source = sources.next(); + Gear target = loadGear(source); + result.add(target); + } + return result; + } + + @Override + public List<Person> getAllPerson() { + Iterator<Object[]> list = queryListWithStatus( + "allPersons", + "observerProfilId", IntegerType.INSTANCE, enumeration.USER_PROFIL_ID_OBSERVER, + "projectMemberProfilId", IntegerType.INSTANCE, enumeration.USER_PROFIL_ID_PROJECT_MEMBER, + "userProfilId", IntegerType.INSTANCE, enumeration.USER_PROFIL_ID_USER); + + List<Person> result = Lists.newArrayList(); + while (list.hasNext()) { + Object[] source = list.next(); + Person target = loadPerson(source); + result.add(target); + } + return result; + } + + @Override + public Person getPerson(Integer personId) { + Object[] source = queryUnique( + "person", + "personId", IntegerType.INSTANCE, personId); + Person result = loadPerson(source); + return result; + } + + @Override + public Gear getGear(Integer gearId) { + Object[] source = queryUnique( + "gear", + "gearId", IntegerType.INSTANCE, gearId); + Gear result = loadGear(source); + return result; + } + + @Override + public boolean isSortedQualitativeValue(CaracteristicQualitativeValue value) { + return value != null && + enumeration.QUALITATIVE_VRAC_ID.toString().equals(value.getId()); + } + + @Override + public List<Species> getAllSpecies() { + + TaxonRefTaxVO[] sources = taxonNameDao.getAllTaxonRefTax(); + + List<Species> result = Lists.newArrayList(); + for (TaxonRefTaxVO source : sources) { + Species target = loadSpecies(source); + result.add(target); + } + return result; + } + + @Override + public Species getSpecies(String speciesId) { + TaxonRefTaxVO source = taxonNameDao.getTaxonRefTax( + Integer.valueOf(speciesId)); + + Species target = loadSpecies(source); + return target; + } + + @Override + public List<Caracteristic> getAllCaracteristic() { + Iterator<Object[]> sources = queryListWithStatus( + "allPmfm", + "unitIdNone", IntegerType.INSTANCE, enumeration.UNIT_ID_NONE); + List<Caracteristic> result = Lists.newArrayList(); + while (sources.hasNext()) { + Object[] source = sources.next(); + Integer pmfmId = (Integer) source[0]; + // Skip some protected PSFM + if (!isProtectedCaracteristic(pmfmId)) { + Caracteristic target = loadCaracteristic(source); + result.add(target); + } + } + return result; + } + + @Override + public Caracteristic getSizeCategoryCaracteristic() { + Integer pmfmId = enumeration.PMFM_ID_SIZE_CATEGORY; + Caracteristic result = getCaracteristic(pmfmId); + return result; + } + + @Override + public Caracteristic getSexCaracteristic() { + Integer pmfmId = enumeration.PMFM_ID_SEX; + Caracteristic result = getCaracteristic(pmfmId); + return result; + } + + @Override + public Caracteristic getSortedUnsortedCaracteristic() { + Integer pmfmId = enumeration.PMFM_ID_SORTED_UNSORTED; + Caracteristic result = getCaracteristic(pmfmId); + + // Search the qualitative value to skip + for (Iterator iterator = result.getQualitativeValue().iterator(); iterator.hasNext(); ) { + CaracteristicQualitativeValue qv = (CaracteristicQualitativeValue) iterator.next(); + if (qv != null && qv.getId() != null + && enumeration.QUALITATIVE_UNSORTED_ID.equals(Integer.valueOf(qv.getId()))) { + result.removeQualitativeValue(qv); + break; + } + } + return result; + } + + @Override + public Caracteristic getMaturityCaracteristic() { + Integer pmfmId = enumeration.PMFM_ID_MATURITY; + Caracteristic result = getCaracteristic(pmfmId); + return result; + } + + @Override + public Caracteristic getMacroWasteCategoryCaracteristic() { + Integer pmfmId = enumeration.PMFM_ID_MARINE_LITTER_TYPE; + Caracteristic result = getCaracteristic(pmfmId); + return result; + } + + @Override + public Caracteristic getMacroWasteSizeCategoryCaracteristic() { + Integer pmfmId = enumeration.PMFM_ID_MARINE_LITTER_SIZE_CATEGORY; + Caracteristic result = getCaracteristic(pmfmId); + return result; + } + + @Override + public Caracteristic getCaracteristic(Integer pmfmId) { + Object[] source = queryUniqueWithStatus("pmfmById", + "pmfmId", IntegerType.INSTANCE, pmfmId, + "unitIdNone", IntegerType.INSTANCE, enumeration.UNIT_ID_NONE); + Caracteristic target = loadCaracteristic(source); + return target; + } + + //------------------------------------------------------------------------// + //-- Internal methods --// + //------------------------------------------------------------------------// + + protected List<FishingOperationLocation> getFishingOperationLocations(Integer locationLevelId) { + Iterator<Object[]> sources = queryListWithStatus( + "allFishingOperationLocation", + "locationClassificationId", IntegerType.INSTANCE, enumeration.LOCATION_CLASSIFICATION_ID_SECTOR, + "locationLevelId", IntegerType.INSTANCE, locationLevelId + ); + List<FishingOperationLocation> result = Lists.newArrayList(); + while (sources.hasNext()) { + Object[] source = sources.next(); + FishingOperationLocation target = new FishingOperationLocation(); + target.setId(String.valueOf(source[0])); + target.setLabel((String) source[1]); + target.setName((String) source[2]); +// target.setDescription((String)source[3]); + target.setLocationLevel((Integer) source[3]); + + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source[4], target); + result.add(target); + } + return result; + } + + protected List<FishingOperationLocation> getFishingOperationLocationsByParent(Integer locationLevelId, Integer parentId, Integer parentLocationLevelId) { + Iterator<Object[]> sources = queryListWithStatus( + "allFishingOperationLocationByParent", + "parentId", IntegerType.INSTANCE, parentId, + "parentLocationLevelId", IntegerType.INSTANCE, parentLocationLevelId, + "locationClassificationId", IntegerType.INSTANCE, enumeration.LOCATION_CLASSIFICATION_ID_SECTOR, + "locationLevelId", IntegerType.INSTANCE, locationLevelId + ); + List<FishingOperationLocation> result = Lists.newArrayList(); + while (sources.hasNext()) { + Object[] source = sources.next(); + FishingOperationLocation target = new FishingOperationLocation(); + target.setId(String.valueOf(source[0])); + target.setLabel((String) source[1]); + target.setName((String) source[2]); +// target.setDescription((String)source[3]); + target.setLocationLevel((Integer) source[3]); + + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source[4], target); + result.add(target); + } + return result; + } + + protected Caracteristic loadCaracteristic(Object[] source) { + + Integer pmfmId = (Integer) source[0]; + + Caracteristic result = new Caracteristic(); + result.setId(pmfmId.toString()); + result.setParameterName((String) source[1]); + result.setMatrixName((String) source[2]); + result.setFractionName((String) source[3]); + result.setMethodName((String) source[4]); + CaracteristicType type = TuttiEntities.getType((Boolean) source[5], + (Boolean) source[6]); + result.setCaracteristicType(type); + result.setSignifFiguresNumber((Integer) source[7]); + result.setMaximumNumberDecimals((Integer) source[8]); + result.setPrecision((Float) source[9]); + result.setUnit((String) source[10]); + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source[11], result); + + if (TuttiEntities.isQualitativeCaracteristic(result)) { + + // load qualitative values + + Iterator<Object[]> sources = queryListWithStatus( + "pmfmQualitativeValues", + "pmfmId", IntegerType.INSTANCE, pmfmId); + + List<CaracteristicQualitativeValue> values = Lists.newArrayList(); + while (sources.hasNext()) { + Object[] source2 = sources.next(); + CaracteristicQualitativeValue target2 = new CaracteristicQualitativeValue(); + target2.setId(String.valueOf(source2[0])); + target2.setName(String.valueOf(source2[1])); + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source2[2], target2); + values.add(target2); + } + result.setQualitativeValue(values); + } + return result; + } + + protected Species loadSpecies(TaxonRefTaxVO source) { + Species target = new Species(); + target.setId(String.valueOf(source.getReferenceTaxonId())); + target.setName(source.getName()); + target.setCodeMemo(source.getRefTaxCode()); + fr.ifremer.adagio.core.dao.referential.Status status = statusDao.load(source.getStatus().getValue()); + setStatus(status, target); + return target; + } + + protected Vessel loadVessel(Object[] source) { + Vessel target = new Vessel(); + target.setId((String) source[0]); + target.setRegistrationCode((String) source[1]); + target.setInternalRegistrationCode((String) source[2]); + target.setName((String) source[3]); + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source[4], target); + return target; + } + + protected Person loadPerson(Object[] source) { + Person target = new Person(); + target.setId(String.valueOf(source[0])); + target.setFirstName((String) source[1]); + target.setLastName((String) source[2]); + target.setDepartment((String) source[3]); + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source[4], target); + return target; + } + + protected Gear loadGear(Object[] source) { + Gear result = new Gear(); + result.setId(String.valueOf(source[0])); + result.setLabel((String) source[1]); + result.setName((String) source[2]); + setStatus((fr.ifremer.adagio.core.dao.referential.Status) source[3], result); + return result; + } + + protected Iterator<Object[]> queryListWithStatus(String queryName, + Object... params) { + Query query = createQuery(queryName, params); + query.setString("statusValidCode", enumeration.STATUS_VALID_CODE); + query.setString("statusTemporaryCode", enumeration.STATUS_TEMPORARY_CODE); + + Iterator result = query.iterate(); + return result; + } + + protected Object[] queryUniqueWithStatus(String queryName, Object... params) { + + Query query = createQuery(queryName, params); + query.setString("statusValidCode", enumeration.STATUS_VALID_CODE); + query.setString("statusTemporaryCode", enumeration.STATUS_TEMPORARY_CODE); + + Object result = query.uniqueResult(); + return (Object[]) result; + } + + protected <E extends AbstractTuttiReferentialEntity> void setStatus(fr.ifremer.adagio.core.dao.referential.Status status, E entity) { + Status newStatus = new Status(); + newStatus.setId(status.getCode()); + newStatus.setName(status.getName()); + entity.setStatus(newStatus); + } + + /** + * Return true if the pmfm should NOT be used for caracteristics lists + * (i.e. because used somewhere when storing some properties into the database) + * + * @param pmfmId + * @return + */ + protected boolean isProtectedCaracteristic(Integer pmfmId) { + return pmfmId.equals(enumeration.PMFM_ID_MULTIRIG_AGGREGATION) + || pmfmId.equals(enumeration.PMFM_ID_MULTIRIG_NUMBER) + || pmfmId.equals(enumeration.PMFM_ID_STATION_NUMBER) + || pmfmId.equals(enumeration.PMFM_ID_RECTILINEAR_OPERATION) + || pmfmId.equals(enumeration.PMFM_ID_HAUL_VALID) + || pmfmId.equals(enumeration.PMFM_ID_TRAWL_DISTANCE); + } + +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,566 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.base.Preconditions; +import com.google.common.collect.Lists; +import fr.ifremer.adagio.core.dao.data.batch.CatchBatchDao; +import fr.ifremer.adagio.core.dao.data.batch.CatchBatchImpl; +import fr.ifremer.adagio.core.dao.data.batch.SortingBatch; +import fr.ifremer.adagio.core.dao.data.batch.SortingBatchDao; +import fr.ifremer.adagio.core.dao.data.batch.SortingBatchImpl; +import fr.ifremer.adagio.core.dao.data.batch.denormalized.DenormalizedBatchDao; +import fr.ifremer.adagio.core.dao.data.measure.QuantificationMeasurement; +import fr.ifremer.adagio.core.dao.data.measure.SortingMeasurement; +import fr.ifremer.adagio.core.dao.referential.QualityFlagImpl; +import fr.ifremer.adagio.core.dao.referential.taxon.ReferenceTaxon; +import fr.ifremer.adagio.core.dao.referential.taxon.ReferenceTaxonImpl; +import fr.ifremer.tutti.persistence.entities.data.SampleCategoryEnum; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicType; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.persistence.service.measure.MeasurementPersistenceHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.FlushMode; +import org.hibernate.type.IntegerType; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.Serializable; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Service("speciesBatchPersistenceService") +public class SpeciesBatchPersistenceServiceImpl extends + AbstractPersistenceService implements SpeciesBatchPersistenceService { + + /** Logger. */ + private static final Log log = LogFactory + .getLog(SpeciesBatchPersistenceServiceImpl.class); + + @Resource(name = "referentialPersistenceService") + protected ReferentialPersistenceService referentialService; + + @Resource(name = "denormalizedBatchDao") + protected DenormalizedBatchDao denormalizedBatchDao; + + @Resource(name = "sortingBatchDao") + protected SortingBatchDao sortingBatchDao; + + @Resource(name = "catchBatchDao") + protected CatchBatchDao catchBatchDao; + + @Resource(name = "measurementPersistenceHelper") + protected MeasurementPersistenceHelper measurementHelper; + + @Override + public List<SpeciesBatch> getAllRootSpeciesBatch(String fishingOperationId) { + Iterator<Object[]> list = queryList("allRootSpeciesBatch", + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(fishingOperationId), + "qualitativeIdSortingType", IntegerType.INSTANCE, enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); + + List<SpeciesBatch> result = new ArrayList<SpeciesBatch>(); + while (list.hasNext()) { + Object[] source = list.next(); + SpeciesBatch speciesBatch = loadSpeciesBatch(source, true); + result.add(speciesBatch); + } + + return result; + } + + @Override + public List<SpeciesBatch> getAllSpeciesBatch(String fishingOperationId) { + Iterator<Object[]> list = queryList("allSpeciesBatch", + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(fishingOperationId)); + + List<SpeciesBatch> result = new ArrayList<SpeciesBatch>(); + List<SpeciesBatch> rootBatchs = new ArrayList<SpeciesBatch>(); + + Map<String, SpeciesBatch> batchMapById = new HashMap<String, SpeciesBatch>(); + Map<String, String> parentBatchMapById = new HashMap<String, String>(); + while (list.hasNext()) { + Object[] source = list.next(); + SpeciesBatch speciesBatch = loadSpeciesBatch(source, false); + batchMapById.put(speciesBatch.getId(), speciesBatch); + + Integer parentbatchId = (Integer) source[11]; + if (parentbatchId != null) { + parentBatchMapById.put(speciesBatch.getId(), parentbatchId.toString()); + } + } + + for (Iterator iterator = batchMapById.values().iterator(); iterator.hasNext(); ) { + SpeciesBatch speciesBatch = (SpeciesBatch) iterator.next(); + + // Retrieve the parent SpeciesBatch + String parentbatchId = parentBatchMapById.get(speciesBatch.getId()); + if (parentbatchId != null) { + SpeciesBatch parentSpeciesBatch = batchMapById.get(parentbatchId); + + // If found, link the batch with its parent : + if (parentSpeciesBatch != null) { + speciesBatch.setParentBatch(parentSpeciesBatch); + if (parentSpeciesBatch.getChildBatchs() == null) { + parentSpeciesBatch.setChildBatchs(Lists.newArrayList(speciesBatch)); + } else { + parentSpeciesBatch.addChildBatchs(speciesBatch); + } + } + + // If no parent found = batch is a child of the catch batch + else { + rootBatchs.add(speciesBatch); + } + } + } + + // Apply inheritance, starting with the catch batch children + applyInheritedProperties(rootBatchs, null, null, result); + + return result; + } + + @Override + public SpeciesBatch getSpeciesBatch(String id) { + Object[] source = queryUnique("speciesBatch", + "batchId", IntegerType.INSTANCE, Integer.valueOf(id)); + + if (source == null) { + throw new DataRetrievalFailureException("Could not retrieve speciesBatch with id=" + id); + } + + SpeciesBatch result = loadSpeciesBatch(source, true); + return result; + } + + @Override + public SpeciesBatch createSpeciesBatch(SpeciesBatch bean, + String parentBatchId) { + Preconditions.checkNotNull(bean); + Preconditions.checkArgument(bean.getId() == null); + Preconditions.checkNotNull(bean.getSpecies()); + Preconditions.checkNotNull(bean.getSpecies().getId()); + Preconditions.checkNotNull(bean.getFishingOperation()); + Preconditions.checkNotNull(bean.getFishingOperation().getId()); + // TODO BLA uncomment this after v1.0 : + // Preconditions.checkNotNull(bean.getCatchBatch()); + + SortingBatch batch = SortingBatch.Factory.newInstance(); + beanToEntity(bean, batch, parentBatchId, true); + batch = sortingBatchDao.create(batch); + + bean.setId(String.valueOf(batch.getId())); + return bean; + } + + @Override + public SpeciesBatch saveSpeciesBatch(SpeciesBatch bean) { + Preconditions.checkNotNull(bean); + Preconditions.checkNotNull(bean.getId()); + + getCurrentSession().clear(); + getCurrentSession().enableFetchProfile("batch-with-measurements"); + getCurrentSession().setFlushMode(FlushMode.COMMIT); + SortingBatch batch = sortingBatchDao.load(Integer.valueOf(bean.getId())); + String parentBatchId = null; + if (bean.getParentBatch() != null) { + parentBatchId = bean.getParentBatch().getId(); + } + beanToEntity(bean, batch, parentBatchId, true); + sortingBatchDao.update(batch); + getCurrentSession().flush(); + return bean; + } + + @Override + public void deleteSpeciesBatch(String id) { + Preconditions.checkNotNull(id); + + getCurrentSession().setFlushMode(FlushMode.COMMIT); + + List<SortingBatch> allChildrenBatchs = Lists.newArrayList(); + removeAllChildrenBatchs(Integer.valueOf(id), allChildrenBatchs); + + getCurrentSession().flush(); + } + + @Override + public void deleteSpeciesSubBatch(String id) { + deleteSpeciesBatch(id); + } + + @Override + public List<SpeciesBatchFrequency> getAllSpeciesBatchFrequency( + String speciesBatchId) { + List<SpeciesBatchFrequency> results = Lists.newArrayList(); + // TODO + return results; + } + + @Override + public List<SpeciesBatchFrequency> saveSpeciesBatchFrequency( + String speciesBatchId, List<SpeciesBatchFrequency> frequencies) { + return frequencies; + } + + // ------------------------------------------------------------------------// + // -- Internal methods --// + // ------------------------------------------------------------------------// + protected void beanToEntity(SpeciesBatch source, SortingBatch target, String parentBatchId, boolean copyIfNull) { + Preconditions.checkNotNull(source.getFishingOperation()); + Preconditions.checkNotNull(source.getFishingOperation().getId()); + + // Retrieve recorder department + // TODO BLA : prendre le service du 1er saisisseur ? + Integer recorderDepartmentId = enumeration.DEPARTMENT_ID_UNKNOWN_RECORDER_DEPARTMENT; + + + // Create lists to store all updates, then remove not updated items + Set<QuantificationMeasurement> notChangedQuantificationMeasurements = new HashSet<QuantificationMeasurement>(); + if (target.getQuantificationMeasurements() != null) { + notChangedQuantificationMeasurements.addAll(target.getQuantificationMeasurements()); + } + Set<SortingMeasurement> notChangedSortingMeasurements = new HashSet<SortingMeasurement>(); + if (target.getSortingMeasurements() != null) { + notChangedSortingMeasurements.addAll(target.getSortingMeasurements()); + } + + // If parent and root need to be set + if (target.getId() == null + || target.getRootBatch() == null + || (target.getParentBatch() != null && !target.getParentBatch().getId().equals(parentBatchId))) { + setBatchParents(source, target, parentBatchId, notChangedSortingMeasurements); + } + + // RankOrder + if (target.getRankOrder() == null) { + short rankOrder = (short) 1; + if (source.getParentBatch() != null && source.getParentBatch().getChildBatchs() != null) { + // TODO BL : vérifier cela (est-ce que l'item est ajouté à son père AVANT d'être passé au service ?) + rankOrder = (short) source.getParentBatch().getChildBatchs().size(); + } + target.setRankOrder(rankOrder); + } + + // Weight or SampleCategoryWeight + if (copyIfNull && source.getWeight() == null) { + // Nothing to do : will be removed later, using notChangedSortingMeasurements + } else if (source.getSampleCategoryWeight() != null) { + QuantificationMeasurement quantificationMeasurement = measurementHelper.setQuantificationMeasurement(target, enumeration.PMFM_ID_WEIGHT_MEASURED, recorderDepartmentId, source.getSampleCategoryWeight(), true); + notChangedQuantificationMeasurements.remove(quantificationMeasurement); + } else if (source.getWeight() != null) { + QuantificationMeasurement quantificationMeasurement = measurementHelper.setQuantificationMeasurement(target, enumeration.PMFM_ID_WEIGHT_MEASURED, recorderDepartmentId, source.getWeight(), true); + notChangedQuantificationMeasurements.remove(quantificationMeasurement); + } + + // Sampling Ratio + if (copyIfNull && (source.getSampleCategoryWeight() == null || source.getWeight() == null)) { + target.setSamplingRatio(null); + target.setSamplingRatioText(null); + } else if (source.getSampleCategoryWeight() != null && source.getWeight() != null) { + String samplingRatioText = source.getSampleCategoryWeight() + "/" + source.getWeight(); + samplingRatioText = samplingRatioText.replaceAll(",", "."); + target.setSamplingRatioText(samplingRatioText); + target.setSamplingRatio(source.getSampleCategoryWeight().floatValue() / source.getWeight().floatValue()); + } + + // Sorting measurement + if (copyIfNull && (source.getSampleCategoryType() == null || source.getSampleCategoryValue() == null)) { + // Nothing to do : will be removed later, using notChangedSortingMeasurements + } else if (source.getSampleCategoryType() != null && source.getSampleCategoryValue() != null) { + Integer pmfmId = measurementHelper.sampleCategory2PmfmId(source.getSampleCategoryType()); + // Do not store sorting measurement if pmfm = SORTED (already store in an ancestor batch) + if (!pmfmId.equals(enumeration.PMFM_ID_SORTED_UNSORTED)) { + SortingMeasurement sortingMeasurement = measurementHelper.setSortingMeasurement(target, recorderDepartmentId, source.getSampleCategoryType(), source.getSampleCategoryValue()); + notChangedSortingMeasurements.remove(sortingMeasurement); + } + } + + // Individual count + if (copyIfNull && source.getNumber() == null) { + target.setIndividualCount(null); + } else if (source.getNumber() != null) { + target.setIndividualCount(source.getNumber()); + } + + // Species + if (copyIfNull && (source.getSpecies() == null || parentBatchId != null)) { + target.setReferenceTaxon(null); + } else if (source.getSpecies() != null && parentBatchId == null) { + ReferenceTaxon referenceTaxon = load(ReferenceTaxonImpl.class, Integer.valueOf(source.getSpecies().getId())); + target.setReferenceTaxon(referenceTaxon); + } + + // QualityFlag + if (source.isSpeciesToConfirm()) { + target.setQualityFlag(load(QualityFlagImpl.class, enumeration.QUALITY_FLAG_CODE_DOUBTFUL)); + } else { + target.setQualityFlag(load(QualityFlagImpl.class, enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + } + + // Comments + if (copyIfNull && source.getComment() == null) { + target.setComments(null); + } else if (source.getComment() != null) { + target.setComments(source.getComment()); + } + + // Removed not changed measurements (in sorting and quantification measurement lists) + if (target.getQuantificationMeasurements() != null && notChangedQuantificationMeasurements.size() > 0) { + for (QuantificationMeasurement qm : notChangedQuantificationMeasurements) { + target.getQuantificationMeasurements().remove(qm); + } + } + if (target.getSortingMeasurements() != null && notChangedSortingMeasurements.size() > 0) { + for (SortingMeasurement sm : notChangedSortingMeasurements) { + target.getSortingMeasurements().remove(sm); + } + } + } + + public void setBatchParents(SpeciesBatch source, SortingBatch target, String parentBatchIdStr, + Set<SortingMeasurement> notChangedSortingMeasurements) { + + Preconditions.checkNotNull(target); + Preconditions.checkNotNull(source.getFishingOperation()); + Preconditions.checkNotNull(source.getFishingOperation().getId()); + + // Retrieve parent and root batch + if (parentBatchIdStr == null) { + // Retrieve category type + Integer pmfmId = measurementHelper.sampleCategory2PmfmId(source.getSampleCategoryType()); + if (pmfmId == null || !pmfmId.equals(enumeration.PMFM_ID_SORTED_UNSORTED)) { + throw new DataIntegrityViolationException(MessageFormat.format("A species batch with no parent should have a sampleCategoryType {0} (PMFM.ID={1})", + new Object[]{SampleCategoryEnum.sortedUnsorted.name(), enumeration.PMFM_ID_SORTED_UNSORTED})); + } + Integer qualitativeValueId = convertSampleCategoryValueIntoQualitativeId(source.getSampleCategoryValue()); + + Object[] cols = queryUnique("parentBatch", + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(source.getFishingOperation().getId()), + "pmfmIdSorted", IntegerType.INSTANCE, enumeration.PMFM_ID_SORTED_UNSORTED, + "qualitativeIdSorted", IntegerType.INSTANCE, qualitativeValueId, + "pmfmIdSortingType", IntegerType.INSTANCE, enumeration.PMFM_ID_SORTING_TYPE, + "qualitativeIdSortingType", IntegerType.INSTANCE, enumeration.QUALITATIVE_ID_SORTING_TYPE_SPECIES); + + if (cols == null) { + throw new DataIntegrityViolationException("Catch batchs not presents, or invalid batch tree structure. Please make sure CatchBatch has been saved before to create a SpeciesBatch."); + } + // Parent Batch + Integer parentBatchId = (Integer) cols[0]; + SortingBatch parentBatch = load(SortingBatchImpl.class, parentBatchId); + target.setParentBatch(parentBatch); + + // Root Batch + Integer rootBatchId = (Integer) cols[1]; + target.setRootBatch(load(CatchBatchImpl.class, rootBatchId)); + } + + // Load existing parent and root + else { + SortingBatch parentBatch = load(SortingBatchImpl.class, Integer.valueOf(parentBatchIdStr)); + target.setParentBatch(parentBatch); + target.setRootBatch(parentBatch.getRootBatch()); + } + } + + protected SpeciesBatch loadSpeciesBatch(Object[] source, boolean sourceHasPmfmGrandParent) { + int colIndex = 0; + + SpeciesBatch result = new SpeciesBatch(); + result.setId(source[colIndex++].toString()); + + // Individual count + result.setNumber((Integer) source[colIndex++]); + + // Weight & sampleCategory Weight + Float sampleWeight = (Float) source[colIndex++]; + Float samplingRatio = (Float) source[colIndex++]; + String samplingRatioText = (String) source[colIndex++]; + if (samplingRatio == null) { + result.setWeight(sampleWeight); + } else if (sampleWeight != null) { + String startStr = sampleWeight.toString().replace(',', '.') + "/"; + if (samplingRatioText != null && samplingRatioText.startsWith(startStr)) { + String weightStr = samplingRatioText.substring(startStr.length()); + if (weightStr != null && !weightStr.isEmpty()) { + result.setSampleCategoryWeight(sampleWeight); + result.setWeight(Float.parseFloat(weightStr)); + } + } + } + + // Comments + result.setComment((String) source[colIndex++]); + + // Sample category type + Integer pmfmId = (Integer) source[colIndex++]; + + // Sample category value + Integer qvValue = (Integer) source[colIndex++]; + Float numValue = (Float) source[colIndex++]; + String alphaValue = (String) source[colIndex++]; + + // Species + Integer referenceTaxonId = (Integer) source[colIndex++]; + if (referenceTaxonId != null) { + // TODO : add cache on getSpecies + Species species = referentialService.getSpecies(referenceTaxonId.toString()); + result.setSpecies(species); + } + + if (sourceHasPmfmGrandParent && colIndex == source.length - 2) { + Integer pmfmIdGrandFather = (Integer) source[colIndex++]; + Integer qualitativeIdGrandFather = (Integer) source[colIndex++]; + + if (pmfmId != null) { + setSampleCategoryQualitative(result, pmfmId, numValue, alphaValue, qvValue); + } + // When no sorting measurement found, retrieve the sorted/unsorted from an ancestor batch + else { + if (referenceTaxonId != null + && enumeration.PMFM_ID_SORTED_UNSORTED.equals(pmfmIdGrandFather) + && qualitativeIdGrandFather != null) { + setSampleCategoryQualitative(result, pmfmIdGrandFather, null, null, qualitativeIdGrandFather); + } else { + // TODO TC : manage this exception in the UI => 'format des captures incompatibles avec tutti...' + // TODO TC : add a throws 'InvalidBatchTreeException' in the interface method ? + throw new DataRetrievalFailureException("Invalid batch tree found in database (no sample category Vrac/HorsVrac found in parents) : could not be load batch with id=" + result.getId()); + } + } + } + + return result; + } + + protected void applyInheritedProperties(List<SpeciesBatch> speciesBatchs, Serializable inheritedSampleCategoryValue, Species inheritedSpecies, List<SpeciesBatch> result) { + if (speciesBatchs == null || speciesBatchs.size() == 0) { + return; + } + boolean hasAppliedCategoryValue = false; + for (Iterator iterator = speciesBatchs.iterator(); iterator.hasNext(); ) { + SpeciesBatch speciesBatch = (SpeciesBatch) iterator.next(); + + if (speciesBatch.getSpecies() != null && speciesBatch.getSampleCategoryType() == null) { + speciesBatch.setSampleCategoryType(SampleCategoryEnum.sortedUnsorted); + speciesBatch.setSampleCategoryValue(inheritedSampleCategoryValue); + hasAppliedCategoryValue = true; + + // Remove the link to the parent (not need after inheritance) + speciesBatch.setParentBatch(null); + } else if (speciesBatch.getSpecies() == null && inheritedSpecies != null) { + speciesBatch.setSpecies(inheritedSpecies); + } + + // Store into result list only if species has been set (ignore upper batch) + if (speciesBatch.getSpecies() != null) { + result.add(speciesBatch); + } + + // Recursive call : propage species but not category if already applied + applyInheritedProperties(speciesBatch.getChildBatchs(), + (hasAppliedCategoryValue ? null : inheritedSampleCategoryValue), + speciesBatch.getSpecies(), result); + } + } + + Integer convertSampleCategoryValueIntoQualitativeId(Serializable value) { + if (value == null) return null; + Integer qualitativeValueId = null; + if (value instanceof CaracteristicQualitativeValue) { + CaracteristicQualitativeValue cqValue = (CaracteristicQualitativeValue) value; + qualitativeValueId = Integer.valueOf(cqValue.getId()); + } else if (value instanceof String) { + qualitativeValueId = Integer.valueOf((String) value); + } + return qualitativeValueId; + } + + protected void setSampleCategoryQualitative(SpeciesBatch target, Integer pmfmId, Float numericalvalue, String alphanumericalValue, Integer qualitativeValueId) { + if (pmfmId == null) { + return; + } + SampleCategoryEnum sampleCategory = measurementHelper.pmfmId2SampleCategory(pmfmId); + target.setSampleCategoryType(sampleCategory); + if (numericalvalue != null) { + target.setSampleCategoryValue(numericalvalue); + return; + } + if (alphanumericalValue != null) { + target.setSampleCategoryValue(alphanumericalValue); + return; + } + + Caracteristic caracteristic = referentialService.getCaracteristic(pmfmId); + if (caracteristic == null || caracteristic.getCaracteristicType() != CaracteristicType.QUALITATIVE) { + return; + } + CaracteristicQualitativeValue value = null; + for (Iterator iterator = caracteristic.getQualitativeValue().iterator(); iterator + .hasNext(); ) { + CaracteristicQualitativeValue qv = (CaracteristicQualitativeValue) iterator.next(); + if (qualitativeValueId.intValue() == Integer.parseInt(qv.getId())) { + value = qv; + break; + } + } + target.setSampleCategoryValue(value); + } + + protected void removeAllChildrenBatchs(Integer batchId, List<SortingBatch> result) { + Iterator<Integer> list = queryListTyped("speciesBatchChildren", + "batchId", IntegerType.INSTANCE, batchId); + + // First, add childrens + while (list.hasNext()) { + + removeAllChildrenBatchs(list.next(), result); + } + + // Then add the given batch (after children, because of order need in "delete") + SortingBatch batch = sortingBatchDao.load(batchId); + //SortingBatch batch = (SortingBatch)getCurrentSession().get(SortingBatchImpl.class, batchId); + batch.getSortingMeasurements().clear(); + batch.getQuantificationMeasurements().clear(); + sortingBatchDao.remove(batch); + } + +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFile.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFile.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFile.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFile.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,204 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.base.Preconditions; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; + +/** + * Contains all constants usable via the enumeration file. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class TuttiEnumerationFile { + + @Value("${GearClassificationId.SCIENTIFIC_CRUISE}") + public final Integer GEAR_CLASSIFICIATION_ID_SCIENTIFIC = null; + + @Value("${GearClassificationId.FAO}") + public final Integer GEAR_CLASSIFICIATION_ID_FISHING = null; + + @Value("${LocationClassificationId.SECTOR}") + public final Integer LOCATION_CLASSIFICATION_ID_SECTOR = null; + + @Value("${LocationLevelId.PAYS_ISO3}") + public final Integer LOCATION_LEVEL_ID_COUNTRY = null; + + @Value("${LocationLevelId.LOCALITE}") + public final Integer LOCATION_LEVEL_ID_LOCALITE = null; + + @Value("${LocationLevelId.PROGRAM}") + public final Integer LOCATION_LEVEL_ID_PROGRAM = null; + + @Value("${LocationLevelId.STRATA}") + public final Integer LOCATION_LEVEL_ID_STRATA = null; + + @Value("${LocationLevelId.SUB_STRATA}") + public final Integer LOCATION_LEVEL_ID_SUB_STRATA = null; + + @Value("${ParameterCode.AGE}") + public final String PARAMETER_CODE_AGE = null; + + @Value("${ParameterCode.WEIGHT}") + public final String PARAMETER_CODE_WEIGHT = null; + + @Value("${PmfmId.SIZE_CATEGORY}") + public final Integer PMFM_ID_SIZE_CATEGORY = null; + + @Value("${PmfmId.SEX}") + public final Integer PMFM_ID_SEX = null; + + @Value("${PmfmId.SORTED_UNSORTED}") + public final Integer PMFM_ID_SORTED_UNSORTED = null; + + @Value("${PmfmId.MATURITY}") + public final Integer PMFM_ID_MATURITY = null; + + @Value("${PmfmId.MARINE_LITTER_TYPE}") + public final Integer PMFM_ID_MARINE_LITTER_TYPE = null; + + @Value("${PmfmId.MARINE_LITTER_SIZE_CATEGORY}") + public final Integer PMFM_ID_MARINE_LITTER_SIZE_CATEGORY = null; + + @Value("${PmfmId.SCIENTIFIC_CRUISE_SORTING_TYPE}") + public final Integer PMFM_ID_SORTING_TYPE = null; + + @Value("${UnitId.NONE}") + public final Integer UNIT_ID_NONE = null; + + @Value("${UserProfilId.OBSERVER}") + public final Integer USER_PROFIL_ID_OBSERVER = null; + + @Value("${UserProfilId.PROJECT_MEMBER}") + public final Integer USER_PROFIL_ID_PROJECT_MEMBER = null; + + @Value("${UserProfilId.USER}") + public final Integer USER_PROFIL_ID_USER = null; + + @Value("${VesselTypeId.SCIENTIFIC_RESEARCH_VESSEL}") + public final Integer VESSEL_TYPE_ID_SCIENTIFIC = null; + + @Value("${VesselTypeId.FISHING_VESSEL}") + public final Integer VESSEL_TYPE_ID_FISHING = null; + + @Value("${LocationLevelId.RECTANGLE_STATISTIQUE_MED}") + public final Integer RECTANGLE_STATISTIQUE_MED = null; + + @Value("${LocationLevelId.RECTANGLE_STATISTIQUE}") + public final Integer RECTANGLE_STATISTIQUE = null; + + @Value("${QualitativeValueId.SORTED_VRAC}") + public final Integer QUALITATIVE_VRAC_ID = null; + + @Value("${QualitativeValueId.SORTED_HORS_VRAC}") + public final Integer QUALITATIVE_HORS_VRAC_ID = null; + + @Value("${QualitativeValueId.UNSORTED}") + public final Integer QUALITATIVE_UNSORTED_ID = null; + + @Value("${QualitativeValueId.SORTING_TYPE_SPECIES}") + public final Integer QUALITATIVE_ID_SORTING_TYPE_SPECIES = null; + + @Value("${StatusCode.ENABLE}") + public final String STATUS_VALID_CODE = null; + + @Value("${StatusCode.TEMPORARY}") + public final String STATUS_TEMPORARY_CODE = null; + + @Value("${PersonId.UNKNOWN_RECORDER_PERSON}") + public final Integer PERSON_ID_UNKNOWN_RECORDER_PERSON = null; + + @Value("${QualityFlagCode.NOTQUALIFIED}") + public final String QUALITY_FLAG_CODE_NOT_QUALIFIED = null; + + @Value("${QualityFlagCode.DOUBTFUL}") + public final String QUALITY_FLAG_CODE_DOUBTFUL = null; + + @Value("${PmfmId.STATION_NUMBER}") + public final Integer PMFM_ID_STATION_NUMBER = null; + + @Value("${PmfmId.TRAWL_DISTANCE}") + public final Integer PMFM_ID_TRAWL_DISTANCE = null; + + @Value("${PmfmId.RECTILINEAR_OPERATION}") + public final Integer PMFM_ID_RECTILINEAR_OPERATION = null; + + @Value("${QualitativeValueId.RECTILINEAR_OPERATION_YES}") + public final Integer QUALITATIVE_RECTILINEAR_OPERATION_YES = null; + + @Value("${QualitativeValueId.RECTILINEAR_OPERATION_NO}") + public final Integer QUALITATIVE_RECTILINEAR_OPERATION_NO = null; + + @Value("${PmfmId.HAUL_VALID}") + public final Integer PMFM_ID_HAUL_VALID = null; + + @Value("${QualitativeValueId.HAUL_VALID_YES}") + public final Integer QUALITATIVE_HAUL_VALID_YES = null; + + @Value("${QualitativeValueId.HAUL_VALID_NO}") + public final Integer QUALITATIVE_HAUL_VALID_NO = null; + + @Value("${PmfmId.MULTIRIG_NUMBER}") + public final Integer PMFM_ID_MULTIRIG_NUMBER = null; + + @Value("${PmfmId.MULTIRIG_AGGREGATION}") + public final Integer PMFM_ID_MULTIRIG_AGGREGATION = null; + + @Value("${PmfmId.WEIGHT_MEASURED}") + public final Integer PMFM_ID_WEIGHT_MEASURED = null; + + @Value("${DepartmentId.UNKNOWN_RECORDER_DEPARTMENT}") + public final Integer DEPARTMENT_ID_UNKNOWN_RECORDER_DEPARTMENT = null; + + @Value("${PmfmId.AGE}") + public final Integer PMFM_ID_AGE = null; + + @Value("${ProgramCode.SCIENTIFIC_CRUISE_PREFIX}") + public final String PROGRAM_CODE_SCIENTIFIC_CRUISE_PREFIX = null; + + @Value("${TaxonGroupTypeCode.COMMERCIAL_SPECIES}") + public final String TAXON_GROUP_TYPE_ID_COMMERCIAL_SPECIES = null; + + public void init() { + + Field[] declaredFields = getClass().getDeclaredFields(); + for (Field declaredField : declaredFields) { + Value annotation = declaredField.getAnnotation(Value.class); + if (annotation != null) { + + // check on that field that his value is here + Object fieldValue = ReflectionUtils.getField(declaredField, this); + Preconditions.checkNotNull( + fieldValue, + annotation.value() + " constant not found (field " + + declaredField.getName() + ")"); + } + } + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/TuttiPersistenceServiceLocator.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,132 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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 fr.ifremer.adagio.core.service.ServiceLocator; +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. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class TuttiPersistenceServiceLocator extends ServiceLocator { + + static { + initTuttiDefault(); + } + + public static void initTuttiDefault() { + instance().init("beanRefFactory.xml", "TuttiBeanRefFactory"); + } + + public static void initTutti(String beanFactoryReferenceLocation, + String beanRefFactoryReferenceId) { + instance().init(beanFactoryReferenceLocation, beanRefFactoryReferenceId); + } + + public static TuttiEnumerationFile getTuttiEnumerationFile() { + return instance().getService("tuttiEnumerationFile", + TuttiEnumerationFile.class); + } + + public static TuttiPersistence getPersistenceService() { + return getPersistenceService("tuttiPersistence", + TuttiPersistence.class); + } + + public static ReferentialPersistenceService getReferentialPersistenceService() { + return instance().getService("referentialPersistenceService", + ReferentialPersistenceService.class); + } + + public static ProgramPersistenceService getProgramPersistenceService() { + return getPersistenceService("programPersistenceService", + ProgramPersistenceService.class); + } + + public static CruisePersistenceService getCruisePersistenceService() { + return getPersistenceService("cruisePersistenceService", + CruisePersistenceService.class); + } + + public static FishingOperationPersistenceService getFishingOperationPersistenceService() { + return getPersistenceService("fishingOperationPersistenceService", + FishingOperationPersistenceService.class); + } + + public static CatchBatchPersistenceService getCatchBatchPersistenceService() { + return getPersistenceService("catchBatchPersistenceService", + CatchBatchPersistenceService.class); + } + + public static SpeciesBatchPersistenceService getSpeciesBatchPersistenceService() { + return getPersistenceService("speciesBatchPersistenceService", + SpeciesBatchPersistenceService.class); + } + + public static BenthosBatchPersistenceService getBenthosBatchPersistenceService() { + return getPersistenceService("benthosBatchPersistenceService", + BenthosBatchPersistenceService.class); + } + + public static PlanktonBatchPersistenceService getPlanktonBatchPersistenceService() { + return getPersistenceService("planktonBatchPersistenceService", + PlanktonBatchPersistenceService.class); + } + + public static MacroWasteBatchPersistenceService getMacroWasteBatchPersistenceService() { + return getPersistenceService("macroWasteBatchPersistenceService", + MacroWasteBatchPersistenceService.class); + } + + public static AccidentalBatchPersistenceService getAccidentalBatchPersistenceService() { + return getPersistenceService("accidentalBatchPersistenceService", + AccidentalBatchPersistenceService.class); + } + + public static ProtocolPersistenceService getProtocolPersistenceService() { + return getPersistenceService("protocolPersistenceService", + ProtocolPersistenceService.class); + } + + public static ReferentialSynchronizeService getReferentialSynchronizeService() { + return getPersistenceService("referentialSynchronizeService", + ReferentialSynchronizeService.class); + } + + public static <S extends TuttiPersistenceServiceImplementor> S getPersistenceService(String name, Class<S> serviceType) { + S service = instance().getService(name, serviceType); + service.init(); + return service; + } + + public static void close() { + instance().shutdown(); + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure/MeasurementPersistenceHelper.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/measure/MeasurementPersistenceHelper.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure/MeasurementPersistenceHelper.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/measure/MeasurementPersistenceHelper.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,344 @@ +package fr.ifremer.tutti.persistence.service.measure; + +/* + * #%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.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import fr.ifremer.adagio.core.dao.administration.user.DepartmentImpl; +import fr.ifremer.adagio.core.dao.data.batch.Batch; +import fr.ifremer.adagio.core.dao.data.batch.SortingBatch; +import fr.ifremer.adagio.core.dao.data.measure.GearPhysicalMeasurement; +import fr.ifremer.adagio.core.dao.data.measure.Measurement; +import fr.ifremer.adagio.core.dao.data.measure.QuantificationMeasurement; +import fr.ifremer.adagio.core.dao.data.measure.SortingMeasurement; +import fr.ifremer.adagio.core.dao.data.survey.fishingTrip.FishingTrip; +import fr.ifremer.adagio.core.dao.data.survey.scientificCruise.ScientificCruise; +import fr.ifremer.adagio.core.dao.data.vessel.feature.physical.GearPhysicalFeatures; +import fr.ifremer.adagio.core.dao.referential.QualityFlagDao; +import fr.ifremer.adagio.core.dao.referential.QualityFlagImpl; +import fr.ifremer.adagio.core.dao.referential.gear.GearImpl; +import fr.ifremer.adagio.core.dao.referential.pmfm.Pmfm; +import fr.ifremer.adagio.core.dao.referential.pmfm.PmfmImpl; +import fr.ifremer.adagio.core.dao.referential.pmfm.QualitativeValue; +import fr.ifremer.adagio.core.dao.referential.pmfm.QualitativeValueImpl; +import fr.ifremer.tutti.persistence.entities.data.SampleCategoryEnum; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicType; +import fr.ifremer.tutti.persistence.service.AbstractPersistenceService; +import fr.ifremer.tutti.persistence.service.ReferentialPersistenceService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.io.Serializable; + +@Component("measurementPersistenceHelper") +public class MeasurementPersistenceHelper extends AbstractPersistenceService { + + @Resource(name = "referentialPersistenceService") + protected ReferentialPersistenceService referentialService; + + @Resource(name = "qualityFlagDao") + protected QualityFlagDao qualityFlagDao; + + public MeasurementPersistenceHelper() { + } + + public QuantificationMeasurement setQuantificationMeasurement( + Batch batch, Integer pmfmId, Integer recorderDepartmentId, + Float weightValue, boolean isReferenceSorting) { + QuantificationMeasurement quantificationMeasurement = getQuantificationMeasurement( + batch, pmfmId, recorderDepartmentId, true); + + quantificationMeasurement.setNumericalValue(weightValue); + quantificationMeasurement + .setIsReferenceQuantification(isReferenceSorting); + return quantificationMeasurement; + } + + public QuantificationMeasurement getQuantificationMeasurement( + Batch batch, Integer pmfmId, Integer recorderDepartmentId, + boolean createIfNotExists) { + QuantificationMeasurement quantificationMeasurement = null; + if (batch.getQuantificationMeasurements() != null) { + for (QuantificationMeasurement qm : batch + .getQuantificationMeasurements()) { + if (pmfmId.equals(qm.getPmfm().getId())) { + quantificationMeasurement = qm; + break; + } + } + } + if (quantificationMeasurement == null) { + if (!createIfNotExists) { + return null; + } + quantificationMeasurement = QuantificationMeasurement.Factory + .newInstance(); + quantificationMeasurement.setBatch(batch); + if (batch.getQuantificationMeasurements() == null) { + batch.setQuantificationMeasurements(Sets + .newHashSet(quantificationMeasurement)); + } else { + batch.getQuantificationMeasurements().add( + quantificationMeasurement); + } + quantificationMeasurement.setQualityFlag(load( + QualityFlagImpl.class, + enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + quantificationMeasurement.setDepartment(load(DepartmentImpl.class, + recorderDepartmentId)); + quantificationMeasurement.setPmfm(load(PmfmImpl.class, pmfmId)); + } + + return quantificationMeasurement; + } + + public void setMeasurement(Measurement measurement, Caracteristic caracteristic, Serializable value) { + if (caracteristic.getCaracteristicType() == CaracteristicType.TEXT) { + measurement.setAlphanumericalValue((String) value); + } else if (caracteristic.getCaracteristicType() == CaracteristicType.NUMBER) { + measurement.setNumericalValue((Float) value); + } else if (caracteristic.getCaracteristicType() == CaracteristicType.QUALITATIVE) { + Integer qvId = null; + if (value instanceof CaracteristicQualitativeValue) { + qvId = Integer.valueOf(((CaracteristicQualitativeValue) value).getId()); + } else if (value instanceof Integer) { + qvId = (Integer) value; + } + // TODO BL : not used ? => to remove + else { + qvId = Integer.valueOf(value.toString()); + } + QualitativeValue qv = load(QualitativeValueImpl.class, qvId); + measurement.setQualitativeValue(qv); + } + } + + public SortingMeasurement setSortingMeasurement( + SortingBatch sortingBatch, Integer recorderDepartmentId, + SampleCategoryEnum sampleCategory, Serializable value) { + Preconditions.checkNotNull(sampleCategory); + Preconditions.checkNotNull(value); + + Integer pmfmId = sampleCategory2PmfmId(sampleCategory); + + Caracteristic caracteristic = referentialService.getCaracteristic(pmfmId); + SortingMeasurement sortingMeasurement = getSortingMeasurement( + sortingBatch, pmfmId, recorderDepartmentId, true); + setMeasurement(sortingMeasurement, caracteristic, value); + return sortingMeasurement; + } + + public SortingMeasurement setSortingMeasurement( + SortingBatch sortingBatch, Integer recorderDepartmentId, + Integer pmfmId, Serializable value) { + Preconditions.checkNotNull(pmfmId); + Preconditions.checkNotNull(value); + + Caracteristic caracteristic = referentialService.getCaracteristic(pmfmId); + SortingMeasurement sortingMeasurement = getSortingMeasurement( + sortingBatch, pmfmId, recorderDepartmentId, true); + setMeasurement(sortingMeasurement, caracteristic, value); + return sortingMeasurement; + } + + public SortingMeasurement getSortingMeasurement( + SortingBatch sortingBatch, Integer pmfmId, Integer recorderDepartmentId, + boolean createIfNotExists) { + SortingMeasurement sortingMeasurement = null; + if (sortingBatch.getSortingMeasurements() != null) { + for (SortingMeasurement qm : sortingBatch + .getSortingMeasurements()) { + if (pmfmId.equals(qm.getPmfm().getId())) { + sortingMeasurement = qm; + break; + } + } + } + if (sortingMeasurement == null) { + if (!createIfNotExists) { + return null; + } + sortingMeasurement = SortingMeasurement.Factory + .newInstance(); + sortingMeasurement.setSortingBatch(sortingBatch); + if (sortingBatch.getSortingMeasurements() == null) { + sortingBatch.setSortingMeasurements(Sets + .newHashSet(sortingMeasurement)); + sortingMeasurement.setRankOrder(1); + } else { + sortingBatch.getSortingMeasurements().add( + sortingMeasurement); + sortingMeasurement.setRankOrder(sortingBatch.getSortingMeasurements().size()); + } + sortingMeasurement.setQualityFlag(load( + QualityFlagImpl.class, + enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + sortingMeasurement.setDepartment(load(DepartmentImpl.class, + recorderDepartmentId)); + sortingMeasurement.setPmfm(load(PmfmImpl.class, pmfmId)); + } + + return sortingMeasurement; + } + + public Integer sampleCategory2PmfmId(SampleCategoryEnum sampleCategory) { + Integer pmfmId = null; + if (sampleCategory == SampleCategoryEnum.sortedUnsorted) { + pmfmId = enumeration.PMFM_ID_SORTED_UNSORTED; + } else if (sampleCategory == SampleCategoryEnum.size) { + pmfmId = enumeration.PMFM_ID_SIZE_CATEGORY; + } else if (sampleCategory == SampleCategoryEnum.maturity) { + pmfmId = enumeration.PMFM_ID_MATURITY; + } else if (sampleCategory == SampleCategoryEnum.sex) { + pmfmId = enumeration.PMFM_ID_SEX; + } else if (sampleCategory == SampleCategoryEnum.age) { + pmfmId = enumeration.PMFM_ID_AGE; + } + if (pmfmId == null) { + throw new IllegalArgumentException("Unable to find corresponding PMFM.ID for sampleCategory : " + sampleCategory.name()); + } + return pmfmId; + } + + public SampleCategoryEnum pmfmId2SampleCategory(Integer pmfmId) { + SampleCategoryEnum sampleCategory = null; + if (pmfmId.intValue() == enumeration.PMFM_ID_SORTED_UNSORTED.intValue()) { + sampleCategory = SampleCategoryEnum.sortedUnsorted; + } else if (enumeration.PMFM_ID_SIZE_CATEGORY.equals(pmfmId)) { + sampleCategory = SampleCategoryEnum.size; + } else if (enumeration.PMFM_ID_MATURITY.equals(pmfmId)) { + sampleCategory = SampleCategoryEnum.maturity; + } else if (enumeration.PMFM_ID_SEX.equals(pmfmId)) { + sampleCategory = SampleCategoryEnum.sex; + } else if (enumeration.PMFM_ID_AGE.equals(pmfmId)) { + sampleCategory = SampleCategoryEnum.age; + } + if (sampleCategory == null) { + throw new IllegalArgumentException("Unable to find corresponding SampleCategoryEnum for PMFM.ID : " + pmfmId); + } + return sampleCategory; + } + + public GearPhysicalFeatures getGearPhysicalfeatures(FishingTrip fishingTrip, Integer gearId) { + return getGearPhysicalfeatures(fishingTrip, gearId, false); + } + + public GearPhysicalFeatures getGearPhysicalfeatures(FishingTrip fishingTrip, Integer gearId, boolean createIfNotExists) { + // Retrieve entities : Gear Physical Features + if (fishingTrip.getGearPhysicalFeatures() != null && fishingTrip.getGearPhysicalFeatures().size() >= 0) { + for (GearPhysicalFeatures guf : fishingTrip.getGearPhysicalFeatures()) { + if (gearId.equals(guf.getGear().getId())) { + return guf; + } + } + } + if (!createIfNotExists) { + return null; + } + + GearPhysicalFeatures gearPhysicalFeature = GearPhysicalFeatures.Factory.newInstance(); + gearPhysicalFeature.setFishingTrip(fishingTrip); + + fr.ifremer.adagio.core.dao.referential.gear.Gear gear = (fr.ifremer.adagio.core.dao.referential.gear.Gear) getCurrentSession().load(GearImpl.class, gearId); + gearPhysicalFeature.setGear(gear); + if (fishingTrip.getGearPhysicalFeatures() == null) { + fishingTrip.setGearPhysicalFeatures(Lists.newArrayList(gearPhysicalFeature)); + } else { + fishingTrip.getGearPhysicalFeatures().add(gearPhysicalFeature); + } + + return gearPhysicalFeature; + } + + public GearPhysicalMeasurement getGearPhysicalMeasurement(GearPhysicalFeatures gearPhysicalFeatures, Integer pmfmId) { + return getGearPhysicalMeasurement(null, gearPhysicalFeatures, pmfmId, false); + } + + protected GearPhysicalMeasurement getGearPhysicalMeasurement(ScientificCruise scientificCruise, GearPhysicalFeatures gearPhysicalFeatures, + Integer pmfmId, boolean createIfNotExists) { + GearPhysicalMeasurement gearPhysicalMeasurement = null; + if (gearPhysicalFeatures.getGearPhysicalMeasurements() != null) { + for (GearPhysicalMeasurement vum : gearPhysicalFeatures.getGearPhysicalMeasurements()) { + if (pmfmId.equals(vum.getPmfm().getId())) { + gearPhysicalMeasurement = vum; + break; + } + } + } + if (gearPhysicalMeasurement == null) { + if (!createIfNotExists) { + return null; + } + gearPhysicalMeasurement = GearPhysicalMeasurement.Factory.newInstance(); + gearPhysicalMeasurement.setGearPhysicalFeatures(gearPhysicalFeatures); + if (gearPhysicalFeatures.getGearPhysicalMeasurements() == null) { + gearPhysicalFeatures.setGearPhysicalMeasurements(Lists.newArrayList(gearPhysicalMeasurement)); + } else { + gearPhysicalFeatures.getGearPhysicalMeasurements().add(gearPhysicalMeasurement); + } + gearPhysicalMeasurement.setQualityFlag(qualityFlagDao.load(enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + gearPhysicalMeasurement.setDepartment(scientificCruise.getRecorderDepartment()); + Pmfm pmfm = (Pmfm) getCurrentSession().load(PmfmImpl.class, pmfmId); + gearPhysicalMeasurement.setPmfm(pmfm); + //gearPhysicalMeasurement.setPmfm(pmfmDao.load(pmfmId)); + } + + return gearPhysicalMeasurement; + } + + public void removeGearPhysicalMeasurement(GearPhysicalFeatures gearPhysicalFeatures, + Integer pmfmId) { + GearPhysicalMeasurement gearPhysicalMeasurement = getGearPhysicalMeasurement(null, gearPhysicalFeatures, pmfmId, false); + if (gearPhysicalMeasurement == null) { + return; + } + gearPhysicalFeatures.getGearPhysicalMeasurements().remove(gearPhysicalMeasurement); + // TOBO BLa : vérifier qu'il ne faut pas dao.delete() en plus + } + + public GearPhysicalMeasurement setGearPhysicalMeasurement(ScientificCruise scientificCruise, GearPhysicalFeatures gearPhysicalFeatures, + Integer pmfmId, + Float numericalValue, + String alphanumericalValue, + Integer qualitativevalueId) { + GearPhysicalMeasurement gearPhysicalMeasurement = getGearPhysicalMeasurement(scientificCruise, gearPhysicalFeatures, pmfmId, true); + + if (alphanumericalValue != null) { + gearPhysicalMeasurement.setAlphanumericalValue(alphanumericalValue); + } else if (numericalValue != null) { + gearPhysicalMeasurement.setNumericalValue(numericalValue); + } else if (qualitativevalueId != null) { + QualitativeValue qv = (QualitativeValue) getCurrentSession().load(QualitativeValueImpl.class, qualitativevalueId); + gearPhysicalMeasurement.setQualitativeValue(qv); + //gearPhysicalMeasurement.setQualitativeValue(qualitativeValueDao.load(qualitativevalueId)); + } + + return gearPhysicalMeasurement; + } +} \ No newline at end of file Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelper.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelper.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelper.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelper.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,376 @@ +package fr.ifremer.tutti.persistence.service.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.Sets; +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.dialect.Dialect; +import org.hibernate.tool.hbm2ddl.ColumnMetadata; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.jdbc.support.JdbcUtils; +import org.springframework.stereotype.Component; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; +import java.util.Properties; +import java.util.Set; + +/** + * Helper to synchronize referential between two databases. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +@Component("referentialSynchronizeHelper") +public class ReferentialSynchronizeHelper { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ReferentialSynchronizeHelper.class); + + /** + * Synchronize database given from {@code localProperties} (means the + * database to update) with remote database (means the database which + * contains the referential to use) given by {@code remoteProperties} + * using the given {@code dialect} to inspect databases metadatas. + * + * @param localProperties properties to connect to local database + * @param remoteProperties properties to connect to remove database + * @param dialect dialect used to seek metadata of databases. + * @return Result of the synchronize operation, if there is an error then + * the {@link ReferentialSynchronizeResult#isSuccess()} is {@code false} + * and you can get the error at + * {@link ReferentialSynchronizeResult#getError()} + */ + public ReferentialSynchronizeResult synchronize(Properties localProperties, + Properties remoteProperties, + Dialect dialect) { + + ReferentialSynchronizeResult result = new ReferentialSynchronizeResult( + TuttiEntities.getUrl(localProperties), + TuttiEntities.getUrl(remoteProperties)); + + Connection targetConnection = null; + Connection synchConnection = null; + try { + + // create local connection + targetConnection = TuttiEntities.createConnection(localProperties); + + // create remote Connection + synchConnection = TuttiEntities.createConnection(remoteProperties); + + + // load metas + TuttiDatabaseMetadata targetMeta = loadDatabaseMetadata(targetConnection, dialect); + TuttiDatabaseMetadata synchMeta = loadDatabaseMetadata(synchConnection, dialect); + + // check schema + try { + checkSchemas(targetMeta, synchMeta); + } catch (DataRetrievalFailureException e) { + result.setError(e); + } + + if (result.isSuccess()) { + + // prepare target (desactivate constraints) + prepareSynch(targetConnection); + + try { + + for (TuttiTable tuttiTable : TuttiTable.values()) { + + synchronizeTable(tuttiTable, + synchMeta, + targetConnection, + synchConnection, + result); + } + } finally { + releaseSynch(synchConnection); + } + + targetConnection.commit(); + } + } catch (SQLException e) { + try { + targetConnection.rollback(); + } catch (SQLException e1) { + + // ignore the rolback error + } + result.setError(e); + } finally { + JdbcUtils.closeConnection(synchConnection); + JdbcUtils.closeConnection(targetConnection); + } + return result; + } + + /** + * 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 TuttiDatabaseMetadata loadDatabaseMetadata(Connection connection, + Dialect dialect) { + TuttiDatabaseMetadata result = new TuttiDatabaseMetadata(connection, dialect); + for (TuttiTable tuttiTable : TuttiTable.values()) { + + String tableName = tuttiTable.name(); + if (log.isDebugEnabled()) { + log.debug("Load metas of table: " + tableName); + } + result.getTable(tableName); + } + return result; + } + + /** + * 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 + */ + public void checkSchemas(TuttiDatabaseMetadata schema1, + TuttiDatabaseMetadata schema2) { + Set<String> internalSchemaTableNames = schema1.getTableNames(); + Set<String> externalSchemaTableNames = schema2.getTableNames(); + if (!internalSchemaTableNames.equals(externalSchemaTableNames)) { + throw new DataRetrievalFailureException("Incompatible schemas"); + } + for (String tableName : internalSchemaTableNames) { + TuttiTableMetadata internalTable = schema1.getTable(tableName); + TuttiTableMetadata 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); + } + } + } + } + + /** + * Gets the last updateDate for the given {@code table} using + * the given datasource + * + * @param connection connection to data source to query + * @param table the table to query + * @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 Date getLastUpdateDate(Connection connection, + TuttiTableMetadata table) throws SQLException { + Date result = null; + + if (table.isWithUpdateDateColumn()) { + + String sql = table.getGetMaxUpdateDateQuery(); + + PreparedStatement statement = connection.prepareStatement(sql); + try { + ResultSet resultSet = statement.executeQuery(); + if (resultSet.next()) { + result = resultSet.getDate(1); + } + statement.close(); + } finally { + TuttiEntities.closeSilently(statement); + } + } + return result; + } + + public ResultSet getDataToUpdate(Connection connection, + TuttiTableMetadata table, + Date fromDate) throws SQLException { + + String sql = table.getGetDataToUpdateQuery(); + + PreparedStatement statement = connection.prepareStatement(sql); + if (table.isWithUpdateDateColumn()) { + statement.setDate(1, new java.sql.Date(fromDate.getTime())); + } + + ResultSet result = statement.executeQuery(); + return result; + } + + public Set<String> getExistingIds(Connection connection, + TuttiTableMetadata table) throws SQLException { + + String sql = table.getGetExistingIdsQuery(); + + PreparedStatement statement = connection.prepareStatement(sql); + + Set<String> result = Sets.newHashSet(); + try { + ResultSet resultSet = statement.executeQuery(); + while (resultSet.next()) { + result.add(String.valueOf(resultSet.getObject(1))); + } + statement.close(); + return result; + } finally { + TuttiEntities.closeSilently(statement); + } + } + + public void updateTable(Connection connection, + TuttiTableMetadata table, + Set<String> existingIds, + ResultSet incomingData, + ReferentialSynchronizeResult result) throws SQLException { + + int columnCount = table.getColumnsCount(); + + + String tableName = table.getName(); + + int pkIndex = table.getPkIndex(); + + String insertSql = table.getInsertQuery(); + String updateSql = table.getUpdateQuery(); + + PreparedStatement insertStatement = connection.prepareStatement(insertSql); + PreparedStatement updateStatement = connection.prepareStatement(updateSql); + + result.addTableName(tableName); + + do { + + Object pk = incomingData.getObject(pkIndex); + + String pkAsString = String.valueOf(pk); + PreparedStatement statement; + String sql; + + boolean doUpdate = existingIds.contains(pkAsString); + if (doUpdate) { + + // use update query + statement = updateStatement; + sql = updateSql; + + result.addUpdate(tableName, pkAsString); + } else { + + // use insert query + sql = insertSql; + statement = insertStatement; + result.addInsert(tableName, pkAsString); + } + + for (int c = 1; c <= columnCount; c++) { + statement.setObject(c, incomingData.getObject(c)); + } + + if (doUpdate) { + statement.setObject(columnCount + 1, pk); + } + + if (log.isDebugEnabled()) { + log.debug(String.format("[%s] Execute query %s (pk:%s)", tableName, sql, pkAsString)); + } + + statement.executeUpdate(); + } + while (incomingData.next()); + + if (log.isDebugEnabled()) { + log.debug(String.format("[%s] INSERT count: %s", tableName, result.getNbInserts(tableName))); + log.debug(String.format("[%s] UPDATE count: %s", tableName, result.getNbUpdates(tableName))); + } + } + + public void synchronizeTable(TuttiTable tuttiTable, + TuttiDatabaseMetadata dbMeta, + Connection localConnection, + Connection remoteConnection, + ReferentialSynchronizeResult result) throws SQLException { + + TuttiTableMetadata table = dbMeta.getTable(tuttiTable.name()); + + Date updateDate = getLastUpdateDate(remoteConnection, table); + + // get data to synch + ResultSet dataToUpdate = getDataToUpdate(remoteConnection, + table, + updateDate); + + try { + if (dataToUpdate.next()) { + + // there is some data to update + + // gets existing ids in the target db + Set<String> existingIds = getExistingIds(localConnection, + table); + + updateTable(localConnection, + table, + existingIds, + dataToUpdate, + result); + } + + dataToUpdate.close(); + } finally { + JdbcUtils.closeResultSet(dataToUpdate); + } + } + + public static void prepareSynch(Connection connection) throws SQLException { + PreparedStatement statement = connection.prepareStatement("SET REFERENTIAL_INTEGRITY FALSE;"); + statement.executeUpdate(); + } + + public static void releaseSynch(Connection connection) throws SQLException { + PreparedStatement statement = connection.prepareStatement("SET REFERENTIAL_INTEGRITY TRUE;"); + statement.executeUpdate(); + } +} Copied: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java (from rev 298, trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java) =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java (rev 0) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImpl.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,82 @@ +package fr.ifremer.tutti.persistence.service.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 fr.ifremer.tutti.persistence.service.AbstractPersistenceService; +import org.apache.commons.dbcp.BasicDataSource; +import org.hibernate.cfg.Environment; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.SessionFactoryImplementor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Properties; + +/** + * TODO + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +@Service("referentialSynchronizeService") +public class ReferentialSynchronizeServiceImpl extends AbstractPersistenceService implements ReferentialSynchronizeService { + + @Autowired + protected BasicDataSource dataSource; + + protected Dialect localDialect; + + protected Properties dbconnexionProperties; + + @Resource(name = "referentialSynchronizeHelper") + protected ReferentialSynchronizeHelper helper; + + @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 ReferentialSynchronizeResult synchronize(Properties remoteConnectionProperties) { + return helper.synchronize(getLocalConnectionProperties(), + remoteConnectionProperties, + getLocalDialect()); + } +} Modified: trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/SexagecimalPosition.java =================================================================== --- trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/SexagecimalPosition.java 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/persistence/spatial/SexagecimalPosition.java 2013-02-02 14:11:58 UTC (rev 300) @@ -25,11 +25,11 @@ */ import org.apache.commons.lang3.ObjectUtils; - -import java.io.Serializable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.io.Serializable; + /** * Define a geo spatial position coordinate in degre, minute, second. * @@ -41,7 +41,7 @@ private static final long serialVersionUID = 1L; private static final Log log = LogFactory.getLog(SexagecimalPosition.class); - + protected boolean sign; protected Integer degre; @@ -173,7 +173,7 @@ public Integer getMinute() { return minute; } - + public Float getMinuteDecimale() { Float minuteDecimale = null; if (minute != null) { @@ -200,12 +200,12 @@ public void setMinute(Integer minute) { this.minute = minute; } - + public void setMinuteDecimale(Float minuteDecimale) { if (minuteDecimale == null) { minute = null; seconde = null; - + } else { Double entier = Math.floor(minuteDecimale); minute = entier.intValue(); Copied: trunk/tutti-persistence/src/main/resources/META-INF/services/org.nuiton.util.ApplicationConfigProvider (from rev 298, trunk/tutti-persistence-adagio/src/main/resources/META-INF/services/org.nuiton.util.ApplicationConfigProvider) =================================================================== --- trunk/tutti-persistence/src/main/resources/META-INF/services/org.nuiton.util.ApplicationConfigProvider (rev 0) +++ trunk/tutti-persistence/src/main/resources/META-INF/services/org.nuiton.util.ApplicationConfigProvider 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1 @@ +fr.ifremer.tutti.persistence.config.TuttiPersistenceConfigProvider \ No newline at end of file Copied: trunk/tutti-persistence/src/main/resources/applicationContext-service-tutti.xml (from rev 298, trunk/tutti-persistence-adagio/src/main/resources/applicationContext-service-tutti.xml) =================================================================== --- trunk/tutti-persistence/src/main/resources/applicationContext-service-tutti.xml (rev 0) +++ trunk/tutti-persistence/src/main/resources/applicationContext-service-tutti.xml 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Tutti :: Persistence API + $Id$ + $HeadURL$ + %% + Copyright (C) 2012 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% + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + + <context:component-scan base-package="fr.ifremer.tutti.persistence.service"/> + + <bean id="tuttiPersistence" init-method="init" destroy-method="close" + class="fr.ifremer.tutti.persistence.TuttiPersistenceImpl"/> + + <bean id="tuttiEnumerationFile" init-method="init" + class="fr.ifremer.tutti.persistence.service.TuttiEnumerationFile"/> + + <!-- Specific caches for tutti (not defined in ehcache.xml) --> + <bean id="tuttiAbstractCache" abstract="true" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> + <property name="cacheManager" ref="ehcache"/> + <property name="maxElementsInMemory" value="5000"/> + <property name="eternal" value="false"/> + <property name="timeToLive" value="300"/> + <property name="timeToIdle" value="300"/> + <property name="overflowToDisk" value="false"/> + <property name="diskPersistent" value="false"/> + <property name="diskExpiryThreadIntervalSeconds" value="300"/> + </bean> + + <bean id="tuttiAllFishingVesselCache" parent="tuttiAbstractCache"> + <property name="cacheName" value="tuttiAllFishingVessel" /> + <property name="eternal" value="true"/> + <property name="overflowToDisk" value="true"/> + <property name="diskPersistent" value="true"/> + <!-- removed inherited properties --> + <property name="timeToLive" value="0"/> + <property name="timeToIdle" value="0"/> + </bean> + + <!-- Example to use to create a new cache area : + <bean id="tuttiOtherCache" parent="tuttiPersistenceDefaultCache"> + </bean> --> + +</beans> \ No newline at end of file Copied: trunk/tutti-persistence/src/main/resources/beanRefFactory.xml (from rev 298, trunk/tutti-persistence-adagio/src/main/resources/beanRefFactory.xml) =================================================================== --- trunk/tutti-persistence/src/main/resources/beanRefFactory.xml (rev 0) +++ trunk/tutti-persistence/src/main/resources/beanRefFactory.xml 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Tutti :: Persistence API + $Id$ + $HeadURL$ + %% + Copyright (C) 2012 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% + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + + <bean id="TuttiBeanRefFactory" + class="org.springframework.context.support.ClassPathXmlApplicationContext"> + <constructor-arg> + <list> + <value>applicationContext-conf.xml</value> + <value>applicationContext-dataSource-${dataSource.type}.xml</value> + <value>applicationContext-entities.xml</value> + <value>applicationContext-service.xml</value> + <value>applicationContext-service-tutti.xml</value> + </list> + </constructor-arg> + </bean> + +</beans> \ No newline at end of file Copied: trunk/tutti-persistence/src/main/resources/queries-override.hbm.xml (from rev 298, trunk/tutti-persistence-adagio/src/main/resources/queries-override.hbm.xml) =================================================================== --- trunk/tutti-persistence/src/main/resources/queries-override.hbm.xml (rev 0) +++ trunk/tutti-persistence/src/main/resources/queries-override.hbm.xml 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,843 @@ +<?xml version="1.0"?> +<!-- + #%L + Tutti :: Persistence API + $Id$ + $HeadURL$ + %% + Copyright (C) 2012 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% + --> + +<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> +<hibernate-mapping> + + <!-- ===================================================================== --> + <!-- === Requete sur données thématiques [DAT-XXX] === --> + <!-- ===================================================================== --> + + <!-- [DAT-01] Get all programs (to list with no detail) --> + <query cacheable="true" name="allPrograms"> + <![CDATA[ + SELECT + p.code, + p.name, + p.description + FROM + ProgramImpl p + WHERE + p.code LIKE :codePattern + ]]> + </query> + + <!-- [DAT-02] Get all cruises for a given program (to list with no detail) --> + <query name="allCruises"> + <![CDATA[ + SELECT + c.id, + c.name, + c.departureDateTime + FROM + ScientificCruiseImpl c + WHERE + c.program.code = :programCode + ORDER BY + c.departureDateTime desc + ]]> + <query-param name="programCode" type="java.lang.String"/> + </query> + + <!-- [DAT-03] Get a detail program --> + <query name="program"> + <![CDATA[ + SELECT + p.code, + p.name, + p.description, + l.id, + l.label, + l.name + FROM + ProgramImpl p + LEFT OUTER JOIN p.locations l + WHERE + p.code = :programCode + AND ( + l is null OR ( + l.locationLevel.id = :locationLevelId + AND l.locationClassification.id = :locationClassificationId + ) + ) + ORDER BY l.label + ]]> + <query-param name="programCode" type="java.lang.String"/> + <query-param name="locationLevelId" type="java.lang.Integer"/> + <query-param name="locationClassificationId" type="java.lang.Integer"/> + </query> + + <!-- [DAT-04] Get a detail cruise --> + <query name="cruise"> + <![CDATA[ + SELECT + sc.program.code AS programCode, + year(sc.departureDateTime) AS year, + sc.name AS name, + lh.locationHierarchyPk.parent.id AS countryId, + lh.locationHierarchyPk.parent.label AS countryLabel, + lh.locationHierarchyPk.parent.name AS countryName, + sc.departureDateTime AS departureDateTime, + sc.returnDateTime AS returnDateTime, + sc.vessel.code AS vesselCode, + mp.id AS managerId, + sc.comments AS scientificCruiseComments, + ft.comments AS fishingTripComments + FROM + ScientificCruiseImpl sc + LEFT OUTER JOIN sc.fishingTrips ft + LEFT OUTER JOIN sc.managerPerson mp, + LocationHierarchyImpl lh + WHERE + sc.id = :cruiseId + AND lh.locationHierarchyPk.parent.locationLevel.id = :countryLocationLevelId + AND lh.locationHierarchyPk.location.id = ft.departureLocation.id + ]]> + <query-param name="cruiseId" type="java.lang.Integer"/> + <query-param name="countryLocationLevelId" type="java.lang.Integer"/> + </query> + + <query name="allCruiseGears"> + <![CDATA[ + SELECT + gpf.gear.id AS gearId, + MAX(CASE gpm.pmfm.id + WHEN :pmfmIdTrawlNet THEN gpm.numericalValue + ELSE 0 + END) as trawlNet, + count(o.id) as operationCount + FROM + ScientificCruiseImpl sc + JOIN sc.fishingTrips ft + JOIN ft.gearPhysicalFeatures gpf + LEFT OUTER JOIN gpf.gearPhysicalMeasurements gpm + LEFT OUTER JOIN gpf.operations o + WHERE + sc.id = :cruiseId + GROUP BY + gpf.gear.id + ORDER BY count(o.id) DESC + ]]> + <query-param name="cruiseId" type="java.lang.Integer"/> + <query-param name="pmfmIdTrawlNet" type="java.lang.Integer"/> + </query> + + <query name="allCruiseSecondaryVessels"> + <![CDATA[ + SELECT + va.operationVesselAssociationPk.vessel.code AS associatedVesselCode + FROM + ScientificCruiseImpl sc + JOIN sc.fishingTrips ft + JOIN ft.operations o + JOIN o.operationVesselAssociations va + WHERE + sc.id = :cruiseId + GROUP BY + va.operationVesselAssociationPk.vessel + ]]> + <query-param name="cruiseId" type="java.lang.Integer"/> + </query> + + <query name="allFishingOperations"> + <![CDATA[ + SELECT + o.id AS id, + o.name AS name, + guf.gear.label AS gearLabel, + o.startDateTime AS startDateTime, + (select vum.alphanumericalValue from VesselUseMeasurementImpl vum where vum.vesselUseFeatures.id = vuf.id and vum.pmfm.id=:pmfmIdStationNumber) AS stationNumber, + (select gum.numericalValue from GearUseMeasurementImpl gum where gum.gearUseFeatures.id = guf.id and gum.pmfm.id=:pmfmIdMultirigAggregation) AS trawNetNumber + FROM + FishingOperationImpl o + LEFT OUTER JOIN o.gearUseFeatures guf + LEFT OUTER JOIN o.vesselUseFeatures vuf + WHERE + o.fishingTrip.scientificCruise.id=:cruiseId + ORDER BY + o.startDateTime + ]]> + <query-param name="cruiseId" type="java.lang.Integer"/> + <query-param name="pmfmIdStationNumber" type="java.lang.Integer"/> + <query-param name="pmfmIdMultirigAggregation" type="java.lang.Integer"/> + </query> + + <query name="fishingOperation"> + <![CDATA[ + SELECT + o.name AS name, + max(guf.gear.label) AS gearLabel, + max(o.startDateTime) AS startDateTime, + max(o.endDateTime) AS endDateTime, + max(o.comments) AS comments, + max(guf.gear.id) AS gearId, + (select vp_start from VesselPositionImpl vp_start where vp_start.operation.id = o.id and vp_start.dateTime = o.startDateTime) AS startVesselPosition, + (select vp_end from VesselPositionImpl vp_end where vp_end.operation.id = o.id and vp_end.dateTime = o.endDateTime) AS endVesselPosition, + max(case when (rl.locationLevel.id = :locationLevelIdStrata) then rl.id else null end) AS strataId, + max(case when (rl.locationLevel.id = :locationLevelIdSubStrata) then rl.id else null end) AS subStrataId, + max(case when (rl.locationLevel.id = :locationLevelIdLocalite) then rl.id else null end) AS localiteId + FROM + FishingOperationImpl o + INNER JOIN o.gearUseFeatures guf + LEFT OUTER JOIN guf.fishingAreas fa + LEFT OUTER JOIN fa.regulationLocation fa2rl + LEFT OUTER JOIN fa2rl.id.location rl + WHERE + o.id=:fishingOperationId + GROUP BY o.name + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + <query-param name="locationLevelIdStrata" type="java.lang.Integer"/> + <query-param name="locationLevelIdSubStrata" type="java.lang.Integer"/> + <query-param name="locationLevelIdLocalite" type="java.lang.Integer"/> + </query> + + <query name="fishingOperationRankOrder"> + <![CDATA[ + SELECT + count(o1.id)+1 as fishingOperationRankOrder + FROM + FishingOperationImpl o1, + FishingOperationImpl o2 + WHERE + o1.fishingTrip.id=o2.fishingTrip.id + and o1.startDateTime < o2.startDateTime + and o2.id = :fishingOperationId + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + </query> + + + + <query name="fishingOperationEnvironment"> + <![CDATA[ + SELECT + vum.pmfm.id as pmfmId, + vum.numericalValue as numericalValue, + vum.alphanumericalValue as alphanumericalValue, + vum.qualitativeValue.id as qualitativeValueId + from + VesselUseFeaturesImpl vuf + join vuf.vesselUseMeasurements vum + WHERE + vuf.operation.id = :fishingOperationId + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + </query> + + <query name="fishingOperationGearShooting"> + <![CDATA[ + SELECT + gum.pmfm.id as pmfmId, + gum.numericalValue as numericalValue, + gum.alphanumericalValue as alphanumericalValue, + gum.qualitativeValue.id as qualitativeValueId + from + GearUseFeaturesImpl guf + join guf.gearUseMeasurements gum + WHERE + guf.operation.id = :fishingOperationId + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + </query> + + <query name="updateFishingOperationCatchBatch"> + <![CDATA[ + UPDATE FishingOperationImpl o + SET o.catchBatch.id=:catchBatchId + WHERE + o.id=:fishingOperationId + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + <query-param name="catchBatchId" type="java.lang.Integer"/> + </query> + + <query name="catchBatch"> + <![CDATA[ + SELECT + cb.id AS catchBatchId, + cbQm.numericalValue as totalWeight, + b1.id AS id1, + b1.samplingRatioText as samplingRatioText1, + (select qm.numericalValue from QuantificationMeasurementImpl qm where qm.batch.id=b1.id and qm.isReferenceQuantification=true) AS weight1, + (select sm.qualitativeValue.id from SortingMeasurementImpl sm where sm.sortingBatch.id=b1.id and sm.pmfm.id=:pmfmIdSorted) AS qv2, + b2.id AS id2, + b2.samplingRatioText AS samplingRatioText2, + (select qm.numericalValue from QuantificationMeasurementImpl qm where qm.batch.id=b2.id and qm.isReferenceQuantification=true) AS weight2, + (select sm.qualitativeValue.id from SortingMeasurementImpl sm where sm.sortingBatch.id=b2.id and sm.pmfm.id=:pmfmIdSortingType) AS qv2 + FROM + CatchBatchImpl cb + INNER JOIN cb.childBatchs b1 + LEFT OUTER JOIN b1.childBatchs b2 + LEFT OUTER JOIN cb.quantificationMeasurements cbQm + WHERE + cb.fishingOperation.id = :fishingOperationId + AND ( + cbQm is null + OR cbQm.isReferenceQuantification=true + ) + ORDER BY b1.id, b2.id + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + <query-param name="pmfmIdSorted" type="java.lang.Integer"/> + <query-param name="pmfmIdSortingType" type="java.lang.Integer"/> + </query> + + <query name="allRootSpeciesBatch"> + <![CDATA[ + SELECT + b.id as batchId, + b.individualCount AS individualCount, + qm.numericalValue AS weight, + b.samplingRatio AS samplingRatio, + b.samplingRatioText AS samplingRatioText, + b.comments AS comments, + sm.pmfm.id AS pmfmId, + sm.qualitativeValue.id as qvValue, + sm.numericalValue AS numValue, + sm.alphanumericalValue AS alphaValue, + b.referenceTaxon.id AS referenceTaxonId, + smSorted.pmfm.id AS pmfmIdGrandFather, + smSorted.qualitativeValue.id AS qualitativeIdGrandFather + FROM + CatchBatchImpl cb + INNER JOIN cb.childBatchs batchSorted + INNER JOIN batchSorted.childBatchs batchSortingType + INNER JOIN batchSortingType.childBatchs b + INNER JOIN batchSortingType.sortingMeasurements smSortingType + LEFT OUTER JOIN batchSorted.sortingMeasurements smSorted + LEFT OUTER JOIN b.sortingMeasurements sm + LEFT OUTER JOIN b.quantificationMeasurements qm + WHERE + cb.fishingOperation.id=:fishingOperationId + AND ( + qm is null + OR qm.isReferenceQuantification=true + ) + AND smSortingType.qualitativeValue.id=:qualitativeIdSortingType + ORDER BY b.id + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + <query-param name="qualitativeIdSortingType" type="java.lang.Integer"/> + </query> + + <query name="allSpeciesBatch"> + <![CDATA[ + SELECT + b.id as batchId, + b.individualCount AS individualCount, + qm.numericalValue AS weight, + b.samplingRatio AS samplingRatio, + b.samplingRatioText AS samplingRatioText, + b.comments AS comments, + sm.pmfm.id AS pmfmId, + sm.qualitativeValue.id as qvValue, + sm.numericalValue AS numValue, + sm.alphanumericalValue AS alphaValue, + b.referenceTaxon.id as referenceTaxonId, + b.parentBatch.id as parentBatchId + FROM + SortingBatchImpl b + INNER JOIN b.rootBatch cb + LEFT OUTER JOIN b.sortingMeasurements sm + LEFT OUTER JOIN b.quantificationMeasurements qm + WHERE + cb.fishingOperation.id=:fishingOperationId + AND ( + qm is null + OR qm.isReferenceQuantification=true + ) + ORDER BY b.id + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + </query> + + <query name="parentBatch"> + <![CDATA[ + SELECT + b2.id as parentBatchId, + cb.id as rootBatchId + FROM + CatchBatchImpl cb + INNER JOIN cb.childBatchs b1 + INNER JOIN b1.childBatchs b2, + SortingMeasurementImpl sm1, + SortingMeasurementImpl sm2 + WHERE + cb.fishingOperation.id = :fishingOperationId + AND sm1.sortingBatch.id=b1.id + AND sm1.pmfm.id=:pmfmIdSorted + AND sm1.qualitativeValue.id=:qualitativeIdSorted + AND sm2.sortingBatch.id=b2.id + AND sm2.pmfm.id=:pmfmIdSortingType + AND sm2.qualitativeValue.id=:qualitativeIdSortingType + ]]> + <query-param name="fishingOperationId" type="java.lang.Integer"/> + <query-param name="pmfmIdSorted" type="java.lang.Integer"/> + <query-param name="qualitativeIdSorted" type="java.lang.Integer"/> + <query-param name="pmfmIdSortingType" type="java.lang.Integer"/> + <query-param name="qualitativeIdSortingType" type="java.lang.Integer"/> + </query> + + <query name="speciesBatch"> + <![CDATA[ + SELECT + b.id AS batchId, + b.individualCount AS individualCount, + qm.numericalValue AS weight, + b.samplingRatio AS samplingRatio, + b.samplingRatioText AS samplingRatioText, + b.comments AS comments, + sm.pmfm.id AS pmfmId, + sm.qualitativeValue.id as qvValue, + sm.numericalValue AS numValue, + sm.alphanumericalValue AS alphaValue, + b.referenceTaxon.id AS referenceTaxonId, + smSorted.pmfm.id AS pmfmIdGrandFather, + smSorted.qualitativeValue.id AS qualitativeIdGrandFather + FROM + SortingBatchImpl b + INNER JOIN b.parentBatch batchSortingType + INNER JOIN batchSortingType.parentBatch batchSorted + LEFT OUTER JOIN batchSorted.sortingMeasurements smSorted + LEFT OUTER JOIN b.sortingMeasurements sm + LEFT OUTER JOIN b.quantificationMeasurements qm + WHERE + b.id = :batchId + AND ( + qm is null + OR qm.isReferenceQuantification=true + ) + ]]> + <query-param name="batchId" type="java.lang.Integer"/> + </query> + + <query name="speciesBatchChildren"> + <![CDATA[ + SELECT + cb.id + FROM + SortingBatchImpl b + INNER JOIN b.childBatchs cb + WHERE + b.id = :batchId + ]]> + <query-param name="batchId" type="java.lang.Integer"/> + </query> + + <!-- ===================================================================== --> + <!-- === Requete techniques sur référentiels [REF-TXXX] === --> + <!-- ===================================================================== --> + + <!-- [REF-T01] Get a pmfm caracteristics by this id --> + <query cacheable="true" name="pmfmById"> + <![CDATA[ + SELECT + p.id AS pmfmId, + p.parameter.name AS parameterName, + p.matrix.name AS matrixName, + p.fraction.name AS fractionName, + p.method.name AS methodName, + p.parameter.isAlphanumeric AS isAlphanumeric, + p.parameter.isQualitative AS isQualitative, + p.signifFiguresNumber, + p.maximumNumberDecimals, + p.precision, + case when (p.unit.id = :unitIdNone) then '' else p.unit.symbol end AS symbol, + p.status AS status + FROM PmfmImpl p + WHERE + p.status.code IN (:statusValidCode, :statusTemporaryCode) + AND p.parameter.isCalculated = false + AND p.id= :pmfmId + ]]> + <query-param name="pmfmId" type="java.lang.Integer"/> + <query-param name="unitIdNone" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <!-- [REF-T02] Get a pmfm qualitative values from his id --> + <query cacheable="true" name="pmfmQualitativeValues"> + <![CDATA[ + SELECT + qv.id AS id, + case when (qv.name = qv.description) then qv.name else concat(qv.name, ' - ', qv.description) end AS name, + qv.status AS status + FROM + PmfmImpl p JOIN p.qualitativeValues qv + WHERE + p.id= :pmfmId + AND qv.status.code IN (:statusValidCode, :statusTemporaryCode) + ]]> + <query-param name="pmfmId" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <!-- [REF-T03] Get all caracteristics --> + <query cacheable="true" name="allPmfm"> + <![CDATA[ + SELECT + p.id AS pmfmId, + p.parameter.name AS parameterName, + p.matrix.name AS matrixName, + p.fraction.name AS fractionName, + p.method.name AS methodName, + p.parameter.isAlphanumeric AS isAlphanumeric, + p.parameter.isQualitative AS isQualitative, + p.signifFiguresNumber, + p.maximumNumberDecimals, + p.precision, + case when (p.unit.id = :unitIdNone) then '' else p.unit.symbol end AS symbol, + p.status AS status + FROM PmfmImpl p + WHERE + p.status.code IN (:statusValidCode, :statusTemporaryCode) + AND p.parameter.isCalculated = false + ]]> + <query-param name="unitIdNone" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + + <!-- ===================================================================== --> + <!-- === Requete sur référentiels [REF-XXX] === --> + <!-- ===================================================================== --> + + <!-- [REF-01] Get all program zones --> + <query cacheable="true" name="allProgramZones"> + <![CDATA[ + SELECT + l.id, + l.label, + l.name, + l.status + FROM LocationImpl l + WHERE + l.locationLevel.id = :locationLevelId + AND l.locationClassification.id = :locationClassificationId + AND l.status.code IN (:statusValidCode, :statusTemporaryCode) + ]]> + <query-param name="locationLevelId" type="java.lang.Integer"/> + <query-param name="locationClassificationId" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <!-- [REF-02] Get all countries --> + <query cacheable="true" name="allCountries"> + <![CDATA[ + SELECT + l.id, + l.label, + l.name, + l.status + FROM LocationImpl l + WHERE + l.locationLevel.id = :locationLevelId + AND l.status.code IN (:statusValidCode, :statusTemporaryCode) + ]]> + <query-param name="locationLevelId" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <!-- [REF-03] Get all fishing operation strata / substrata / localite --> + <query cacheable="true" name="allFishingOperationLocationByParent"> + <![CDATA[ + SELECT + l.id as locationId, + l.label as locationLabel, + l.name as locationName, + l.locationLevel.id as locationLevelId, + l.status as status + FROM + LocationImpl l, + LocationHierarchyImpl lh + WHERE + l.status.code IN (:statusValidCode, :statusTemporaryCode) + AND l.locationLevel.id = :locationLevelId + AND l.locationClassification.id = :locationClassificationId + AND l.id = lh.locationHierarchyPk.location.id + AND lh.locationHierarchyPk.parent.id = :parentId + AND lh.locationHierarchyPk.parent.locationLevel.id = :parentLocationLevelId + ]]> + <query-param name="parentId" type="java.lang.Integer"/> + <query-param name="parentLocationLevelId" type="java.lang.Integer"/> + <query-param name="locationLevelId" type="java.lang.Integer"/> + <query-param name="locationClassificationId" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <query cacheable="true" name="allFishingOperationLocation"> + <![CDATA[ + SELECT + l.id as locationId, + l.label as locationLabel, + l.name as locationName, + l.locationLevel.id as locationLevelId, + l.status as status + FROM + LocationImpl l + WHERE + l.status.code IN (:statusValidCode, :statusTemporaryCode) + AND l.locationLevel.id = :locationLevelId + AND l.locationClassification.id = :locationClassificationId + ]]> + <query-param name="locationLevelId" type="java.lang.Integer"/> + <query-param name="locationClassificationId" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <!-- [REF-04] et [REF-05] Get all vessel for a given vesselType --> + <query cacheable="true" name="allVessels"> + <![CDATA[ + SELECT + v.code AS vesselCode, + vrp.registrationCode AS nationalRegistrationCode, + vrp.internationalRegistrationCode as internationalRegistrationCode, + vf.name AS vesselName, + v.status AS status + FROM + VesselImpl v + INNER JOIN v.vesselRegistrationPeriods AS vrp + LEFT OUTER JOIN v.vesselFeatures AS vf + WHERE + v.vesselType.id = :vesselTypeId + AND v.status.code IN (:statusValidCode, :statusTemporaryCode) + AND NOT(coalesce(vrp.endDateTime, '2999-12-31 00:00:00') < coalesce(:refDate,sysdate) + OR vrp.vesselRegistrationPeriodPk.startDateTime > coalesce(:refDate,sysdate) + ) + AND NOT(coalesce(vf.endDateTime, '2999-12-31 00:00:00') < coalesce(:refDate,sysdate) + OR vf.startDateTime > coalesce(:refDate,sysdate) + ) + ]]> + <query-param name="vesselTypeId" type="java.lang.Integer"/> + <query-param name="refDate" type="java.util.Date"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <query cacheable="true" name="allSimpleVessels"> + <![CDATA[ + SELECT + v.code AS vesselCode, + vf.name AS vesselName, + v.status AS status, + vf.startDateTime + FROM + VesselImpl v + INNER JOIN v.vesselFeatures AS vf + WHERE + v.vesselType.id = :vesselTypeId + AND v.status.code IN (:statusValidCode, :statusTemporaryCode) + ORDER BY vf.startDateTime DESC + ]]> + <query-param name="vesselTypeId" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <!-- Get a vessel for a given vesselType --> + <query cacheable="true" name="vessel"> + <![CDATA[ + SELECT + v.code AS vesselCode, + vrp.registrationCode AS nationalRegistrationCode, + vrp.internationalRegistrationCode as internationalRegistrationCode, + vf.name AS vesselName, + v.status AS status + FROM + VesselImpl v + INNER JOIN v.vesselRegistrationPeriods AS vrp + LEFT OUTER JOIN v.vesselFeatures AS vf + WHERE + v.code = :vesselCode + AND v.status.code IN (:statusValidCode, :statusTemporaryCode) + AND NOT(coalesce(vrp.endDateTime, '2999-12-31 00:00:00') < coalesce(:refDate,sysdate) + OR vrp.vesselRegistrationPeriodPk.startDateTime > coalesce(:refDate,sysdate) + ) + ORDER BY vf.startDateTime DESC + ]]> + <query-param name="vesselCode" type="java.lang.String"/> + <query-param name="refDate" type="java.util.Date"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <!-- Get a vessel for a given vesselType --> + <query cacheable="true" name="vessel2"> + <![CDATA[ + SELECT + vrp.registrationCode AS nationalRegistrationCode, + vrp.internationalRegistrationCode as internationalRegistrationCode + FROM + VesselImpl v + INNER JOIN v.vesselRegistrationPeriods AS vrp + WHERE + v.code = :vesselCode + AND NOT(coalesce(vrp.endDateTime, '2999-12-31 00:00:00') < coalesce(:refDate,sysdate) + OR vrp.vesselRegistrationPeriodPk.startDateTime > coalesce(:refDate,sysdate) + ) + ]]> + <query-param name="vesselCode" type="java.lang.String"/> + <query-param name="refDate" type="java.util.Date"/> + </query> + + <!-- [REF-06] [REF-07] Get all gears --> + <query cacheable="true" name="allGears"> + <![CDATA[ + SELECT + g.id, + g.label, + g.name, + g.status AS status + FROM GearImpl g + WHERE + g.gearClassification.id= :gearClassificiationId + AND g.status.code IN (:statusValidCode, :statusTemporaryCode) + ]]> + <query-param name="gearClassificiationId" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <query cacheable="true" name="gear"> + <![CDATA[ + SELECT + g.id, + g.label, + g.name, + g.status AS status + FROM GearImpl g + WHERE + g.id = :gearId + ]]> + <query-param name="gearId" type="java.lang.Integer"/> + </query> + + <!-- [REF-08] Get all persons --> + <query cacheable="true" name="allPersons"> + <![CDATA[ + SELECT DISTINCT + p.id, + p.lastname, + p.firstname, + p.department.code, + p.status + FROM + PersonImpl p + LEFT OUTER JOIN p.profils pp + WHERE + p.status.code IN (:statusValidCode, :statusTemporaryCode) + AND pp.id IN ( + :observerProfilId, + :projectMemberProfilId, + :userProfilId + ) + AND p.department.code LIKE 'PDG-%' + ]]> + <query-param name="observerProfilId" type="java.lang.Integer"/> + <query-param name="projectMemberProfilId" type="java.lang.Integer"/> + <query-param name="userProfilId" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <!-- [REF-08-1] Get one person --> + <query cacheable="true" name="person"> + <![CDATA[ + SELECT DISTINCT + p.id, + p.firstname, + p.lastname, + p.department.code, + p.status + FROM PersonImpl p + WHERE p.id = :personId + ]]> + <query-param name="personId" type="java.lang.Integer"/> + </query> + + <!-- [REF-16] Get all length step catacteristics --> + <query cacheable="true" name="allLengthStepCaracteristics"> + <![CDATA[ + SELECT + p.id AS pmfmId, + p.parameter.name AS parameterName, + p.matrix.name AS matrixName, + p.fraction.name AS fractionName, + p.method.name AS methodName, + p.parameter.isAlphanumeric AS isAlphanumeric, + p.parameter.isQualitative AS isQualitative, + p.signifFiguresNumber, + p.maximumNumberDecimals, + p.precision, + p.unit.symbol AS symbol, + p.status AS status + FROM PmfmImpl p + WHERE + p.status.code IN (:statusValidCode, :statusTemporaryCode) + AND p.matrix.id = :matrixId + AND p.parameter.isQualitative=false + AND p.parameter.isAlphanumeric=false + AND p.parameter.isCalculated=false + AND p.parameter.code not in (:ageParameterCode, :weightParameterCode) + AND p.method.id <> :methodDeclarationId + ]]> + <query-param name="matrixId" type="java.lang.Integer"/> + <query-param name="ageParameterCode" type="java.lang.String"/> + <query-param name="weightParameterCode" type="java.lang.String"/> + <query-param name="methodDeclarationId" type="java.lang.Integer"/> + <query-param name="statusValidCode" type="java.lang.String"/> + <query-param name="statusTemporaryCode" type="java.lang.String"/> + </query> + + <!-- ===================================================================== --> + <!-- === Fetch profiles === --> + <!-- ===================================================================== --> + + + <!--<fetch-profile name="tutti">--> + <!--TODO Create fetch profile to avoid eager loading --> + <!--</fetch-profile>--> + + <fetch-profile name="batch-with-measurements"> + <fetch entity="BatchImpl" association="quantificationMeasurements" style="join"/> + <fetch entity="CatchBatchImpl" association="quantificationMeasurements" style="join"/> + <fetch entity="SortingBatchImpl" association="sortingMeasurements" style="join"/> + <fetch entity="SortingBatchImpl" association="quantificationMeasurements" style="join"/> + </fetch-profile> + <fetch-profile name="batch-with-childs"> + <fetch entity="BatchImpl" association="childBatchs" style="join"/> + </fetch-profile> + + +</hibernate-mapping> Copied: trunk/tutti-persistence/src/main/resources/tutti-db-conf.properties (from rev 298, trunk/tutti-persistence-adagio/src/main/resources/tutti-db-conf.properties) =================================================================== --- trunk/tutti-persistence/src/main/resources/tutti-db-conf.properties (rev 0) +++ trunk/tutti-persistence/src/main/resources/tutti-db-conf.properties 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,47 @@ +### +# #%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% +### +# dataSource : jndi ou local +dataSource.type=local + +# Si 'dataSource.type=jndi' : +# - pour tomcat : jdbc/adagio-ds +# - pour jboss : java:jdbc/adagio-ds +#dataSource.jndi-name=jdbc/adagio-ds + +# Si 'dataSource.type=local' : +dataSource.jdbc.driver=${tutti.persistence.jdbc.driver} +dataSource.jdbc.username=${tutti.persistence.jdbc.username} +dataSource.jdbc.password=${tutti.persistence.jdbc.password} +dataSource.jdbc.url=${tutti.persistence.jdbc.url} +#dataSource.jdbc.url=jdbc:hsqldb:hsql://localhost/toto + +# Hibernate configuration : +hibernate.dialect=${tutti.persistence.hibernate.dialect} +hibernate.show_sql=${tutti.persistence.hibernate.showSql} +hibernate.format_sql=${tutti.persistence.hibernate.formatSql} +hibernate.use_sql_comments=${tutti.persistence.hibernate.useSqlComment} +hibernate.generate_statistics=false +hibernate.query.substitutions=true 1, false 0 +hibernate.hbm2ddl.auto=none +hibernate.default_batch_fetch_size=1 \ No newline at end of file Copied: trunk/tutti-persistence/src/main/resources/tutti-db-enumerations.properties (from rev 298, trunk/tutti-persistence-adagio/src/main/resources/tutti-db-enumerations.properties) =================================================================== --- trunk/tutti-persistence/src/main/resources/tutti-db-enumerations.properties (rev 0) +++ trunk/tutti-persistence/src/main/resources/tutti-db-enumerations.properties 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,378 @@ +### +# #%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% +### +# Version de preprod + +AcquisitionLevelCode.ACTIVITY=MONTHLY_ACTIVITY +AcquisitionLevelCode.ACTIVITY_CALENDAR=ACTIVITY_CALENDAR +AcquisitionLevelCode.BATCH=BATCH +AcquisitionLevelCode.FISHING_EFFORT_CALENDAR=EFFORT_CALENDAR +AcquisitionLevelCode.FISHING_OPERATION=OPERATION +AcquisitionLevelCode.FISHING_TRIP=FISHING_TRIP +AcquisitionLevelCode.FISHING_TRIP_PHYSICAL_GEAR=OBSERVED_FISHING_TRIP_PHYSICAL_GEAR +AcquisitionLevelCode.LANDING=LANDING +AcquisitionLevelCode.MONTHLY_EFFORT=MONTHLY_FISHING_EFFORT +AcquisitionLevelCode.OBSERVED_LANDING=OBSERVED_LANDING +AcquisitionLevelCode.OBSERVED_SALE=OBSERVED_SALE +AcquisitionLevelCode.OBSERVED_TRIP_ON_BOARD=OBSERVED_FISHING_TRIP +AcquisitionLevelCode.OPERATION=OPERATION_fake +AcquisitionLevelCode.OPERATION_GROUP=OPERATION_GROUP +AcquisitionLevelCode.PHYSICAL_GEAR=PHYSICAL_GEAR_SURVEY +AcquisitionLevelCode.SALE=SALE +AcquisitionLevelCode.SALE_SURVEY=SALE_SURVEY +AcquisitionLevelCode.SAMPLE=SAMPLE +AcquisitionLevelCode.SCIENTIFIC_CRUISE=SCIENTIFIC_CRUISE +AcquisitionLevelCode.VESSEL_PHYSICALFEATURES=VESSEL_PHYSICAL_FEATURES +AcquisitionLevelCode.YEARLYEFFORT=YEARLY_FISHING_EFFORT +AcquisitionLevelCode.CONTROLS_REFERENTIAL=CONTROLS_REFERENTIAL +ActivityCalendarNumericalPmfmIds.GREATER_VALUE_PMFM=241 +ActivityCalendarNumericalPmfmIds.LOWER_VALUE_PMFM=242 +AggregationLevelId.DAY=4 +AggregationLevelId.FISHING_TRIP=9 +AggregationLevelId.HOUR=3 +AggregationLevelId.MONTH=21 +AggregationLevelId.NONE=1 +AggregationLevelId.SEMESTER=7 +AggregationLevelId.TRIMESTER=6 +AggregationLevelId.YEAR=8 +CriteriaType.DEFAULT=0 +CriteriaType.EXISTS=3 +CriteriaType.JOIN=1 +CriteriaType.NOT_EXISTS=4 +CriteriaType.SELECT=2 +DepartmentCode.OUTSIDE=EXTERIEUR +Filters.RESULTS_SIZE_WARNING_VALUE=10000 +FractionId.ALL=1 +FractionId.GEAR=2 +GearClassificationId.CNTS=5 +GearClassificationId.EU=4 +GearClassificationId.FAO=1 +GearClassificationId.SCIENTIFIC_CRUISE=5 +GearUseFeaturesOriginMapping.ACTIVITY_CALENDAR=Activit\u00E9 N-1|<PROGRAM>,Enqu\u00EAteur|<INVESTIGATOR>,Document d\u00E9claratif|<DECLARATIVE>,Ventes|OFIMER +GearUseFeaturesOriginMapping.EFFORT_CALENDAR=Activit\u00E9 N-1|<PROGRAM>,Enqu\u00EAteur|<INVESTIGATOR>,Document d\u00E9claratif|<DECLARATIVE>,Ventes|OFIMER +isActive.ACTIVE=1 +isActive.INACTIVE=0 +isActive.NOT_EXISTS=2 +LocationClassificationId.REGULATION=3 +LocationClassificationId.SECTOR=2 +LocationClassificationId.TERRITORIAL=1 +LocationLabel.FRANCE=FRA +LocationLabel.MEDITERRANEAN_AND_BLACK_SEA=37 +LocationLevelId.CRIEE=7 +LocationLevelId.DEPARTEMENT=32 +LocationLevelId.FAO_ZONE=101 +LocationLevelId.PAYS_ISO3=21 +LocationLevelId.PORT=6 +LocationLevelId.QUARTIER=13 +LocationLevelId.RECTANGLE_STATISTIQUE=113 +LocationLevelId.REGION=31 +LocationLevelId.SOUS_RECTANGLE_STATISTIQUE=114 +ManageDataTypeId.ACTIVITY_CALENDAR=4 +ManageDataTypeId.OBSERVED_FISHING_TRIP_ON_BOARD=5 +ManageDataTypeId.PHYSICAL_GEAR_SURVEY=7 +ManageDataTypeId.SALE=8 +ManageDataTypeId.SCIENTIFIC_CRUISE=9 +MatrixId.FISHING_METIER=6 +MatrixId.GEAR=3 +MatrixId.OPERATION=21 +MatrixId.VESSEL=5 +MatrixId.SUPPORT_WITH_GEAR=17 +MatrixId.SUPPORT_WITH_METIER=18 +MethodId.ALIVE_WEIGHT_EQUIVALENT=5 +MethodId.ESTIMATED=45 +MethodId.HEIGHT_WEIGHT=47 +MethodId.TOTAL_BATCH=283 +OrderTypeId.NORTH_SOUTH_LOCATION_RANK=1 +ParameterCode.ANOTHER_SURVEY=ACCEPT_OTHER_SURVEY +ParameterCode.BULK=SORTED +ParameterCode.CALCULATED_WEIGHT=WEIGHT_CALCULATED +ParameterCode.CONTRACT_CODE=CONTRACT_CODE +ParameterCode.CREW_SIZE=CREW_SIZE +ParameterCode.DATA_RELIABILITY=SURVEY_RELIABILITY +ParameterCode.DISCARD_TYPE=DISCARD_TYPE +ParameterCode.ENGIN_TIME=ENGIN_DURATION +ParameterCode.FISHING_DAY_COUNT=FISHING_DURATION +ParameterCode.GEAR_DEPTH=GEAR_DEPTH +ParameterCode.IS_SAMPLING=IS_SAMPLING +ParameterCode.LANDING_REJECTION=DISCARD_OR_LANDING +ParameterCode.PRESENTATION=DRESSING +ParameterCode.PROCEEDING=TRIP_PROGRESS +ParameterCode.RECEPTION_QUALITY=WELCOME_QUALITY +ParameterCode.SEA_DAY_COUNT=DURATION_AT_SEA +ParameterCode.SEA_STATE=SEA_STATE +ParameterCode.SEX=SEX +ParameterCode.SIZE=LENGTH_TOTAL +ParameterCode.STATUS=QUALITY +ParameterCode.SURVEY_QUALIFICATION=SURVEY_QUALIFICATION +ParameterCode.VALIDATION_PROGRAM=IS_VALIDATED_PRG +ParameterCode.VALIDATION_SUPERVISOR=IS_VALIDATED +ParameterCode.WEIGHT=WEIGHT +ParameterCode.SIZE_UNLI_CAT=SIZE_UNLI_CAT +ParameterCode.SIZE_UE_CAT=SIZE_UE_CAT +ParameterCode.CASE=CASE +ParameterCode.SORTING_TYPE=SORTING_TYPE +ParameterCode.PRESERVATION=PRESERVATION +ParameterCode.DRESSING=DRESSING +ParameterCode.AGE=AGE +ParameterCode.LENGTH_TOTAL=LENGTH_TOTAL +ParameterCode.LONG_CARAPACE=LONG_CARAPACE +ParameterCode.LENGTH_PREANAL=LENGTH_PREANAL +ParameterCode.LENGTH=LENGTH +ParameterCode.LENGTH_CARAPACE=LENGTH_CARAPACE +ParameterCode.LENGTH_FORK=LENGTH_FORK +ParameterCode.LENGTH_LM_FORK=LENGTH_LM_FORK +ParameterCode.LENGTH_MANTLE=LENGTH_MANTLE +ParameterCode.LENGTH_PELVIC=LENGTH_PELVIC +ParameterCode.LENGTH_PRE_SUPRA_CAUDAL=LENGTH_PRE_SUPRA_CAUDAL +ParameterCode.LENGTH_STANDARD=LENGTH_STANDARD +ParameterCode.BEAM_LENGTH=BEAM_LENGTH +ParameterCode.BEAM_TOTAL_LENGTH=BEAM_TOTAL_LENGTH +ParameterCode.GEAR_TOTAL_LENGTH=GEAR_TOTAL_LENGTH +ParameterCode.HEADLINE_LENGTH=HEADLINE_LENGTH +ParameterCode.LBP=LBP +ParameterCode.LG_ENGINS_PERDUS=LG_ENGINS_PERDUS +ParameterCode.LG_RELEVEE=LG_RELEVEE +ParameterCode.LOA=LOA +ParameterCode.LONG=LONG +ParameterCode.LONGLINE_LENGTH=LONGLINE_LENGTH +ParameterCode.LONG_FORK=LONG_FORK +ParameterCode.LONG_MANTLE=LONG_MANTLE +ParameterCode.NET_LENGTH=NET_LENGTH +ParameterCode.SEGMENT_LENGTH=SEGMENT_LENGTH +ParameterCode.SEINE_LENGTH=SEINE_LENGTH +ParameterCode.STD_CURVE_LENGTH=STD_CURVE_LENGTH +ParameterCode.STD_STRAIGTH_LENGTH=STD_STRAIGTH_LENGTH +ParameterCode.SWEEP_LENGTH=SWEEP_LENGTH +ParameterCode.TOTAL_LENGTH_HAULED=TOTAL_LENGTH_HAULED +ParameterCode.TOTAL_LENGTH_SOAKED=TOTAL_LENGTH_SOAKED +ParameterCode.WARP_LENGTH=WARP_LENGTH +ParameterCode.CIRCUMFERENCE=CIRCUMFERENCE +ParameterCode.WIDTH=WIDTH +ParameterGroupId.SURVEY_MEASUREMENT=21 +PmfmId.ALIVE_WEIGHT_CALCULATED=WEIGHT_CALCULATED;1;1;5 +PmfmId.CALCULATED_WEIGHT_CHILDREN_SUM=WEIGHT_CALCULATED;1;1;341 +PmfmId.WEIGHT_SIZE_CALCULATED=WEIGHT_CALCULATED;1;1;47 +PmfmId.WEIGHT_SIZE_EXTRAPOLATE=WEIGHT_CALCULATED;1;1;283 +PmfmId.WEIGHT_TOTAL_CALCULATED=WEIGHT_CALCULATED;1;1;22 +PmfmId.MAX_DURATION_FOR_OPERATION_WITH_GEAR=DUREE_MAX_OPERATION;17;1;1 +PmfmId.MAX_DISTANCE_FOR_OPERATION_WITH_GEAR=DISTANCE_MAX_OPERATION;17;1;1 +PmfmId.MAX_DURATION_FOR_OPERATION_WITH_METIER=DUREE_MAX_OPERATION;18;1;1 +PmfmId.MAX_DISTANCE_FOR_OPERATION_WITH_METIER=DISTANCE_MAX_OPERATION;18;1;1 +PmfmId.STORAGE_STATE=CLOSE_OBSVENTE_STOCK;61;61;21 +ProgramCode.ACTIVITY=SIH-ACTIFLOT +ProgramCode.ACTIVITY_MERGE=SIH-ACTIFLOT-CONFLIT +ProgramCode.DECLARATIVE_FLOW=SIH-ACTIPRED +ProgramCode.PRE_RECOPESCA=SIH-preRECOPESCA +ProgramCode.RECOPESCA=SIH-RECOPESCA +ProgramCode.SIH_OBSERVED_FISHING_TRIP_ON_BOARD=SIH-OBSMER +ProgramCode.SIH_OBSMER=SIH-OBSMER +ProgramCode.SIH_STATPECHE_CONFLIT=SIH-ACTIFLOT-CONFLIT +ProgramCode.STAT_PECHE=SIH-ACTIFLOT +SaleDateControlByProgram.MAX_DAYS_AFTER_FISHING_TRIP=SIH-OBSMER|3,SIH-OBSVENTE|3 +BatchControl.SORTING_CRITERIA_PARAMETER_NEEDS_REFERENCE_WEIGHT=DRESSING,SIZE_UNLI_CAT,SEX +BatchControl.CHILDREN_SUM_DIFFERENCE_BETWEEN_REFERENCE_AND_SIZE_WEIGHT_RULE1_THRESHOLD_PERCENT=SIH-OBSMER|50,SIH-OBSVENTE|50 +BatchControl.CHILDREN_SUM_DIFFERENCE_BETWEEN_REFERENCE_AND_SIZE_WEIGHT_RULE1_KILO_MIN=SIH-OBSMER|5,SIH-OBSVENTE|5 +BatchControl.CHILDREN_SUM_DIFFERENCE_BETWEEN_REFERENCE_AND_SIZE_WEIGHT_RULE2_THRESHOLD_PERCENT=SIH-OBSMER|100,SIH-OBSVENTE|100 +BatchControl.CHILDREN_SUM_DIFFERENCE_BETWEEN_REFERENCE_AND_SIZE_WEIGHT_RULE2_KILO_MAX=SIH-OBSMER|5,SIH-OBSVENTE|5 +ProgramManagedDataTypeMapping.FISHING_TRIP=SIH-OBSMER|5 +ProgramManagedDataTypeMapping.SALE=SIH-OBSVENTE|8 +ProgramObjectTypeMapping.FISHING_TRIP=SIH-OBSMER|OBSERVED_FISHING_TRIP +ProgramObjectTypeMapping.SALE=SIH-OBSVENTE|OBSERVED_SALE +ProgramPrivilegeId.MANAGER=1 +ProgramPrivilegeId.QUALIFICATOR=5 +ProgramPrivilegeId.RECORDER=2 +ProgramPrivilegeId.VALIDATOR=4 +ProgramPrivilegeId.VIEWER=3 +QualitativeValueId.ABNORMAL=328 +QualitativeValueId.ANOTHER_SURVEY_NO=847 +QualitativeValueId.ANOTHER_SURVEY_YES=846 +QualitativeValueId.DIRECT_SURVEY=965 +QualitativeValueId.DISCARD_TYPE_ANIMALS=407 +QualitativeValueId.ESTIMATE_SURVEY=967 +QualitativeValueId.FRY_STATUS=142 +QualitativeValueId.INDIRECT_SURVEY=966 +QualitativeValueId.INTEGRAL_PRESENTATION=139 +QualitativeValueId.IS_SAMPLING=415 +QualitativeValueId.LANDING=203 +QualitativeValueId.NON_SEXED_SEX=302 +QualitativeValueId.VALIDATION_PROGRAM_DO_CORRECTION=942 +QualitativeValueId.VALIDATION_SUPERVISOR_NO=418 +QualitativeValueId.VALIDATION_SUPERVISOR_YES=417 +QualitativeValueId.SORTING_TYPE_TPN=1746 +QualitativeValueId.SORTING_TYPE_TCC=1747 +QualitativeValueId.REJECTED=204 +QualitativeValueId.VRAC=311 +QualityFlagCode.BAD=4 +QualityFlagCode.CORRECTED=5 +QualityFlagCode.DOUBTFUL=3 +QualityFlagCode.GOOD=1 +QualityFlagCode.INCOMPLETE=8 +QualityFlagCode.MISSING=9 +QualityFlagCode.NOTQUALIFIED=0 +QualityFlagCode.OUT_OF_STAT=2 +QualityFlagConfiguration.COLOR_MAPPING=GOOD|0,128,0;DOUBTFUL|255,128,0;BAD|255,0,0;CORRECTED|0,128,255 +QualityFlagConfiguration.INVALID_FLAG_LIST=2,4,8,9 +SaleTypeId.COOPERATIVE=-5 +SaleTypeId.CRIEE=1 +SaleTypeId.HORS_CONTROLE=9 +SaleTypeId.MARCHE_EXTERIEUR=5 +SaleTypeId.MARCHE_INTERIEUR=4 +SaleTypeId.MAREYEUR=2 +SaleTypeId.POISSONNIER=-6 +SaleTypeId.PRODUCTEUR=6 +SaleTypeId.RESTAURATION_COLLECTIVE=-3 +SaleTypeId.RESTAURATION_PRIVEE=-2 +SaleTypeId.RETRAIT_OP=7 +SaleTypeId.RETRAIT_SANITAIRE=8 +SaleTypeId.SUPERMARCHE=-4 +SaleTypeId.TRANSFORMATEUR=3 +SaleTypeId.VENTE_PARTICULIER=-1 +SamplingSchemeControl.MANDATORY_PROGRAM_LIST=SIH-OBSVENTE +SpatialItemTypeId.DEPTH_GRADIENT=1 +SpatialItemTypeId.DISTANCE_TO_COAST_GRADIENT=3 +SpatialItemTypeId.GEAR=5 +SpatialItemTypeId.METIER=7 +SpatialItemTypeId.NEARBY_SPECIFIC_AREA=2 +SpatialItemTypeId.TAXON_GROUP=4 +StatusCode.DELETED=3 +StatusCode.DISABLE=0 +StatusCode.ENABLE=1 +StatusCode.TEMPORARY=2 +StorageStateValues.CLOSED=69 +SurveyQualificationId.DIRECT=0 +SurveyQualificationId.ESTIMATION=0 +SurveyQualificationId.INDIRECT=0 +SurveyQualificationId.PREDOCUMENTATION=0 +SurveyQualificationId.UNKNOWN=0 +SynchronizationStatus.DELETED=DELETED +SynchronizationStatus.DIRTY=DIRTY +SynchronizationStatus.READY_TO_SYNCHRONIZE=READY_TO_SYNC +SynchronizationStatus.SYNCHRONIZED=SYNC +TaxonGroupId.FISH=1712 +TaxonGroupTypeCode.COMMERCIAL_SPECIES=2 +TaxonGroupTypeCode.METIER_SPECIES=3 +TaxonomicLevelCode.SPECIES=SPECIES +TaxonomicLevelCode.VARIETY=SUBSPECIES +TranscribingSideId.IN=2 +TranscribingSideId.IN_OUT=3 +TranscribingSideId.OUT=1 +TranscribingSystemId.FAO=4 +TranscribingSystemId.HARMONIE=5 +TranscribingSystemId.OFIMER=3 +TranscribingSystemId.SIPA=2 +UnitId.DAY=17 +UnitId.DECIMAL_HOURS=9 +UnitId.MILLIMETER=6 +UnitId.NONE=1 +UserProfilId.OBSERVER=2 +UserProfilId.PROJECT_MEMBER=3 +UserProfilId.REFERENTIAL_ADMINISTRATOR=1 +UserProfilId.USER=4 +VesselTypeId.FISHING_VESSEL=1 +VesselTypeId.FISHING_VESSEL_GROUP=2 +VesselTypeId.PLEASURE_BOAT=4 +VesselTypeId.SCIENTIFIC_RESEARCH_VESSEL=8 +VesselTypeId.SHELLFISH_GATHERER=3 +ZoneCompetenceMapping.GROUND=Corse|394;391,Guadeloupe|430,Guyanne|423,La Réunion|433,Martinique|425,Mayotte|424;429,Méditerranée|408;410;420;415;419;415;419,Mer du nord manche atlantique|386;387;388;389;390;392;393;395;396;397;398;399;400;401;402;403;404;405;406;407;409;411;412;414;416;417;418;421;422;432;435;436,Saint Pierre et Miquelon|434 +ZoneCompetenceMapping.SEA=Corse|4022,Guadeloupe|4020,Guyanne|4020,La Réunion|4028,Martinique|4020,Mayotte|4028,Méditerranée|4022,Mer du nord manche atlantique|4018,Saint Pierre et Miquelon|4017 +ZoneCompetenceMapping.DEFAULT_LOCATION_LEVEL=Corse|142,Guadeloupe|158;159,Guyanne|154;156,La Réunion|151;152,Martinique|158;159,Mayotte|,Méditerranée|142,Mer du nord manche atlantique|113;114,Saint Pierre et Miquelon|101 + +# 10/01/2012 BLA Need to retrieve a Location from a given position (Lat/Long) +LocationLevelId.RECTANGLE_STATISTIQUE_MED=145 + +################################################################################ +### Ajout pour Tutti ########################################################### +################################################################################ + +# zone d'étude +LocationLevelId.PROGRAM=301 +# strate +LocationLevelId.STRATA=302 +# sous strate +LocationLevelId.SUB_STRATA=303 +# localité +LocationLevelId.LOCALITE=304 +# radiale +LocationLevelId.RADIALE=305 + +PmfmId.SEX=196 +PmfmId.SIZE_CATEGORY=198 +PmfmId.AGE=1430 + +# Catégorie maturité +PmfmId.MATURITY=174 + +# Catégorie macro-déchet +PmfmId.MARINE_LITTER_TYPE=1421 + +# Classe de taille macro-déchet +PmfmId.MARINE_LITTER_SIZE_CATEGORY=1422 + +# TODO A creer (dans les enumerations Allegro) +PmfmId.STATION_NUMBER=1243 +# TODO A creer (dans les enumerations Allegro) +PmfmId.TRAWL_DISTANCE=113 +# TODO A creer (dans les enumerations Allegro) +PmfmId.HAUL_VALID=1163 +QualitativeValueId.HAUL_VALID_YES=1575 +QualitativeValueId.HAUL_VALID_NO=1576 +# TODO A creer (dans les enumerations Allegro) +PmfmId.RECTILINEAR_OPERATION=192 +QualitativeValueId.RECTILINEAR_OPERATION_YES=277 +# TODO A creer (dans les enumerations Allegro) +QualitativeValueId.RECTILINEAR_OPERATION_NO=278 + +# PSFM "Nombre de poche" d'un chalut (écran campagne) +PmfmId.MULTIRIG_NUMBER=1420 +# PSFM "Liste des poches observées" (écran opération) +PmfmId.MULTIRIG_AGGREGATION=1424 + +# TODO A creer (dans les enumerations Allegro) +# PSFM "Poids - observation par une observateur" (écran captures, onglet espèce, benthos, etc) +PmfmId.WEIGHT_MEASURED=220 + +# TODO A creer (dans les enumerations Allegro) +# PSFM "Vaac/Hors Vrac" - "Organisation des données campagnes" +PmfmId.SORTED_UNSORTED=1428 +QualitativeValueId.SORTED_VRAC=311 +QualitativeValueId.SORTED_HORS_VRAC=310 +QualitativeValueId.UNSORTED=2146 + +PmfmId.SCIENTIFIC_CRUISE_SORTING_TYPE=1429 +QualitativeValueId.SORTING_TYPE_SPECIES=2147 +QualitativeValueId.SORTING_TYPE_BENTHOS=2148 +QualitativeValueId.SORTING_TYPE_PLANCTON=2149 +QualitativeValueId.SORTING_TYPE_MACRO_WASTE=2150 +QualitativeValueId.SORTING_TYPE_ACCIDENTAL_CATCH=2151 + + +#TODO A creer (dans les enumerations Allegro) +# (20=observateur volant, 95=Administrateur SIH) -> L'avantage du 20 est qu'il est inactif (=20), donc plus facilement detectable +PersonId.UNKNOWN_RECORDER_PERSON=20 + +#TODO A creer (dans les enumerations Allegro) +# 181=PDG-RBE (à confirmer par Vincent) +DepartmentId.UNKNOWN_RECORDER_DEPARTMENT=181 + +#TODO A creer (dans les enumerations Allegro) +ProgramCode.SCIENTIFIC_CRUISE_PREFIX=CAM- \ No newline at end of file Property changes on: trunk/tutti-persistence/src/test ___________________________________________________________________ Added: svn:ignore + db Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/DatabaseFixtures.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/DatabaseFixtures.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/DatabaseFixtures.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/DatabaseFixtures.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,228 @@ +package fr.ifremer.tutti.persistence; + +/* + * #%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% + */ + +/** + * Fixtures for the allegro db. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class DatabaseFixtures { + + public String programCode() { + // campaign CGFS + return "CAM-CGFS"; + } + + public String cruiseId() { + // cruise CGFS2010 + return "100000"; + } + + public String fishingVesselCode() { + return "851751"; + } + + public String zoneId() { + // zone CGFS + return "61979"; + } + + public String strataId() { + // strate 6M + return "57377"; + } + + public String subStrataId() { + // substrata 61995 + return "61995"; + } + + public String localite() { + // Localite 8Q3 + return "57774"; + } + + public int nbPmfm() { + return 551; + } + + public int nbGearClassification() { + return 5; + } + + public int nbGear() { + return 192; + } + + public int refNbCaracteristic() { + return 482; + } + + public int refNbSpecies() { + return 8516; + } + + public int refNbScientificGear() { + return 9; + } + + public int refNbFishingGear() { + return 75; + } + + public int refNbCountry() { + return 240; + } + + public int refNbProgramZone() { + return 16; + } + + public int refNbStrata() { + return 76; + } + + public int refNbSubStrata() { + return 16; + } + + public int refNbLocalite() { + return 129; + } + + public int nbLocationClassification() { + return 3; + } + + public int nbLocationLevel() { + return 87; + } + + public int nbLocation() { + return 58488; + } + + public int nbTaxonomicLevel() { + return 30; + } + + public int nbReferenceTaxon() { + return 8690; + } + + public int nbTaxonName() { + return 16901; + } + + public int nbTaxonGroupType() { + return 4; + } + + public int nbTaxonGroup() { + return 13357; + } + + public int nbRoundWeightConversion() { + return 3518; + } + + public int nbWeightLegnthConversion() { + return 2579; + } + + public int nbVesselType() { + return 10; + } + + public int nbVessel() { + return 193007; + } + + public int refNbFishingVessel() { + return 24805; + } + + public int refNbScientificVessel() { + return 2; + } + + public int nbUserProfil() { + return 4; + } + + public int nbDepartment() { + return 77; + } + + public int nbPerson() { + return 430; + } + + public int refNbPerson() { + return 123; + } + + public int nbQualitativeValue() { + return 1196; + } + + public int nbStatus() { + return 4; + } + + public int nbQualityFlag() { + return 8; + } + + public int nbUnit() { + return 30; + } + + public int nbAggregationLevel() { + return 8; + } + + public int nbParameterGroup() { + return 11; + } + + public int nbParameter() { + return 300; + } + + public int nbMatrix() { + return 17; + } + + public int nbFraction() { + return 54; + } + + public int nbMethod() { + return 42; + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/DatabaseResource.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/DatabaseResource.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/DatabaseResource.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/DatabaseResource.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,288 @@ +package fr.ifremer.tutti.persistence; + +/* + * #%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.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.io.Files; +import fr.ifremer.tutti.persistence.config.TuttiPersistenceConfig; +import fr.ifremer.tutti.persistence.config.TuttiPersistenceConfigOption; +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator; +import org.apache.commons.io.FileUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assume; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.nuiton.util.ApplicationConfig; + +import java.io.File; +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; +import java.util.Set; + +/** + * To box the persistence service as a test resource. + * + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class DatabaseResource implements TestRule { + + /** Logger. */ + private static final Log log = LogFactory.getLog(DatabaseResource.class); + + public static final String TUTTI_PERSISTENCE_JDBC_CREATE_SCRIPT = "tutti.persistence.jdbc.createScript"; + + public static long BUILD_TIMESTAMP = System.nanoTime(); + + private static ClassLoader oldClassLoader; + + private File resourceDirectory; + + private TuttiPersistenceConfig config; + + private DatabaseFixtures fixtures; + + private final String beanFactoryReferenceLocation; + + private final String beanRefFactoryReferenceId; + + public DatabaseResource() { + this(null, null); + } + + public DatabaseResource(String beanFactoryReferenceLocation, + String beanRefFactoryReferenceId) { + this.beanFactoryReferenceLocation = beanFactoryReferenceLocation; + this.beanRefFactoryReferenceId = beanRefFactoryReferenceId; + } + + public TuttiPersistenceConfig getConfig() { + return config; + } + + public DatabaseFixtures getFixtures() { + return fixtures; + } + + public File getResourceDirectory(String name) { + return new File(resourceDirectory, name); + } + + @Override + public Statement apply(final Statement base, final Description description) { + + return new Statement() { + @Override + public void evaluate() throws Throwable { + before(description); + try { + base.evaluate(); + } finally { + after(description); + } + } + }; + } + + protected void before(Description description) throws Throwable { + Class<?> testClass = description.getTestClass(); + + File db = new File("src/test/db"); + if (!db.exists()) { + + if (log.isWarnEnabled()) { + log.warn("Could not find db at " + db + ", test [" + + testClass + "] is skipped."); + } + Assume.assumeTrue(false); + } + + if (log.isInfoEnabled()) { + log.info("Prepare test " + testClass); + } + + fixtures = new DatabaseFixtures(); + + resourceDirectory = getTestSpecificDirectory(testClass, ""); + + RessourceClassLoader loader = + new RessourceClassLoader(testClass.getClassLoader()); + + oldClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(loader); + + ApplicationConfig applicationConfig = + new ApplicationConfig("tutti-test.properties"); + applicationConfig.loadDefaultOptions( + TuttiPersistenceConfigOption.values()); + applicationConfig.setDefaultOption("tutti.data.directory", + resourceDirectory.getAbsolutePath()); + applicationConfig.parse(); + + config = new TuttiPersistenceConfig(applicationConfig); + + config.initConfig(loader); + + TuttiPersistenceConfig.setInstance(config); + + if (log.isDebugEnabled()) { + log.debug("Use conf.properties at " + config.getDbConfigurationPath()); + } + + if (beanFactoryReferenceLocation != null) { + TuttiPersistenceServiceLocator.initTutti( + beanFactoryReferenceLocation, + beanRefFactoryReferenceId); + } + } + + protected void after(Description description) throws IOException { + Class<?> testClass = description.getTestClass(); + if (log.isInfoEnabled()) { + log.info("After test " + testClass); + } + // push back old classLoader + if (oldClassLoader != null) { + Thread.currentThread().setContextClassLoader(oldClassLoader); + } + + TuttiPersistenceServiceLocator.close(); + + if (beanFactoryReferenceLocation != null) { + + // push back default tutti configuration + TuttiPersistenceServiceLocator.initTuttiDefault(); + } + + TuttiPersistenceConfig.setInstance(null); + } + + public Connection createEmptyDb(String dbDirectory, + String dbName) throws IOException, SQLException { + File externalDbFile = getResourceDirectory(dbDirectory); + return createEmptyDb(externalDbFile, dbName); + } + + public static File getTestSpecificDirectory(Class<?> testClass, + String name) throws IOException { + // Trying to look for the temporary folder to store data for the test + String tempDirPath = System.getProperty("java.io.tmpdir"); + if (tempDirPath == null) { + // can this really occur ? + tempDirPath = ""; + if (log.isWarnEnabled()) { + log.warn("'\"java.io.tmpdir\" not defined"); + } + } + File tempDirFile = new File(tempDirPath); + + // create the directory to store database data + String dataBasePath = testClass.getName() + + File.separator // a directory with the test class name + + name // a sub-directory with the method name + + '_' + + BUILD_TIMESTAMP; // and a timestamp + File databaseFile = new File(tempDirFile, dataBasePath); + FileUtils.forceMkdir(databaseFile); + + return databaseFile; + } + + public Connection createEmptyDb(File directory, + String dbName) throws SQLException, IOException { + + if (log.isInfoEnabled()) { + log.info("Create new db at " + directory); + } + String jdbcUrl = "jdbc:hsqldb:file:" + directory.getAbsolutePath() + "/" + dbName; + String user = "SA"; + String password = ""; + + File scriptFile = config.getConfig().getOptionAsFile(TUTTI_PERSISTENCE_JDBC_CREATE_SCRIPT); + + Preconditions.checkNotNull("Could not find db script in configuration with key " + TUTTI_PERSISTENCE_JDBC_CREATE_SCRIPT); + Preconditions.checkState(scriptFile.exists(), "Could not find db script at " + scriptFile); + + if (log.isInfoEnabled()) { + log.info("Will use create script: " + scriptFile); + } + Connection connection = TuttiEntities.createConnection(jdbcUrl, user, password); + + if (log.isInfoEnabled()) { + log.info("Created connection at " + connection.getMetaData().getURL()); + } + + List<String> importScriptSql = getImportScriptSql(scriptFile); + for (String sql : importScriptSql) { + PreparedStatement statement = connection.prepareStatement(sql); + statement.execute(); + } + connection.commit(); + return connection; + } + + protected List<String> getImportScriptSql(File scriptFile) throws IOException { + List<String> lines = Files.readLines(scriptFile, Charsets.UTF_8); + + List<String> result = Lists.newArrayListWithCapacity(lines.size()); + + Predicate<String> predicate = new Predicate<String>() { + + Set<String> forbiddenStarts = Sets.newHashSet( + "SET ", + "CREATE USER ", + "CREATE SCHEMA ", + "GRANT DBA TO "); + + @Override + public boolean apply(String input) { + boolean accept = true; + for (String forbiddenStart : forbiddenStarts) { + if (input.startsWith(forbiddenStart)) { + accept = false; + break; + } + } + return accept; + } + }; + for (String line : lines) { + if (predicate.apply(line.trim().toUpperCase())) { + result.add(line); + } + } + return result; + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/AccidentalBatchPersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,73 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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 fr.ifremer.tutti.persistence.DatabaseResource; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Ignore +public class AccidentalBatchPersistenceServiceTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected AccidentalBatchPersistenceService service; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getAccidentalBatchPersistenceService(); + } + + @Test + public void getAllAccidentalBatch(/*String fishingOperationId*/) { + + } + + @Test + public void getAccidentalBatch(/*String id*/) { + + } + + @Test + public void createAccidentalBatch(/*AccidentalBatch bean*/) { + + } + + @Test + public void saveAccidentalBatch(/*AccidentalBatch bean*/) { + + } + + @Test + public void deleteAccidentalBatch(/*String id*/) { + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/BenthosBatchPersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,73 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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 fr.ifremer.tutti.persistence.DatabaseResource; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Ignore +public class BenthosBatchPersistenceServiceTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected BenthosBatchPersistenceService service; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getBenthosBatchPersistenceService(); + } + + @Test + public void getAllBenthosBatch(/*String fishingOperationId*/) { + + } + + @Test + public void getBenthosBatch(/*String id*/) { + + } + + @Test + public void createBenthosBatch(/*BenthosBatch bean*/) { + + } + + @Test + public void saveBenthosBatch(/*BenthosBatch bean*/) { + + } + + @Test + public void deleteBenthosBatch(/*String id*/) { + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImplTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImplTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImplTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/CatchBatchPersistenceServiceImplTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,209 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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 fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.entities.data.CatchBatch; +import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +public class CatchBatchPersistenceServiceImplTest { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(CatchBatchPersistenceServiceImplTest.class); + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected CatchBatchPersistenceService service; + + protected CruisePersistenceService cruiseService; + + protected FishingOperationPersistenceService fishingOperationService; + + protected ReferentialPersistenceService referentialService; + + protected Cruise cruise; + + protected FishingOperation fishingOperation; + + protected List<Species> species; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getCatchBatchPersistenceService(); + cruiseService = TuttiPersistenceServiceLocator.getCruisePersistenceService(); + fishingOperationService = TuttiPersistenceServiceLocator.getFishingOperationPersistenceService(); + referentialService = TuttiPersistenceServiceLocator.getReferentialPersistenceService(); + + cruise = cruiseService.getCruise(dbResource.getFixtures().cruiseId()); + cruise.setId(null); + Calendar calendar = new GregorianCalendar(); + cruise.setBeginDate(calendar.getTime()); + cruise.setYear(calendar.get(Calendar.YEAR)); + calendar.add(Calendar.MONTH, 1); // add one month + cruise.setEndDate(calendar.getTime()); + cruise = cruiseService.createCruise(cruise); + + List<FishingOperation> fishingOperations = fishingOperationService.getAllFishingOperation(dbResource.getFixtures().cruiseId()); + assertNotNull(fishingOperations); + assertTrue(fishingOperations.size() > 0); + fishingOperation = fishingOperations.get(0); + fishingOperation = fishingOperationService.getFishingOperation(fishingOperation.getId()); + fishingOperation.setId(null); + fishingOperation.setCruise(cruise); + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 1); + calendar.set(Calendar.MILLISECOND, 0); + fishingOperation.setGearShootingStartDate(calendar.getTime()); + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 10); + calendar.set(Calendar.MILLISECOND, 0); + fishingOperation.setGearShootingEndDate(calendar.getTime()); + + fishingOperation = fishingOperationService.createFishingOperation(fishingOperation); + } + + @Test + public void getCatchBatchFromFishingOperation() throws Exception { + + //TODO + } + + @Test + public void createAndSaveCatchBatch() throws Exception { + CatchBatch catchBatch = null; + CatchBatch createdCatchBatch = null; + CatchBatch reloadedCatchBatch = null; + + catchBatch = new CatchBatch(); + catchBatch.setFishingOperation(fishingOperation); + + // ----------------------------------------------------------------------------- + // 1. Test with only mandatory properties + // ----------------------------------------------------------------------------- + + // Create and reload (test round trip) + createdCatchBatch = service.createCatchBatch(catchBatch); + assertNotNull(createdCatchBatch); + assertNotNull(createdCatchBatch.getId()); + + reloadedCatchBatch = service.getCatchBatchFromFishingOperation(fishingOperation.getId()); + assertNotNull(reloadedCatchBatch); + assertEquals(createdCatchBatch.getId(), reloadedCatchBatch.getId()); + + // ----------------------------------------------------------------------------- + // 2. Test with all properties + // ----------------------------------------------------------------------------- + catchBatch.setId(null); + // total weight : 100kg + catchBatch.setCatchTotalWeight(75f); + // Vrac : + { + // note : poids trie par la balance tremis (thalassa) (init par pupitri) + catchBatch.setCatchTotalSortedTremisWeight(50f); + // note : poids vrac caroussel (thalassa) (init par pupitri) (vrac trie) ou bien "poids trié fournie par la table de tri (Sum(Si) + catchBatch.setCatchTotalSortedCarousselWeight(45f); + + // Species + { + catchBatch.setSpeciesTotalSortedWeight(12f); + catchBatch.setSpeciesTotalSampleSortedWeight(8f); + } + } + // Hors Vrac : 10kg + { + catchBatch.setCatchTotalUnsortedWeight(10f); + + // Species + { + catchBatch.setSpeciesTotalUnsortedWeight(10f); + } + } + // Rejet : 15kg + catchBatch.setCatchTotalRejectedWeight(15f); + + // Create and reload (test round trip) + createdCatchBatch = service.createCatchBatch(catchBatch); + assertNotNull(createdCatchBatch); + assertNotNull(createdCatchBatch.getId()); + + reloadedCatchBatch = service.getCatchBatchFromFishingOperation(fishingOperation.getId()); + assertNotNull(reloadedCatchBatch); + assertEquals(createdCatchBatch.getCatchTotalWeight(), reloadedCatchBatch.getCatchTotalWeight()); + assertEquals(createdCatchBatch.getCatchTotalSortedCarousselWeight(), reloadedCatchBatch.getCatchTotalSortedCarousselWeight()); + assertEquals(createdCatchBatch.getCatchTotalSortedTremisWeight(), reloadedCatchBatch.getCatchTotalSortedTremisWeight()); + assertEquals(createdCatchBatch.getCatchTotalUnsortedWeight(), reloadedCatchBatch.getCatchTotalUnsortedWeight()); + + assertEquals(createdCatchBatch.getSpeciesTotalSampleSortedWeight(), reloadedCatchBatch.getSpeciesTotalSampleSortedWeight()); + assertEquals(createdCatchBatch.getSpeciesTotalSortedWeight(), reloadedCatchBatch.getSpeciesTotalSortedWeight()); + assertEquals(createdCatchBatch.getSpeciesTotalUnsortedWeight(), reloadedCatchBatch.getSpeciesTotalUnsortedWeight()); + + // ----------------------------------------------------------------------------- + // 2. Test save after modification + // ----------------------------------------------------------------------------- + catchBatch.setCatchTotalSortedTremisWeight(null); + catchBatch.setCatchTotalSortedCarousselWeight(null); + catchBatch.setSpeciesTotalSortedWeight(null); + catchBatch.setSpeciesTotalSampleSortedWeight(null); + catchBatch.setCatchTotalUnsortedWeight(null); + catchBatch.setSpeciesTotalUnsortedWeight(null); + CatchBatch savedCatchBatch = service.saveCatchBatch(catchBatch); + assertNotNull(savedCatchBatch); + assertNotNull(savedCatchBatch.getId()); + + reloadedCatchBatch = service.getCatchBatchFromFishingOperation(fishingOperation.getId()); + assertNotNull(reloadedCatchBatch); + assertEquals(createdCatchBatch.getCatchTotalWeight(), reloadedCatchBatch.getCatchTotalWeight()); + assertEquals(createdCatchBatch.getCatchTotalSortedCarousselWeight(), reloadedCatchBatch.getCatchTotalSortedCarousselWeight()); + assertEquals(createdCatchBatch.getCatchTotalSortedTremisWeight(), reloadedCatchBatch.getCatchTotalSortedTremisWeight()); + assertEquals(createdCatchBatch.getCatchTotalUnsortedWeight(), reloadedCatchBatch.getCatchTotalUnsortedWeight()); + + assertEquals(createdCatchBatch.getSpeciesTotalSampleSortedWeight(), reloadedCatchBatch.getSpeciesTotalSampleSortedWeight()); + assertEquals(createdCatchBatch.getSpeciesTotalSortedWeight(), reloadedCatchBatch.getSpeciesTotalSortedWeight()); + assertEquals(createdCatchBatch.getSpeciesTotalUnsortedWeight(), reloadedCatchBatch.getSpeciesTotalUnsortedWeight()); + } + +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,248 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.Lists; +import fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.tutti.persistence.entities.referential.Country; +import fr.ifremer.tutti.persistence.entities.referential.Gear; +import fr.ifremer.tutti.persistence.entities.referential.Person; +import fr.ifremer.tutti.persistence.entities.referential.Vessel; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class CruisePersistenceServiceTest { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(CruisePersistenceServiceTest.class); + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected ReferentialPersistenceService referentialService; + + protected ProgramPersistenceService programService; + + protected CruisePersistenceService service; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getCruisePersistenceService(); + referentialService = TuttiPersistenceServiceLocator.getReferentialPersistenceService(); + programService = TuttiPersistenceServiceLocator.getProgramPersistenceService(); + } + + @Test + public void getAllCruise(/*String programId*/) { + String programCode = dbResource.getFixtures().programCode(); + List<Cruise> result = service.getAllCruise(programCode); + Assert.assertNotNull(result); + Assert.assertFalse(result.isEmpty()); + } + + @Test + public void getCruise(/*String id*/) { + + String cruiseId = dbResource.getFixtures().cruiseId(); + Cruise result = service.getCruise(cruiseId); + Assert.assertNotNull(result); + } + + @Ignore + @Test + public void createCruise(/*Cruise bean*/) { + String programCode = dbResource.getFixtures().programCode(); + Cruise cruise = new Cruise(); + + // ----------------------------------------------------------------------------- + // 1. Test with all properties filled + // ----------------------------------------------------------------------------- + cruise.setId(null); + + cruise.setName("Unit-test-" + System.currentTimeMillis()); + + cruise.setProgram(programService.getProgram(programCode)); + + Calendar calendar = new GregorianCalendar(); + cruise.setBeginDate(calendar.getTime()); + + cruise.setYear(calendar.get(Calendar.YEAR)); + + calendar.add(Calendar.MONTH, 1); // add one month + cruise.setEndDate(calendar.getTime()); + + Country country = null; + List<Country> countries = referentialService.getAllCountry(); + for (Country aCountry : countries) { + if (aCountry.getLabel() != null && aCountry.getLabel().equals("FRA")) { + country = aCountry; + break; + } + } + assertNotNull("Could not load FRA country", country); + cruise.setCountry(country); + + List<Gear> gears = referentialService.getAllFishingGear(); + cruise.setGear(gears); + + cruise.setComment("My comments on cruise"); + + Person managerPerson = referentialService.getAllPerson().get(0); + cruise.setHeadOfMission(Lists.newArrayList(managerPerson)); + + List<Vessel> vessels = Lists.newArrayList(); + vessels.add(referentialService.getAllScientificVessel().get(0)); + Vessel fishingVessel = new Vessel(); + fishingVessel.setId(dbResource.getFixtures().fishingVesselCode()); + vessels.add(fishingVessel); + + cruise.setVessel(vessels); + + cruise.setMultirigNumber(2); + + // Create cruise in database + Cruise createdCruise = service.createCruise(cruise); + assertNotNull(createdCruise); + assertNotNull(createdCruise.getId()); + assertEquals(cruise.getName(), createdCruise.getName()); + + if (log.isInfoEnabled()) { + log.info("Created cruise: " + createdCruise.getId()); + } + + // Then reload cruise and compare + Cruise reloadedCruise = service.getCruise(createdCruise.getId()); + calendar.setTime(createdCruise.getBeginDate()); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + assertEquals(calendar.getTime(), reloadedCruise.getBeginDate()); + calendar.setTime(createdCruise.getEndDate()); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + assertEquals(calendar.getTime(), reloadedCruise.getEndDate()); + assertEquals(cruise.getMultirigNumber(), reloadedCruise.getMultirigNumber()); + + // ----------------------------------------------------------------------------- + // 2. Test with only mandatory properties + // ----------------------------------------------------------------------------- + createdCruise.setId(null); + createdCruise.setHeadOfMission(null); + createdCruise.setBeginDate(null); + createdCruise.setEndDate(null); + createdCruise.setComment(null); + createdCruise.setMultirigNumber(null); + + // Save cruise + createdCruise = service.createCruise(cruise); + assertNotNull(createdCruise); + assertNotNull(createdCruise.getId()); + assertEquals(cruise.getName(), createdCruise.getName()); + + // Reload to compare + reloadedCruise = service.getCruise(createdCruise.getId()); + + assertEquals(createdCruise.getBeginDate(), reloadedCruise.getBeginDate()); + assertEquals(createdCruise.getEndDate(), reloadedCruise.getEndDate()); + assertEquals(createdCruise.getComment(), reloadedCruise.getComment()); + assertEquals(createdCruise.getMultirigNumber(), reloadedCruise.getMultirigNumber()); + assertNull(reloadedCruise.getHeadOfMission()); + assertNotNull(reloadedCruise.getVessel()); + assertEquals(createdCruise.getVessel().get(0), reloadedCruise.getVessel().get(0)); + assertEquals(cruise.getCountry().getId(), reloadedCruise.getCountry().getId()); + assertNotNull(reloadedCruise.getVessel()); + assertEquals(vessels.size(), reloadedCruise.getVessel().size()); + assertNotNull(reloadedCruise.getGear()); + assertEquals(gears.size(), reloadedCruise.getGear().size()); + } + + @Test + public void saveCruise(/*Cruise bean*/) { + // ----------------------------------------------------------------------------- + // 1. Init a cruise (by copy) + // ----------------------------------------------------------------------------- + Cruise cruise = service.getCruise(dbResource.getFixtures().cruiseId()); + + cruise.setId(null); + Calendar calendar = new GregorianCalendar(); + cruise.setBeginDate(calendar.getTime()); + + cruise.setYear(calendar.get(Calendar.YEAR)); + + calendar.add(Calendar.MONTH, 1); // add one month + cruise.setEndDate(calendar.getTime()); + + cruise = service.createCruise(cruise); + + // ----------------------------------------------------------------------------- + // 2. Apply some changes + // ----------------------------------------------------------------------------- + + // Name : + cruise.setName("Unit-test-" + System.currentTimeMillis()); + + // Remove gear, then add another gear + Gear previousGear = cruise.getGear(0); + cruise.getGear().clear(); + List<Gear> gears = referentialService.getAllFishingGear(); + for (Gear gear : gears) { + // Make sure the gear is different before to add it + if (gear.getId() != null && !gear.getId().equals(previousGear.getId())) { + cruise.addGear(gear); + break; + } + } + + // Save changes, then check + Cruise savedCruise = service.saveCruise(cruise); + assertNotNull(savedCruise); + Cruise reloadedCruise = service.getCruise(savedCruise.getId()); + + assertEquals(cruise.getId(), reloadedCruise.getId()); + assertEquals(cruise.getName(), reloadedCruise.getName()); + assertEquals(cruise.getComment(), reloadedCruise.getComment()); + assertNotNull(reloadedCruise.getGear()); + assertEquals(cruise.getGear().size(), reloadedCruise.getGear().size()); + assertEquals(cruise.getGear(0).getId(), reloadedCruise.getGear(0).getId()); + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,388 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.Lists; +import fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.entities.CaracteristicMap; +import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicType; +import fr.ifremer.tutti.persistence.entities.referential.FishingOperationLocation; +import fr.ifremer.tutti.persistence.entities.referential.Gear; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; + +import java.io.Serializable; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class FishingOperationPersistenceServiceTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected FishingOperationPersistenceService service; + + protected ReferentialPersistenceService referentialService; + + protected ProgramPersistenceService programService; + + protected CruisePersistenceService cruiseService; + + protected Cruise cruise = null; + + @Autowired(required = true) + protected TuttiEnumerationFile enumeration; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getFishingOperationPersistenceService(); + cruiseService = TuttiPersistenceServiceLocator.getCruisePersistenceService(); + referentialService = TuttiPersistenceServiceLocator.getReferentialPersistenceService(); + programService = TuttiPersistenceServiceLocator.getProgramPersistenceService(); + + } + + @Test + public void getAllFishingOperation(/*String cruiseId*/) { + List<FishingOperation> fishingOperations = service.getAllFishingOperation(dbResource.getFixtures().cruiseId()); + assertNotNull(fishingOperations); + assertTrue(fishingOperations.size() > 1); + } + + @Test + @Ignore + public void getFishingOperation(/*String id*/) { + + } + + @Test + @Ignore + public void createFishingOperation(/*FishingOperation bean*/) { + // ----------------------------------------------------------------------------- + // Prepare data and other entities + // ----------------------------------------------------------------------------- + Calendar calendar = new GregorianCalendar(); + FishingOperation reloadedFishingOperation; + FishingOperation createdFishingOperation; + + // Duplicate an existing cruise, to attach new fishing operations + cruise = cruiseService.getCruise(dbResource.getFixtures().cruiseId()); + cruise.setId(null); + cruise.setName("Unit-test-" + System.currentTimeMillis()); + cruise.setBeginDate(new Date()); + cruise.setEndDate(null); + cruise.setMultirigNumber(2); + // Keep only one gear in the cruise : (need for case n°4) + List<Gear> cruiseGears = cruise.getGear(); + assertNotNull(cruiseGears); + assertTrue(cruiseGears.size() > 0); + Gear cruiseGear = cruiseGears.get(0); + assertNotNull(cruiseGear.getId()); + cruise.setGear(Lists.newArrayList(cruiseGear)); + + cruise = cruiseService.createCruise(cruise); + assertNotNull(cruise.getId()); + + // Retrieve some environment caracteristics + List<Caracteristic> allEnvironmentCaracteristics = referentialService.getAllCaracteristic(); + CaracteristicMap environmentCaracteristics = new CaracteristicMap(); + CaracteristicMap environmentValuesOneEntry = new CaracteristicMap(); + for (Caracteristic caracteristic : allEnvironmentCaracteristics) { + Serializable value = null; + if (caracteristic.getCaracteristicType() == CaracteristicType.NUMBER) { + value = 1.0f; + } else if (caracteristic.getCaracteristicType() == CaracteristicType.TEXT) { + value = "some text"; + } else if (caracteristic.getCaracteristicType() == CaracteristicType.QUALITATIVE + && caracteristic.getQualitativeValue(0) != null) { + // Choose the first qualitative value + value = caracteristic.getQualitativeValue(0).getId(); + } + if (value != null) { + environmentCaracteristics.put(caracteristic, value); + if (environmentValuesOneEntry.size() == 0) { + environmentValuesOneEntry.put(caracteristic, value); + } + } + } + + // Retrieve some gear use caracteristics + List<Caracteristic> allGearShootingCaracteristics = referentialService.getAllCaracteristic(); + CaracteristicMap gearShootingCaracteristics = new CaracteristicMap(); + CaracteristicMap gearShootingCaracteristicsOneEntry = new CaracteristicMap(); + for (Caracteristic caracteristic : allGearShootingCaracteristics) { + Serializable value = null; + if (caracteristic.getCaracteristicType() == CaracteristicType.NUMBER) { + value = 1.0f; + } else if (caracteristic.getCaracteristicType() == CaracteristicType.TEXT) { + value = "some text"; + } else if (caracteristic.getCaracteristicType() == CaracteristicType.QUALITATIVE + && caracteristic.getQualitativeValue(0) != null) { + // Choose the first qualitative value + value = caracteristic.getQualitativeValue(0).getId(); + } + if (value != null) { + gearShootingCaracteristics.put(caracteristic, value); + if (gearShootingCaracteristicsOneEntry.size() == 0) { + gearShootingCaracteristicsOneEntry.put(caracteristic, value); + } + } + } + + + // Create new fishing operation : + FishingOperation fishingOperation = new FishingOperation(); + + // ----------------------------------------------------------------------------- + // 1. Test with only mandatory properties + // ----------------------------------------------------------------------------- + + // Set properties (with optional value to null) + fishingOperation.setCruise(cruise); + fishingOperation.setStationNumber("STA1"); + fishingOperation.setFishingOperationNumber(1); + fishingOperation.setMultirigAggregation("1"); + fishingOperation.setGearShootingStartDate(null); + fishingOperation.setGearShootingEndDate(null); + fishingOperation.setGear(null); + fishingOperation.setGearShootingStartLatitude(33.2541f); + fishingOperation.setComment(null); + + // Store fishing operation into database : + createdFishingOperation = service.createFishingOperation(fishingOperation); + assertNotNull("Fishing operation ID must not be null after creation in database", createdFishingOperation); + assertNotNull(createdFishingOperation.getId()); + + // Trying to reload this fishing operation + reloadedFishingOperation = service.getFishingOperation(createdFishingOperation.getId()); + assertNotNull(reloadedFishingOperation); + assertNull(reloadedFishingOperation.getGearShootingStartDate()); + + // ----------------------------------------------------------------------------- + // 2. Test with all properties set + // ----------------------------------------------------------------------------- + // Set properties + fishingOperation.setId(null); + fishingOperation.setStationNumber("STA2"); + fishingOperation.setFishingOperationNumber(2); + fishingOperation.setMultirigAggregation("1"); + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 1); + calendar.set(Calendar.MILLISECOND, 99); + fishingOperation.setGearShootingStartDate(calendar.getTime()); + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 10); + calendar.set(Calendar.MILLISECOND, 99); + fishingOperation.setGearShootingEndDate(calendar.getTime()); + fishingOperation.setGearShootingStartLatitude(47.6f); + fishingOperation.setGearShootingStartLongitude(-5.05f); + fishingOperation.setGearShootingEndLatitude(47.9854f); + fishingOperation.setGearShootingEndLongitude(-5.597f); + + fishingOperation.setTrawlDistance(100.12345f); + fishingOperation.setFishingOperationRectiligne(true); + fishingOperation.setFishingOperationValid(Boolean.TRUE); + fishingOperation.setComment("Unit test createFishingOperation() - Part n°2 : All properties set"); + fishingOperation.setGear(cruiseGear); + fishingOperation.setEnvironmentCaracteristics(environmentCaracteristics); + fishingOperation.setGearShootingCaracteristics(gearShootingCaracteristics); + + FishingOperationLocation strata = new FishingOperationLocation(); + strata.setId(dbResource.getFixtures().strataId()); + fishingOperation.setStrata(strata); + FishingOperationLocation subStrata = new FishingOperationLocation(); + subStrata.setId(dbResource.getFixtures().subStrataId()); + fishingOperation.setSubStrata(subStrata); + FishingOperationLocation localite = new FishingOperationLocation(); + localite.setId(dbResource.getFixtures().localite()); + fishingOperation.setLocation(localite); + + // Store fishing operation into database : + createdFishingOperation = service.createFishingOperation(fishingOperation); + assertNotNull("Fishing operation ID must not be null after creation in database", createdFishingOperation); + assertNotNull(createdFishingOperation.getId()); + + reloadedFishingOperation = service.getFishingOperation(createdFishingOperation.getId()); + assertNotNull(reloadedFishingOperation.getGear()); + assertEquals(fishingOperation.getStationNumber(), reloadedFishingOperation.getStationNumber()); + assertEquals(fishingOperation.getFishingOperationNumber(), reloadedFishingOperation.getFishingOperationNumber()); + assertEquals(fishingOperation.getMultirigAggregation(), reloadedFishingOperation.getMultirigAggregation()); + assertNotNull(reloadedFishingOperation.getGearShootingStartDate()); + calendar.setTime(fishingOperation.getGearShootingStartDate()); + calendar.set(Calendar.MILLISECOND, 0); + assertEquals(calendar.getTime(), reloadedFishingOperation.getGearShootingStartDate()); + assertEquals(fishingOperation.getGearShootingStartLatitude(), reloadedFishingOperation.getGearShootingStartLatitude()); + assertEquals(fishingOperation.getGearShootingStartLongitude(), reloadedFishingOperation.getGearShootingStartLongitude()); + assertNotNull(reloadedFishingOperation.getGearShootingEndDate()); + calendar.setTime(fishingOperation.getGearShootingEndDate()); + calendar.set(Calendar.MILLISECOND, 0); + assertEquals(calendar.getTime(), reloadedFishingOperation.getGearShootingEndDate()); + assertEquals(fishingOperation.getGearShootingEndLatitude(), reloadedFishingOperation.getGearShootingEndLatitude()); + assertEquals(fishingOperation.getGearShootingEndLongitude(), reloadedFishingOperation.getGearShootingEndLongitude()); + assertEquals(fishingOperation.getTrawlDistance(), reloadedFishingOperation.getTrawlDistance()); + assertEquals(fishingOperation.isFishingOperationRectiligne(), reloadedFishingOperation.isFishingOperationRectiligne()); + assertEquals(fishingOperation.getFishingOperationValid(), reloadedFishingOperation.getFishingOperationValid()); + assertEquals(fishingOperation.getComment(), reloadedFishingOperation.getComment()); + assertNotNull(reloadedFishingOperation.getEnvironmentCaracteristics()); + assertEquals(environmentCaracteristics.size(), fishingOperation.getEnvironmentCaracteristics().size()); + assertNotNull(reloadedFishingOperation.getGearShootingCaracteristics()); + assertEquals(gearShootingCaracteristics.size(), reloadedFishingOperation.getGearShootingCaracteristics().size()); + assertNotNull(reloadedFishingOperation.getStrata()); + assertNotNull(reloadedFishingOperation.getStrata().getId()); + assertEquals(fishingOperation.getStrata().getId(), reloadedFishingOperation.getStrata().getId()); + assertNotNull(reloadedFishingOperation.getSubStrata()); + assertNotNull(reloadedFishingOperation.getSubStrata().getId()); + assertEquals(fishingOperation.getSubStrata().getId(), reloadedFishingOperation.getSubStrata().getId()); + assertNotNull(reloadedFishingOperation.getLocation()); + assertNotNull(reloadedFishingOperation.getLocation().getId()); + assertEquals(fishingOperation.getLocation().getId(), reloadedFishingOperation.getLocation().getId()); + + // ----------------------------------------------------------------------------- + // 3. Test : + // - startDate and startLat filled, but empty endLong + // - endLat and endLong filled but empty endDate + // - isFishingOperationRectiligne = false + // - trawlDistance empty + // - fishingOperationValid = false + // ----------------------------------------------------------------------------- + fishingOperation.setId(null); + fishingOperation.setStationNumber("STA3"); + fishingOperation.setFishingOperationNumber(3); + fishingOperation.setMultirigAggregation("2"); + fishingOperation.setGearShootingStartLongitude(null); + fishingOperation.setGearShootingEndDate(null); + fishingOperation.setTrawlDistance(null); + fishingOperation.setFishingOperationRectiligne(false); + fishingOperation.setFishingOperationValid(false); + fishingOperation.setComment("Unit test createFishingOperation() - Part n°3 :\n-startDate and startLat filled, but empty endLong\n- endLat and endLong filled but empty endDate"); + createdFishingOperation = service.createFishingOperation(fishingOperation); + reloadedFishingOperation = service.getFishingOperation(createdFishingOperation.getId()); + assertEquals(fishingOperation.getGearShootingStartLatitude(), reloadedFishingOperation.getGearShootingStartLatitude()); + assertEquals(fishingOperation.getGearShootingStartLongitude(), reloadedFishingOperation.getGearShootingStartLongitude()); + assertNull(reloadedFishingOperation.getGearShootingEndDate()); + assertEquals(fishingOperation.getGearShootingEndLatitude(), reloadedFishingOperation.getGearShootingEndLatitude()); + assertEquals(fishingOperation.getGearShootingEndLongitude(), reloadedFishingOperation.getGearShootingEndLongitude()); + assertEquals(fishingOperation.getTrawlDistance(), reloadedFishingOperation.getTrawlDistance()); + assertEquals(fishingOperation.isFishingOperationRectiligne(), reloadedFishingOperation.isFishingOperationRectiligne()); + assertEquals(fishingOperation.getFishingOperationValid(), reloadedFishingOperation.getFishingOperationValid()); + + // ----------------------------------------------------------------------------- + // 4. Test exceptions : + // - try to save a operation using a gear not declared in the cruise + // - try to save a operation using a multirig aggregation greater than the cruise multirig number + // ----------------------------------------------------------------------------- + fishingOperation.setId(null); + + // Find and set a gear not used in the cruise + List<Gear> gears = referentialService.getAllFishingGear(); + assertNotNull(gears); + assertTrue(gears.size() > 0); + for (Gear gear : gears) { + if (!cruiseGear.getId().equals(gear.getId())) { + fishingOperation.setGear(gear); + break; + } + } + + try { + createdFishingOperation = service.createFishingOperation(fishingOperation); + fail("A fishing operation must not be saved if the gear is not declared in the cruise."); + } catch (DataIntegrityViolationException dive) { + assertNotNull(dive); + fishingOperation.setGear(cruiseGear); + } + + fishingOperation.setMultirigAggregation("3"); + try { + createdFishingOperation = service.createFishingOperation(fishingOperation); + fail("A fishing operation must not be saved if the 'multirig aggregation' > 'cruise multirig number'."); + } catch (DataIntegrityViolationException dive) { + assertNotNull(dive); + fishingOperation.setMultirigAggregation("1"); + } + + // ----------------------------------------------------------------------------- + // 5. Test update (delete unecessary data) + // - remove positons + // - remove strata, substrata, localite + // - remove some environment carateristics + // - remove some gear shooting carateristics + // ----------------------------------------------------------------------------- + fishingOperation.setId(reloadedFishingOperation.getId()); + fishingOperation.setGearShootingStartLatitude(null); + fishingOperation.setGearShootingStartLongitude(null); + fishingOperation.setGearShootingEndDate(null); + fishingOperation.setGearShootingEndLatitude(null); + fishingOperation.setGearShootingEndLongitude(null); + fishingOperation.setTrawlDistance(null); + fishingOperation.setStrata(null); + fishingOperation.setSubStrata(null); + fishingOperation.setLocation(null); + fishingOperation.setEnvironmentCaracteristics(environmentValuesOneEntry); + fishingOperation.setGearShootingCaracteristics(gearShootingCaracteristicsOneEntry); + fishingOperation.setComment(fishingOperation.getComment() + "\n\nUnit test createFishingOperation() - Part n°5 : check if deleted sub items in DB"); + createdFishingOperation = service.saveFishingOperation(fishingOperation); + reloadedFishingOperation = service.getFishingOperation(createdFishingOperation.getId()); + assertNull(reloadedFishingOperation.getGearShootingStartLatitude()); + assertNull(reloadedFishingOperation.getGearShootingStartLongitude()); + assertNull(reloadedFishingOperation.getGearShootingEndDate()); + assertNull(reloadedFishingOperation.getGearShootingEndLatitude()); + assertNull(reloadedFishingOperation.getGearShootingEndLongitude()); + assertNull(reloadedFishingOperation.getStrata()); + assertNull(reloadedFishingOperation.getSubStrata()); + assertNull(reloadedFishingOperation.getLocation()); + assertNotNull(reloadedFishingOperation.getEnvironmentCaracteristics()); + assertEquals(environmentValuesOneEntry.size(), reloadedFishingOperation.getEnvironmentCaracteristics().size()); + assertNotNull(reloadedFishingOperation.getGearShootingCaracteristics()); + assertEquals(gearShootingCaracteristicsOneEntry.size(), reloadedFishingOperation.getGearShootingCaracteristics().size()); + } + + @Test + @Ignore + public void saveFishingOperation(/*FishingOperation bean*/) { + + } + + +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/MacroWasteBatchPersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,73 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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 fr.ifremer.tutti.persistence.DatabaseResource; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Ignore +public class MacroWasteBatchPersistenceServiceTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected MacroWasteBatchPersistenceService service; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getMacroWasteBatchPersistenceService(); + } + + @Test + public void getAllMacroWasteBatch(/*String fishingOperationId*/) { + + } + + @Test + public void getMacroWasteBatch(/*String id*/) { + + } + + @Test + public void createMacroWasteBatch(/*MacroWasteBatch bean*/) { + + } + + @Test + public void saveMacroWasteBatch(/*MacroWasteBatch bean*/) { + + } + + @Test + public void deleteMacroWasteBatch(/*String id*/) { + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/PlanktonBatchPersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,73 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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 fr.ifremer.tutti.persistence.DatabaseResource; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Ignore +public class PlanktonBatchPersistenceServiceTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected PlanktonBatchPersistenceService service; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getPlanktonBatchPersistenceService(); + } + + @Test + public void getAllPlanktonBatch(/*String fishingOperationId*/) { + + } + + @Test + public void getPlanktonBatch(/*String id*/) { + + } + + @Test + public void createPlanktonBatch(/*PlanktonBatch bean*/) { + + } + + @Test + public void savePlanktonBatch(/*PlanktonBatch bean*/) { + + } + + @Test + public void deletePlanktonBatch(/*String id*/) { + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ProgramPersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,136 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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 fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.entities.data.Program; +import fr.ifremer.tutti.persistence.entities.referential.Zone; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class ProgramPersistenceServiceTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected ProgramPersistenceService service; + + protected ReferentialPersistenceService referentialService; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getProgramPersistenceService(); + referentialService = TuttiPersistenceServiceLocator.getReferentialPersistenceService(); + } + + @Test + public void getAllProgram() { + List<Program> result = service.getAllProgram(); + Assert.assertNotNull(result); + Assert.assertTrue("More than one program must be found", result.size() > 0); + for (Program program : result) { + Assert.assertNotNull(program.getId()); + Assert.assertNotEquals("SIH-OBSMER", program.getId()); + Assert.assertNotEquals("SIH-ACTIFLOT", program.getId()); + } + } + + @Test + public void getProgram(/*String id*/) { + String programCode = dbResource.getFixtures().programCode(); + Program actual = service.getProgram(programCode); + Assert.assertNotNull(actual); + Assert.assertNotNull(actual.getId()); + Assert.assertNotNull(actual.getName()); + //comment, because in test database, "CAM-CGFS" could have a location that is not a zone + //Assert.assertNotNull(actual.getZone()); + Assert.assertEquals(programCode, actual.getId()); + } + + @Test + public void createAndSaveProgram(/*Program bean*/) { + + List<Zone> zones = referentialService.getAllProgramZone(); + assertNotNull(zones); + assertTrue(zones.size() > 0); + + Program program = new Program(); + String name = "UniTest" + System.currentTimeMillis(); + if (name.length() > 40) { + name = name.substring(0, 39); + } + program.setName(name); + + program.setComment("Comments on " + name); + program.setZone(zones.get(0)); + + // Create program + Program createdProgram = service.createProgram(program); + assertNotNull(createdProgram); + assertNotNull(createdProgram.getId()); + + // Reload program and compare + Program reloadedProgram = service.getProgram(createdProgram.getId()); + assertNotNull(reloadedProgram); + assertEquals(createdProgram.getId(), reloadedProgram.getId()); + assertEquals(program.getName(), reloadedProgram.getName()); + assertEquals(program.getComment(), reloadedProgram.getComment()); + assertNotNull(program.getZone()); + assertEquals(program.getZone().getId(), reloadedProgram.getZone().getId()); + + // Modify program + program.setId(createdProgram.getId()); + program.setName("NEW_NAME"); + program.setComment(program.getComment() + "\nAdd some modification"); + program.setZone(zones.get(1)); + + // Create program + Program savedProgram = service.saveProgram(program); + assertNotNull(savedProgram); + assertNotNull(savedProgram.getId()); + + // Reload program and compare + reloadedProgram = service.getProgram(savedProgram.getId()); + assertNotNull(reloadedProgram); + assertEquals(program.getId(), reloadedProgram.getId()); + assertEquals(program.getName(), reloadedProgram.getName()); + assertEquals(program.getComment(), reloadedProgram.getComment()); + assertNotNull(program.getZone()); + assertEquals(program.getZone().getId(), reloadedProgram.getZone().getId()); + } + +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ProtocolPersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,189 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.Lists; +import fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.List; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +@Ignore +public class ProtocolPersistenceServiceTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected ProtocolPersistenceService service; + + public static final String PROTOCOL_FILE_CONTENT = + "id: 1\n" + + "name: protocolName\n" + + "comment: Commentaire\n" + + "environmentPmfmId: \n" + + "- 114\n" + + "- 228\n" + + "- 821\n" + + "gearPmfmId: \n" + + "- 21\n" + + "- 22\n" + + "hydrologyPmfmId: []\n" + + "lengthClassesPmfmId: \n" + + "- 14\n" + + "- 18\n" + + "species: \n" + + "- !SpeciesProtocol\n" + + " id: 1\n" + + " calcifySampleEnabled: true\n" + + " lengthStepPmfmId: 1394\n" + + " maturityEnabled: true\n" + + " sexEnabled: true\n" + + " speciesId: 11242\n" + + " weightEnabled: true\n" + + "- !SpeciesProtocol\n" + + " id: 2\n" + + " ageEnabled: true\n" + + " calcifySampleEnabled: true\n" + + " countIfNoFrequencyEnabled: true\n" + + " lengthStepPmfmId: 323\n" + + " maturityEnabled: true\n" + + " sexEnabled: true\n" + + " sizeEnabled: true\n" + + " speciesId: 3835\n" + + " weightEnabled: true"; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getProtocolPersistenceService(); + } + + @Test + public void getAllProtocol() { + + List<TuttiProtocol> allProtocol = service.getAllProtocol(); + Assert.assertTrue(allProtocol.isEmpty()); + + TuttiProtocol protocol = createProtocolFixture(); + TuttiProtocol createdProtocol = service.createProtocol(protocol); + allProtocol = service.getAllProtocol(); + Assert.assertFalse(allProtocol.isEmpty()); + Assert.assertEquals(createdProtocol, allProtocol.get(0)); + } + + @Test + public void getProtocol(/*String id*/) { + TuttiProtocol protocol = createProtocolFixture(); + TuttiProtocol createdProtocol = service.createProtocol(protocol); + Assert.assertNotNull(createdProtocol); + String id = createdProtocol.getId(); + TuttiProtocol loadedProtocol = service.getProtocol(id); + Assert.assertNotNull(loadedProtocol); + } + + @Test + public void createProtocol(/*TuttiProtocol bean*/) { + + TuttiProtocol protocol = createProtocolFixture(); + TuttiProtocol createdProtocol = service.createProtocol(protocol); + Assert.assertNotNull(createdProtocol); + String id = createdProtocol.getId(); + Assert.assertTrue(service.getAllProtocolId().contains(id)); + + } + + @Test + public void saveProtocol(/*TuttiProtocol bean*/) { + + TuttiProtocol protocol = createProtocolFixture(); + TuttiProtocol createdProtocol = service.createProtocol(protocol); + + Assert.assertNotNull(createdProtocol); + String id = createdProtocol.getId(); + Assert.assertTrue(service.getAllProtocolId().contains(id)); + + TuttiProtocol savedProtocol = service.saveProtocol(createdProtocol); + Assert.assertNotNull(savedProtocol); + } + + @Test + public void deleteProtocol() { + + TuttiProtocol protocol = createProtocolFixture(); + TuttiProtocol createdProtocol = service.createProtocol(protocol); + Assert.assertNotNull(createdProtocol); + + String id = createdProtocol.getId(); + Assert.assertTrue(service.getAllProtocolId().contains(id)); + + service.deleteProtocol(id); + Assert.assertFalse(service.getAllProtocolId().contains(id)); + } + + protected TuttiProtocol createProtocolFixture() { + TuttiProtocol protocol = new TuttiProtocol(); + protocol.setId("1"); + protocol.setName("protocolName"); + protocol.setComment("Commentaire"); + protocol.setLengthClassesPmfmId(Lists.newArrayList("14", "18")); + protocol.setEnvironmentPmfmId(Lists.newArrayList("114", "228", "821")); + protocol.setGearPmfmId(Lists.newArrayList("21", "22")); + protocol.setHydrologyPmfmId(Lists.<String>newArrayList()); + + protocol.setSpecies(Lists.<SpeciesProtocol>newArrayList()); + SpeciesProtocol sp1 = new SpeciesProtocol(); + sp1.setId("1"); + sp1.setSpeciesId("11242"); + sp1.setLengthStepPmfmId("1394"); + sp1.setCalcifySampleEnabled(true); + sp1.setMaturityEnabled(true); + sp1.setSexEnabled(true); + sp1.setWeightEnabled(true); + protocol.addSpecies(sp1); + + SpeciesProtocol sp2 = new SpeciesProtocol(); + sp2.setId("2"); + sp2.setSpeciesId("3835"); + sp2.setLengthStepPmfmId("323"); + sp2.setAgeEnabled(true); + sp2.setCalcifySampleEnabled(true); + sp2.setCountIfNoFrequencyEnabled(true); + sp2.setMaturityEnabled(true); + sp2.setSexEnabled(true); + sp2.setSizeEnabled(true); + sp2.setWeightEnabled(true); + protocol.addSpecies(sp2); + return protocol; + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/ReferentialPersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,361 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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.base.Preconditions; +import fr.ifremer.adagio.core.service.technical.CacheService; +import fr.ifremer.tutti.persistence.DatabaseFixtures; +import fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.TuttiPersistenceDevImpl; +import fr.ifremer.tutti.persistence.entities.IdAware; +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.Country; +import fr.ifremer.tutti.persistence.entities.referential.FishingOperationLocation; +import fr.ifremer.tutti.persistence.entities.referential.Gear; +import fr.ifremer.tutti.persistence.entities.referential.Person; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.persistence.entities.referential.Vessel; +import fr.ifremer.tutti.persistence.entities.referential.Zone; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.nuiton.util.ApplicationConfig; + +import java.io.IOException; +import java.util.List; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class ReferentialPersistenceServiceTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ReferentialPersistenceServiceTest.class); + + protected static TuttiPersistenceDevImpl storage; + + protected ReferentialPersistenceService service; + + protected CacheService cacheService; + + protected DatabaseFixtures fixtures; + + @BeforeClass + public static void beforeClass() throws IOException { + + // create a storage + + ApplicationConfig applicationConfig = dbResource.getConfig().getConfig(); + + applicationConfig.setOption( + TuttiPersistenceDevImpl.SKIP_FIXTURES_OPTION, Boolean.TRUE.toString()); + + storage = new TuttiPersistenceDevImpl(applicationConfig) { + + @Override + public <B extends IdAware> B create(String type, + B bean, + boolean sychronize) { + Preconditions.checkNotNull(bean, "Can't persist a null bean"); + B result = TuttiEntities.newEntity(bean); + result.setId(bean.getId()); + if (log.isDebugEnabled()) { + log.debug("Will persist [" + type + ":" + bean.getId() + "]"); + } + super.persist(type, bean, result, sychronize); + return result; + } + }; + + if (log.isInfoEnabled()) { + log.info("Will init persistence driver " + storage.getImplementationName()); + } + + storage.init(); + } + + @AfterClass + public static void afterClass() throws IOException { + storage.close(); + } + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getReferentialPersistenceService(); + cacheService = TuttiPersistenceServiceLocator.instance().getCacheService(); + + // This is need for test : getAllFishingVessel() + cacheService.clearAllCaches(); + fixtures = dbResource.getFixtures(); + } + + @Test + public void getAllProgramZone() { + List<Zone> result = service.getAllProgramZone(); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbProgramZone(), result.size()); + + persistList(Zone.class, result); + assertSize(result, storage.getAllProgramZone()); + } + + @Test + public void getAllCountry() { + List<Country> result = service.getAllCountry(); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbCountry(), result.size()); + + persistList(Country.class, result); + assertSize(result, storage.getAllCountry()); + } + + @Test + public void getAllFishingOperationStrata(/*String zoneId*/) { + String zoneId = dbResource.getFixtures().zoneId(); + List<FishingOperationLocation> result = + service.getAllFishingOperationStrata(zoneId); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbStrata(), result.size()); + + persistList(FishingOperationLocation.class, "Strata", result); + assertSize(result, storage.getAllFishingOperationStrata(zoneId)); + } + + @Test + public void getAllFishingOperationSubStrata(/*String zoneId, String strataId*/) { + String zoneId = dbResource.getFixtures().zoneId(); + List<FishingOperationLocation> result = + service.getAllFishingOperationSubStrata(zoneId, null); + Assert.assertNotNull(result); + Assert.assertEquals(0, result.size()); + + persistList(FishingOperationLocation.class, "SubStrata", result); + assertSize(result, storage.getAllFishingOperationSubStrata(zoneId, null)); + + // try with a strataId + String strataId = dbResource.getFixtures().strataId(); + result = service.getAllFishingOperationLocation(zoneId, strataId, null); + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + } + + @Test + public void getAllFishingOperationLocation(/*String zoneId, String strataId, String subStrataId*/) { + String zoneId = dbResource.getFixtures().zoneId(); + List<FishingOperationLocation> result = + service.getAllFishingOperationLocation(zoneId, null, null); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbLocalite(), result.size()); + + persistList(FishingOperationLocation.class, "Localite", result); + assertSize(result, storage.getAllFishingOperationLocation(zoneId, null, null)); + + // try with a strataId + String strataId = dbResource.getFixtures().strataId(); + result = service.getAllFishingOperationLocation(zoneId, strataId, null); + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + + // try with a subStrataId + String subStrataId = dbResource.getFixtures().subStrataId(); + result = service.getAllFishingOperationLocation(zoneId, strataId, subStrataId); + Assert.assertNotNull(result); + Assert.assertEquals(3, result.size()); + } + + @Test + public void getAllScientificVessel() { + List<Vessel> result = service.getAllScientificVessel(); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbScientificVessel(), result.size()); + persistList(Vessel.class, "Scientific", result); + assertSize(result, storage.getAllScientificVessel()); + } + + @Test + public void getAllFishingVessel() { + long time = System.currentTimeMillis(); + List<Vessel> result = service.getAllFishingVessel(); + long delta1 = System.currentTimeMillis() - time; + + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbFishingVessel(), result.size()); + + // try again, to check cache is enable + time = System.currentTimeMillis(); + result = service.getAllFishingVessel(); + long delta2 = System.currentTimeMillis() - time; + + float reduceFactor = delta2 * 100 / delta1; + Assert.assertTrue("The cache on getAllFishingVessel() should have speed up more than factor 10. Make sure EhCache is well configured.", reduceFactor < 0.1); + + persistList(Vessel.class, "Fishing", result); + assertSize(result, storage.getAllFishingVessel()); + } + + @Test + public void getAllScientificGear() { + List<Gear> result = service.getAllScientificGear(); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbScientificGear(), result.size()); + persistList(Gear.class, "Scientific", result); + assertSize(result, storage.getAllScientificGear()); + } + + @Test + public void getAllFishingGear() { + List<Gear> result = service.getAllFishingGear(); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbFishingGear(), result.size()); + persistList(Gear.class, "Fishing", result); + assertSize(result, storage.getAllFishingGear()); + } + + @Test + public void getAllPerson() { + List<Person> result = service.getAllPerson(); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbPerson(), result.size()); + persistList(Person.class, result); + assertSize(result, storage.getAllPerson()); + } + + @Test + public void getAllSpecies() { + List<Species> result = service.getAllSpecies(); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbSpecies(), result.size()); + persistList(Species.class, result); + assertSize(result, storage.getAllSpecies()); + } + + @Test + public void getSpecies(/*String speciesId*/) { + } + + @Test + public void getAllCaracteristic() { + List<Caracteristic> result = service.getAllCaracteristic(); + Assert.assertNotNull(result); + Assert.assertEquals(fixtures.refNbCaracteristic(), result.size()); + } + + @Test + public void getSizeCategoryCaracteristic() { + Caracteristic result = service.getSizeCategoryCaracteristic(); + assertCaracteristicQualitative(result, 6); + } + + @Test + public void getSexCaracteristic() { + Caracteristic result = service.getSexCaracteristic(); + assertCaracteristicQualitative(result, 4); + } + + @Test + public void getSortedUnsortedCaracteristic() { + Caracteristic result = service.getSortedUnsortedCaracteristic(); + assertCaracteristicQualitative(result, 2); + } + + @Test + public void getMaturityCaracteristic() { + Caracteristic result = service.getMaturityCaracteristic(); + assertCaracteristicQualitative(result, 6); + } + + @Test + public void getMacroWasteCategoryCaracteristic() { + Caracteristic result = service.getMacroWasteCategoryCaracteristic(); + assertCaracteristicQualitative(result, 21); + } + + @Test + public void getMacroWasteSizeCategoryCaracteristic() { + Caracteristic result = service.getMacroWasteSizeCategoryCaracteristic(); + assertCaracteristicQualitative(result, 6); + } + + protected <S extends IdAware> void persistList(Class<S> type, List<S> result) { + persistList(type, null, result); + } + + protected <S extends IdAware> void persistList(Class<S> type, String context, List<S> result) { + + String key = TuttiPersistenceDevImpl.getKey(type, context); + for (S s : result) { + storage.create(key, s, false); + } + storage.persistToFile(key); + } + + protected <S extends IdAware> void persist(Class<S> type, S result) { + persist(type, null, result); + } + + protected <S extends IdAware> void persist(Class<S> type, String context, S result) { + String key = TuttiPersistenceDevImpl.getKey(type, context); + storage.create(key, result, true); + } + + protected void assertSize(List<?> expectedList, List<?> storageList) { + Assert.assertNotNull(expectedList); + Assert.assertNotNull(storageList); + expectedList.removeAll(storageList); + Assert.assertTrue("Some " + expectedList.size() + " entities were not persisted in storage :" + + expectedList, expectedList.isEmpty()); + + } + + protected void assertCaracteristicQualitative(Caracteristic result, int nbValues) { + Assert.assertNotNull(result); + Assert.assertNotNull(result.getCaracteristicType()); + Assert.assertTrue(TuttiEntities.isQualitativeCaracteristic(result)); + Assert.assertNotNull(result.getQualitativeValue()); + Assert.assertEquals(nbValues, result.sizeQualitativeValue()); + } + + protected void assertCaracteristicSize(Caracteristic incoming, + Caracteristic caracteristic) { + Assert.assertNotNull(incoming); + Assert.assertNotNull(caracteristic); + Assert.assertEquals(incoming, caracteristic); + Assert.assertEquals(incoming.getCaracteristicType(), + caracteristic.getCaracteristicType()); + Assert.assertEquals(incoming.sizeQualitativeValue(), + caracteristic.sizeQualitativeValue()); + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/SpeciesBatchPersistenceServiceTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,393 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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 fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.entities.data.CatchBatch; +import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.data.SampleCategoryEnum; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.dao.DataRetrievalFailureException; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 0.3 + */ +public class SpeciesBatchPersistenceServiceTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + protected SpeciesBatchPersistenceService service; + + protected CruisePersistenceService cruiseService; + + protected FishingOperationPersistenceService fishingOperationService; + + protected CatchBatchPersistenceService catchBatchService; + + protected ReferentialPersistenceService referentialService; + + protected Cruise cruise; + + protected FishingOperation fishingOperation; + + protected CatchBatch catchBacth; + + protected List<Species> species; + + protected Caracteristic sortedUnsortedPMFM; + + protected CaracteristicQualitativeValue horsVracQualitativeValue; + + protected CaracteristicQualitativeValue vracQualitativeValue; + + protected Caracteristic maturityPMFM; + + protected CaracteristicQualitativeValue firstMaturityQualitativeValue; + + protected Caracteristic sexPMFM; + + protected CaracteristicQualitativeValue maleQualitativeValue; + + protected CaracteristicQualitativeValue femaleQualitativeValue; + + protected CaracteristicQualitativeValue unkQualitativeValue; + + + protected String speciesBacthId = null; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getSpeciesBatchPersistenceService(); + cruiseService = TuttiPersistenceServiceLocator.getCruisePersistenceService(); + fishingOperationService = TuttiPersistenceServiceLocator.getFishingOperationPersistenceService(); + referentialService = TuttiPersistenceServiceLocator.getReferentialPersistenceService(); + catchBatchService = TuttiPersistenceServiceLocator.getCatchBatchPersistenceService(); + + cruise = cruiseService.getCruise(dbResource.getFixtures().cruiseId()); + cruise.setId(null); + Calendar calendar = new GregorianCalendar(); + cruise.setBeginDate(calendar.getTime()); + cruise.setYear(calendar.get(Calendar.YEAR)); + calendar.add(Calendar.MONTH, 1); // add one month + cruise.setEndDate(calendar.getTime()); + cruise = cruiseService.createCruise(cruise); + + List<FishingOperation> fishingOperations = fishingOperationService.getAllFishingOperation(dbResource.getFixtures().cruiseId()); + assertNotNull(fishingOperations); + assertTrue(fishingOperations.size() > 0); + fishingOperation = fishingOperations.get(0); + fishingOperation = fishingOperationService.getFishingOperation(fishingOperation.getId()); + fishingOperation.setId(null); + fishingOperation.setCruise(cruise); + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 1); + calendar.set(Calendar.MILLISECOND, 0); + fishingOperation.setGearShootingStartDate(calendar.getTime()); + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 10); + calendar.set(Calendar.MILLISECOND, 0); + fishingOperation.setGearShootingEndDate(calendar.getTime()); + + fishingOperation = fishingOperationService.createFishingOperation(fishingOperation); + + catchBacth = new CatchBatch(); + catchBacth.setFishingOperation(fishingOperation); + catchBacth = catchBatchService.createCatchBatch(catchBacth); + + species = referentialService.getAllSpecies(); + assertNotNull(species); + assertTrue(species.size() > 2); + + sortedUnsortedPMFM = referentialService.getSortedUnsortedCaracteristic(); + horsVracQualitativeValue = sortedUnsortedPMFM.getQualitativeValue(0); + vracQualitativeValue = sortedUnsortedPMFM.getQualitativeValue(1); + maturityPMFM = referentialService.getMaturityCaracteristic(); + firstMaturityQualitativeValue = maturityPMFM.getQualitativeValue(0); + sexPMFM = referentialService.getSexCaracteristic(); + maleQualitativeValue = sexPMFM.getQualitativeValue(1); + femaleQualitativeValue = sexPMFM.getQualitativeValue(2); + unkQualitativeValue = sexPMFM.getQualitativeValue(3); + } + + @Test + public void createSpeciesBatch(/*SpeciesBatch bean, String parentBatchId*/) { + SpeciesBatch esp1Batch = null; + SpeciesBatch esp2Batch = null; + SpeciesBatch batch = null; + Species taxon1 = species.get(0); + Species taxon2 = species.get(1); + + // ----------------------------------------------------------------------------- + // 1. Test with only mandatory properties + // ----------------------------------------------------------------------------- + // batch : "ESP1 - Vrac/5" + batch = new SpeciesBatch(); + batch.setParentBatch(null); + batch.setFishingOperation(fishingOperation); + // TODO TC : add link between Speciesbatch and CatchBatch + //batch.setCatchBatch(catchBatch); + batch.setSpecies(taxon1); + batch.setSampleCategoryType(SampleCategoryEnum.sortedUnsorted); + batch.setSampleCategoryValue(vracQualitativeValue); + batch.setWeight(5f); + + assertCreateAndReloadSpeciesBatch(batch, null); + + // Save ESP1 batch + esp1Batch = batch; + + // ----------------------------------------------------------------------------- + // 2. Test child "Male/2" + // ----------------------------------------------------------------------------- + // Batch : ESP1 - Vrac/5 Male/2 ss-ech/1 Nombre/7 + batch = new SpeciesBatch(); + batch.setId(null); + batch.setParentBatch(esp1Batch); + batch.setSpecies(taxon1); + batch.setComment("ESP1 - Vrac/5 Male/2 ss-ech/1 Nombre/7"); + batch.setWeight(2f); + batch.setSampleCategoryType(SampleCategoryEnum.sex); + batch.setSampleCategoryValue(maleQualitativeValue); + batch.setSampleCategoryWeight(1f); + batch.setNumber(7); + + assertCreateAndReloadSpeciesBatch(batch, batch.getParentBatch().getId()); + + // ----------------------------------------------------------------------------- + // 3. Test child "Female/2" + // ----------------------------------------------------------------------------- + // Batch : ESP1 - Vrac/5 Female/3 Nombre/14 + batch = new SpeciesBatch(); + batch.setId(null); + batch.setParentBatch(esp1Batch); + batch.setSpecies(taxon1); + batch.setComment("ESP1 - Vrac/5 Female/3 Nombre/14"); + batch.setWeight(3f); + batch.setSampleCategoryType(SampleCategoryEnum.sex); + batch.setSampleCategoryValue(femaleQualitativeValue); + batch.setSampleCategoryWeight(null); + batch.setNumber(14); + + assertCreateAndReloadSpeciesBatch(batch, batch.getParentBatch().getId()); + + // ----------------------------------------------------------------------------- + // 4. Test : ESP2 - Vrac/7 + // \- ESP2 - Vrac/7 UNK/2 ss-ech/1 Nombre/11 + // ----------------------------------------------------------------------------- + // batch : "ESP2 - Vrac/7 " + batch = new SpeciesBatch(); + batch.setParentBatch(null); + // TODO TC : add link between Speciesbatch and CatchBatch + //batch.setCatchBatch(catchBatch); + batch.setSpecies(taxon2); + batch.setSampleCategoryType(SampleCategoryEnum.sortedUnsorted); + batch.setSampleCategoryValue(vracQualitativeValue); + batch.setWeight(7f); + + assertCreateAndReloadSpeciesBatch(batch, null); + esp2Batch = batch; + + // Batch : ESP2 - Vrac/7 UNK/2 ss-ech/1 Nombre/11 + batch = new SpeciesBatch(); + batch.setId(null); + batch.setParentBatch(esp2Batch); + batch.setSpecies(taxon1); + batch.setComment("ESP2 - Vrac/7 UNK/2 ss-ech/1 Nombre/11"); + batch.setSampleCategoryType(SampleCategoryEnum.maturity); + batch.setSampleCategoryValue(firstMaturityQualitativeValue); + batch.setWeight(2f); + batch.setSampleCategoryWeight(1f); + batch.setNumber(11); + + assertCreateAndReloadSpeciesBatch(batch, batch.getParentBatch().getId()); + + // ----------------------------------------------------------------------------- + // 5. Test save after modifications + // ----------------------------------------------------------------------------- + // Batch : ESP2 - Vrac/7 UNK/1.75 ss-ech/1.11 Nombre/99 + batch.setSampleCategoryType(SampleCategoryEnum.sex); + batch.setSampleCategoryValue(unkQualitativeValue); + batch.setComment("ESP2 - Vrac/7 UNK/1.75 ss-ech/1.11 Nombre/99"); + batch.setWeight(1.75f); + batch.setSampleCategoryWeight(1.11f); + batch.setFishingOperation(fishingOperation); + batch.setNumber(99); + + // Save and reload, then check + SpeciesBatch savedBatch = service.saveSpeciesBatch(batch); + assertSpeciesBatch(savedBatch, batch, false); + SpeciesBatch reloadedBatch = service.getSpeciesBatch(savedBatch.getId()); + assertSpeciesBatch(reloadedBatch, savedBatch, true); + + // ----------------------------------------------------------------------------- + // 6. Test get all root species + // ----------------------------------------------------------------------------- + List<SpeciesBatch> rootSpeciesBatch = service.getAllRootSpeciesBatch(fishingOperation.getId()); + assertNotNull(rootSpeciesBatch); + assertEquals(2, rootSpeciesBatch.size()); + + // ----------------------------------------------------------------------------- + // 4. Test get all species + // ----------------------------------------------------------------------------- + List<SpeciesBatch> allSpeciesBatch = service.getAllSpeciesBatch(fishingOperation.getId()); + assertNotNull(allSpeciesBatch); + assertEquals(5, allSpeciesBatch.size()); + } + + @Test + @Ignore + public void saveSpeciesBatch(/*SpeciesBatch bean*/) { + + } + + + @Test + @Ignore + public void getSpeciesBatch(/*String id*/) { + if (speciesBacthId == null) return; + SpeciesBatch batch = service.getSpeciesBatch(speciesBacthId); + assertNotNull(batch); + } + + @Test + @Ignore + public void getAllSpeciesBatch(/*String fishingOperationId*/) { + + } + + @Test + @Ignore + public void getAllRootSpeciesBatch(/*String fishingOperationId*/) { + } + + @Test + public void deleteSpeciesBatch(/*String id*/) { + SpeciesBatch esp1Batch = null; + SpeciesBatch childBatch = null; + SpeciesBatch batch = null; + Species taxon1 = species.get(0); + + // ----------------------------------------------------------------------------- + // 1. Create two batchs (parent + child), then remove the parent batch + // ----------------------------------------------------------------------------- + // batch : ESP1 Vrac/5 + batch = new SpeciesBatch(); + batch.setParentBatch(null); + batch.setFishingOperation(fishingOperation); + batch.setSpecies(taxon1); + batch.setSampleCategoryType(SampleCategoryEnum.sortedUnsorted); + batch.setSampleCategoryValue(vracQualitativeValue); + batch.setWeight(5f); + assertCreateAndReloadSpeciesBatch(batch, null); + esp1Batch = batch; + + // batch : ESP1 Vrac/5 Male/2 + batch = new SpeciesBatch(); + batch.setParentBatch(esp1Batch); + batch.setFishingOperation(fishingOperation); + batch.setSpecies(taxon1); + batch.setSampleCategoryType(SampleCategoryEnum.sex); + batch.setSampleCategoryValue(maleQualitativeValue); + batch.setWeight(2f); + assertCreateAndReloadSpeciesBatch(batch, esp1Batch.getId()); + + // Try to remove + service.deleteSpeciesBatch(esp1Batch.getId()); + + // Check if remove + try { + batch = service.getSpeciesBatch(esp1Batch.getId()); + assertNull(batch); + } catch (DataRetrievalFailureException drfe) { + assertNotNull(drfe); + } + } + + @Test + @Ignore + public void deleteSpeciesSubBatch(/*String id*/) { + // Idem deleteSpeciesBatch + } + + @Test + @Ignore + public void getAllSpeciesBatchFrequency(/*String speciesBatchId*/) { + + } + + protected void assertCreateAndReloadSpeciesBatch(SpeciesBatch batch, String parentBatchId) { + batch.setFishingOperation(fishingOperation); + + // Create batch + SpeciesBatch createdBatch = service.createSpeciesBatch(batch, parentBatchId); + assertSpeciesBatch(createdBatch, batch, false); + + // then reload (for round trip check) + SpeciesBatch reloadedBatch = service.getSpeciesBatch(createdBatch.getId()); + assertNull(reloadedBatch.getParentBatch()); + assertSpeciesBatch(reloadedBatch, batch, false); + + batch.setId(createdBatch.getId()); + } + + protected void assertSpeciesBatch(SpeciesBatch expectedBatch, SpeciesBatch actualBatch, boolean assertIdEquals) { + assertNotNull(actualBatch); + assertNotNull(actualBatch.getId()); + if (assertIdEquals && expectedBatch.getId() != null) { + assertEquals(expectedBatch.getId(), actualBatch.getId()); + } + assertEquals(expectedBatch.getWeight(), actualBatch.getWeight()); + assertEquals(expectedBatch.getSampleCategoryType(), actualBatch.getSampleCategoryType()); + assertEquals(expectedBatch.getSampleCategoryValue(), actualBatch.getSampleCategoryValue()); + assertEquals(expectedBatch.getSampleCategoryWeight(), actualBatch.getSampleCategoryWeight()); + assertEquals(expectedBatch.getNumber(), actualBatch.getNumber()); + assertEquals(expectedBatch.getComment(), actualBatch.getComment()); + if (expectedBatch.getSpecies() != null) { + assertNotNull(actualBatch.getSpecies()); + assertEquals(expectedBatch.getSpecies().getId(), actualBatch.getSpecies().getId()); + } + } + +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFileTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFileTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFileTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/TuttiEnumerationFileTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,54 @@ +package fr.ifremer.tutti.persistence.service; + +/* + * #%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 fr.ifremer.tutti.persistence.DatabaseResource; +import org.junit.Assert; +import org.junit.ClassRule; +import org.junit.Test; + +/** + * This test load the {@link TuttiEnumerationFile} via Spring and then + * validates that we miss not constant. + * + * @author tchemit <chemit@codelutin.com> + * @see TuttiEnumerationFile#init() + * @since 1.0 + */ +public class TuttiEnumerationFileTest { + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource( + "beanRefFactoryWitNoDb.xml", "TuttiBeanRefFactoryWithNoDb"); + + @Test + public void init() { + + TuttiEnumerationFile file = + TuttiPersistenceServiceLocator.getTuttiEnumerationFile(); + Assert.assertNotNull(file); + } + +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelperTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelperTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelperTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeHelperTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,680 @@ +package fr.ifremer.tutti.persistence.service.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 fr.ifremer.tutti.persistence.DatabaseFixtures; +import fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.dialect.Dialect; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.jdbc.support.JdbcUtils; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Calendar; +import java.util.Date; +import java.util.Properties; +import java.util.Set; + +/** + * TODO + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +public class ReferentialSynchronizeHelperTest { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ReferentialSynchronizeHelperTest.class); + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + @Rule + public final TestName n = new TestName(); + + + protected Connection externalConnection; + + protected Connection internalConnection; + + protected ReferentialSynchronizeHelper helper; + + protected Dialect dialect; + + protected Properties localConnectionProperties; + + @Before + public void setUp() throws Exception { + helper = new ReferentialSynchronizeHelper(); + ReferentialSynchronizeService service = + TuttiPersistenceServiceLocator.getReferentialSynchronizeService(); + dialect = service.getLocalDialect(); + localConnectionProperties = service.getLocalConnectionProperties(); + } + + @After + public void tearDown() throws Exception { + helper = null; + dialect = null; + localConnectionProperties = null; + + try { + if (internalConnection != null && !internalConnection.isClosed()) { + internalConnection.rollback(); + } + } finally { + + try { + if (externalConnection != null && !externalConnection.isClosed()) { + externalConnection.rollback(); + } + + } finally { + JdbcUtils.closeConnection(internalConnection); + JdbcUtils.closeConnection(externalConnection); + } + } + } + + @Test + public void loadDatabaseMetadata() throws Exception { + + Assert.assertNotNull(dialect); + + createInternalConnection(); + TuttiDatabaseMetadata internalDb = + helper.loadDatabaseMetadata(internalConnection, dialect); + assertTuttiDatabaseMetadata(internalDb); + + createExternalDb(); + TuttiDatabaseMetadata externalDb = + helper.loadDatabaseMetadata(externalConnection, dialect); + assertTuttiDatabaseMetadata(externalDb); + } + + @Test + public void checkSchemas() throws Exception { + + createInternalConnection(); + + TuttiDatabaseMetadata internalDb = + helper.loadDatabaseMetadata(internalConnection, dialect); + Assert.assertNotNull(internalDb); + + helper.checkSchemas(internalDb, internalDb); + + // create a external empty db + createExternalDb(); + + TuttiDatabaseMetadata externalDb = + helper.loadDatabaseMetadata(externalConnection, dialect); + Assert.assertNotNull(externalDb); + helper.checkSchemas(internalDb, externalDb); + + // add a column in a table and recheck schemas + PreparedStatement statement = externalConnection.prepareStatement("ALTER TABLE PUBLIC.LOCATION ADD newColumn" + System.nanoTime() + " int NOT NULL;"); + statement.execute(); + externalConnection.commit(); + + try { + // reload external schema, it has changed + externalDb = helper.loadDatabaseMetadata(externalConnection, dialect); + + helper.checkSchemas(internalDb, externalDb); + Assert.fail(); + } catch (DataRetrievalFailureException e) { + + Assert.assertTrue(true); + } + } + + @Test + public void getLastUpdateDate() throws Exception { + + createInternalConnection(); + + TuttiDatabaseMetadata internalDb = + helper.loadDatabaseMetadata(internalConnection, dialect); + Assert.assertNotNull(internalDb); + + getLastUpdateDate(TuttiTable.UNIT, internalDb, getSqlDate(2012, 8, 17)); + getLastUpdateDate(TuttiTable.AGGREGATION_LEVEL, internalDb, getSqlDate(2011, 6, 9)); + getLastUpdateDate(TuttiTable.PARAMETER_GROUP, internalDb, getSqlDate(2013, 1, 29)); + getLastUpdateDate(TuttiTable.PARAMETER, internalDb, getSqlDate(2013, 1, 29)); + getLastUpdateDate(TuttiTable.MATRIX, internalDb, getSqlDate(2013, 1, 24)); + getLastUpdateDate(TuttiTable.FRACTION, internalDb, getSqlDate(2013, 1, 24)); + getLastUpdateDate(TuttiTable.METHOD, internalDb, getSqlDate(2013, 1, 29)); + getLastUpdateDate(TuttiTable.PMFM, internalDb, getSqlDate(2013, 1, 29)); + getLastUpdateDate(TuttiTable.GEAR_CLASSIFICATION, internalDb, getSqlDate(2012, 12, 18)); + getLastUpdateDate(TuttiTable.GEAR, internalDb, getSqlDate(2012, 12, 18)); + getLastUpdateDate(TuttiTable.LOCATION_CLASSIFICATION, internalDb, getSqlDate(2010, 10, 26)); + getLastUpdateDate(TuttiTable.LOCATION_LEVEL, internalDb, getSqlDate(2013, 1, 28)); + getLastUpdateDate(TuttiTable.LOCATION, internalDb, getSqlDate(2013, 1, 29)); + getLastUpdateDate(TuttiTable.TAXONOMIC_LEVEL, internalDb, getSqlDate(2012, 4, 18)); + getLastUpdateDate(TuttiTable.REFERENCE_TAXON, internalDb, getSqlDate(2013, 1, 21)); + getLastUpdateDate(TuttiTable.TAXON_NAME, internalDb, getSqlDate(2013, 1, 21)); + getLastUpdateDate(TuttiTable.TAXON_GROUP_TYPE, internalDb, getSqlDate(2012, 5, 24)); + getLastUpdateDate(TuttiTable.TAXON_GROUP, internalDb, getSqlDate(2013, 1, 16)); + getLastUpdateDate(TuttiTable.ROUND_WEIGHT_CONVERSION, internalDb, getSqlDate(2012, 10, 4)); + getLastUpdateDate(TuttiTable.WEIGHT_LENGTH_CONVERSION, internalDb, getSqlDate(2013, 1, 17)); + getLastUpdateDate(TuttiTable.VESSEL_TYPE, internalDb, getSqlDate(2012, 4, 25)); + getLastUpdateDate(TuttiTable.VESSEL, internalDb, getSqlDate(2013, 1, 25)); + getLastUpdateDate(TuttiTable.USER_PROFIL, internalDb, getSqlDate(2009, 6, 18)); + getLastUpdateDate(TuttiTable.DEPARTMENT, internalDb, getSqlDate(2013, 1, 24)); + getLastUpdateDate(TuttiTable.PERSON, internalDb, getSqlDate(2013, 1, 29)); + + // try it on a empty db (all values are to null) + + // create a external empty db + createExternalDb(); + + TuttiDatabaseMetadata externalDb = + helper.loadDatabaseMetadata(externalConnection, dialect); + + for (TuttiTable tuttiTable : TuttiTable.values()) { + getLastUpdateDate(tuttiTable, externalDb, true, null); + } + } + + @Test + public void getExistingIds() throws SQLException, IOException { + + createInternalConnection(); + + TuttiDatabaseMetadata internalDb = + helper.loadDatabaseMetadata(internalConnection, dialect); + Assert.assertNotNull(internalDb); + + DatabaseFixtures fixtures = dbResource.getFixtures(); + getExistingIds(TuttiTable.STATUS, fixtures.nbStatus()); + getExistingIds(TuttiTable.QUALITY_FLAG, fixtures.nbQualityFlag()); + getExistingIds(TuttiTable.UNIT, fixtures.nbUnit()); + getExistingIds(TuttiTable.AGGREGATION_LEVEL, fixtures.nbAggregationLevel()); + getExistingIds(TuttiTable.PARAMETER_GROUP, fixtures.nbParameterGroup()); + getExistingIds(TuttiTable.QUALITATIVE_VALUE, fixtures.nbQualitativeValue()); + getExistingIds(TuttiTable.PARAMETER, fixtures.nbParameter()); + getExistingIds(TuttiTable.MATRIX, fixtures.nbMatrix()); + getExistingIds(TuttiTable.FRACTION, fixtures.nbFraction()); + getExistingIds(TuttiTable.METHOD, fixtures.nbMethod()); + getExistingIds(TuttiTable.PMFM, fixtures.nbPmfm()); + getExistingIds(TuttiTable.GEAR_CLASSIFICATION, fixtures.nbGearClassification()); + getExistingIds(TuttiTable.GEAR, fixtures.nbGear()); + getExistingIds(TuttiTable.LOCATION_CLASSIFICATION, fixtures.nbLocationClassification()); + getExistingIds(TuttiTable.LOCATION_LEVEL, fixtures.nbLocationLevel()); + getExistingIds(TuttiTable.LOCATION, fixtures.nbLocation()); + getExistingIds(TuttiTable.TAXONOMIC_LEVEL, fixtures.nbTaxonomicLevel()); + getExistingIds(TuttiTable.REFERENCE_TAXON, fixtures.nbReferenceTaxon()); + getExistingIds(TuttiTable.TAXON_NAME, fixtures.nbTaxonName()); + getExistingIds(TuttiTable.TAXON_GROUP_TYPE, fixtures.nbTaxonGroupType()); + getExistingIds(TuttiTable.TAXON_GROUP, fixtures.nbTaxonGroup()); + getExistingIds(TuttiTable.ROUND_WEIGHT_CONVERSION, fixtures.nbRoundWeightConversion()); + getExistingIds(TuttiTable.WEIGHT_LENGTH_CONVERSION, fixtures.nbWeightLegnthConversion()); + getExistingIds(TuttiTable.VESSEL_TYPE, fixtures.nbVesselType()); + getExistingIds(TuttiTable.VESSEL, fixtures.nbVessel()); + getExistingIds(TuttiTable.USER_PROFIL, fixtures.nbUserProfil()); + getExistingIds(TuttiTable.DEPARTMENT, fixtures.nbDepartment()); + getExistingIds(TuttiTable.PERSON, fixtures.nbPerson()); + + // try it on a empty db (nothing to synch) + + // create a external empty db + createExternalDb(); + + for (TuttiTable tuttiTable : TuttiTable.values()) { + getExistingIds(tuttiTable, true, 0); + } + } + + @Test + public void getDataToUpdate() throws SQLException, IOException { + + Date fromDate = getDate(1980, 1, 1); + + createInternalConnection(); + + TuttiDatabaseMetadata internalDb = + helper.loadDatabaseMetadata(internalConnection, dialect); + Assert.assertNotNull(internalDb); + + DatabaseFixtures fixtures = dbResource.getFixtures(); + getDataToUpdate(TuttiTable.STATUS, internalDb, internalConnection, fromDate, fixtures.nbStatus()); + getDataToUpdate(TuttiTable.QUALITY_FLAG, internalDb, internalConnection, fromDate, fixtures.nbQualityFlag()); + getDataToUpdate(TuttiTable.UNIT, internalDb, internalConnection, fromDate, fixtures.nbUnit()); + getDataToUpdate(TuttiTable.AGGREGATION_LEVEL, internalDb, internalConnection, fromDate, fixtures.nbAggregationLevel()); + getDataToUpdate(TuttiTable.PARAMETER_GROUP, internalDb, internalConnection, fromDate, fixtures.nbParameterGroup()); + getDataToUpdate(TuttiTable.QUALITATIVE_VALUE, internalDb, internalConnection, fromDate, fixtures.nbQualitativeValue()); + getDataToUpdate(TuttiTable.PARAMETER, internalDb, internalConnection, fromDate, fixtures.nbParameter()); + getDataToUpdate(TuttiTable.MATRIX, internalDb, internalConnection, fromDate, fixtures.nbMatrix()); + getDataToUpdate(TuttiTable.FRACTION, internalDb, internalConnection, fromDate, fixtures.nbFraction()); + getDataToUpdate(TuttiTable.METHOD, internalDb, internalConnection, fromDate, fixtures.nbMethod()); + getDataToUpdate(TuttiTable.PMFM, internalDb, internalConnection, fromDate, fixtures.nbPmfm()); + getDataToUpdate(TuttiTable.GEAR_CLASSIFICATION, internalDb, internalConnection, fromDate, fixtures.nbGearClassification()); + getDataToUpdate(TuttiTable.GEAR, internalDb, internalConnection, fromDate, fixtures.nbGear()); + getDataToUpdate(TuttiTable.LOCATION_CLASSIFICATION, internalDb, internalConnection, fromDate, fixtures.nbLocationClassification()); + getDataToUpdate(TuttiTable.LOCATION_LEVEL, internalDb, internalConnection, fromDate, fixtures.nbLocationLevel()); + getDataToUpdate(TuttiTable.LOCATION, internalDb, internalConnection, fromDate, fixtures.nbLocation()); + getDataToUpdate(TuttiTable.TAXONOMIC_LEVEL, internalDb, internalConnection, fromDate, fixtures.nbTaxonomicLevel()); + getDataToUpdate(TuttiTable.REFERENCE_TAXON, internalDb, internalConnection, fromDate, fixtures.nbReferenceTaxon()); + getDataToUpdate(TuttiTable.TAXON_NAME, internalDb, internalConnection, fromDate, fixtures.nbTaxonName()); + getDataToUpdate(TuttiTable.TAXON_GROUP_TYPE, internalDb, internalConnection, fromDate, fixtures.nbTaxonGroupType()); + getDataToUpdate(TuttiTable.TAXON_GROUP, internalDb, internalConnection, fromDate, fixtures.nbTaxonGroup()); + getDataToUpdate(TuttiTable.ROUND_WEIGHT_CONVERSION, internalDb, internalConnection, fromDate, fixtures.nbRoundWeightConversion()); + getDataToUpdate(TuttiTable.WEIGHT_LENGTH_CONVERSION, internalDb, internalConnection, fromDate, fixtures.nbWeightLegnthConversion()); + getDataToUpdate(TuttiTable.VESSEL_TYPE, internalDb, internalConnection, fromDate, fixtures.nbVesselType()); + getDataToUpdate(TuttiTable.VESSEL, internalDb, internalConnection, fromDate, fixtures.nbVessel()); + getDataToUpdate(TuttiTable.USER_PROFIL, internalDb, internalConnection, fromDate, fixtures.nbUserProfil()); + getDataToUpdate(TuttiTable.DEPARTMENT, internalDb, internalConnection, fromDate, fixtures.nbDepartment()); + getDataToUpdate(TuttiTable.PERSON, internalDb, internalConnection, fromDate, fixtures.nbPerson()); + + // try it on a empty db (nothing to synch) + + // create a external empty db + createExternalDb(); + + TuttiDatabaseMetadata externalDb = + helper.loadDatabaseMetadata(externalConnection, dialect); + + for (TuttiTable tuttiTable : TuttiTable.values()) { + getDataToUpdate(tuttiTable, externalDb, externalConnection, fromDate, 0); + } + } + + @Test + public void updateTable() throws SQLException, IOException { + + Date fromDate = getDate(1980, 1, 1); + + createInternalConnection(); + + TuttiDatabaseMetadata internalDb = + helper.loadDatabaseMetadata(internalConnection, dialect); + Assert.assertNotNull(internalDb); + + // create a external empty db + createExternalDb(); + + TuttiDatabaseMetadata externalDb = + helper.loadDatabaseMetadata(externalConnection, dialect); + Assert.assertNotNull(externalDb); + + DatabaseFixtures fixtures = dbResource.getFixtures(); + updateTable(TuttiTable.STATUS, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbStatus(), 0); + updateTable(TuttiTable.QUALITY_FLAG, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbQualityFlag(), 0); + updateTable(TuttiTable.UNIT, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbUnit(), 0); + updateTable(TuttiTable.AGGREGATION_LEVEL, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbAggregationLevel(), 0); + updateTable(TuttiTable.PARAMETER_GROUP, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbParameterGroup(), 0); + updateTable(TuttiTable.QUALITATIVE_VALUE, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbQualitativeValue(), 0); + updateTable(TuttiTable.PARAMETER, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbParameter(), 0); + updateTable(TuttiTable.MATRIX, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbMatrix(), 0); + updateTable(TuttiTable.FRACTION, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbFraction(), 0); + updateTable(TuttiTable.METHOD, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbMethod(), 0); + updateTable(TuttiTable.PMFM, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbPmfm(), 0); + updateTable(TuttiTable.GEAR_CLASSIFICATION, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbGearClassification(), 0); + updateTable(TuttiTable.GEAR, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbGear(), 0); + updateTable(TuttiTable.LOCATION_CLASSIFICATION, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbLocationClassification(), 0); + updateTable(TuttiTable.LOCATION_LEVEL, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbLocationLevel(), 0); + updateTable(TuttiTable.LOCATION, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbLocation(), 0); + updateTable(TuttiTable.TAXONOMIC_LEVEL, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbTaxonomicLevel(), 0); + updateTable(TuttiTable.REFERENCE_TAXON, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbReferenceTaxon(), 0); + updateTable(TuttiTable.TAXON_NAME, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbTaxonName(), 0); + updateTable(TuttiTable.TAXON_GROUP_TYPE, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbTaxonGroupType(), 0); + updateTable(TuttiTable.TAXON_GROUP, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbTaxonGroup(), 0); + updateTable(TuttiTable.ROUND_WEIGHT_CONVERSION, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbRoundWeightConversion(), 0); + updateTable(TuttiTable.WEIGHT_LENGTH_CONVERSION, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbWeightLegnthConversion(), 0); + updateTable(TuttiTable.VESSEL_TYPE, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbVesselType(), 0); + updateTable(TuttiTable.VESSEL, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbVessel(), 0); + updateTable(TuttiTable.USER_PROFIL, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbUserProfil(), 0); + updateTable(TuttiTable.DEPARTMENT, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbDepartment(), 0); + updateTable(TuttiTable.PERSON, internalDb, internalConnection, externalConnection, fromDate, fixtures.nbPerson(), 0); + + externalConnection.commit(); +// externalConnection.rollback(); + + // try to synch with a update date from a old date (so synch everything on update) + fromDate = getDate(1980, 1, 1); + + if (log.isInfoEnabled()) { + log.info("From " + fromDate); + } + + updateTable(TuttiTable.STATUS, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbStatus()); + updateTable(TuttiTable.QUALITY_FLAG, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbQualityFlag()); + updateTable(TuttiTable.UNIT, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbUnit()); + updateTable(TuttiTable.AGGREGATION_LEVEL, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbAggregationLevel()); + updateTable(TuttiTable.PARAMETER_GROUP, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbParameterGroup()); + updateTable(TuttiTable.QUALITATIVE_VALUE, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbQualitativeValue()); + updateTable(TuttiTable.PARAMETER, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbParameter()); + updateTable(TuttiTable.MATRIX, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbMatrix()); + updateTable(TuttiTable.FRACTION, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbFraction()); + updateTable(TuttiTable.METHOD, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbMethod()); + updateTable(TuttiTable.PMFM, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbPmfm()); + updateTable(TuttiTable.GEAR_CLASSIFICATION, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbGearClassification()); + updateTable(TuttiTable.GEAR, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbGear()); + updateTable(TuttiTable.LOCATION_CLASSIFICATION, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbLocationClassification()); + updateTable(TuttiTable.LOCATION_LEVEL, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbLocationLevel()); + updateTable(TuttiTable.LOCATION, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbLocation()); + updateTable(TuttiTable.TAXONOMIC_LEVEL, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbTaxonomicLevel()); + updateTable(TuttiTable.REFERENCE_TAXON, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbReferenceTaxon()); + updateTable(TuttiTable.TAXON_NAME, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbTaxonName()); + updateTable(TuttiTable.TAXON_GROUP_TYPE, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbTaxonGroupType()); + updateTable(TuttiTable.TAXON_GROUP, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbTaxonGroup()); + updateTable(TuttiTable.ROUND_WEIGHT_CONVERSION, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbRoundWeightConversion()); + updateTable(TuttiTable.WEIGHT_LENGTH_CONVERSION, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbWeightLegnthConversion()); + updateTable(TuttiTable.VESSEL_TYPE, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbVesselType()); + updateTable(TuttiTable.VESSEL, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbVessel()); + updateTable(TuttiTable.USER_PROFIL, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbUserProfil()); + updateTable(TuttiTable.DEPARTMENT, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbDepartment()); + updateTable(TuttiTable.PERSON, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbPerson()); + + externalConnection.commit(); + + // try to synch with a update date from next year (so nothing to synch, expect with no update_date table) + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + + calendar.setTime(new Date()); + fromDate = getDate(calendar.get(Calendar.YEAR) + 1, + calendar.get(Calendar.MONTH), + calendar.get(Calendar.DAY_OF_MONTH)); + + if (log.isInfoEnabled()) { + log.info("From " + fromDate); + } + + updateTable(TuttiTable.STATUS, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbStatus()); + updateTable(TuttiTable.QUALITY_FLAG, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbQualityFlag()); + updateTable(TuttiTable.UNIT, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.AGGREGATION_LEVEL, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.PARAMETER_GROUP, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.QUALITATIVE_VALUE, internalDb, internalConnection, externalConnection, fromDate, 0, fixtures.nbQualitativeValue()); + updateTable(TuttiTable.PARAMETER, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.MATRIX, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.FRACTION, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.METHOD, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.PMFM, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.GEAR_CLASSIFICATION, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.GEAR, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.LOCATION_CLASSIFICATION, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.LOCATION_LEVEL, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.LOCATION, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.TAXONOMIC_LEVEL, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.REFERENCE_TAXON, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.TAXON_NAME, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.TAXON_GROUP_TYPE, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.TAXON_GROUP, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.ROUND_WEIGHT_CONVERSION, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.WEIGHT_LENGTH_CONVERSION, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.VESSEL_TYPE, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.VESSEL, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.USER_PROFIL, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.DEPARTMENT, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + updateTable(TuttiTable.PERSON, internalDb, internalConnection, externalConnection, fromDate, 0, 0); + + // add a aggregation level then synch + String query = "INSERT INTO AGGREGATION_LEVEL (ID, NAME, RANK_ORDER, UPDATE_DATE) VALUES (-1000, 'NAME', -1000, NULL)"; + PreparedStatement statement = internalConnection.prepareStatement(query); + statement.executeUpdate(); + + updateTable(TuttiTable.AGGREGATION_LEVEL, internalDb, internalConnection, externalConnection, fromDate, 1, 0); + } + + protected ResultSet getDataToUpdate(TuttiTable tuttiTable, + TuttiDatabaseMetadata db, + Connection connection, + Date fromDate, + int expectedResult) throws SQLException { + + TuttiTableMetadata table = db.getTable(tuttiTable.name()); + ResultSet actual = helper.getDataToUpdate(connection, table, fromDate); + + Assert.assertNotNull(actual); + int nbRows = 0; + while (actual.next()) { + nbRows++; + } + if (log.isDebugEnabled()) { + log.debug("getDataToUpdate(TuttiTable." + tuttiTable + ", internalDb, fromDate, " + nbRows + ");"); + } + Assert.assertEquals(expectedResult, nbRows); + return actual; + } + + protected void updateTable(TuttiTable tuttiTable, + TuttiDatabaseMetadata synchroDb, + Connection synchConnection, + Connection targetConnection, + Date fromDate, + int expectedInserts, + int expectedUpdates) throws SQLException { + + // internal is syncrho + ReferentialSynchronizeResult result = new ReferentialSynchronizeResult( + targetConnection.getMetaData().getURL(), + synchConnection.getMetaData().getURL() + ); + + String tableName = tuttiTable.name(); + + TuttiTableMetadata table = synchroDb.getTable(tableName); + + ResultSet dataToUpdate = + helper.getDataToUpdate(synchConnection, table, fromDate); + + if (dataToUpdate.next()) { + + Set<String> existingIds = + helper.getExistingIds(targetConnection, table); + + ReferentialSynchronizeHelper.prepareSynch(targetConnection); + + try { + helper.updateTable(targetConnection, + table, + existingIds, + dataToUpdate, + result); + } finally { + ReferentialSynchronizeHelper.releaseSynch(targetConnection); + } + + } + if (log.isDebugEnabled()) { + log.debug("updateTable(TuttiTable." + tuttiTable + + ", internalDb, externalDb, internalConnection, " + + "externalConnection, fromDate, " + + result.getNbInserts(tableName) + ", 0);"); + } + Assert.assertNotNull(result.getTableNames()); + if (expectedInserts + expectedUpdates == 0) { + + Assert.assertEquals(0, result.getTableNames().size()); + } else { + Assert.assertEquals(1, result.getTableNames().size()); + Assert.assertTrue(result.getTableNames().contains(tableName)); + } + Assert.assertEquals(expectedInserts, result.getNbInserts(tableName)); + Assert.assertEquals(expectedUpdates, result.getNbUpdates(tableName)); + } + + protected void getLastUpdateDate(TuttiTable tuttiTable, + TuttiDatabaseMetadata db, + Date expected) throws SQLException { + getLastUpdateDate(tuttiTable, db, false, expected); + } + + protected void getLastUpdateDate(TuttiTable tuttiTable, + TuttiDatabaseMetadata db, + boolean external, + Date expected) throws SQLException { + + TuttiTableMetadata table = db.getTable(tuttiTable.name()); + Date actual; + if (external) { + actual = helper.getLastUpdateDate(externalConnection, table); + } else { + actual = helper.getLastUpdateDate(internalConnection, table); + } + if (expected == null) { + + Assert.assertNull(actual); + } else { + + if (log.isDebugEnabled()) { + Calendar instance = Calendar.getInstance(); + instance.setTime(actual); + log.debug("getLastUpdateDate(TuttiTable." + tuttiTable.name() + ", internalDb, getSqlDate(" + instance.get(Calendar.YEAR) + ", " + instance.get(Calendar.MONTH) + ", " + instance.get(Calendar.DAY_OF_MONTH) + "));"); + } + + assertDate(expected, actual); + } + } + + protected void getExistingIds(TuttiTable tuttiTable, + int expectedResult) throws SQLException { + getExistingIds(tuttiTable, false, expectedResult); + } + + protected void getExistingIds(TuttiTable tuttiTable, + boolean external, + int expectedResult) throws SQLException { + + + TuttiDatabaseMetadata internalDb = helper.loadDatabaseMetadata(internalConnection, dialect); + TuttiTableMetadata table = internalDb.getTable(tuttiTable.name()); + Assert.assertNotNull(internalDb); + Set<String> actual; + if (external) { + actual = helper.getExistingIds(externalConnection, table); + } else { + actual = helper.getExistingIds(internalConnection, table); + } + Assert.assertNotNull(actual); + Assert.assertEquals(expectedResult, actual.size()); + } + + protected void assertTuttiDatabaseMetadata(TuttiDatabaseMetadata db) { + Assert.assertNotNull(db); + Assert.assertEquals(TuttiTable.values().length, db.getTableCount()); + + assertDatabaseMetadata(TuttiTable.STATUS, db, false, false); + assertDatabaseMetadata(TuttiTable.QUALITY_FLAG, db, false, false); + assertDatabaseMetadata(TuttiTable.UNIT, db, false, true); + assertDatabaseMetadata(TuttiTable.AGGREGATION_LEVEL, db, false, true); + assertDatabaseMetadata(TuttiTable.PARAMETER_GROUP, db, false, true); + assertDatabaseMetadata(TuttiTable.QUALITATIVE_VALUE, db, false, false); + assertDatabaseMetadata(TuttiTable.PARAMETER, db, false, true); + assertDatabaseMetadata(TuttiTable.MATRIX, db, false, true); + assertDatabaseMetadata(TuttiTable.FRACTION, db, false, true); + assertDatabaseMetadata(TuttiTable.METHOD, db, false, true); + assertDatabaseMetadata(TuttiTable.PMFM, db, false, true); + assertDatabaseMetadata(TuttiTable.GEAR_CLASSIFICATION, db, false, true); + assertDatabaseMetadata(TuttiTable.GEAR, db, false, true); + assertDatabaseMetadata(TuttiTable.LOCATION_CLASSIFICATION, db, false, true); + assertDatabaseMetadata(TuttiTable.LOCATION_LEVEL, db, false, true); + assertDatabaseMetadata(TuttiTable.LOCATION, db, false, true); + assertDatabaseMetadata(TuttiTable.TAXONOMIC_LEVEL, db, false, true); + assertDatabaseMetadata(TuttiTable.REFERENCE_TAXON, db, false, true); + assertDatabaseMetadata(TuttiTable.TAXON_NAME, db, false, true); + assertDatabaseMetadata(TuttiTable.TAXON_GROUP_TYPE, db, false, true); + assertDatabaseMetadata(TuttiTable.TAXON_GROUP, db, false, true); + assertDatabaseMetadata(TuttiTable.ROUND_WEIGHT_CONVERSION, db, false, true); + assertDatabaseMetadata(TuttiTable.WEIGHT_LENGTH_CONVERSION, db, false, true); + assertDatabaseMetadata(TuttiTable.VESSEL_TYPE, db, false, true); + assertDatabaseMetadata(TuttiTable.VESSEL, db, false, true); + assertDatabaseMetadata(TuttiTable.USER_PROFIL, db, false, true); + assertDatabaseMetadata(TuttiTable.DEPARTMENT, db, false, true); + assertDatabaseMetadata(TuttiTable.PERSON, db, false, true); + } + + protected void assertDatabaseMetadata(TuttiTable tableName, + TuttiDatabaseMetadata db, + boolean associationTable, + boolean withUpdateDateColumn) { + TuttiTableMetadata table = db.getTable(tableName.name()); + Assert.assertNotNull(table); + if (!ObjectUtils.equals(associationTable, table.isAssociationTable())) { + if (log.isWarnEnabled()) { + log.warn("[" + tableName + "] associationTable should be " + associationTable); + } + } + if (!ObjectUtils.equals(withUpdateDateColumn, table.isWithUpdateDateColumn())) { + if (log.isWarnEnabled()) { + log.warn("[" + tableName + "] withUpdateDateColumn should be " + associationTable); + } + } + Assert.assertEquals(associationTable, table.isAssociationTable()); + Assert.assertEquals(withUpdateDateColumn, table.isWithUpdateDateColumn()); + } + + public static void assertDate(Date expected, Date actual) { + Calendar expectedCal = Calendar.getInstance(); + expectedCal.setTime(expected); + Calendar actualCal = Calendar.getInstance(); + actualCal.setTime(actual); + Assert.assertEquals(expectedCal.get(Calendar.YEAR), actualCal.get(Calendar.YEAR)); + Assert.assertEquals(expectedCal.get(Calendar.MONTH), actualCal.get(Calendar.MONTH)); + Assert.assertEquals(expectedCal.get(Calendar.DAY_OF_MONTH), actualCal.get(Calendar.DAY_OF_MONTH)); + } + + + public static Date getSqlDate(int year, int month, int day) { + return getDate(year, month - 1, day); + } + + public static Date getDate(int year, int month, int day) { + Date fromDate = DateUtils.setYears(new Date(), year); + fromDate = DateUtils.setMonths(fromDate, month); + fromDate = DateUtils.setDays(fromDate, day); + return fromDate; + } + + protected void createExternalDb() throws IOException, SQLException { + externalConnection = dbResource.createEmptyDb(n.getMethodName(), "newDb"); + Assert.assertNotNull(externalConnection); + } + + protected void createInternalConnection() throws SQLException { + internalConnection = + TuttiEntities.createConnection(localConnectionProperties); + + } +} Copied: trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java (from rev 298, trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java) =================================================================== --- trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java (rev 0) +++ trunk/tutti-persistence/src/test/java/fr/ifremer/tutti/persistence/service/synchro/ReferentialSynchronizeServiceImplTest.java 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,84 @@ +package fr.ifremer.tutti.persistence.service.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 fr.ifremer.tutti.persistence.DatabaseResource; +import fr.ifremer.tutti.persistence.service.TuttiPersistenceServiceLocator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.springframework.jdbc.support.JdbcUtils; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 1.0 + */ +@Ignore +public class ReferentialSynchronizeServiceImplTest { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ReferentialSynchronizeServiceImplTest.class); + + @ClassRule + public static final DatabaseResource dbResource = new DatabaseResource(); + + @Rule + public final TestName n = new TestName(); + + protected ReferentialSynchronizeService service; + + protected Connection externalConnection; + + protected Connection internalConnection; + + @Before + public void setUp() throws Exception { + service = TuttiPersistenceServiceLocator.getReferentialSynchronizeService(); + } + + @After + public void tearDown() throws Exception { + service = null; + JdbcUtils.closeConnection(internalConnection); + JdbcUtils.closeConnection(externalConnection); + } + + protected void createExternalDb() throws IOException, SQLException { + externalConnection = dbResource.createEmptyDb(n.getMethodName(), "newDb"); + Assert.assertNotNull(externalConnection); + } + +} Copied: trunk/tutti-persistence/src/test/resources/applicationContext-service-resources.xml (from rev 298, trunk/tutti-persistence-adagio/src/test/resources/applicationContext-service-resources.xml) =================================================================== --- trunk/tutti-persistence/src/test/resources/applicationContext-service-resources.xml (rev 0) +++ trunk/tutti-persistence/src/test/resources/applicationContext-service-resources.xml 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,37 @@ +<!-- + #%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% + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + + <!-- needed to load @Value on tuttiEnumerationFile --> + <context:annotation-config/> + + <bean id="tuttiEnumerationFile" init-method="init" lazy-init="true" + class="fr.ifremer.tutti.persistence.service.TuttiEnumerationFile"/> + +</beans> \ No newline at end of file Copied: trunk/tutti-persistence/src/test/resources/beanRefFactoryWitNoDb.xml (from rev 298, trunk/tutti-persistence-adagio/src/test/resources/beanRefFactoryWitNoDb.xml) =================================================================== --- trunk/tutti-persistence/src/test/resources/beanRefFactoryWitNoDb.xml (rev 0) +++ trunk/tutti-persistence/src/test/resources/beanRefFactoryWitNoDb.xml 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Tutti :: Persistence API + $Id$ + $HeadURL$ + %% + Copyright (C) 2012 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% + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + + <bean id="TuttiBeanRefFactoryWithNoDb" + class="org.springframework.context.support.ClassPathXmlApplicationContext"> + <constructor-arg> + <list> + <value>applicationContext-conf.xml</value> + <value>applicationContext-service-resources.xml</value> + </list> + </constructor-arg> + </bean> + +</beans> \ No newline at end of file Copied: trunk/tutti-persistence/src/test/resources/log4j.properties (from rev 298, trunk/tutti-persistence-adagio/src/test/resources/log4j.properties) =================================================================== --- trunk/tutti-persistence/src/test/resources/log4j.properties (rev 0) +++ trunk/tutti-persistence/src/test/resources/log4j.properties 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,42 @@ +### +# #%L +# Tutti :: Persistence API +# $Id$ +# $HeadURL$ +# %% +# Copyright (C) 2012 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% +### +# Global logging configuration + +log4j.rootCategory=WARN, A1 +log4j.logger.no.api=DEBUG +log4j.appender.A1=org.apache.log4j.ConsoleAppender +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%d %-4r [%t] %-5p %c %x - %m%n + +log4j.logger.org.springframework=WARN +#log4j.logger.org.apache.commons.beanutils=WARN + +log4j.logger.org.hibernate=WARN +#log4j.logger.org.hibernate.SQL=DEBUG + +#log4j.logger.net.sf.ehcache=WARN + +log4j.logger.fr.ifremer.adagio.core=DEBUG +log4j.logger.fr.ifremer.tutti=INFO +log4j.logger.org.nuiton=INFO Copied: trunk/tutti-persistence/src/test/resources/tutti-test.properties (from rev 298, trunk/tutti-persistence-adagio/src/test/resources/tutti-test.properties) =================================================================== --- trunk/tutti-persistence/src/test/resources/tutti-test.properties (rev 0) +++ trunk/tutti-persistence/src/test/resources/tutti-test.properties 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,26 @@ +### +# #%L +# Tutti :: Persistence API +# $Id$ +# $HeadURL$ +# %% +# Copyright (C) 2012 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% +### +#tutti.persistence.jdbc.url=jdbc:hsqldb:file:src/test/db/allegro +tutti.persistence.jdbc.url=jdbc:hsqldb:hsql://localhost/allegro +tutti.persistence.jdbc.createScript=src/test/db/allegro.script Copied: trunk/tutti-persistence/src/test/server.properties (from rev 298, trunk/tutti-persistence-adagio/src/test/server.properties) =================================================================== --- trunk/tutti-persistence/src/test/server.properties (rev 0) +++ trunk/tutti-persistence/src/test/server.properties 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,25 @@ +### +# #%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% +### +server.database.0=file:db/allegro +server.dbname.0=allegro \ No newline at end of file Copied: trunk/tutti-persistence/src/test/startServer.sh (from rev 298, trunk/tutti-persistence-adagio/src/test/startServer.sh) =================================================================== --- trunk/tutti-persistence/src/test/startServer.sh (rev 0) +++ trunk/tutti-persistence/src/test/startServer.sh 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,3 @@ +#! /bin/sh + +java -classpath ~/.m2/repository/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar org.hsqldb.Server --database.0 file:db/allegro --dbname.0 allegro Copied: trunk/tutti-persistence/src/test/startServerNew.sh (from rev 298, trunk/tutti-persistence-adagio/src/test/startServerNew.sh) =================================================================== --- trunk/tutti-persistence/src/test/startServerNew.sh (rev 0) +++ trunk/tutti-persistence/src/test/startServerNew.sh 2013-02-02 14:11:58 UTC (rev 300) @@ -0,0 +1,3 @@ +#! /bin/sh + +java -classpath ~/.m2/repository/org/hsqldb/hsqldb/2.2.9/hsqldb-2.2.9.jar org.hsqldb.Server --database.0 file:db/allegro --dbname.0 allegro \ No newline at end of file Modified: trunk/tutti-service/pom.xml =================================================================== --- trunk/tutti-service/pom.xml 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-service/pom.xml 2013-02-02 14:11:58 UTC (rev 300) @@ -49,13 +49,6 @@ </dependency> <dependency> - <groupId>${project.groupId}</groupId> - <artifactId>tutti-persistence-adagio</artifactId> - <version>${project.version}</version> - </dependency> - - - <dependency> <groupId>org.nuiton</groupId> <artifactId>nuiton-utils</artifactId> </dependency> Modified: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/PersistenceService.java 2013-02-02 14:11:58 UTC (rev 300) @@ -26,7 +26,7 @@ import fr.ifremer.tutti.persistence.TuttiPersistence; import fr.ifremer.tutti.persistence.TuttiPersistenceDevImpl; -import fr.ifremer.tutti.persistence.config.TuttiPersistenceAdagioConfig; +import fr.ifremer.tutti.persistence.config.TuttiPersistenceConfig; import fr.ifremer.tutti.persistence.entities.data.AccidentalBatch; import fr.ifremer.tutti.persistence.entities.data.BenthosBatch; import fr.ifremer.tutti.persistence.entities.data.CatchBatch; @@ -97,9 +97,9 @@ TuttiServiceConfig serviceConfig = context.getConfig(); - TuttiPersistenceAdagioConfig driverConfig = + TuttiPersistenceConfig driverConfig = serviceConfig.getAdagioDriverConfig(); - TuttiPersistenceAdagioConfig.setInstance(driverConfig); + TuttiPersistenceConfig.setInstance(driverConfig); if (driverConfig.isDbExists()) { Modified: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/config/TuttiServiceConfig.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/config/TuttiServiceConfig.java 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/config/TuttiServiceConfig.java 2013-02-02 14:11:58 UTC (rev 300) @@ -25,7 +25,7 @@ */ import com.google.common.base.Preconditions; -import fr.ifremer.tutti.persistence.config.TuttiPersistenceAdagioConfig; +import fr.ifremer.tutti.persistence.config.TuttiPersistenceConfig; import org.apache.commons.io.FileUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -50,20 +50,20 @@ /** Delegate application config object containing configuration. */ protected final ApplicationConfig applicationConfig; - protected final TuttiPersistenceAdagioConfig adagioDriverConfig; + protected final TuttiPersistenceConfig adagioDriverConfig; public TuttiServiceConfig(ApplicationConfig applicationConfig) { this.applicationConfig = applicationConfig; - adagioDriverConfig = new TuttiPersistenceAdagioConfig(applicationConfig); + adagioDriverConfig = new TuttiPersistenceConfig(applicationConfig); } public ApplicationConfig getApplicationConfig() { return applicationConfig; } - public TuttiPersistenceAdagioConfig getAdagioDriverConfig() { + public TuttiPersistenceConfig getAdagioDriverConfig() { return adagioDriverConfig; } Modified: trunk/tutti-ui-swing/pom.xml =================================================================== --- trunk/tutti-ui-swing/pom.xml 2013-02-02 13:05:14 UTC (rev 299) +++ trunk/tutti-ui-swing/pom.xml 2013-02-02 14:11:58 UTC (rev 300) @@ -230,13 +230,6 @@ </dependency> <dependency> - <groupId>${project.groupId}</groupId> - <artifactId>tutti-persistence-adagio</artifactId> - <version>${project.version}</version> - <!--<scope>runtime</scope>--> - </dependency> - - <dependency> <groupId>org.nuiton</groupId> <artifactId>nuiton-utils</artifactId> </dependency>
participants (1)
-
tchemit@users.forge.codelutin.com