diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cbabcaa7435745f1be7ceba6c4696768a2bcdae..d8db44858604f849ff3ebec26936e5023068f896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## Sprint 87 - v3.9.4 + +- Pas de mise à jour de modèle + + +## Sprint 86 - v3.9.3 + +- Pas de mise à jour de modèle + + ## Sprint 85 - v3.8.3 - Pas de mise à jour de modèle @@ -12,6 +22,37 @@ - Version corrective devant utiliser le server de synchronisation 3.6.3.1 uniquement +## Sprint 83 - v3.9.2 + +- Pas de mise à jour de modèle + +- Une nouvelle option a été ajoutée pour gérer les transcodages des référentiels suivant : + + reefdb.transcribingItemType.label.pmfmExtraction + + Sa valeur par défaut est `REEFDB-PMFM.PMFM_EXTRACTION`. Couplée avec l'option `reefdb.transcribingItemType.label.pmfmNm`, elle permet de transcoder les libellé des PSFMU lors des extractions avec la priorité suivante: + + 1- libellé transcodé pour extraction + 2- libellé transcodé pour écran de saisie + 3- libellé interne du psfmu (issu du transcodage pour écran de saisie) + 4- libellé du paramètre + +- Pour simplifier la configuration du serveur de synchronisation, l'option `quadrige3.synchro.import.referential.transcribingItemType.label.includes` + qui doit contenir tous les libellés des types de transcodage à importer, accepte désormais le caractère '%'. + + quadrige3.synchro.import.referential.transcribingItemType.label.includes=REEFDB% (tous les types de transcodage commençant par REEFDB seront importés) + + +## Sprint 82 - v3.9.1 + +- Pas de mise à jour de modèle + + +## Sprint 81 - v3.9.0 + +- Pas de mise à jour de modèle + + ## Sprint 80 - v3.8.1 - Pas de mise à jour de modèle diff --git a/pom.xml b/pom.xml index 9deafa7eac6f6eb66e3f81069c7fdcd8395a4ea7..6935c13e3e5dfeda064531061beff8057e7db6e1 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ fr.ifremer.reefdb reefdb - 3.8.4-SNAPSHOT + 3.9.5-SNAPSHOT pom Reef DB @@ -171,7 +171,7 @@ true - 3.6.3.2 + 3.6.10 3.0.3 @@ -261,7 +261,7 @@ reefdb-public-group - http://server.e-is.pro/nexus/content/groups/reefdb + https://nexus.e-is.pro/nexus/content/groups/reefdb true fail @@ -276,7 +276,7 @@ reefdb-public-group - http://server.e-is.pro/nexus/content/groups/reefdb + https://nexus.e-is.pro/nexus/content/groups/reefdb true fail @@ -342,6 +342,18 @@ ${junit.version} test + + junit-addons + junit-addons + 1.4 + test + + + junit + junit + + + fr.ifremer.quadrige3 quadrige3-test-shared @@ -1119,10 +1131,10 @@ scpexe://${distribution.site.host}${distribution.site.path} eis-nexus-deploy - http://server.e-is.pro/nexus/content/repositories/reefdb-releases + https://nexus.e-is.pro/nexus/content/repositories/reefdb-releases eis-nexus-deploy - http://server.e-is.pro/nexus/content/repositories/reefdb-snapshots + https://nexus.e-is.pro/nexus/content/repositories/reefdb-snapshots ${distribution.repository.url} diff --git a/reefdb-converter/pom.xml b/reefdb-converter/pom.xml index eeffe37a4263e8ea2d1dd70819a99b73b1c04f2c..83fc00ea80e465fd8e5dbb47d323ab7c43706a80 100644 --- a/reefdb-converter/pom.xml +++ b/reefdb-converter/pom.xml @@ -76,7 +76,7 @@ reefdb-public-group - http://server.e-is.pro/nexus/content/groups/reefdb + https://nexus.e-is.pro/nexus/content/groups/reefdb true fail @@ -91,7 +91,7 @@ reefdb-public-group - http://server.e-is.pro/nexus/content/groups/reefdb + https://nexus.e-is.pro/nexus/content/groups/reefdb true fail @@ -242,12 +242,12 @@ eis-nexus-deploy - http://server.e-is.pro/nexus/content/repositories/reefdb-releases + https://nexus.e-is.pro/nexus/content/repositories/reefdb-releases eis-nexus-deploy - http://server.e-is.pro/nexus/content/repositories/reefdb-snapshots + https://nexus.e-is.pro/nexus/content/repositories/reefdb-snapshots - http://server.e-is.pro/nexus/content/groups/public + https://nexus.e-is.pro/nexus/content/groups/public diff --git a/reefdb-core/pom.xml b/reefdb-core/pom.xml index c7098d6dcb062d33c1784c26950c8af06c000aed..3ddec9765e795dd5097462a3735f498d2ceb2049 100644 --- a/reefdb-core/pom.xml +++ b/reefdb-core/pom.xml @@ -4,7 +4,7 @@ fr.ifremer.reefdb reefdb - 3.8.4-SNAPSHOT + 3.9.5-SNAPSHOT reefdb-core @@ -60,6 +60,16 @@ quadrige3-test-shared test + + junit + junit + test + + + junit-addons + junit-addons + test + diff --git a/reefdb-core/src/license/THIRD-PARTY.properties b/reefdb-core/src/license/THIRD-PARTY.properties index 2ed7e5ebaa358dae84a891359a1f409f5ef1b02e..7a5b719617c5eb4e7c6694195253a250d624e2bd 100644 --- a/reefdb-core/src/license/THIRD-PARTY.properties +++ b/reefdb-core/src/license/THIRD-PARTY.properties @@ -35,8 +35,11 @@ # Please fill the missing licenses for dependencies : # # -#Fri Feb 09 17:30:26 CET 2018 +#Thu Feb 27 14:37:52 CET 2020 com.oracle--ojdbc7--12.1.0.2.0=OTN license commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0 dom4j--dom4j--1.6.1=BSD License +junit-addons--junit-addons--1.4= org.hibernate--hibernate-spatial--4.3-20140213=Lesser General Public License (LGPL) +xerces--xercesImpl--2.6.2= +xerces--xmlParserAPIs--2.6.2= diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/config/ReefDbConfiguration.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/config/ReefDbConfiguration.java index 6d45a61efc59b27d68a11d4cfca8412e4982efe6..1221ef63f12c325bd6e29c621aa9de49f1a4daf8 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/config/ReefDbConfiguration.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/config/ReefDbConfiguration.java @@ -967,6 +967,10 @@ public final class ReefDbConfiguration extends QuadrigeCoreConfiguration { return applicationConfig.getOption(ReefDbConfigurationOption.TRANSCRIBING_ITEM_TYPE_LB_PMFM_NM.getKey()); } + public String getTranscribingItemTypeLbForPmfmExtraction() { + return applicationConfig.getOption(ReefDbConfigurationOption.TRANSCRIBING_ITEM_TYPE_LB_PMFM_EXTRACTION.getKey()); + } + /** *

getAlternativeTaxonOriginTaxRef.

* diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/config/ReefDbConfigurationOption.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/config/ReefDbConfigurationOption.java index 3a08a719b0669e24d3c5cf45eea0720c1e368d59..24c91253a3182ecfdf5c3e1f8b752ed527fc2951 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/config/ReefDbConfigurationOption.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/config/ReefDbConfigurationOption.java @@ -24,7 +24,6 @@ package fr.ifremer.reefdb.config; */ import fr.ifremer.quadrige3.core.dao.referential.UnitId; -import fr.ifremer.quadrige3.core.dao.referential.transcribing.TranscribingItemTypeLb; import fr.ifremer.quadrige3.core.dao.technical.QuadrigeEnumerationDef; import org.nuiton.config.ConfigOptionDef; import org.nuiton.version.Version; @@ -303,7 +302,13 @@ public enum ReefDbConfigurationOption implements ConfigOptionDef { TRANSCRIBING_ITEM_TYPE_LB_PMFM_NM( "reefdb.transcribingItemType.label.pmfmNm", n("reefdb.config.option.transcribingItemType.label.pmfmNm.description"), - String.format("${%s}", TranscribingItemTypeLb.REEFDB_PMFM_NM.getKey()), // 1 + String.format("${%s%s}", QuadrigeEnumerationDef.CONFIG_OPTION_PREFIX, "TranscribingItemTypeLb.REEFDB_PMFM_NM"), + String.class, + false), + TRANSCRIBING_ITEM_TYPE_LB_PMFM_EXTRACTION( + "reefdb.transcribingItemType.label.pmfmExtraction", + n("reefdb.config.option.transcribingItemType.label.pmfmExtraction.description"), + String.format("${%s%s}", QuadrigeEnumerationDef.CONFIG_OPTION_PREFIX, "TranscribingItemTypeLb.REEFDB_PMFM_EXTRACTION"), String.class, false), /* constants used to calculate transition length */ diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/administration/strategy/ReefDbStrategyDao.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/administration/strategy/ReefDbStrategyDao.java index 4b065649a1288440f62e9e5c7249be051c46ac6d..84a944278abbc40c835741cf6402c78bee0eb8d1 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/administration/strategy/ReefDbStrategyDao.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/administration/strategy/ReefDbStrategyDao.java @@ -102,6 +102,16 @@ public interface ReefDbStrategyDao { @Cacheable(value = PMFM_STRATEGIES_BY_PROG_LOC_DATE_CACHE) Set getPmfmStrategiesByProgramCodeAndLocation(String programCode, Integer monitoringLocationId, LocalDate date); + /** + * Retrieve all PMFM strategies that are applied on given programs and date range + * + * @param programCodes program codes + * @param startDate + * @param endDate + * @return set of pmfm strategies + */ + Set getPmfmStrategiesByProgramCodesAndDates(Collection programCodes, LocalDate startDate, LocalDate endDate); + /** * Retrieve all strategies that are applied on the given program and monitoring location * diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/administration/strategy/ReefDbStrategyDaoImpl.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/administration/strategy/ReefDbStrategyDaoImpl.java index 912a9a0cca940a4ac5d76fd837024158b0ffc034..7134746710c4fcc3c3ff315e3536d812c7903d2b 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/administration/strategy/ReefDbStrategyDaoImpl.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/administration/strategy/ReefDbStrategyDaoImpl.java @@ -241,6 +241,39 @@ public class ReefDbStrategyDaoImpl extends StrategyDaoImpl implements ReefDbStra return ImmutableSet.copyOf(pmfmStrategies); } + @Override + public Set getPmfmStrategiesByProgramCodesAndDates(Collection programCodes, LocalDate startDate, LocalDate endDate) { + Set pmfmStrategies = new HashSet<>(); + + List appliedStrategies = getAppliedStrategiesByProgramCodes(programCodes); + for (ProgStratDTO appliedStrategy: appliedStrategies) { + // filter on date range + if (appliedStrategy.getStartDate() != null && appliedStrategy.getEndDate() != null + && !appliedStrategy.getStartDate().isAfter(endDate) && !appliedStrategy.getEndDate().isBefore(startDate)) { + // add all pmfm strategies in date range + pmfmStrategies.addAll(getPmfmsAppliedStrategy(appliedStrategy.getId())); + } + } + + return ImmutableSet.copyOf(pmfmStrategies); + + } + + @SuppressWarnings("unchecked") + private List getAppliedStrategiesByProgramCodes(Collection programCodes) { + Query query = createQuery("appliedStrategiesByProgramCodes").setParameterList("programCodes", programCodes); + Iterator rows = query.iterate(); + + List result = Lists.newArrayList(); + TimeZone dbTimezone = config.getDbTimezone(); + while (rows.hasNext()) { + result.add(toProgStratDTO(Arrays.asList(rows.next()).iterator(), dbTimezone)); + } + + return result; + } + + /** {@inheritDoc} */ @Override public List getStrategiesByProgramCodeAndMonitoringLocationId(String programCode, int monitoringLocationId) { @@ -915,7 +948,7 @@ public class ReefDbStrategyDaoImpl extends StrategyDaoImpl implements ReefDbStra // code, name program.setCode((String) source.next()); program.setName((String) source.next()); - //TODO (report Q3): program.setStatus(Daos.getStatus((String) source.next())); + program.setStatus(Daos.getStatus((String) source.next())); } // strategy: id, name diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/system/extraction/ReefDbExtractionResultDao.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/system/extraction/ReefDbExtractionResultDao.java index 824247b013df6028d653038d2851c7a7f93a14d9..ad90538a3462ce7d6901e17e2267abdfaf85abdf 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/system/extraction/ReefDbExtractionResultDao.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/system/extraction/ReefDbExtractionResultDao.java @@ -24,6 +24,7 @@ package fr.ifremer.reefdb.dao.system.extraction; */ import fr.ifremer.quadrige3.core.dao.technical.csv.CSVDao; +import fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO; import org.springframework.jdbc.core.RowMapper; import java.util.List; @@ -36,6 +37,14 @@ import java.util.Map; */ public interface ReefDbExtractionResultDao extends CSVDao { + /** + *

queryCount.

+ * + * @param query a {@link String} object. + * @return a {@link java.lang.Long} object. + */ + long queryCount(String query); + /** *

queryCount.

* @@ -67,6 +76,14 @@ public interface ReefDbExtractionResultDao extends CSVDao { List queryStringList(String query, Map queryBindings); + /** + *

queryUpdate

+ * + * @param query a {@link java.lang.String} object. + * @return a int. + */ + int queryUpdate(String query); + /** *

queryUpdate.

* @@ -75,4 +92,10 @@ public interface ReefDbExtractionResultDao extends CSVDao { * @return a int. */ int queryUpdate(String query, Map queryBindings); + + String getPmfmNameForExtraction(PmfmDTO pmfm); + + String getPmfmUnitNameForExtraction(PmfmDTO pmfm); + + } diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/system/extraction/ReefDbExtractionResultDaoImpl.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/system/extraction/ReefDbExtractionResultDaoImpl.java index 20b8eb3a6f9958dcffd5202137d323d8a8e33029..b063536ee69253759777b75d365deca0e6bda1ab 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/system/extraction/ReefDbExtractionResultDaoImpl.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/dao/system/extraction/ReefDbExtractionResultDaoImpl.java @@ -23,18 +23,24 @@ package fr.ifremer.reefdb.dao.system.extraction; * #L% */ +import fr.ifremer.quadrige3.core.dao.referential.transcribing.TranscribingItemExtendDao; +import fr.ifremer.quadrige3.core.dao.technical.Assert; import fr.ifremer.quadrige3.core.dao.technical.csv.CSVDaoImpl; +import fr.ifremer.reefdb.config.ReefDbConfiguration; +import fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; +import org.springframework.dao.DataRetrievalFailureException; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; +import javax.annotation.Resource; import javax.sql.DataSource; -import java.math.BigInteger; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Properties; /** @@ -50,6 +56,12 @@ public class ReefDbExtractionResultDaoImpl extends CSVDaoImpl implements ReefDbE protected final Properties connectionProperties; + @Resource + protected ReefDbConfiguration config; + + @Resource(name = "transcribingItemDao") + private TranscribingItemExtendDao transcribingItemDao; + /** *

Constructor for ReefDbExtractionResultDaoImpl.

* @@ -78,24 +90,19 @@ public class ReefDbExtractionResultDaoImpl extends CSVDaoImpl implements ReefDbE this.connectionProperties = connectionProperties; } + @Override + public long queryCount(String query) { + return queryCount(query, null); + } + /** * {@inheritDoc} */ @Override public Long queryCount(String query, Map queryBindings) { - - return query(connectionProperties, query, queryBindings, resultSet -> { - Object result = resultSet.getObject(1); - if (log.isDebugEnabled()) { - log.debug(String.format("queryCount result: %s", result)); - } - if (result instanceof Integer) { - return ((Integer) result).longValue(); - } else if (result instanceof BigInteger) { - return ((BigInteger) result).longValue(); - } - return (Long) result; - }); + Long count = queryCount(connectionProperties, query, queryBindings); + if (count == null) throw new DataRetrievalFailureException(String.format("query count result is null: %s ; bindings=%s", query, queryBindings)); + return count; } /** @@ -106,6 +113,11 @@ public class ReefDbExtractionResultDaoImpl extends CSVDaoImpl implements ReefDbE return query(connectionProperties, sql, queryBindings, rowMapper); } + @Override + public int queryUpdate(String query) { + return queryUpdate(query, null); + } + /** * {@inheritDoc} */ @@ -114,6 +126,25 @@ public class ReefDbExtractionResultDaoImpl extends CSVDaoImpl implements ReefDbE return queryUpdate(connectionProperties, query, paramMap); } + @Override + public String getPmfmNameForExtraction(PmfmDTO pmfm) { + Assert.notNull(pmfm); + return Optional + .ofNullable(transcribingItemDao.getTranscribingItemById(config.getTranscribingItemTypeLbForPmfmExtraction(), pmfm.getId())) + .orElse( + Optional.ofNullable(transcribingItemDao.getTranscribingItemById(config.getTranscribingItemTypeLbForPmfmNm(), pmfm.getId())) + .orElse( + Optional.ofNullable(pmfm.getName()) + .orElse(pmfm.getParameter().getName()) + ) + ); } + + @Override + public String getPmfmUnitNameForExtraction(PmfmDTO pmfm) { + Assert.notNull(pmfm); + return pmfm.getUnit() == null || config.getExtractionUnitIdsToIgnore().contains(pmfm.getUnit().getId()) ? "" : pmfm.getUnit().getName(); + } + /** * {@inheritDoc} */ @@ -126,4 +157,5 @@ public class ReefDbExtractionResultDaoImpl extends CSVDaoImpl implements ReefDbE public List queryStringList(String query, Map queryBindings) { return query(connectionProperties, query, queryBindings, (resultSet, i) -> resultSet.getString(1)); } + } diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/decorator/DecoratorServiceImpl.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/decorator/DecoratorServiceImpl.java index d6b54ed8e2762ddbfda8bd5ce5a73c902856d108..50f571664bc3134dd28fab9c856eafd8b80f56ad 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/decorator/DecoratorServiceImpl.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/decorator/DecoratorServiceImpl.java @@ -287,6 +287,7 @@ public class DecoratorServiceImpl extends fr.ifremer.quadrige3.core.service.deco } } + @Deprecated private class PMFMExtractionDecorator extends PMFMNameDecorator { static final String SEPARATOR = "-"; diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/dto/ReefDbBeans.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/dto/ReefDbBeans.java index f984c0e9f0fec35a91c715898051337e6fc66bdb..515f9bdad1f8cd222898681ea107e047baf3247f 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/dto/ReefDbBeans.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/dto/ReefDbBeans.java @@ -53,6 +53,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.nuiton.util.DateUtil; +import javax.annotation.Nonnull; import java.sql.Array; import java.sql.SQLException; import java.time.format.DateTimeFormatter; @@ -177,8 +178,8 @@ public class ReefDbBeans extends QuadrigeBeans { } else if (bean instanceof ExtractionPeriodDTO) { ExtractionPeriodDTO period = (ExtractionPeriodDTO) bean; return Dates.formatDate(period.getStartDate(), DEFAULT_DATE_FORMAT) - + " => " - + Dates.formatDate(period.getEndDate(), DEFAULT_DATE_FORMAT); + + " => " + + Dates.formatDate(period.getEndDate(), DEFAULT_DATE_FORMAT); } return bean.toString(); @@ -496,16 +497,30 @@ public class ReefDbBeans extends QuadrigeBeans { public static boolean haveSameMeasurements(Collection measurements, Collection otherMeasurements) { List pmfmIds = measurements.stream() - .filter(measurement -> !isMeasurementEmpty(measurement)) - .map(measurement -> measurement.getPmfm().getId()) - .collect(Collectors.toList()); + .filter(measurement -> !isMeasurementEmpty(measurement)) + .map(measurement -> measurement.getPmfm().getId()) + .collect(Collectors.toList()); List otherPmfmIds = otherMeasurements.stream() - .filter(measurement -> !isMeasurementEmpty(measurement)) - .map(measurement -> measurement.getPmfm().getId()) - .collect(Collectors.toList()); + .filter(measurement -> !isMeasurementEmpty(measurement)) + .map(measurement -> measurement.getPmfm().getId()) + .collect(Collectors.toList()); return pmfmIds.containsAll(otherPmfmIds) && otherPmfmIds.containsAll(pmfmIds); } + /** + * Compare measurement values only (not pmfm or other propoerty) + * + * @param measurement1 first measurement + * @param measurement2 second measurement + * @return true if their values are equals or null + */ + public static boolean measurementValuesEquals(@Nonnull MeasurementDTO measurement1, @Nonnull MeasurementDTO measurement2) { + return (measurement1.getNumericalValue() == null && measurement2.getNumericalValue() == null + && measurement1.getQualitativeValue() == null && measurement2.getQualitativeValue() == null) + || (measurement1.getNumericalValue() != null && measurement1.getNumericalValue().equals(measurement2.getNumericalValue())) + || (measurement1.getQualitativeValue() != null && measurement1.getQualitativeValue().equals(measurement2.getQualitativeValue())); + } + /** * Get the unified comments from all individual measurements * @@ -642,9 +657,9 @@ public class ReefDbBeans extends QuadrigeBeans { return new ArrayList<>(); } return filterCollection(bean.getErrors(), error -> error.isError() - && (controlOnly == null || (controlOnly == error.isControl())) - && error.containsPropertyName(propertyName) - && (pmfmId == null || pmfmId.equals(error.getPmfmId()))); + && (controlOnly == null || (controlOnly == error.isControl())) + && error.containsPropertyName(propertyName) + && (pmfmId == null || pmfmId.equals(error.getPmfmId()))); } /** @@ -694,14 +709,14 @@ public class ReefDbBeans extends QuadrigeBeans { */ public static List getWarnings(ErrorAware bean, final String propertyName, final Integer pmfmId, final Boolean controlOnly) { if (bean == null || CollectionUtils.isEmpty(bean.getErrors()) - // if an error is found, return empty list because error is priority - || !getErrors(bean, propertyName, pmfmId, controlOnly).isEmpty()) { + // if an error is found, return empty list because error is priority + || !getErrors(bean, propertyName, pmfmId, controlOnly).isEmpty()) { return new ArrayList<>(); } return filterCollection(bean.getErrors(), error -> error.isWarning() - && (controlOnly == null || (controlOnly == error.isControl())) - && error.containsPropertyName(propertyName) - && (pmfmId == null || pmfmId.equals(error.getPmfmId()))); + && (controlOnly == null || (controlOnly == error.isControl())) + && error.containsPropertyName(propertyName) + && (pmfmId == null || pmfmId.equals(error.getPmfmId()))); } /** @@ -794,13 +809,13 @@ public class ReefDbBeans extends QuadrigeBeans { private static Predicate errorEqualPredicate(ErrorDTO thisError) { return error -> error.isError() == thisError.isError() - && error.isWarning() == thisError.isWarning() - && error.isControl() == thisError.isControl() - && Objects.equals(error.getControlElementCode(), thisError.getControlElementCode()) - && Objects.deepEquals(error.getPropertyName().toArray(), thisError.getPropertyName().toArray()) - && Objects.equals(error.getPmfmId(), thisError.getPmfmId()) - && Objects.equals(error.getIndividualId(), thisError.getIndividualId()) - && Objects.equals(error.getMessage(), thisError.getMessage()); + && error.isWarning() == thisError.isWarning() + && error.isControl() == thisError.isControl() + && Objects.equals(error.getControlElementCode(), thisError.getControlElementCode()) + && Objects.deepEquals(error.getPropertyName().toArray(), thisError.getPropertyName().toArray()) + && Objects.equals(error.getPmfmId(), thisError.getPmfmId()) + && Objects.equals(error.getIndividualId(), thisError.getIndividualId()) + && Objects.equals(error.getMessage(), thisError.getMessage()); } /** @@ -811,9 +826,9 @@ public class ReefDbBeans extends QuadrigeBeans { */ public static boolean isPmfmMandatory(ControlRuleDTO controlRule) { return ControlElementValues.MEASUREMENT.equals(controlRule.getControlElement()) && - (ControlFeatureMeasurementValues.PMFM.equals(controlRule.getControlFeature()) - || ControlFeatureMeasurementValues.NUMERICAL_VALUE.equals(controlRule.getControlFeature()) - || ControlFeatureMeasurementValues.QUALITATIVE_VALUE.equals(controlRule.getControlFeature())); + (ControlFeatureMeasurementValues.PMFM.equals(controlRule.getControlFeature()) + || ControlFeatureMeasurementValues.NUMERICAL_VALUE.equals(controlRule.getControlFeature()) + || ControlFeatureMeasurementValues.QUALITATIVE_VALUE.equals(controlRule.getControlFeature())); } public static boolean isPreconditionRule(ControlRuleDTO controlRule) { @@ -826,14 +841,14 @@ public class ReefDbBeans extends QuadrigeBeans { public static boolean isQualitativeControlRule(ControlRuleDTO controlRule) { return ControlFunctionValues.IS_AMONG.equals(controlRule.getFunction()) - && ControlElementValues.MEASUREMENT.equals(controlRule.getControlElement()) - && ControlFeatureMeasurementValues.QUALITATIVE_VALUE.equals(controlRule.getControlFeature()); + && ControlElementValues.MEASUREMENT.equals(controlRule.getControlElement()) + && ControlFeatureMeasurementValues.QUALITATIVE_VALUE.equals(controlRule.getControlFeature()); } public static boolean isNumericalControlRule(ControlRuleDTO controlRule) { return ControlFunctionValues.MIN_MAX.equals(controlRule.getFunction()) - && ControlElementValues.MEASUREMENT.equals(controlRule.getControlElement()) - && ControlFeatureMeasurementValues.NUMERICAL_VALUE.equals(controlRule.getControlFeature()); + && ControlElementValues.MEASUREMENT.equals(controlRule.getControlElement()) + && ControlFeatureMeasurementValues.NUMERICAL_VALUE.equals(controlRule.getControlFeature()); } /** @@ -844,8 +859,8 @@ public class ReefDbBeans extends QuadrigeBeans { */ public static boolean isSurveyValidated(SurveyDTO survey) { return survey.getValidationDate() != null - || SynchronizationStatusValues.SYNCHRONIZED.equals(survey.getSynchronizationStatus()) - || SynchronizationStatusValues.READY_TO_SYNCHRONIZE.equals(survey.getSynchronizationStatus()); + || SynchronizationStatusValues.SYNCHRONIZED.equals(survey.getSynchronizationStatus()) + || SynchronizationStatusValues.READY_TO_SYNCHRONIZE.equals(survey.getSynchronizationStatus()); } /** @@ -858,8 +873,8 @@ public class ReefDbBeans extends QuadrigeBeans { public static FilterDTO getFilterOfType(ExtractionDTO extraction, ExtractionFilterValues extractionFilter) { return CollectionUtils.isNotEmpty(extraction.getFilters()) - ? findByProperty(extraction.getFilters(), FilterDTO.PROPERTY_FILTER_TYPE_ID, extractionFilter.getFilterTypeId()) - : null; + ? findByProperty(extraction.getFilters(), FilterDTO.PROPERTY_FILTER_TYPE_ID, extractionFilter.getFilterTypeId()) + : null; } /** @@ -881,11 +896,28 @@ public class ReefDbBeans extends QuadrigeBeans { return null; } + public static void setFilterElements(ExtractionDTO extraction, ExtractionFilterValues extractionFilter, List elements) { + FilterDTO filter = getFilterOfType(extraction, extractionFilter); + if (filter == null) { + filter = ReefDbBeanFactory.newFilterDTO(); + filter.setFilterTypeId(extractionFilter.getFilterTypeId()); + extraction.addFilters(filter); + } + filter.setElements(elements); + } + public static List getIdsAsString(Collection beans) { if (beans == null) return null; - return beans.stream().map(bean -> bean instanceof CodeOnly ? ((CodeOnly)bean).getCode() : bean.getId().toString()).collect(Collectors.toList()); + return beans.stream().map(bean -> bean instanceof CodeOnly ? ((CodeOnly) bean).getCode() : bean.getId().toString()).collect(Collectors.toList()); + } + + public static List getExtractionPeriods(ExtractionDTO extraction) { + + FilterDTO periodFilter = getFilterOfType(extraction, ExtractionFilterValues.PERIOD); + if (periodFilter == null || periodFilter.getElements() == null) return new ArrayList<>(); + return periodFilter.getElements().stream().map((Function) ExtractionPeriodDTO.class::cast).collect(Collectors.toList()); } } diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/dto/enums/ExtractionFilterValues.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/dto/enums/ExtractionFilterValues.java index ba8f6a5fa7d7c2901f129fbc81161baf5e812c68..bbd76c2ffc848a4bedb868c4f1f01396c6ff5db9 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/dto/enums/ExtractionFilterValues.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/dto/enums/ExtractionFilterValues.java @@ -36,7 +36,7 @@ public enum ExtractionFilterValues { PERIOD(null, n("reefdb.core.enums.extractionFilter.period"), false), PROGRAM(FilterTypeId.PROGRAM, n("reefdb.core.enums.extractionFilter.program"), false), LOCATION(FilterTypeId.MONITORING_LOCATION, n("reefdb.core.enums.extractionFilter.location"), false), -// CAMPAIGN(FilterTypeId.CAMPAIGN, n("reefdb.core.enums.extractionFilter.campaign"), false), + CAMPAIGN(FilterTypeId.CAMPAIGN, n("reefdb.core.enums.extractionFilter.campaign"), false), TAXON(FilterTypeId.TAXON_NAME, n("reefdb.core.enums.extractionFilter.taxon"), false), TAXON_GROUP(FilterTypeId.TAXON_GROUP, n("reefdb.core.enums.extractionFilter.taxonGroup"), false), DEPARTMENT(FilterTypeId.DEPARTMENT, n("reefdb.core.enums.extractionFilter.department"), false), diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceImpl.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceImpl.java index 6a2551848ed3deeec5e3c96e730ae7aab575eef9..20c260eb4eeb737e9c4290827828fdd9fcf92ef2 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceImpl.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceImpl.java @@ -10,29 +10,33 @@ package fr.ifremer.reefdb.service.extraction; * it under the terms of the GNU Affero 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 Affero General Public License * along with this program. If not, see . * #L% */ -import com.google.common.base.Joiner; + import com.google.common.collect.Maps; import fr.ifremer.quadrige3.core.ProgressionCoreModel; import fr.ifremer.quadrige3.core.dao.technical.Assert; import fr.ifremer.quadrige3.core.dao.technical.Dates; +import fr.ifremer.quadrige3.core.dao.technical.Times; +import fr.ifremer.quadrige3.core.dao.technical.xmlQuery.XMLQuery; import fr.ifremer.reefdb.config.ReefDbConfiguration; +import fr.ifremer.reefdb.dao.administration.strategy.ReefDbStrategyDao; import fr.ifremer.reefdb.dao.referential.pmfm.ReefDbPmfmDao; import fr.ifremer.reefdb.dao.system.extraction.ReefDbExtractionResultDao; import fr.ifremer.reefdb.dao.technical.Daos; -import fr.ifremer.reefdb.decorator.DecoratorService; import fr.ifremer.reefdb.dto.ReefDbBeanFactory; import fr.ifremer.reefdb.dto.ReefDbBeans; import fr.ifremer.reefdb.dto.configuration.filter.FilterDTO; +import fr.ifremer.reefdb.dto.configuration.programStrategy.PmfmStrategyDTO; +import fr.ifremer.reefdb.dto.configuration.programStrategy.ProgramDTO; import fr.ifremer.reefdb.dto.enums.ExtractionFilterValues; import fr.ifremer.reefdb.dto.enums.ExtractionOutputType; import fr.ifremer.reefdb.dto.referential.GroupingTypeDTO; @@ -47,20 +51,26 @@ import fr.ifremer.reefdb.service.ReefDbServiceLocator; import fr.ifremer.reefdb.service.ReefDbTechnicalException; import fr.ifremer.reefdb.service.administration.program.ProgramStrategyService; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.map.HashedMap; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jdom2.Element; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.File; import java.io.IOException; +import java.net.URL; import java.util.*; +import java.util.function.Predicate; +import java.util.stream.Collectors; import static org.nuiton.i18n.I18n.t; /** + * New extraction perform service + * Base Mantis #49970 + * * @author peck7 on 14/05/2019. */ @Service("reefdbExtractionPerformService") @@ -68,13 +78,14 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService { private static final Log LOG = LogFactory.getLog(ExtractionPerformServiceImpl.class); - private static final String EXTRACTION_START_DATE = "EXTRACTION_START_DATE"; - private static final String EXTRACTION_END_DATE = "EXTRACTION_END_DATE"; + private static final String TABLE_NAME_PREFIX = "EXT_"; + private static final String BASE_TABLE_NAME_PATTERN = TABLE_NAME_PREFIX + "B%s"; + private static final String RAW_TABLE_NAME_PATTERN = TABLE_NAME_PREFIX + "R%s"; + private static final String PMFM_TABLE_NAME_PATTERN = TABLE_NAME_PREFIX + "P%s_%s"; + private static final String COMMON_TABLE_NAME_PATTERN = TABLE_NAME_PREFIX + "C%s"; + private static final String RESULT_TABLE_NAME_PATTERN = TABLE_NAME_PREFIX + "E%s"; - private static final String RAW_TABLE_NAME_PATTERN = "R%s"; - private static final String COMMON_TABLE_NAME_PATTERN = "C%s"; - private static final String SPLIT_TABLE_NAME_PATTERN = "S%s"; - private static final String PMFM_TABLE_NAME_PATTERN = "P%s_%s"; + private static final String XML_QUERY_PATH = "xmlQuery/extraction"; private static final String LS = System.lineSeparator(); @@ -96,6 +107,9 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService { @Resource(name = "reefDbPmfmDao") protected ReefDbPmfmDao pmfmDao; + @Resource(name = "reefDbStrategyDao") + protected ReefDbStrategyDao strategyDao; + @Override public void performExtraction(ExtractionDTO extraction, ExtractionOutputType outputType, File outputFile, ProgressionCoreModel progressionModel) { Assert.notNull(extraction); @@ -108,8 +122,11 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService { // ensure all filters are loaded extractionService.loadFilteredElements(extraction); + + // init progression model progressionModel.setMessage(""); - progressionModel.setTotal(9); + progressionModel.setTotal(8); + long startTime = System.currentTimeMillis(); if (LOG.isInfoEnabled()) { LOG.info(String.format("Beginning a %s extraction (id=%s) with:", outputType, extraction.getId())); @@ -126,1161 +143,539 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService { try { try { - // count root data to extract - Long count = countRootData(extraction); - progressionModel.increments(1); - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s surveys have to be extract", count)); - } - if (count == 0) { - throw new ReefDbBusinessException(t("reefdb.service.extraction.noData.error")); - } - - // create the concat functions used to concat distinct strings (ex: DEP_NM) - createConcatDistinctFunction("MEAS_CM", "VARCHAR(2000)"/*, " - "*/); - createConcatDistinctFunction("DEP_NM", "VARCHAR(255)"/*, ","*/); - createConcatDistinctFunction("MEAS_ID", "INTEGER"/*, "|"*/); - // Extraction context ExtractionContextDTO context = ReefDbBeanFactory.newExtractionContextDTO(); context.setExtraction(extraction); context.setUniqueId(System.currentTimeMillis()); + context.setBaseTableName(String.format(BASE_TABLE_NAME_PATTERN, context.getUniqueId())); context.setRawTableName(String.format(RAW_TABLE_NAME_PATTERN, context.getUniqueId())); context.setCommonTableName(String.format(COMMON_TABLE_NAME_PATTERN, context.getUniqueId())); - context.setSplitTableName(String.format(SPLIT_TABLE_NAME_PATTERN, context.getUniqueId())); + context.setResultTableName(String.format(RESULT_TABLE_NAME_PATTERN, context.getUniqueId())); - // create the first temp table - createRawTable(context, outputType); + // create the concat functions used to concat distinct strings (ex: DEP_NM) + createConcatDistinctFunction("STRING", "VARCHAR(2000)"); + createConcatDistinctFunction("INTEGER", "INTEGER"); - // insert raw data in temp table - int nbRowsInserted = insertRawData(context, outputType); + // STEP 1 : Create the base table + long nbRowsInserted = createBaseTable(context, outputType); progressionModel.increments(1); if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s rows of raw data inserted into %s", nbRowsInserted, context.getRawTableName())); + LOG.debug(String.format("%s surveys/sampling operations have to be extract (temp table : %s)", nbRowsInserted, context.getBaseTableName())); + } else { + LOG.info(String.format("%s surveys/sampling operations have to be extract", nbRowsInserted)); + } + if (nbRowsInserted == 0) { + throw new ReefDbBusinessException(t("reefdb.service.extraction.noData.error")); } - // build pmfm metadata - List pmfmInfos = getPmfmInfo(context); + // STEP 2 : Create the raw table with full measurements data in line + nbRowsInserted = createRawTable(context, outputType); progressionModel.increments(1); - - // Mantis #29139: remove all individual measurement on survey - pmfmInfos = ReefDbBeans.filterCollection(pmfmInfos, input -> !(input.isSurvey() && input.isIndividual())); - - if (CollectionUtils.isEmpty(pmfmInfos)) { - throw new ReefDbBusinessException(t("reefdb.service.extraction.noPmfm.error")); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s rows of raw data (temp table : %s)", nbRowsInserted, context.getRawTableName())); + } else { + LOG.info(String.format("%s rows of raw data", nbRowsInserted)); } - context.setPmfmInfos(pmfmInfos); - // if a pmfm, taxon or taxon group filter is defined, will remove raw line not corresponding to filter (avoid blank cells in split table) - int nbRowsRemoved = cleanRawData(context, outputType); + // STEP 3 : Build PMFM metadata + buildPmfmInformation(context); progressionModel.increments(1); if (LOG.isDebugEnabled()) { - if (nbRowsRemoved > 0) { - LOG.debug(String.format("%s rows removed from raw data which not corresponding to PMFMU filter", nbRowsRemoved)); - } LOG.debug(String.format("list of pmfmu ids to split : %s", ReefDbBeans.collectProperties(context.getPmfmInfos(), ExtractionPmfmInfoDTO.PROPERTY_PMFM_ID))); } - // Second clean operation: remove surveys from hermetic programs if user is not allowed (Mantis #47660) - int nbRowsRemoved2 = cleanHermeticData(context); + // STEP 4 : Clean raw data + int nbRowsRemoved = cleanRawData(context, outputType); progressionModel.increments(1); - if (LOG.isDebugEnabled() && nbRowsRemoved2 > 0) { - LOG.debug(String.format("%s rows removed from raw data which not corresponding to user rights (hermetic programs)", nbRowsRemoved2)); - } - - // if all the rows have been removed because of filters, there is no more data to extract - if (nbRowsRemoved + nbRowsRemoved2 == nbRowsInserted) { + // if all the rows have been removed because of cleaning, there is no more data to extract + if (nbRowsRemoved == nbRowsInserted) { throw new ReefDbBusinessException(t("reefdb.service.extraction.noPmfm.error")); } - // create pmfm tables - createPmfmTables(context, outputType); - - // insert raw data in pmfm tables - insertPmfmData(context, outputType); + // STEP 5 : Create pmfm tables + createPmfmTables(context); progressionModel.increments(1); - // create common table - createCommonTable(context, outputType); + Map fieldNamesByAlias = Maps.newHashMap(); + Map decimalFormats = Maps.newHashMap(); + Map dateFormats = Maps.newHashMap(); - // insert common part of raw table into common table - nbRowsInserted = insertCommonData(context, outputType); + // STEP 6 : Create common table (todo ? with non individual measurements) + createCommonTable(context, outputType); progressionModel.increments(1); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s rows of common raw data inserted into %s", nbRowsInserted, context.getCommonTableName())); - } - - // create split data table - createSplitTable(context, outputType); - // insert data from raw table to result table = split pmfms in columns - nbRowsInserted = insertSplitData(context, outputType); + // STEP 7 : Create result table + nbRowsInserted = createResultTable(context, outputType, fieldNamesByAlias, decimalFormats, dateFormats); progressionModel.increments(1); if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s rows of split data inserted into %s", nbRowsInserted, context.getSplitTableName())); + LOG.debug(String.format("%s rows to write (result table : %s)", nbRowsInserted, context.getResultTableName())); + } else { + LOG.info(String.format("%s rows to write", nbRowsInserted)); } - // final query and write to csv file - writeExtraction(context, outputType, outputFile); + // STEP 8 : Final query and write to csv file + writeExtraction(context, outputType, fieldNamesByAlias, decimalFormats, dateFormats, outputFile); progressionModel.increments(1); if (LOG.isInfoEnabled()) { - LOG.info(String.format("Extraction %s performed. result file is : %s", outputType, outputFile.getAbsolutePath())); + long time = System.currentTimeMillis() - startTime; + LOG.info(String.format("Extraction %s performed in %s. result file is : %s", outputType, Times.durationToString(time), outputFile.getAbsolutePath())); } + } catch (ReefDbBusinessException e) { + throw e; // throw directly } catch (Exception e) { throw new ReefDbTechnicalException(t("reefdb.service.extraction.error"), e); } } finally { // drop concat functions - dropConcatDistinctFunction("MEAS_CM"); - dropConcatDistinctFunction("DEP_NM"); - dropConcatDistinctFunction("MEAS_ID"); + dropConcatDistinctFunction("STRING"); + dropConcatDistinctFunction("INTEGER"); } } - private void createConcatDistinctFunction(String functionName, String valueType/*, String separator*/) { - - dropConcatDistinctFunction(functionName); - - // new function with external java method - String query = "CREATE FUNCTION CONCAT_DISTINCT_" + functionName + "(IN_ARRAY " + valueType + " ARRAY, SEPARATOR VARCHAR(10)) RETURNS LONGVARCHAR" + LS + - "LANGUAGE JAVA DETERMINISTIC NO SQL EXTERNAL NAME 'CLASSPATH:fr.ifremer.reefdb.dto.ReefDbBeans.getUnifiedSQLString';"; - - // old function with internal hsqldb method -// String query = "CREATE FUNCTION CONCAT_DISTINCT_" + functionName + "(IN_ARRAY " + valueType + " ARRAY) RETURNS LONGVARCHAR" + LS + -// "BEGIN ATOMIC" + LS + -// "DECLARE ARRAY_IT INTEGER DEFAULT 1;" + LS + -// "DECLARE VAR_ARRAY " + valueType + " ARRAY;" + LS + -// "SET VAR_ARRAY = IN_ARRAY;" + LS + -// "WHILE ARRAY_IT < CARDINALITY(VAR_ARRAY) DO" + LS + -// "IF POSITION_ARRAY(VAR_ARRAY[ARRAY_IT] IN VAR_ARRAY FROM ARRAY_IT + 1) != 0 THEN" + LS + -// "SET VAR_ARRAY[ARRAY_IT] = NULL;" + LS + -// "END IF;" + LS + -// "SET ARRAY_IT = ARRAY_IT + 1;" + LS + -// "END WHILE;" + LS + -// "RETURN (SELECT GROUP_CONCAT(RESULT.VALUE SEPARATOR '" + separator + "') FROM UNNEST(VAR_ARRAY) AS RESULT(VALUE));" + LS + -// "END;"; -// - extractionResultDao.queryUpdate(query, null); + private long createBaseTable(ExtractionContextDTO context, ExtractionOutputType outputType) { + XMLQuery xmlQuery = createXMLQuery("createBaseTable"); + xmlQuery.bind("baseTableName", context.getBaseTableName()); + xmlQuery.bind("orderItemTypeCode", getOrderItemTypeCode(context.getExtraction())); - } + // active groups depending the output type + setGroups(xmlQuery, outputType); - private String getConcatDistinctFunction(String functionName) { + // add mandatory period filter + List periodFilters = ReefDbBeans.getExtractionPeriods(context.getExtraction()); + Element periodFilter = xmlQuery.getFirstTag(XMLQuery.TAG_WHERE, XMLQuery.ATTR_GROUP, "periodFilter"); + Assert.notNull(periodFilter); + for (int i = 0; i < periodFilters.size(); i++) { + XMLQuery periodFilterQuery = createXMLQuery("injectionPeriodFilter"); + if (i > 0) { + periodFilterQuery.getDocumentQuery().getRootElement().setAttribute(XMLQuery.ATTR_OPERATOR, "OR"); + } + String periodAlias = "PERIOD" + i; + periodFilterQuery.replaceAllBindings("PERIOD", periodAlias); + periodFilter.addContent(periodFilterQuery.getDocument().getRootElement().detach()); + xmlQuery.bind(periodAlias + "_startDate", Dates.formatDate(periodFilters.get(i).getStartDate(), "dd/MM/yyyy")); + xmlQuery.bind(periodAlias + "_endDate", Dates.formatDate(periodFilters.get(i).getEndDate(), "dd/MM/yyyy")); + } + + // add program filter + List programCodes = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.PROGRAM); + xmlQuery.setGroup("programFilter", CollectionUtils.isNotEmpty(programCodes)); + xmlQuery.bind("progCodes", Daos.getInStatementFromStringCollection(programCodes)); + + // add monitoring location filter + List locationIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.LOCATION); + xmlQuery.setGroup("locationFilter", CollectionUtils.isNotEmpty(locationIds)); + xmlQuery.bind("monLocIds", Daos.getInStatementFromIntegerCollection(locationIds)); + + // add campaign filter + List campaignIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.CAMPAIGN); + xmlQuery.setGroup("campaignFilter", CollectionUtils.isNotEmpty(campaignIds)); + xmlQuery.bind("campaignIds", Daos.getInStatementFromIntegerCollection(campaignIds)); + + // add department filter + List departmentIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.DEPARTMENT); + xmlQuery.setGroup("departmentFilter", CollectionUtils.isNotEmpty(departmentIds)); + xmlQuery.bind("depIds", Daos.getInStatementFromIntegerCollection(departmentIds)); + + // add pmfm filter + List pmfmIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.PMFM); + xmlQuery.setGroup("pmfmFilter", CollectionUtils.isNotEmpty(pmfmIds)); + xmlQuery.bind("pmfmIds", Daos.getInStatementFromIntegerCollection(pmfmIds)); - return "CONCAT_DISTINCT_" + functionName; - } + // execute insertion + execute(xmlQuery); - private void dropConcatDistinctFunction(String functionName) { + // if no program filter, gather them from base table + if (CollectionUtils.isEmpty(programCodes)) { + gatherProgramCodes(context); + } - extractionResultDao.queryUpdate("DROP FUNCTION CONCAT_DISTINCT_" + functionName + " IF EXISTS", null); + return countFrom(context.getBaseTableName()); } - private Long countRootData(ExtractionDTO extraction) { - - String countQuery = "SELECT COUNT(*)" + LS + - getFromClauseMinimal() + - getWhereClause(extraction); - - Map queryBindings = getQueryBindings(extraction); - - return extractionResultDao.queryCount(countQuery, queryBindings); + private void gatherProgramCodes(ExtractionContextDTO context) { + // gather program codes from base table + XMLQuery xmlQuery = createXMLQuery("programCodes"); + xmlQuery.bind("baseTableName", context.getBaseTableName()); + List programCodes = extractionResultDao.queryStringList(xmlQuery.getSQLQueryAsString(), null); + // set into program filter + ReefDbBeans.setFilterElements(context.getExtraction(), ExtractionFilterValues.PROGRAM, + programCodes.stream().map(programCode -> { + ProgramDTO program = ReefDbBeanFactory.newProgramDTO(); + program.setCode(programCode); + return program; + }).collect(Collectors.toList())); } - private List getPmfmInfo(ExtractionContextDTO context) { - - // retrieve pmfm ids from filter - List pmfmIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.PMFM); - - // query the raw table to retrieve pmfm metadata - String pmfmQuery = "SELECT DISTINCT PMFM_ID, IS_SURVEY_MEAS, CASE WHEN MEAS_INDIV_ID IS NULL THEN FALSE ELSE TRUE END FROM " + context.getRawTableName(); - if (CollectionUtils.isNotEmpty(pmfmIds)) { - pmfmQuery += " WHERE PMFM_ID IN (" + Daos.getInStatementFromIntegerCollection(pmfmIds) + ")"; - } - - return extractionResultDao.query(pmfmQuery, null, (resultSet, i) -> { - ExtractionPmfmInfoDTO pmfmInfo = ReefDbBeanFactory.newExtractionPmfmInfoDTO(); - pmfmInfo.setPmfmId(resultSet.getInt(1)); - pmfmInfo.setSurvey(resultSet.getBoolean(2)); - pmfmInfo.setIndividual(resultSet.getBoolean(3)); - // compute alias - String safePmfmId = pmfmInfo.getPmfmId() < 0 ? "M" : "" + pmfmInfo.getPmfmId(); - pmfmInfo.setAlias((pmfmInfo.isSurvey() ? "SU" : "SO") + (pmfmInfo.isIndividual() ? "I" : "") + safePmfmId); - return pmfmInfo; - }); - } + private long createRawTable(ExtractionContextDTO context, ExtractionOutputType outputType) { - private void createRawTable(ExtractionContextDTO context, ExtractionOutputType outputType) { - - StringBuilder queryBuilder = new StringBuilder(); - - queryBuilder.append("DECLARE LOCAL TEMPORARY TABLE ").append(context.getRawTableName()).append(" ("); - queryBuilder.append("SURVEY_ID INTEGER, "); - queryBuilder.append("SURVEY_PROG_CD VARCHAR(40), "); - queryBuilder.append("REC_DEP_ID INTEGER, "); - queryBuilder.append("MON_LOC_NM VARCHAR(100), "); - queryBuilder.append("SURVEY_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_ID INTEGER, "); - queryBuilder.append("SAMPLING_OPER_LB VARCHAR(50), "); - queryBuilder.append("MON_LOC_ID INTEGER, "); - queryBuilder.append("MON_LOC_LB VARCHAR(50), "); - queryBuilder.append("ORDER_ITEM_NM VARCHAR(100), "); - queryBuilder.append("SURVEY_POSITION_LONG VARCHAR(20), "); - queryBuilder.append("SURVEY_POSITION_LAT VARCHAR(20), "); - queryBuilder.append("SAMPLING_EQUIPMENT_NM VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_DEP_NM VARCHAR(255), "); - if (outputType != ExtractionOutputType.PAMPA) { - queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); - } - queryBuilder.append("SURVEY_LB VARCHAR(50), "); - queryBuilder.append("SAMPLING_OPER_SIZE DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_SIZE_UNIT_SYMBOL VARCHAR(100), "); - - if (outputType == ExtractionOutputType.COMPLETE) { - queryBuilder.append("ORDER_ITEM_TYPE_NM VARCHAR(100), "); - queryBuilder.append("ORDER_ITEM_CD VARCHAR(40), "); - queryBuilder.append("MON_LOC_ORDER_ITEM_NUMBER DOUBLE, "); - queryBuilder.append("SURVEY_TIME DOUBLE, "); - queryBuilder.append("SURVEY_CM VARCHAR(2000), "); - queryBuilder.append("SURVEY_CONTROL_DT TIMESTAMP, "); - queryBuilder.append("SURVEY_VALID_DT TIMESTAMP, "); - queryBuilder.append("SURVEY_QUAL_FLAG VARCHAR(100), "); - queryBuilder.append("SURVEY_QUALIF_DT TIMESTAMP, "); - queryBuilder.append("SURVEY_QUALIF_CM VARCHAR(2000), "); - queryBuilder.append("SURVEY_INHERITED_POSITION VARCHAR(1), "); - queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); - queryBuilder.append("SAMPLING_OPER_DEPTH DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_MIN_DEPTH DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_MAX_DEPTH DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_INHERITED_POSITION VARCHAR(1), "); - queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT_SYMBOL VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_CM VARCHAR(2000), "); - queryBuilder.append("SAMPLING_EQUIPMENT_SIZE DOUBLE, "); - queryBuilder.append("SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_NUMBER_INDIV DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_CONTROL_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_VALID_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_QUAL_FLAG VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_QUALIF_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_QUALIF_CM VARCHAR(2000), "); - queryBuilder.append("SAMPLING_OPER_POSITION_LONG VARCHAR(20), "); - queryBuilder.append("SAMPLING_OPER_POSITION_LAT VARCHAR(20), "); - } else if (outputType == ExtractionOutputType.PAMPA) { - queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); - queryBuilder.append("SURVEY_BOTTOM_DEPTH DOUBLE, "); - queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); - } + XMLQuery xmlQuery = createXMLQuery("createRawTable"); + xmlQuery.bind("rawTableName", context.getRawTableName()); + xmlQuery.bind("baseTableName", context.getBaseTableName()); - queryBuilder.append("MEAS_ID INTEGER, "); - queryBuilder.append("TAXON_MEAS_ID INTEGER, "); - queryBuilder.append("IS_SURVEY_MEAS BOOLEAN, "); - queryBuilder.append("MEAS_INDIV_ID INTEGER,"); - queryBuilder.append("PMFM_ID INTEGER, "); - queryBuilder.append("DEP_NM VARCHAR(255), "); - queryBuilder.append("MEAS_NUMER_VALUE DOUBLE, "); - queryBuilder.append("QUAL_VALUE_NM VARCHAR(100), "); - queryBuilder.append("TAXON_NAME_ID INTEGER, "); - queryBuilder.append("TAXON_NAME_NM VARCHAR(255), "); - queryBuilder.append("TAXON_GROUP_ID INTEGER, "); - queryBuilder.append("TAXON_GROUP_NM VARCHAR(100), "); - queryBuilder.append("MEAS_CM VARCHAR(2000), "); - - if (outputType == ExtractionOutputType.PAMPA) { - queryBuilder.append("TAXON_PAMPA VARCHAR(40), "); - } else { - queryBuilder.append("INPUT_TAXON_NAME_NM VARCHAR(255), "); - queryBuilder.append("INPUT_TAXON_NAME_ID INTEGER, "); - } + // active groups depending the output type + setGroups(xmlQuery, outputType); - String query = trimAtLastSequence(queryBuilder.toString(), ",").concat(")"); + // add pampa configuration + xmlQuery.bind("alternativeTaxonOriginPampa", config.getAlternativeTaxonOriginPAMPA()); - extractionResultDao.queryUpdate(query, null); + execute(xmlQuery); + return countFrom(context.getRawTableName()); } - private void createPmfmTables(ExtractionContextDTO context, ExtractionOutputType outputType) { - - if (!context.isPmfmInfosEmpty()) { - for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { - - // Generate pmfm table name - String pmfmTableName = String.format(PMFM_TABLE_NAME_PATTERN, context.getUniqueId(), pmfmInfo.getAlias()); - pmfmInfo.setTableName(pmfmTableName); - - StringBuilder queryBuilder = new StringBuilder(); - queryBuilder.append("DECLARE LOCAL TEMPORARY TABLE ").append(pmfmTableName).append(" ("); - queryBuilder.append(pmfmInfo.isSurvey() ? "SURVEY_ID INTEGER, " : "SAMPLING_OPER_ID INTEGER, "); - queryBuilder.append("MEAS_ID INTEGER, "); - queryBuilder.append("TAXON_MEAS_ID INTEGER, "); - queryBuilder.append("IS_SURVEY_MEAS BOOLEAN, "); - queryBuilder.append("MEAS_INDIV_ID INTEGER, "); - queryBuilder.append("PMFM_ID INTEGER, "); - queryBuilder.append("DEP_NM VARCHAR(255), "); - queryBuilder.append("MEAS_NUMER_VALUE DOUBLE, "); - queryBuilder.append("QUAL_VALUE_NM VARCHAR(100), "); - queryBuilder.append("TAXON_NAME_NM VARCHAR(255), "); - queryBuilder.append("TAXON_GROUP_NM VARCHAR(100), "); - queryBuilder.append("MEAS_CM VARCHAR(2000), "); - - if (outputType == ExtractionOutputType.PAMPA) { - queryBuilder.append("TAXON_PAMPA VARCHAR(40), "); - } else { - queryBuilder.append("INPUT_TAXON_NAME_NM VARCHAR(255), "); - queryBuilder.append("INPUT_TAXON_NAME_ID INTEGER, "); - } - - String query = trimAtLastSequence(queryBuilder.toString(), ",").concat(")"); - extractionResultDao.queryUpdate(query, null); - } - } - } + private void buildPmfmInformation(ExtractionContextDTO context) { - private void createCommonTable(ExtractionContextDTO context, ExtractionOutputType outputType) { + // Gather pmfm from raw table + List pmfmInfos = getPmfmInfo(context); - StringBuilder queryBuilder = new StringBuilder(); - queryBuilder.append("DECLARE LOCAL TEMPORARY TABLE ").append(context.getCommonTableName()).append(" ("); - queryBuilder.append("SURVEY_ID INTEGER, "); - queryBuilder.append("SURVEY_PROG_CD VARCHAR(40), "); - queryBuilder.append("MON_LOC_NM VARCHAR(100), "); - queryBuilder.append("SURVEY_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_ID INTEGER, "); - queryBuilder.append("SAMPLING_OPER_LB VARCHAR(50), "); - queryBuilder.append("MON_LOC_ID INTEGER, "); - queryBuilder.append("MON_LOC_LB VARCHAR(50), "); - queryBuilder.append("ORDER_ITEM_NM VARCHAR(100), "); - queryBuilder.append("SURVEY_POSITION_LONG VARCHAR(20), "); - queryBuilder.append("SURVEY_POSITION_LAT VARCHAR(20), "); - queryBuilder.append("SAMPLING_EQUIPMENT_NM VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_DEP_NM VARCHAR(255), "); - if (outputType != ExtractionOutputType.PAMPA) { - queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); - } - queryBuilder.append("SURVEY_LB VARCHAR(50), "); - queryBuilder.append("SAMPLING_OPER_SIZE DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_SIZE_UNIT_SYMBOL VARCHAR(100), "); - if (outputType == ExtractionOutputType.COMPLETE) { - queryBuilder.append("ORDER_ITEM_TYPE_NM VARCHAR(100), "); - queryBuilder.append("ORDER_ITEM_CD VARCHAR(40), "); - queryBuilder.append("MON_LOC_ORDER_ITEM_NUMBER DOUBLE, "); - queryBuilder.append("SURVEY_TIME DOUBLE, "); - queryBuilder.append("SURVEY_CM VARCHAR(2000), "); - queryBuilder.append("SURVEY_CONTROL_DT TIMESTAMP, "); - queryBuilder.append("SURVEY_VALID_DT TIMESTAMP, "); - queryBuilder.append("SURVEY_QUAL_FLAG VARCHAR(100), "); - queryBuilder.append("SURVEY_QUALIF_DT TIMESTAMP, "); - queryBuilder.append("SURVEY_QUALIF_CM VARCHAR(2000), "); - queryBuilder.append("SURVEY_INHERITED_POSITION VARCHAR(1), "); - queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); - queryBuilder.append("SAMPLING_OPER_DEPTH DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_MIN_DEPTH DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_MAX_DEPTH DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_INHERITED_POSITION VARCHAR(1), "); - queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT_SYMBOL VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_CM VARCHAR(2000), "); - queryBuilder.append("SAMPLING_EQUIPMENT_SIZE DOUBLE, "); - queryBuilder.append("SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_NUMBER_INDIV DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_CONTROL_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_VALID_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_QUAL_FLAG VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_QUALIF_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_QUALIF_CM VARCHAR(2000), "); - queryBuilder.append("SAMPLING_OPER_POSITION_LONG VARCHAR(20), "); - queryBuilder.append("SAMPLING_OPER_POSITION_LAT VARCHAR(20), "); - } else if (outputType == ExtractionOutputType.PAMPA) { - queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); - queryBuilder.append("SURVEY_BOTTOM_DEPTH DOUBLE, "); - queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); + if (CollectionUtils.isEmpty(pmfmInfos)) { + throw new ReefDbBusinessException(t("reefdb.service.extraction.noPmfm.error")); } - queryBuilder.append("MEAS_INDIV_ID INTEGER)"); - extractionResultDao.queryUpdate(queryBuilder.toString(), null); + // Get PMFM strategies corresponding to extraction filters and compute pmfm sort order + List programCodes = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.PROGRAM); + Set allPmfmStrategies = ReefDbBeans.getExtractionPeriods(context.getExtraction()).stream() + .collect(HashSet::new, + (pmfmStrategies, period) -> + pmfmStrategies.addAll(strategyDao.getPmfmStrategiesByProgramCodesAndDates(programCodes, period.getStartDate(), period.getEndDate())), + HashSet::addAll); - } + Map rankOrdersByPmfmId = allPmfmStrategies.stream() + .collect(HashMap::new, + (map, pmfmStrategy) -> + map.put(pmfmStrategy.getPmfm().getId(), pmfmStrategy.getRankOrder()), + HashMap::putAll); - private void createSplitTable(ExtractionContextDTO context, ExtractionOutputType outputType) { - - StringBuilder queryBuilder = new StringBuilder(); - queryBuilder.append("DECLARE LOCAL TEMPORARY TABLE ").append(context.getSplitTableName()).append(" ("); - queryBuilder.append("SURVEY_ID INTEGER, "); - queryBuilder.append("SURVEY_PROG_CD VARCHAR(40), "); - queryBuilder.append("MON_LOC_NM VARCHAR(100), "); - queryBuilder.append("SURVEY_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_ID INTEGER, "); - queryBuilder.append("SAMPLING_OPER_LB VARCHAR(50), "); - queryBuilder.append("MON_LOC_ID INTEGER, "); - queryBuilder.append("MON_LOC_LB VARCHAR(50), "); - queryBuilder.append("ORDER_ITEM_NM VARCHAR(100), "); - queryBuilder.append("SURVEY_POSITION_LONG VARCHAR(20), "); - queryBuilder.append("SURVEY_POSITION_LAT VARCHAR(20), "); - queryBuilder.append("SAMPLING_EQUIPMENT_NM VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_DEP_NM VARCHAR(255), "); - if (outputType != ExtractionOutputType.PAMPA) { - queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); - } - queryBuilder.append("SURVEY_LB VARCHAR(50), "); - queryBuilder.append("SAMPLING_OPER_SIZE DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_SIZE_UNIT_SYMBOL VARCHAR(100), "); - if (outputType == ExtractionOutputType.COMPLETE) { - queryBuilder.append("ORDER_ITEM_TYPE_NM VARCHAR(100), "); - queryBuilder.append("ORDER_ITEM_CD VARCHAR(40), "); - queryBuilder.append("MON_LOC_ORDER_ITEM_NUMBER DOUBLE, "); - queryBuilder.append("SURVEY_TIME DOUBLE, "); - queryBuilder.append("SURVEY_CM VARCHAR(2000), "); - queryBuilder.append("SURVEY_CONTROL_DT TIMESTAMP, "); - queryBuilder.append("SURVEY_VALID_DT TIMESTAMP, "); - queryBuilder.append("SURVEY_QUAL_FLAG VARCHAR(100), "); - queryBuilder.append("SURVEY_QUALIF_DT TIMESTAMP, "); - queryBuilder.append("SURVEY_QUALIF_CM VARCHAR(2000), "); - queryBuilder.append("SURVEY_INHERITED_POSITION VARCHAR(1), "); - queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); - queryBuilder.append("SAMPLING_OPER_DEPTH DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_MIN_DEPTH DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_MAX_DEPTH DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_INHERITED_POSITION VARCHAR(1), "); - queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT_SYMBOL VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_CM VARCHAR(2000), "); - queryBuilder.append("SAMPLING_EQUIPMENT_SIZE DOUBLE, "); - queryBuilder.append("SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_NUMBER_INDIV DOUBLE, "); - queryBuilder.append("SAMPLING_OPER_CONTROL_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_VALID_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_QUAL_FLAG VARCHAR(100), "); - queryBuilder.append("SAMPLING_OPER_QUALIF_DT TIMESTAMP, "); - queryBuilder.append("SAMPLING_OPER_QUALIF_CM VARCHAR(2000), "); - queryBuilder.append("SAMPLING_OPER_POSITION_LONG VARCHAR(20), "); - queryBuilder.append("SAMPLING_OPER_POSITION_LAT VARCHAR(20), "); - } else if (outputType == ExtractionOutputType.PAMPA) { - queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); - queryBuilder.append("SURVEY_BOTTOM_DEPTH DOUBLE, "); - queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); - } - queryBuilder.append("MEAS_INDIV_ID INTEGER, "); - - if (!context.isPmfmInfosEmpty()) { - for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { - - queryBuilder.append(pmfmInfo.getAlias()).append("_MEAS_ID INTEGER, "); - queryBuilder.append(pmfmInfo.getAlias()).append("_TAXON_MEAS_ID INTEGER, "); - queryBuilder.append(pmfmInfo.getAlias()).append("_MEAS_NUMER_VALUE DOUBLE, "); - queryBuilder.append(pmfmInfo.getAlias()).append("_QUAL_VALUE_NM VARCHAR(100), "); - queryBuilder.append(pmfmInfo.getAlias()).append("_DEP_NM VARCHAR(255), "); - if (pmfmInfo.isIndividual()) { - queryBuilder.append(pmfmInfo.getAlias()).append("_TAXON_NAME_NM VARCHAR(255), "); - queryBuilder.append(pmfmInfo.getAlias()).append("_TAXON_GROUP_NM VARCHAR(100), "); - queryBuilder.append(pmfmInfo.getAlias()).append("_MEAS_CM VARCHAR(2000), "); - if (outputType == ExtractionOutputType.PAMPA) { - queryBuilder.append(pmfmInfo.getAlias()).append("_TAXON_PAMPA VARCHAR(40), "); - } else { - queryBuilder.append(pmfmInfo.getAlias()).append("_INPUT_TAXON_NAME_NM VARCHAR(255), "); - queryBuilder.append(pmfmInfo.getAlias()).append("_INPUT_TAXON_NAME_ID INTEGER, "); - } - } + // Affect rank order + pmfmInfos.forEach(pmfmInfo -> { + Integer rankOrder = rankOrdersByPmfmId.get(pmfmInfo.getPmfmId()); + // put the pmfm outside a strategy at the end (Mantis #43695) + pmfmInfo.setRankOrder(rankOrder != null ? rankOrder : Integer.MAX_VALUE); } - } + ); - String query = trimAtLastSequence(queryBuilder.toString(), ",").concat(")"); - - extractionResultDao.queryUpdate(query, null); + // Sort by rankOrder + pmfmInfos.sort(Comparator.comparingInt(ExtractionPmfmInfoDTO::getRankOrder)); + // Affect to context + context.setPmfmInfos(pmfmInfos); } - private int insertRawData(ExtractionContextDTO context, ExtractionOutputType outputType) { - - // Base select - StringBuilder baseSelectBuilder = new StringBuilder(); - baseSelectBuilder.append("SELECT BASE.SURVEY_ID, BASE.SURVEY_PROG_CD, BASE.REC_DEP_ID, BASE.MON_LOC_NM, BASE.SURVEY_DT, BASE.SAMPLING_OPER_ID, BASE.SAMPLING_OPER_LB, "); - baseSelectBuilder.append("BASE.MON_LOC_ID, BASE.MON_LOC_LB, MLOI.ORDER_ITEM_NM, BASE.SURVEY_POSITION_LONG, BASE.SURVEY_POSITION_LAT, "); - baseSelectBuilder.append("BASE.SAMPLING_EQUIPMENT_NM, BASE.SAMPLING_OPER_DEP_NM, "); - if (outputType != ExtractionOutputType.PAMPA) { - baseSelectBuilder.append("BASE.SURVEY_QUSERS, "); - } - baseSelectBuilder.append("BASE.SURVEY_LB, BASE.SAMPLING_OPER_SIZE, BASE.SAMPLING_OPER_SIZE_UNIT_SYMBOL, "); - - if (outputType == ExtractionOutputType.COMPLETE) { - baseSelectBuilder.append("MLOI.ORDER_ITEM_TYPE_NM, MLOI.ORDER_ITEM_CD, MLOI.MON_LOC_ORDER_ITEM_NUMBER, " + - "BASE.SURVEY_TIME, BASE.SURVEY_CM, BASE.SURVEY_CONTROL_DT, BASE.SURVEY_VALID_DT, BASE.SURVEY_QUAL_FLAG, " + - "BASE.SURVEY_QUALIF_DT, BASE.SURVEY_QUALIF_CM, BASE.SURVEY_INHERITED_POSITION, BASE.SAMPLING_OPER_TIME, " + - "BASE.SAMPLING_OPER_DEPTH, BASE.SAMPLING_OPER_MIN_DEPTH, BASE.SAMPLING_OPER_MAX_DEPTH, " + - "BASE.SAMPLING_OPER_INHERITED_POSITION, BASE.SAMPLING_OPER_DEPTH_UNIT_SYMBOL, BASE.SAMPLING_OPER_DEPTH_UNIT, " + - "BASE.SAMPLING_OPER_CM, BASE.SAMPLING_EQUIPMENT_SIZE, BASE.SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, BASE.SAMPLING_OPER_NUMBER_INDIV, " + - "BASE.SAMPLING_OPER_CONTROL_DT, BASE.SAMPLING_OPER_VALID_DT, BASE.SAMPLING_OPER_QUAL_FLAG, BASE.SAMPLING_OPER_QUALIF_DT, " + - "BASE.SAMPLING_OPER_QUALIF_CM, BASE.SAMPLING_OPER_POSITION_LONG, BASE.SAMPLING_OPER_POSITION_LAT, "); - } else if (outputType == ExtractionOutputType.PAMPA) { - baseSelectBuilder.append("BASE.SAMPLING_OPER_TIME, BASE.SURVEY_BOTTOM_DEPTH, BASE.SURVEY_QUSERS, "); - } - String baseSelect = baseSelectBuilder.toString(); - - // base sub query - StringBuilder insertQueryBuiler = new StringBuilder(); - insertQueryBuiler.append("INSERT INTO ").append(context.getRawTableName()).append(LS); - insertQueryBuiler.append("WITH BASE AS (").append(LS); - insertQueryBuiler.append("SELECT S.SURVEY_ID, PROG.PROG_CD AS SURVEY_PROG_CD, S.REC_DEP_ID, ML.MON_LOC_NM, S.SURVEY_DT,").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_ID, SO.SAMPLING_OPER_LB, ML.MON_LOC_ID, ML.MON_LOC_LB,").append(LS); - insertQueryBuiler.append("REGEXP_SUBSTRING(SP.SURVEY_POSITION, '[0-9.-]+') AS SURVEY_POSITION_LONG,").append(LS); - insertQueryBuiler.append("TRIM(TRAILING ')' FROM REGEXP_SUBSTRING(SP.SURVEY_POSITION, '[0-9.-]+\\)$')) AS SURVEY_POSITION_LAT,").append(LS); - insertQueryBuiler.append("SE.SAMPLING_EQUIPMENT_NM, DEP.DEP_NM AS SAMPLING_OPER_DEP_NM, ").append(LS); - if (outputType != ExtractionOutputType.PAMPA) { - insertQueryBuiler.append("GROUP_CONCAT(Q.QUSER_FIRST_NM || ' ' || Q.QUSER_LAST_NM || ' - ' || QD.DEP_NM separator '|') AS SURVEY_QUSERS,").append(LS); - } - insertQueryBuiler.append("S.SURVEY_LB,").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_SIZE, SU.UNIT_SYMBOL AS SAMPLING_OPER_SIZE_UNIT_SYMBOL").append(LS); - - if (outputType == ExtractionOutputType.COMPLETE) { - insertQueryBuiler.append(", S.SURVEY_TIME, S.SURVEY_CM, S.SURVEY_CONTROL_DT, S.SURVEY_VALID_DT, SQF.QUAL_FLAG_NM AS SURVEY_QUAL_FLAG, ").append(LS); - insertQueryBuiler.append("S.SURVEY_QUALIF_DT, S.SURVEY_QUALIF_CM, CASEWHEN(IFNULL(S.SURVEY_ACTUAL_POSITION,'0')='0','1','0') AS SURVEY_INHERITED_POSITION, SO.SAMPLING_OPER_TIME, ").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_DEPTH, SO.SAMPLING_OPER_MIN_DEPTH, SO.SAMPLING_OPER_MAX_DEPTH, CASEWHEN(IFNULL(SO.SAMPLING_OPER_ACTUAL_POSITION,'0')='0','1','0') AS.SAMPLING_OPER_INHERITED_POSITION, ").append(LS); - insertQueryBuiler.append("DU.UNIT_SYMBOL AS SAMPLING_OPER_DEPTH_UNIT_SYMBOL, DU.UNIT_NM AS SAMPLING_OPER_DEPTH_UNIT, SO.SAMPLING_OPER_CM, ").append(LS); - insertQueryBuiler.append("SE.SAMPLING_EQUIPMENT_SIZE, SEU.UNIT_SYMBOL AS SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, ").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_NUMBER_INDIV, SO.SAMPLING_OPER_CONTROL_DT, SO.SAMPLING_OPER_VALID_DT, SOQF.QUAL_FLAG_NM AS SAMPLING_OPER_QUAL_FLAG, ").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_QUALIF_DT, SO.SAMPLING_OPER_QUALIF_CM, ").append(LS); - insertQueryBuiler.append("REGEXP_SUBSTRING(SOP.SAMPLING_OPER_POSITION, '[0-9.-]+') AS SAMPLING_OPER_POSITION_LONG, ").append(LS); - insertQueryBuiler.append("TRIM(TRAILING ')' FROM REGEXP_SUBSTRING(SOP.SAMPLING_OPER_POSITION, '[0-9.-]+\\)$')) AS SAMPLING_OPER_POSITION_LAT").append(LS); - } else if (outputType == ExtractionOutputType.PAMPA) { - insertQueryBuiler.append(", SO.SAMPLING_OPER_TIME, S.SURVEY_BOTTOM_DEPTH, GROUP_CONCAT(Q.QUSER_FIRST_NM || ' ' || Q.QUSER_LAST_NM separator '|') AS SURVEY_QUSERS").append(LS); - } - - insertQueryBuiler.append(getFromClauseMinimal()); - insertQueryBuiler.append("LEFT OUTER JOIN SURVEY_POINT SP ON SP.SURVEY_ID = S.SURVEY_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN SAMPLING_OPERATION SO ON SO.SURVEY_ID = S.SURVEY_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN SAMPLING_EQUIPMENT SE ON SE.SAMPLING_EQUIPMENT_ID = SO.SAMPLING_EQUIPMENT_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT DEP ON DEP.DEP_ID = SO.DEP_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN UNIT SU ON SU.UNIT_ID = SO.SAMPLING_OPER_SIZE_UNIT_ID").append(LS); - if (outputType != ExtractionOutputType.PAMPA) { - insertQueryBuiler.append("LEFT OUTER JOIN SURVEY_QUSER SQ ON SQ.SURVEY_ID = S.SURVEY_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN QUSER Q ON Q.QUSER_ID = SQ.QUSER_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT QD ON QD.DEP_ID = Q.DEP_ID").append(LS); - } - - if (outputType == ExtractionOutputType.COMPLETE) { - insertQueryBuiler.append("LEFT OUTER JOIN QUALITY_FLAG SQF ON S.QUAL_FLAG_CD = SQF.QUAL_FLAG_CD").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN UNIT DU ON SO.SAMPLING_OPER_DEPTH_UNIT_ID = DU.UNIT_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN UNIT SEU ON SE.UNIT_ID = SEU.UNIT_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN QUALITY_FLAG SOQF ON SO.QUAL_FLAG_CD = SOQF.QUAL_FLAG_CD").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN SAMPLING_OPER_POINT SOP ON SO.SAMPLING_OPER_ID = SOP.SAMPLING_OPER_ID").append(LS); - } else if (outputType == ExtractionOutputType.PAMPA) { - insertQueryBuiler.append("LEFT OUTER JOIN SURVEY_QUSER SQ ON SQ.SURVEY_ID = S.SURVEY_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN QUSER Q ON SQ.QUSER_ID = Q.QUSER_ID").append(LS); - } - - insertQueryBuiler.append(getWhereClause(context.getExtraction())); - - // Add GROUP BY because of GROUP_CONCAT aggregation method - insertQueryBuiler.append("GROUP BY S.SURVEY_ID, PROG.PROG_CD, ML.MON_LOC_NM, S.SURVEY_DT,").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_ID, SO.SAMPLING_OPER_LB, ML.MON_LOC_ID, ML.MON_LOC_LB,").append(LS); - insertQueryBuiler.append("SURVEY_POSITION_LONG, SURVEY_POSITION_LAT,").append(LS); - insertQueryBuiler.append("SE.SAMPLING_EQUIPMENT_NM, DEP.DEP_NM, S.SURVEY_LB,").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_SIZE, SU.UNIT_SYMBOL").append(LS); - if (outputType == ExtractionOutputType.COMPLETE) { - insertQueryBuiler.append(", S.SURVEY_TIME, S.SURVEY_CM, S.SURVEY_CONTROL_DT, S.SURVEY_VALID_DT, SQF.QUAL_FLAG_NM,").append(LS); - insertQueryBuiler.append("S.SURVEY_QUALIF_DT, S.SURVEY_QUALIF_CM, CASEWHEN(IFNULL(S.SURVEY_ACTUAL_POSITION,'0')='0','1','0'), SO.SAMPLING_OPER_TIME,").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_DEPTH, SO.SAMPLING_OPER_MIN_DEPTH, SO.SAMPLING_OPER_MAX_DEPTH, CASEWHEN(IFNULL(SO.SAMPLING_OPER_ACTUAL_POSITION,'0')='0','1','0'),").append(LS); - insertQueryBuiler.append("DU.UNIT_SYMBOL, DU.UNIT_NM, SO.SAMPLING_OPER_CM, SE.SAMPLING_EQUIPMENT_SIZE, SEU.UNIT_SYMBOL, ").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_NUMBER_INDIV, SO.SAMPLING_OPER_CONTROL_DT, SO.SAMPLING_OPER_VALID_DT, SOQF.QUAL_FLAG_NM, ").append(LS); - insertQueryBuiler.append("SO.SAMPLING_OPER_QUALIF_DT, SO.SAMPLING_OPER_QUALIF_CM, ").append(LS); - insertQueryBuiler.append("REGEXP_SUBSTRING(SOP.SAMPLING_OPER_POSITION, '[0-9.-]+'), ").append(LS); - insertQueryBuiler.append("TRIM(TRAILING ')' FROM REGEXP_SUBSTRING(SOP.SAMPLING_OPER_POSITION, '[0-9.-]+\\)$'))").append(LS); - } else if (outputType == ExtractionOutputType.PAMPA) { - insertQueryBuiler.append(", SO.SAMPLING_OPER_TIME, S.SURVEY_BOTTOM_DEPTH").append(LS); - } - - insertQueryBuiler.append("ORDER BY S.SURVEY_ID)").append(LS); - // end of base sub query - - // order item on location query - insertQueryBuiler.append(", MLOI AS (").append(LS); - insertQueryBuiler.append("SELECT MLOI.MON_LOC_ID, OI.ORDER_ITEM_NM, OIT.ORDER_ITEM_TYPE_NM, OI.ORDER_ITEM_CD, MLOI.MON_LOC_ORDER_ITEM_NUMBER").append(LS); - insertQueryBuiler.append("FROM MON_LOC_ORDER_ITEM MLOI").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN ORDER_ITEM OI ON MLOI.ORDER_ITEM_ID = OI.ORDER_ITEM_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN ORDER_ITEM_TYPE OIT ON OI.ORDER_ITEM_TYPE_CD = OIT.ORDER_ITEM_TYPE_CD").append(LS); - insertQueryBuiler.append("WHERE OI.ORDER_ITEM_TYPE_CD = '").append(getOrderItemTypeCode(context.getExtraction())).append("')").append(LS); - - if (outputType == ExtractionOutputType.PAMPA) { - // alternative taxon for pampa - insertQueryBuiler.append(", ALT AS (").append(LS); - insertQueryBuiler.append("SELECT ALT.TAXON_NAME_ID, ALT.ALTERN_TAXON_CD FROM ALTERNATIVE_TAXON ALT").append(LS); - insertQueryBuiler.append("WHERE ALT.ALTERN_TAXON_ORIGIN_CD = '").append(config.getAlternativeTaxonOriginPAMPA()).append("')"); - } + private List getPmfmInfo(ExtractionContextDTO context) { - // SURVEY MEASUREMENTS - insertQueryBuiler.append(baseSelect).append(LS); - insertQueryBuiler.append("SM.REMOTE_ID AS MEAS_ID, NULL AS TAXON_MEAS_ID, 1 AS IS_SURVEY_MEAS, SM.MEAS_INDIV_ID, SM.PMFM_ID, D.DEP_NM, SM.MEAS_NUMER_VALUE, QV.QUAL_VALUE_NM,").append(LS); - insertQueryBuiler.append("NULL AS TAXON_NAME_ID, NULL AS TAXON_NAME_NM, NULL AS TAXON_GROUP_ID, NULL AS TAXON_GROUP_NM, SM.MEAS_CM"); - insertQueryBuiler.append(outputType == ExtractionOutputType.PAMPA ? ", NULL AS TAXON_PAMPA" : ", NULL AS INPUT_TAXON_NAME_NM, NULL AS INPUT_TAXON_NAME_ID").append(LS); - insertQueryBuiler.append("FROM BASE").append(LS); - insertQueryBuiler.append("INNER JOIN MEASUREMENT SM ON BASE.SURVEY_ID = SM.SURVEY_ID AND SM.SAMPLING_OPER_ID IS NULL").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT D ON SM.DEP_ID = D.DEP_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN QUALITATIVE_VALUE QV ON SM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN MLOI ON MLOI.MON_LOC_ID = BASE.MON_LOC_ID").append(LS); - insertQueryBuiler.append("UNION").append(LS); - - // SURVEY TAXON MEASUREMENTS - insertQueryBuiler.append(baseSelect).append(LS); - insertQueryBuiler.append("NULL AS MEAS_ID, STM.REMOTE_ID AS TAXON_MEAS_ID, 1 AS IS_SURVEY_MEAS, STM.TAXON_MEAS_INDIV_ID, STM.PMFM_ID, D.DEP_NM, STM.TAXON_MEAS_NUMER_VALUE, QV.QUAL_VALUE_NM,").append(LS); - insertQueryBuiler.append("TN.TAXON_NAME_ID, TN.TAXON_NAME_COMPLETE_NM AS TAXON_NAME_NM, TG.TAXON_GROUP_ID, TG.TAXON_GROUP_NM, STM.TAXON_MEAS_CM"); - insertQueryBuiler.append(outputType == ExtractionOutputType.PAMPA ? ", ALT.ALTERN_TAXON_CD AS TAXON_PAMPA" : ", STM.TAXON_NAME_NM AS INPUT_TAXON_NAME_NM, STM.TAXON_NAME_ID AS INPUT_TAXON_NAME_ID").append(LS); - insertQueryBuiler.append("FROM BASE").append(LS); - insertQueryBuiler.append("INNER JOIN TAXON_MEASUREMENT STM ON BASE.SURVEY_ID = STM.SURVEY_ID AND STM.SAMPLING_OPER_ID IS NULL").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT D ON STM.DEP_ID = D.DEP_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN QUALITATIVE_VALUE QV ON STM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN TAXON_NAME TN ON STM.REF_TAXON_ID = TN.REF_TAXON_ID AND TN.TAXON_NAME_IS_REFER = 1").append(LS); - if (outputType == ExtractionOutputType.PAMPA) { - insertQueryBuiler.append("LEFT OUTER JOIN ALT ON ALT.TAXON_NAME_ID = TN.TAXON_NAME_ID").append(LS); - } - insertQueryBuiler.append("LEFT OUTER JOIN TAXON_GROUP TG ON STM.TAXON_GROUP_ID = TG.TAXON_GROUP_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN MLOI ON MLOI.MON_LOC_ID = BASE.MON_LOC_ID").append(LS); - insertQueryBuiler.append("UNION").append(LS); - - // SAMPLING OPERATION MEASUREMENTS - insertQueryBuiler.append(baseSelect).append(LS); - insertQueryBuiler.append("SM.REMOTE_ID AS MEAS_ID, NULL AS TAXON_MEAS_ID, 0 AS IS_SURVEY_MEAS, SM.MEAS_INDIV_ID, SM.PMFM_ID, D.DEP_NM, SM.MEAS_NUMER_VALUE, QV.QUAL_VALUE_NM,").append(LS); - insertQueryBuiler.append("NULL AS TAXON_NAME_ID, NULL AS TAXON_NAME_NM, NULL AS TAXON_GROUP_ID, NULL AS TAXON_GROUP_NM, SM.MEAS_CM"); - insertQueryBuiler.append(outputType == ExtractionOutputType.PAMPA ? ", NULL AS TAXON_PAMPA" : ", NULL AS INPUT_TAXON_NAME_NM, NULL AS INPUT_TAXON_NAME_ID").append(LS); - insertQueryBuiler.append("FROM BASE").append(LS); - insertQueryBuiler.append("INNER JOIN MEASUREMENT SM ON BASE.SAMPLING_OPER_ID = SM.SAMPLING_OPER_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT D ON SM.DEP_ID = D.DEP_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN QUALITATIVE_VALUE QV ON SM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN MLOI ON MLOI.MON_LOC_ID = BASE.MON_LOC_ID").append(LS); - insertQueryBuiler.append("UNION").append(LS); - - // SAMPLING OPERATION TAXON MEASUREMENTS - insertQueryBuiler.append(baseSelect).append(LS); - insertQueryBuiler.append("NULL AS MEAS_ID, STM.REMOTE_ID AS TAXON_MEAS_ID, 0 AS IS_SURVEY_MEAS, STM.TAXON_MEAS_INDIV_ID, STM.PMFM_ID, D.DEP_NM, STM.TAXON_MEAS_NUMER_VALUE, QV.QUAL_VALUE_NM,").append(LS); - insertQueryBuiler.append("TN.TAXON_NAME_ID, TN.TAXON_NAME_COMPLETE_NM AS TAXON_NAME_NM, TG.TAXON_GROUP_ID, TG.TAXON_GROUP_NM, STM.TAXON_MEAS_CM"); - insertQueryBuiler.append(outputType == ExtractionOutputType.PAMPA ? ", ALT.ALTERN_TAXON_CD AS TAXON_PAMPA" : ", STM.TAXON_NAME_NM AS INPUT_TAXON_NAME_NM, STM.TAXON_NAME_ID AS INPUT_TAXON_NAME_ID").append(LS); - insertQueryBuiler.append("FROM BASE").append(LS); - insertQueryBuiler.append("INNER JOIN TAXON_MEASUREMENT STM ON BASE.SAMPLING_OPER_ID = STM.SAMPLING_OPER_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT D ON STM.DEP_ID = D.DEP_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN QUALITATIVE_VALUE QV ON STM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN TAXON_NAME TN ON STM.REF_TAXON_ID = TN.REF_TAXON_ID AND TN.TAXON_NAME_IS_REFER = 1").append(LS); - if (outputType == ExtractionOutputType.PAMPA) { - insertQueryBuiler.append("LEFT OUTER JOIN ALT ON ALT.TAXON_NAME_ID = TN.TAXON_NAME_ID").append(LS); - } - insertQueryBuiler.append("LEFT OUTER JOIN TAXON_GROUP TG ON STM.TAXON_GROUP_ID = TG.TAXON_GROUP_ID").append(LS); - insertQueryBuiler.append("LEFT OUTER JOIN MLOI ON MLOI.MON_LOC_ID = BASE.MON_LOC_ID").append(LS); + XMLQuery xmlQuery = createXMLQuery("pmfmInfo"); + xmlQuery.bind("rawTableName", context.getRawTableName()); - return extractionResultDao.queryUpdate(insertQueryBuiler.toString(), getQueryBindings(context.getExtraction())); + // retrieve pmfm ids from filter + List pmfmIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.PMFM); + xmlQuery.setGroup("pmfmFilter", CollectionUtils.isNotEmpty(pmfmIds)); + xmlQuery.bind("pmfmIds", Daos.getInStatementFromIntegerCollection(pmfmIds)); + return extractionResultDao.query(xmlQuery.getSQLQueryAsString(), null, (resultSet, i) -> newPmfmInfo(context, + resultSet.getInt(1), + resultSet.getBoolean(2), + resultSet.getBoolean(3))); } - private int cleanRawData(ExtractionContextDTO context, ExtractionOutputType outputType) { - - List pmfmIds = ReefDbBeans.collectProperties(context.getPmfmInfos(), ExtractionPmfmInfoDTO.PROPERTY_PMFM_ID); - List taxonNameIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.TAXON); - List taxonGroupIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.TAXON_GROUP); - - // clause for taxon / taxon group filtering - StringBuilder taxonWhereClause = new StringBuilder(); - if (CollectionUtils.isNotEmpty(taxonGroupIds)) { - taxonWhereClause.append(" OR ((TAXON_GROUP_ID NOT IN (") - .append(Daos.getInStatementFromIntegerCollection(taxonGroupIds)) - .append(") OR TAXON_GROUP_ID IS NULL) AND MEAS_INDIV_ID IS NOT NULL)"); - } - if (CollectionUtils.isNotEmpty(taxonNameIds)) { - taxonWhereClause.append(" OR (((TAXON_NAME_ID NOT IN ") - .append("(").append(Daos.getInStatementFromIntegerCollection(taxonNameIds)).append(")"); - if (outputType != ExtractionOutputType.PAMPA) { - taxonWhereClause.append(" AND INPUT_TAXON_NAME_ID NOT IN ") - .append("(").append(Daos.getInStatementFromIntegerCollection(taxonNameIds)).append(")"); - } - taxonWhereClause.append(") OR TAXON_NAME_ID IS NULL) AND MEAS_INDIV_ID IS NOT NULL)"); - } + private ExtractionPmfmInfoDTO newPmfmInfo(ExtractionContextDTO context, int pmfmId, boolean isSurvey, boolean isIndividual) { - String query = "DELETE FROM " + context.getRawTableName() - + " WHERE PMFM_ID NOT IN (" + Daos.getInStatementFromIntegerCollection(pmfmIds) + ")" - + taxonWhereClause.toString(); + ExtractionPmfmInfoDTO pmfmInfo = ReefDbBeanFactory.newExtractionPmfmInfoDTO(); + pmfmInfo.setPmfmId(pmfmId); + pmfmInfo.setSurvey(isSurvey); + pmfmInfo.setIndividual(isIndividual); - return extractionResultDao.queryUpdate(query, null); + // compute alias + String safePmfmId = pmfmInfo.getPmfmId() < 0 ? "M" : "" + pmfmInfo.getPmfmId(); + pmfmInfo.setAlias((pmfmInfo.isSurvey() ? "SU" : "SO") + (pmfmInfo.isIndividual() ? "I" : "") + safePmfmId); + // Generate pmfm table name + pmfmInfo.setTableName(String.format(PMFM_TABLE_NAME_PATTERN, context.getUniqueId(), pmfmInfo.getAlias())); + return pmfmInfo; } - private int cleanHermeticData(ExtractionContextDTO context) { - - // 1- first populate distinct programs from raw table - String query = "SELECT P.PROG_CD FROM PROGRAMME P WHERE P.IS_DEPARTMENT_HERMETIC = '1' AND P.PROG_CD IN " + - "(SELECT DISTINCT SURVEY_PROG_CD FROM " + context.getRawTableName() + ")"; - List hermeticPrograms = extractionResultDao.queryStringList(query, null); + private int cleanRawData(ExtractionContextDTO context, ExtractionOutputType outputType) { - if (CollectionUtils.isEmpty(hermeticPrograms)) { - return 0; - } + int nbRowsRemovedFromRawData = 0; - // 2- collect managed programs - int nbRemoves = 0; - Integer userId= dataContext.getRecorderPersonId(); - Assert.notNull(userId); - Integer recDepId = dataContext.getRecorderDepartmentId(); - Assert.notNull(recDepId); - Set managedProgramCodes = programStrategyService.getManagedProgramCodesByQuserId(userId); - - // 3- iterate hermetic programs and test with rec_dep_id if user is not manager - for (String hermeticProgram: hermeticPrograms) { - if (managedProgramCodes == null || !managedProgramCodes.contains(hermeticProgram)) { - query = "DELETE FROM " + context.getRawTableName() + " WHERE SURVEY_PROG_CD = '" + hermeticProgram + "' AND REC_DEP_ID != " + recDepId; - nbRemoves += extractionResultDao.queryUpdate(query, null); - } - } + // remove lines with taxon group or taxon corresponding to filters + { + XMLQuery xmlQuery = createXMLQuery("cleanTaxon"); + xmlQuery.bind("tableName", context.getRawTableName()); + // active groups depending the output type + setGroups(xmlQuery, outputType); - return nbRemoves; - } + // if a taxon or taxon group filter is defined, will remove raw line not corresponding to filter (avoid blank cells in split table) + List taxonGroupIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.TAXON_GROUP); + List taxonNameIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.TAXON); - @SuppressWarnings("StringBufferReplaceableByString") - private void insertPmfmData(ExtractionContextDTO context, ExtractionOutputType outputType) { + if (CollectionUtils.isNotEmpty(taxonGroupIds) || CollectionUtils.isNotEmpty(taxonNameIds)) { - if (!context.isPmfmInfosEmpty()) { - for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { + if (CollectionUtils.isNotEmpty(taxonGroupIds)) { + xmlQuery.setGroup("taxonGroup", true); + xmlQuery.bind("taxonGroupIds", Daos.getInStatementFromIntegerCollection(taxonGroupIds)); + } else { + xmlQuery.setGroup("taxonGroup", false); + } - StringBuilder query = new StringBuilder(); - query.append("INSERT INTO ").append(pmfmInfo.getTableName()).append(LS); - query.append("SELECT DISTINCT "); - query.append(pmfmInfo.isSurvey() ? "SURVEY_ID," : "SAMPLING_OPER_ID, "); - query.append("MEAS_ID, TAXON_MEAS_ID, IS_SURVEY_MEAS, MEAS_INDIV_ID, "); - query.append("PMFM_ID, DEP_NM, MEAS_NUMER_VALUE, QUAL_VALUE_NM, TAXON_NAME_NM, TAXON_GROUP_NM, MEAS_CM"); - query.append(outputType == ExtractionOutputType.PAMPA ? ", TAXON_PAMPA" : ", INPUT_TAXON_NAME_NM, INPUT_TAXON_NAME_ID").append(LS); - query.append("FROM ").append(context.getRawTableName()).append(LS); - query.append("WHERE PMFM_ID = ").append(pmfmInfo.getPmfmId()).append(" AND IS_SURVEY_MEAS = ").append(pmfmInfo.isSurvey() ? "1" : "0").append(" "); - query.append("AND MEAS_INDIV_ID IS ").append(pmfmInfo.isIndividual() ? "NOT " : "").append("NULL"); + if (CollectionUtils.isNotEmpty(taxonNameIds)) { + xmlQuery.setGroup("taxonName", true); + xmlQuery.bind("taxonNameIds", Daos.getInStatementFromIntegerCollection(taxonNameIds)); + } else { + xmlQuery.setGroup("taxonName", false); + } - int nbRowsInserted = extractionResultDao.queryUpdate(query.toString(), null); + int nbRemoved = execute(xmlQuery); if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s rows of pmfmu raw data inserted into %s", nbRowsInserted, pmfmInfo.getTableName())); + if (nbRemoved > 0) { + LOG.debug(String.format("%s rows removed from raw data which not corresponding to taxon and taxon group filter", nbRemoved)); + } } + nbRowsRemovedFromRawData += nbRemoved; } } - } - private int insertCommonData(ExtractionContextDTO context, ExtractionOutputType outputType) { + // remove surveys from hermetic programs if user is not allowed (Mantis #47660) + { + // Get program list from context if exists + List programCodes = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.PROGRAM); + List hermeticProgramCodes = programStrategyService.getProgramsByCodes(programCodes).stream() + .filter(ProgramDTO::isDepartmentHermetic) + .map(ProgramDTO::getCode) + .collect(Collectors.toList()); - StringBuilder query = new StringBuilder(); - query.append("INSERT INTO ").append(context.getCommonTableName()).append(LS); - query.append("SELECT DISTINCT SURVEY_ID, SURVEY_PROG_CD, MON_LOC_NM, SURVEY_DT, SAMPLING_OPER_ID, SAMPLING_OPER_LB, MON_LOC_ID, MON_LOC_LB, ORDER_ITEM_NM, "); - query.append("SURVEY_POSITION_LONG, SURVEY_POSITION_LAT, SAMPLING_EQUIPMENT_NM, SAMPLING_OPER_DEP_NM, "); - if (outputType != ExtractionOutputType.PAMPA) { - query.append("SURVEY_QUSERS, "); - } - query.append("SURVEY_LB, SAMPLING_OPER_SIZE, SAMPLING_OPER_SIZE_UNIT_SYMBOL, "); - if (outputType == ExtractionOutputType.COMPLETE) { - query.append("ORDER_ITEM_TYPE_NM, ORDER_ITEM_CD, MON_LOC_ORDER_ITEM_NUMBER, "); - query.append("SURVEY_TIME, SURVEY_CM, SURVEY_CONTROL_DT, SURVEY_VALID_DT, SURVEY_QUAL_FLAG, "); - query.append("SURVEY_QUALIF_DT, SURVEY_QUALIF_CM, SURVEY_INHERITED_POSITION, SAMPLING_OPER_TIME, "); - query.append("SAMPLING_OPER_DEPTH, SAMPLING_OPER_MIN_DEPTH, SAMPLING_OPER_MAX_DEPTH, "); - query.append("SAMPLING_OPER_INHERITED_POSITION, SAMPLING_OPER_DEPTH_UNIT_SYMBOL, SAMPLING_OPER_DEPTH_UNIT, "); - query.append("SAMPLING_OPER_CM, SAMPLING_EQUIPMENT_SIZE, SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, SAMPLING_OPER_NUMBER_INDIV, "); - query.append("SAMPLING_OPER_CONTROL_DT, SAMPLING_OPER_VALID_DT, SAMPLING_OPER_QUAL_FLAG, SAMPLING_OPER_QUALIF_DT, "); - query.append("SAMPLING_OPER_QUALIF_CM, SAMPLING_OPER_POSITION_LONG, SAMPLING_OPER_POSITION_LAT, "); - } else if (outputType == ExtractionOutputType.PAMPA) { - query.append("SAMPLING_OPER_TIME, SURVEY_BOTTOM_DEPTH, SURVEY_QUSERS, "); - } - query.append("MEAS_INDIV_ID FROM ").append(context.getRawTableName()); + if (!hermeticProgramCodes.isEmpty()) { - return extractionResultDao.queryUpdate(query.toString(), null); - } + // Collect managed programs + int nbRemoved = 0; + Integer userId = dataContext.getRecorderPersonId(); + Assert.notNull(userId); + Integer recDepId = dataContext.getRecorderDepartmentId(); + Assert.notNull(recDepId); + Set managedProgramCodes = programStrategyService.getManagedProgramCodesByQuserId(userId); - private int insertSplitData(ExtractionContextDTO context, ExtractionOutputType outputType) { + // Iterate hermetic programs and test with rec_dep_id if user is not manager + for (String hermeticProgramCode : hermeticProgramCodes) { + if (managedProgramCodes == null || !managedProgramCodes.contains(hermeticProgramCode)) { - // common part - StringBuilder insertPart = new StringBuilder(); - insertPart.append("INSERT INTO ").append(context.getSplitTableName()).append(LS); - insertPart.append("SELECT COMMON.SURVEY_ID, COMMON.SURVEY_PROG_CD, COMMON.MON_LOC_NM, COMMON.SURVEY_DT, COMMON.SAMPLING_OPER_ID, COMMON.SAMPLING_OPER_LB, COMMON.MON_LOC_ID, "); - insertPart.append("COMMON.MON_LOC_LB, COMMON.ORDER_ITEM_NM, COMMON.SURVEY_POSITION_LONG, COMMON.SURVEY_POSITION_LAT, COMMON.SAMPLING_EQUIPMENT_NM, COMMON.SAMPLING_OPER_DEP_NM, "); - if (outputType != ExtractionOutputType.PAMPA) { - insertPart.append("COMMON.SURVEY_QUSERS, "); - } - insertPart.append("COMMON.SURVEY_LB, COMMON.SAMPLING_OPER_SIZE, COMMON.SAMPLING_OPER_SIZE_UNIT_SYMBOL, "); - if (outputType == ExtractionOutputType.COMPLETE) { - insertPart.append("COMMON.ORDER_ITEM_TYPE_NM, COMMON.ORDER_ITEM_CD, COMMON.MON_LOC_ORDER_ITEM_NUMBER, "); - insertPart.append("COMMON.SURVEY_TIME, COMMON.SURVEY_CM, COMMON.SURVEY_CONTROL_DT, COMMON.SURVEY_VALID_DT, COMMON.SURVEY_QUAL_FLAG, "); - insertPart.append("COMMON.SURVEY_QUALIF_DT, COMMON.SURVEY_QUALIF_CM, COMMON.SURVEY_INHERITED_POSITION, COMMON.SAMPLING_OPER_TIME, "); - insertPart.append("COMMON.SAMPLING_OPER_DEPTH, COMMON.SAMPLING_OPER_MIN_DEPTH, COMMON.SAMPLING_OPER_MAX_DEPTH, "); - insertPart.append("COMMON.SAMPLING_OPER_INHERITED_POSITION, COMMON.SAMPLING_OPER_DEPTH_UNIT_SYMBOL, COMMON.SAMPLING_OPER_DEPTH_UNIT, "); - insertPart.append("COMMON.SAMPLING_OPER_CM, COMMON.SAMPLING_EQUIPMENT_SIZE, COMMON.SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, COMMON.SAMPLING_OPER_NUMBER_INDIV, "); - insertPart.append("COMMON.SAMPLING_OPER_CONTROL_DT, COMMON.SAMPLING_OPER_VALID_DT, COMMON.SAMPLING_OPER_QUAL_FLAG, COMMON.SAMPLING_OPER_QUALIF_DT, "); - insertPart.append("COMMON.SAMPLING_OPER_QUALIF_CM, COMMON.SAMPLING_OPER_POSITION_LONG, COMMON.SAMPLING_OPER_POSITION_LAT, "); - } else if (outputType == ExtractionOutputType.PAMPA) { - insertPart.append("COMMON.SAMPLING_OPER_TIME, COMMON.SURVEY_BOTTOM_DEPTH, COMMON.SURVEY_QUSERS, "); - } - insertPart.append("COMMON.MEAS_INDIV_ID, "); - - StringBuilder query = new StringBuilder(insertPart); - - // all pmfm part - StringBuilder join = new StringBuilder(); - if (!context.isPmfmInfosEmpty()) { - for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { - query.append(pmfmInfo.getAlias()).append(".MEAS_ID, "); - query.append(pmfmInfo.getAlias()).append(".TAXON_MEAS_ID, "); - query.append(pmfmInfo.getAlias()).append(".MEAS_NUMER_VALUE, "); - query.append(pmfmInfo.getAlias()).append(".QUAL_VALUE_NM, "); - query.append(pmfmInfo.getAlias()).append(".DEP_NM, "); - if (pmfmInfo.isIndividual()) { - query.append(pmfmInfo.getAlias()).append(".TAXON_NAME_NM, "); - query.append(pmfmInfo.getAlias()).append(".TAXON_GROUP_NM, "); - query.append(pmfmInfo.getAlias()).append(".MEAS_CM, "); - if (outputType == ExtractionOutputType.PAMPA) { - query.append(pmfmInfo.getAlias()).append(".TAXON_PAMPA, "); - } else { - query.append(pmfmInfo.getAlias()).append(".INPUT_TAXON_NAME_NM, "); - query.append(pmfmInfo.getAlias()).append(".INPUT_TAXON_NAME_ID, "); + XMLQuery xmlQuery = createXMLQuery("cleanHermeticData"); + xmlQuery.bind("tableName", context.getRawTableName()); + xmlQuery.bind("programCode", hermeticProgramCode); + xmlQuery.bind("recDepId", recDepId.toString()); + + nbRemoved += execute(xmlQuery); } } - join.append("LEFT OUTER JOIN ").append(pmfmInfo.getTableName()).append(" ").append(pmfmInfo.getAlias()).append(" ON "); - join.append(pmfmInfo.isSurvey() ? "COMMON.SURVEY_ID = " + pmfmInfo.getAlias() + ".SURVEY_ID" : "COMMON.SAMPLING_OPER_ID = " + pmfmInfo.getAlias() + ".SAMPLING_OPER_ID"); - join.append(pmfmInfo.isIndividual() ? " AND COMMON.MEAS_INDIV_ID = " + pmfmInfo.getAlias() + ".MEAS_INDIV_ID" : ""); - join.append(LS); - } - } - query = new StringBuilder(trimAtLastSequence(query.toString(), ",")).append(LS); - - // add from clause - query.append("FROM ").append(context.getCommonTableName()).append(" COMMON").append(LS); - // add all join tables - query.append(join); - // filter out non individual measurements - query.append("WHERE COMMON.MEAS_INDIV_ID IS NOT NULL"); - - int nbInsert = extractionResultDao.queryUpdate(query.toString(), null); - - // add rows from non individual measurements that are not already inserted - query = new StringBuilder(insertPart); - - // all pmfm part - // TODO maybe simplify joins : remove individual pmfms - join = new StringBuilder(); - if (!context.isPmfmInfosEmpty()) { - for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { - query.append(pmfmInfo.getAlias()).append(".MEAS_ID, "); - query.append(pmfmInfo.getAlias()).append(".TAXON_MEAS_ID, "); - query.append(pmfmInfo.getAlias()).append(".MEAS_NUMER_VALUE, "); - query.append(pmfmInfo.getAlias()).append(".QUAL_VALUE_NM, "); - query.append(pmfmInfo.getAlias()).append(".DEP_NM, "); - if (pmfmInfo.isIndividual()) { - query.append(pmfmInfo.getAlias()).append(".TAXON_NAME_NM, "); - query.append(pmfmInfo.getAlias()).append(".TAXON_GROUP_NM, "); - query.append(pmfmInfo.getAlias()).append(".MEAS_CM, "); - if (outputType == ExtractionOutputType.PAMPA) { - query.append(pmfmInfo.getAlias()).append(".TAXON_PAMPA, "); - } else { - query.append(pmfmInfo.getAlias()).append(".INPUT_TAXON_NAME_NM, "); - query.append(pmfmInfo.getAlias()).append(".INPUT_TAXON_NAME_ID, "); - } + if (LOG.isDebugEnabled() && nbRemoved > 0) { + LOG.debug(String.format("%s rows removed from raw data which not corresponding to user rights (hermetic programs)", nbRemoved)); } - join.append("LEFT OUTER JOIN ").append(pmfmInfo.getTableName()).append(" ").append(pmfmInfo.getAlias()).append(" ON "); - join.append(pmfmInfo.isSurvey() ? "COMMON.SURVEY_ID = " + pmfmInfo.getAlias() + ".SURVEY_ID" : "COMMON.SAMPLING_OPER_ID = " + pmfmInfo.getAlias() + ".SAMPLING_OPER_ID"); - join.append(pmfmInfo.isIndividual() ? " AND COMMON.MEAS_INDIV_ID = " + pmfmInfo.getAlias() + ".MEAS_INDIV_ID" : ""); - join.append(LS); + + nbRowsRemovedFromRawData += nbRemoved; } } - query = new StringBuilder(trimAtLastSequence(query.toString(), ",")).append(LS); - - // add from clause - query.append("FROM ").append(context.getCommonTableName()).append(" COMMON").append(LS); - // add all join tables - query.append(join); - // filter out already present individual measurements - query.append("WHERE COMMON.MEAS_INDIV_ID IS NULL AND NOT EXISTS (SELECT * FROM "); - query.append(context.getSplitTableName()); - query.append(" SPLIT WHERE SPLIT.SURVEY_ID = COMMON.SURVEY_ID AND SPLIT.SAMPLING_OPER_ID = COMMON.SAMPLING_OPER_ID AND SPLIT.MEAS_INDIV_ID IS NOT NULL )"); - - nbInsert += extractionResultDao.queryUpdate(query.toString(), null); - - return nbInsert; + return nbRowsRemovedFromRawData; } - private void writeExtraction(ExtractionContextDTO context, ExtractionOutputType outputType, File outputFile) throws IOException { - - Map fieldNamesByAlias = new HashMap<>(); - Map decimalFormats = new HashMap<>(); - - // taxon & taxon group fields - String taxonField = "NULL AS TAXON_NAME_NM, "; - String taxonGroupField = "NULL AS TAXON_GROUP_NM, "; - String taxonPampaField = "NULL AS TAXON_PAMPA, "; - String inputTaxonNameField = "NULL AS INPUT_TAXON_NAME_NM, "; - String inputTaxonIdField = "NULL AS INPUT_TAXON_NAME_ID, "; - String commentField = "NULL AS MEAS_CM, "; - - // get only individual pmfm info - List individualPmfmInfos = ReefDbBeans.filterCollection(context.getPmfmInfos(), ExtractionPmfmInfoDTO::isIndividual); - if (individualPmfmInfos.size() >= 2) { - - // must coalesce these fields - taxonField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "TAXON_NAME_NM") + ") AS TAXON_NAME_NM, "; - taxonGroupField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "TAXON_GROUP_NM") + ") AS TAXON_GROUP_NM, "; - if (outputType == ExtractionOutputType.PAMPA) { - taxonPampaField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "TAXON_PAMPA") + ") AS TAXON_PAMPA, "; - } else { - inputTaxonNameField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "INPUT_TAXON_NAME_NM") + ") AS INPUT_TAXON_NAME_NM, "; - inputTaxonIdField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "INPUT_TAXON_NAME_ID") + ") AS INPUT_TAXON_NAME_ID, "; + private void createPmfmTables(ExtractionContextDTO context) { + + context.getPmfmInfos().forEach(pmfmInfo -> { + XMLQuery xmlQuery = createXMLQuery("createPmfmTable"); + xmlQuery.bind("pmfmTableName", pmfmInfo.getTableName()); + xmlQuery.bind("rawTableName", context.getRawTableName()); + xmlQuery.bind("parentId", pmfmInfo.isSurvey() ? "SURVEY_ID" : "SAMPLING_OPER_ID"); + xmlQuery.bind("pmfmId", String.valueOf(pmfmInfo.getPmfmId())); + xmlQuery.bind("isSurveyMeas", pmfmInfo.isSurvey() ? "1" : "0"); + xmlQuery.bind("measIndivId", pmfmInfo.isIndividual() ? "NOT NULL" : "NULL"); + execute(xmlQuery); + if (LOG.isDebugEnabled()) { + + // Count inserted data + long nbRowsInserted = countFrom(pmfmInfo.getTableName()); + LOG.debug(String.format("%s rows of pmfm raw data inserted into %s", nbRowsInserted, pmfmInfo.getTableName())); } + }); + } - } else if (individualPmfmInfos.size() == 1) { - - // only 1 pmfm, no coalesce - ExtractionPmfmInfoDTO pmfmInfo = individualPmfmInfos.get(0); - taxonField = pmfmInfo.getAlias() + "_TAXON_NAME_NM AS TAXON_NAME_NM, "; - taxonGroupField = pmfmInfo.getAlias() + "_TAXON_GROUP_NM AS TAXON_GROUP_NM, "; - if (outputType == ExtractionOutputType.PAMPA) { - taxonPampaField = pmfmInfo.getAlias() + "_TAXON_PAMPA AS TAXON_PAMPA, "; - } else { - inputTaxonNameField = pmfmInfo.getAlias() + "_INPUT_TAXON_NAME_NM AS INPUT_TAXON_NAME_NM, "; - inputTaxonIdField = pmfmInfo.getAlias() + "_INPUT_TAXON_NAME_ID AS INPUT_TAXON_NAME_ID, "; - } - - } - - // use concat distinct function for comments - // Mantis #35443 : don't call the function when no individual pmfm infos - if (!individualPmfmInfos.isEmpty()) { - commentField = getConcatDistinctFunction("MEAS_CM") + "(ARRAY[" + getAliasedFields(individualPmfmInfos, "MEAS_CM") + "], ' - ') AS MEAS_CM, "; - } - - // measurements (individual first) - StringBuilder measurementFields = new StringBuilder(); - String departmentField = "NULL AS MEAS_DEP_NM, "; - String measIds = "NULL AS MEAS_IDS, "; - String taxonMeasIds = "NULL AS TAXON_MEAS_IDS, "; - - if (!context.isPmfmInfosEmpty()) { - - DecoratorService decoratorService = ReefDbServiceLocator.instance().getDecoratorService(); - - // Sort by individual measurements first - List sortedPmfmInfos = sortPmfmInfos(context.getPmfmInfos()); - for (ExtractionPmfmInfoDTO pmfmInfo : sortedPmfmInfos) { - - // decorate the PMFM to obtain field name - PmfmDTO pmfm = pmfmDao.getPmfmById(pmfmInfo.getPmfmId()); - String pmfmName = decoratorService.getDecoratorByType(PmfmDTO.class, DecoratorService.FOR_EXTRACTION).toString(pmfm); - - // add prefix - String formattedPmfmName = String.format("%s_%s", - pmfmInfo.isSurvey() ? t("reefdb.service.extraction.fieldNamePrefix.SURVEY") : t("reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER"), - pmfmName); + private void createCommonTable(ExtractionContextDTO context, ExtractionOutputType outputType) { - measurementFields.append(pmfmInfo.getAlias()); - // get the correct value depending on parameter type - measurementFields.append(pmfm.getParameter().isQualitative() ? "_QUAL_VALUE_NM" : "_MEAS_NUMER_VALUE"); - measurementFields.append(" AS ").append(pmfmInfo.getAlias()).append("_VALUE, "); + XMLQuery xmlQuery = createXMLQuery("createCommonTable"); + xmlQuery.bind("commonTableName", context.getCommonTableName()); + xmlQuery.bind("rawTableName", context.getRawTableName()); - fieldNamesByAlias.put(pmfmInfo.getAlias() + "_VALUE", formattedPmfmName); - } + // Active groups depending the output type + setGroups(xmlQuery, outputType); - // use concat_distinct for measIds & taxonMeasIds - measIds = getConcatDistinctFunction("MEAS_ID") + "(ARRAY[" + getAliasedFields(sortedPmfmInfos, "MEAS_ID") + "], '|') AS MEAS_IDS, "; - taxonMeasIds = getConcatDistinctFunction("MEAS_ID") + "(ARRAY[" + getAliasedFields(sortedPmfmInfos, "TAXON_MEAS_ID") + "], '|') AS TAXON_MEAS_IDS, "; + execute(xmlQuery); - // must use concat_distinct function for this field - departmentField = getConcatDistinctFunction("DEP_NM") + "(ARRAY[" + getAliasedFields(sortedPmfmInfos, "DEP_NM") + "], ',') AS MEAS_DEP_NM, "; + if (LOG.isDebugEnabled()) { + // Count inserted data + long nbRowsInserted = countFrom(context.getCommonTableName()); + LOG.debug(String.format("%s rows of common data inserted into %s", nbRowsInserted, context.getCommonTableName())); } - // common field names - fieldNamesByAlias.put("SURVEY_PROG_CD", t("reefdb.service.extraction.fieldName.SURVEY_PROG_CD")); - fieldNamesByAlias.put("MON_LOC_NM", t("reefdb.service.extraction.fieldName.MON_LOC_NM")); - fieldNamesByAlias.put("SURVEY_DT", t("reefdb.service.extraction.fieldName.SURVEY_DT")); - fieldNamesByAlias.put("SAMPLING_OPER_LB", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_LB")); - fieldNamesByAlias.put("MON_LOC_ID", t("reefdb.service.extraction.fieldName.MON_LOC_ID")); - fieldNamesByAlias.put("MON_LOC_LB", t("reefdb.service.extraction.fieldName.MON_LOC_LB")); - fieldNamesByAlias.put("ORDER_ITEM_NM", t("reefdb.service.extraction.fieldName.ORDER_ITEM_NM")); - fieldNamesByAlias.put("SURVEY_POSITION_LONG_MIN", t("reefdb.service.extraction.fieldName.SURVEY_POSITION_LONG_MIN")); - fieldNamesByAlias.put("SURVEY_POSITION_LONG_MAX", t("reefdb.service.extraction.fieldName.SURVEY_POSITION_LONG_MAX")); - fieldNamesByAlias.put("SURVEY_POSITION_LAT_MIN", t("reefdb.service.extraction.fieldName.SURVEY_POSITION_LAT_MIN")); - fieldNamesByAlias.put("SURVEY_POSITION_LAT_MAX", t("reefdb.service.extraction.fieldName.SURVEY_POSITION_LAT_MAX")); - fieldNamesByAlias.put("SAMPLING_EQUIPMENT_NM", t("reefdb.service.extraction.fieldName.SAMPLING_EQUIPMENT_NM")); - fieldNamesByAlias.put("SAMPLING_OPER_DEP_NM", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_DEP_NM")); - fieldNamesByAlias.put("SURVEY_QUSERS", t("reefdb.service.extraction.fieldName.SURVEY_QUSERS")); - fieldNamesByAlias.put("SURVEY_LB", t("reefdb.service.extraction.fieldName.SURVEY_LB")); - fieldNamesByAlias.put("SAMPLING_OPER_SIZE", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_SIZE")); - fieldNamesByAlias.put("SAMPLING_OPER_SIZE_UNIT_SYMBOL", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_SIZE_UNIT_SYMBOL")); - fieldNamesByAlias.put("TAXON_NAME_NM", t("reefdb.service.extraction.fieldName.TAXON_NAME_NM")); - fieldNamesByAlias.put("INPUT_TAXON_NAME_NM", t("reefdb.service.extraction.fieldName.INPUT_TAXON_NAME_NM")); - fieldNamesByAlias.put("INPUT_TAXON_NAME_ID", t("reefdb.service.extraction.fieldName.INPUT_TAXON_NAME_ID")); - fieldNamesByAlias.put("TAXON_GROUP_NM", t("reefdb.service.extraction.fieldName.TAXON_GROUP_NM")); - fieldNamesByAlias.put("MEAS_CM", t("reefdb.service.extraction.fieldName.MEAS_CM")); - fieldNamesByAlias.put("MEAS_DEP_NM", t("reefdb.service.extraction.fieldName.MEAS_DEP_NM")); - fieldNamesByAlias.put("MEAS_IDS", t("reefdb.service.extraction.fieldName.MEAS_IDS")); - fieldNamesByAlias.put("TAXON_MEAS_IDS", t("reefdb.service.extraction.fieldName.TAXON_MEAS_IDS")); - - // the final query - StringBuilder query = new StringBuilder(); - query.append("SELECT SURVEY_PROG_CD, MON_LOC_NM, SURVEY_DT, SAMPLING_OPER_LB, "); - query.append(taxonField); - query.append(taxonGroupField); - query.append(measurementFields); - query.append(departmentField); - query.append("MON_LOC_ID, MON_LOC_LB, ORDER_ITEM_NM, SURVEY_POSITION_LONG AS SURVEY_POSITION_LONG_MIN, SURVEY_POSITION_LONG AS SURVEY_POSITION_LONG_MAX, "); - query.append("SURVEY_POSITION_LAT AS SURVEY_POSITION_LAT_MIN, SURVEY_POSITION_LAT AS SURVEY_POSITION_LAT_MAX, SAMPLING_EQUIPMENT_NM, SAMPLING_OPER_DEP_NM, "); - if (outputType != ExtractionOutputType.PAMPA) { - query.append("SURVEY_QUSERS, "); - } - query.append("SURVEY_LB, SAMPLING_OPER_SIZE, SAMPLING_OPER_SIZE_UNIT_SYMBOL, "); - query.append(commentField); + } - // Adaptation for PAMPA (see Mantis #32080) - if (outputType == ExtractionOutputType.PAMPA) { - query.append("SAMPLING_OPER_ID, TO_CHAR(TIMESTAMP(SAMPLING_OPER_TIME), 'HH24:MI:SS') AS SAMPLING_OPER_TIME, SURVEY_BOTTOM_DEPTH, SURVEY_QUSERS, "); - query.append(taxonPampaField); + private long createResultTable(ExtractionContextDTO context, + ExtractionOutputType outputType, + Map fieldNamesByAlias, + Map decimalFormats, + Map dateFormats) { + + XMLQuery xmlQuery = createXMLQuery("createResultTable"); + xmlQuery.bind("resultTableName", context.getResultTableName()); + xmlQuery.bind("commonTableName", context.getCommonTableName()); + xmlQuery.bind("baseTableName", context.getBaseTableName()); + + // Active groups depending the output type + setGroups(xmlQuery, outputType); + + Collection pmfmInfos = context.getPmfmInfos(); + + Predicate surveyMeasurementPredicate = pmfmInfo -> pmfmInfo.isSurvey() && !pmfmInfo.isIndividual(); + Predicate samplingMeasurementPredicate = pmfmInfo -> !pmfmInfo.isSurvey() && !pmfmInfo.isIndividual(); + Predicate surveyIndividualMeasurementPredicate = pmfmInfo -> pmfmInfo.isSurvey() && pmfmInfo.isIndividual(); + Predicate samplingIndividualMeasurementPredicate = pmfmInfo -> !pmfmInfo.isSurvey() && pmfmInfo.isIndividual(); + + // Active measurement groups + xmlQuery.setGroup(getInjectionName(true, false), pmfmInfos.stream().anyMatch(surveyMeasurementPredicate)); + xmlQuery.setGroup(getInjectionName(false, false), pmfmInfos.stream().anyMatch(samplingMeasurementPredicate)); + xmlQuery.setGroup(getInjectionName(true, true), pmfmInfos.stream().anyMatch(surveyIndividualMeasurementPredicate)); + xmlQuery.setGroup(getInjectionName(false, true), pmfmInfos.stream().anyMatch(samplingIndividualMeasurementPredicate)); + + // Add all measurements + pmfmInfos.forEach(pmfmInfo -> { + + PmfmDTO pmfm = pmfmDao.getPmfmById(pmfmInfo.getPmfmId()); + + // Add injection query for pmfm table (replacing all bindings by the pmfm alias) + xmlQuery.injectQuery(getXMLQueryFile("injectionPmfm"), "PMFM_ALIAS", pmfmInfo.getAlias(), getInjectionName(pmfmInfo)); + + // Bind table names + xmlQuery.bind(pmfmInfo.getAlias() + "_pmfmTableName", pmfmInfo.getTableName()); + + // Active value + xmlQuery.setGroup(pmfmInfo.getAlias() + "_numerical_without_zero", !pmfm.getParameter().isQualitative()); + xmlQuery.setGroup(pmfmInfo.getAlias() + "_numerical_with_zero", false); + xmlQuery.setGroup(pmfmInfo.getAlias() + "_qualitative", pmfm.getParameter().isQualitative()); + + // Active join link + xmlQuery.setGroup(pmfmInfo.getAlias() + "_surveyJoin", surveyMeasurementPredicate.test(pmfmInfo)); + xmlQuery.setGroup(pmfmInfo.getAlias() + "_samplingOperationJoin", samplingMeasurementPredicate.test(pmfmInfo)); + xmlQuery.setGroup(pmfmInfo.getAlias() + "_surveyJoin_individual", surveyIndividualMeasurementPredicate.test(pmfmInfo)); + xmlQuery.setGroup(pmfmInfo.getAlias() + "_samplingOperationJoin_individual", samplingIndividualMeasurementPredicate.test(pmfmInfo)); + + // Build output name using transcribing (see Mantis #50725) + String unitName = extractionResultDao.getPmfmUnitNameForExtraction(pmfm); + String pmfmName = String.format("%s%s", extractionResultDao.getPmfmNameForExtraction(pmfm), StringUtils.isNotBlank(unitName) ? "-" + unitName : ""); + String formattedPmfmName = String.format("%s_%s", + pmfmInfo.isSurvey() ? t("reefdb.service.extraction.fieldNamePrefix.SURVEY") : t("reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER"), + pmfmName); + fieldNamesByAlias.put(pmfmInfo.getAlias(), ReefDbBeans.toFullySecuredString(formattedPmfmName)); + + // Build number format + if (!pmfm.getParameter().isQualitative()) { + decimalFormats.put(pmfmInfo.getAlias(), getNumericFormat(pmfm)); + } + }); - fieldNamesByAlias.put("SAMPLING_OPER_ID", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_ID")); - fieldNamesByAlias.put("SAMPLING_OPER_TIME", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_TIME")); - fieldNamesByAlias.put("SURVEY_BOTTOM_DEPTH", t("reefdb.service.extraction.fieldName.SURVEY_BOTTOM_DEPTH")); - decimalFormats.put("SURVEY_BOTTOM_DEPTH", getDefaultNumericFormat()); - fieldNamesByAlias.put("TAXON_PAMPA", t("reefdb.service.extraction.fieldName.TAXON_PAMPA")); + // Add analyst from measurements + xmlQuery.bind("depNmFields", getAliasedFields(pmfmInfos, "DEP_NM")); - } else { + // Add measurement comment + xmlQuery.bind("measCmFields", getAliasedFields(pmfmInfos, "MEAS_CM")); - // Add input taxon - query.append(inputTaxonNameField); - query.append(inputTaxonIdField); + // add measurement quality flags + xmlQuery.bind("measQualFlagFields", getAliasedFields(pmfmInfos, "MEAS_QUAL_FLAG_NM")); - // Add measId and taxonMeasId for other output types - query.append(measIds).append(taxonMeasIds); - } + // add measurement qualification dates + xmlQuery.bind("measQualifDtFields", getAliasedFields(pmfmInfos, "MEAS_QUALIF_DT")); - if (outputType == ExtractionOutputType.COMPLETE) { - query.append("ORDER_ITEM_TYPE_NM, ORDER_ITEM_CD, MON_LOC_ORDER_ITEM_NUMBER, "); - query.append("TO_CHAR(TIMESTAMP(SURVEY_TIME), 'HH24:MI:SS') AS SURVEY_TIME, SURVEY_CM, SURVEY_CONTROL_DT, SURVEY_VALID_DT, SURVEY_QUAL_FLAG, "); - query.append("SURVEY_QUALIF_DT, SURVEY_QUALIF_CM, SURVEY_INHERITED_POSITION, TO_CHAR(TIMESTAMP(SAMPLING_OPER_TIME), 'HH24:MI:SS') AS SAMPLING_OPER_TIME, "); - query.append("SAMPLING_OPER_DEPTH, SAMPLING_OPER_MIN_DEPTH, SAMPLING_OPER_MAX_DEPTH, "); - query.append("SAMPLING_OPER_INHERITED_POSITION, SAMPLING_OPER_DEPTH_UNIT_SYMBOL, SAMPLING_OPER_DEPTH_UNIT, "); - query.append("SAMPLING_OPER_CM, SAMPLING_EQUIPMENT_SIZE, SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, SAMPLING_OPER_NUMBER_INDIV, "); - query.append("SAMPLING_OPER_CONTROL_DT, SAMPLING_OPER_VALID_DT, SAMPLING_OPER_QUAL_FLAG, SAMPLING_OPER_QUALIF_DT, "); - query.append("SAMPLING_OPER_QUALIF_CM, SAMPLING_OPER_POSITION_LONG AS SAMPLING_OPER_POSITION_LONG_MIN, SAMPLING_OPER_POSITION_LONG AS SAMPLING_OPER_POSITION_LONG_MAX, "); - query.append("SAMPLING_OPER_POSITION_LAT AS SAMPLING_OPER_POSITION_LAT_MIN, SAMPLING_OPER_POSITION_LAT AS SAMPLING_OPER_POSITION_LAT_MAX, MEAS_INDIV_ID, "); - - fieldNamesByAlias.put("ORDER_ITEM_TYPE_NM", t("reefdb.service.extraction.fieldName.ORDER_ITEM_TYPE_NM")); - fieldNamesByAlias.put("ORDER_ITEM_CD", t("reefdb.service.extraction.fieldName.ORDER_ITEM_CD")); - fieldNamesByAlias.put("MON_LOC_ORDER_ITEM_NUMBER", t("reefdb.service.extraction.fieldName.MON_LOC_ORDER_ITEM_NUMBER")); - fieldNamesByAlias.put("SURVEY_TIME", t("reefdb.service.extraction.fieldName.SURVEY_TIME")); - fieldNamesByAlias.put("SURVEY_CM", t("reefdb.service.extraction.fieldName.SURVEY_CM")); - fieldNamesByAlias.put("SURVEY_CONTROL_DT", t("reefdb.service.extraction.fieldName.SURVEY_CONTROL_DT")); - fieldNamesByAlias.put("SURVEY_VALID_DT", t("reefdb.service.extraction.fieldName.SURVEY_VALID_DT")); - fieldNamesByAlias.put("SURVEY_QUAL_FLAG", t("reefdb.service.extraction.fieldName.SURVEY_QUAL_FLAG")); - fieldNamesByAlias.put("SURVEY_QUALIF_DT", t("reefdb.service.extraction.fieldName.SURVEY_QUALIF_DT")); - fieldNamesByAlias.put("SURVEY_QUALIF_CM", t("reefdb.service.extraction.fieldName.SURVEY_QUALIF_CM")); - fieldNamesByAlias.put("SURVEY_INHERITED_POSITION", t("reefdb.service.extraction.fieldName.SURVEY_INHERITED_POSITION")); - fieldNamesByAlias.put("SAMPLING_OPER_TIME", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_TIME")); - fieldNamesByAlias.put("SAMPLING_OPER_DEPTH", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_DEPTH")); - fieldNamesByAlias.put("SAMPLING_OPER_MIN_DEPTH", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_MIN_DEPTH")); - fieldNamesByAlias.put("SAMPLING_OPER_MAX_DEPTH", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_MAX_DEPTH")); - fieldNamesByAlias.put("SAMPLING_OPER_INHERITED_POSITION", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_INHERITED_POSITION")); - fieldNamesByAlias.put("SAMPLING_OPER_DEPTH_UNIT_SYMBOL", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_DEPTH_UNIT_SYMBOL")); - fieldNamesByAlias.put("SAMPLING_OPER_DEPTH_UNIT", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_DEPTH_UNIT")); - fieldNamesByAlias.put("SAMPLING_OPER_CM", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_CM")); - fieldNamesByAlias.put("SAMPLING_EQUIPMENT_SIZE", t("reefdb.service.extraction.fieldName.SAMPLING_EQUIPMENT_SIZE")); - fieldNamesByAlias.put("SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL", t("reefdb.service.extraction.fieldName.SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL")); - fieldNamesByAlias.put("SAMPLING_OPER_NUMBER_INDIV", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_NUMBER_INDIV")); - fieldNamesByAlias.put("SAMPLING_OPER_CONTROL_DT", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_CONTROL_DT")); - fieldNamesByAlias.put("SAMPLING_OPER_VALID_DT", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_VALID_DT")); - fieldNamesByAlias.put("SAMPLING_OPER_QUAL_FLAG", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_QUAL_FLAG")); - fieldNamesByAlias.put("SAMPLING_OPER_QUALIF_DT", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_QUALIF_DT")); - fieldNamesByAlias.put("SAMPLING_OPER_QUALIF_CM", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_QUALIF_CM")); - fieldNamesByAlias.put("SAMPLING_OPER_POSITION_LONG_MIN", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LONG_MIN")); - fieldNamesByAlias.put("SAMPLING_OPER_POSITION_LONG_MAX", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LONG_MAX")); - fieldNamesByAlias.put("SAMPLING_OPER_POSITION_LAT_MIN", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LAT_MIN")); - fieldNamesByAlias.put("SAMPLING_OPER_POSITION_LAT_MAX", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LAT_MAX")); - fieldNamesByAlias.put("MEAS_INDIV_ID", t("reefdb.service.extraction.fieldName.MEAS_INDIV_ID")); - } + // add measurement qualification comments + xmlQuery.bind("measQualifCmFields", getAliasedFields(pmfmInfos, "MEAS_QUALIF_CM")); - // remove last comma - query = new StringBuilder(trimAtLastSequence(query.toString(), ",")).append(LS); + // add measurement and taxon measurement ids + xmlQuery.bind("measIdFields", getAliasedFields(pmfmInfos, "MEAS_ID")); + xmlQuery.bind("taxonMeasIdFields", getAliasedFields(pmfmInfos, "TAXON_MEAS_ID")); - // add ordering clause - query.append("FROM "); - query.append(context.getSplitTableName()); - query.append(" ORDER BY SURVEY_PROG_CD, MON_LOC_NM, SURVEY_DT, SAMPLING_OPER_LB, MEAS_INDIV_ID"); + prepare(xmlQuery, fieldNamesByAlias, decimalFormats, dateFormats); - // some field formats - Map dateFormats = Maps.newHashMap(); - dateFormats.put("SURVEY_DT", "dd/MM/yyyy"); + execute(xmlQuery); - // write result - extractionResultDao.dumpQueryToCSV(outputFile, query.toString(), fieldNamesByAlias, dateFormats, decimalFormats, null); + return countFrom(context.getResultTableName()); + } + private String getInjectionName(ExtractionPmfmInfoDTO pmfmInfo) { + return getInjectionName(pmfmInfo.isSurvey(), pmfmInfo.isIndividual()); } - private List sortPmfmInfos(Collection pmfmInfos) { + private String getInjectionName(boolean isSurvey, boolean isIndividual) { + return String.format("%s%sMeasurements", isSurvey ? "survey" : "sampling", isIndividual ? "Individual" : "" + ); + } - List sorted = new ArrayList<>(pmfmInfos); + private void writeExtraction(ExtractionContextDTO context, ExtractionOutputType outputType, + Map fieldNamesByAlias, + Map decimalFormats, + Map dateFormats, + File outputFile) + throws IOException { - sorted.sort((o1, o2) -> { - // individual first - int individualFirst = -Boolean.compare(o1.isIndividual(), o2.isIndividual()); - if (individualFirst == 0) { - // then sampling operation first - return Boolean.compare(o1.isSurvey(), o2.isSurvey()); - } - return individualFirst; - }); + XMLQuery xmlQuery = createXMLQuery("selectResultTable"); + xmlQuery.bind("resultTableName", context.getResultTableName()); - return sorted; - } + // Ignore some Fields + List fieldsToIgnore = new ArrayList<>(); + fieldsToIgnore.add("SURVEY_ID"); + if (outputType != ExtractionOutputType.PAMPA) + fieldsToIgnore.add("SAMPLING_OPER_ID"); + if (outputType != ExtractionOutputType.COMPLETE) + fieldsToIgnore.add("MEAS_INDIV_ID"); - private String getAliasedFields(List pmfmInfos, final String fieldName) { + prepare(xmlQuery, fieldNamesByAlias, decimalFormats, dateFormats); - return Joiner.on(',').join(ReefDbBeans.transformCollection(pmfmInfos, pmfmInfo -> pmfmInfo.getAlias() + "_" + fieldName)); + // write result + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("write result into file : %s", outputFile.getAbsolutePath())); + } + extractionResultDao.dumpQueryToCSV(outputFile, xmlQuery.getSQLQueryAsString(), fieldNamesByAlias, dateFormats, decimalFormats, fieldsToIgnore); } - private Map getQueryBindings(ExtractionDTO extraction) { - Map bindings = new HashedMap<>(); - FilterDTO periodFilter = getPeriodFilter(extraction); - for (int i = 0; i < periodFilter.getElements().size(); i++) { - ExtractionPeriodDTO period = (ExtractionPeriodDTO) periodFilter.getElements().get(i); - bindings.put(EXTRACTION_START_DATE + i, Dates.convertToDate(period.getStartDate(), config.getDbTimezone())); - bindings.put(EXTRACTION_END_DATE + i, Dates.convertToDate(period.getEndDate(), config.getDbTimezone())); + private void setGroups(XMLQuery xmlQuery, ExtractionOutputType outputType) { + for (ExtractionOutputType type : ExtractionOutputType.values()) { + xmlQuery.setGroup(type.name().toLowerCase(), type == outputType); } - return bindings; } - private String getFromClauseMinimal() { - - // generate the minimal from clause - return "FROM SURVEY S" + LS + - "INNER JOIN MONITORING_LOCATION ML ON ML.MON_LOC_ID = S.MON_LOC_ID" + LS + - "INNER JOIN SURVEY_PROG PROG ON PROG.SURVEY_ID = S.SURVEY_ID" + LS; - } + private void createConcatDistinctFunction(String functionName, String valueType) { - private String getWhereClause(ExtractionDTO extraction) { + dropConcatDistinctFunction(functionName); - // generate the main WHERE clause - StringBuilder whereClause = new StringBuilder("WHERE ("); - for (int i = 0; i < getPeriodFilter(extraction).getElements().size(); i++) { - whereClause.append("(S.SURVEY_DT >= :" + EXTRACTION_START_DATE).append(i); - whereClause.append(" AND S.SURVEY_DT <= :").append(EXTRACTION_END_DATE).append(i).append(") OR "); - } - whereClause = new StringBuilder(trimAtLastSequence(whereClause.toString(), " OR")).append(")").append(LS); + // new function with external java method + String query = "CREATE FUNCTION CONCAT_DISTINCT_" + functionName + "(IN_ARRAY " + valueType + " ARRAY, SEPARATOR VARCHAR(10)) RETURNS LONGVARCHAR" + LS + + "LANGUAGE JAVA DETERMINISTIC NO SQL EXTERNAL NAME 'CLASSPATH:fr.ifremer.reefdb.dto.ReefDbBeans.getUnifiedSQLString';"; - List programCodes = ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.PROGRAM); - if (CollectionUtils.isNotEmpty(programCodes)) { - whereClause.append("AND PROG.PROG_CD IN (").append(Daos.getInStatementFromStringCollection(programCodes)).append(")").append(LS); - } + extractionResultDao.queryUpdate(query, null); - List locationIds = ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.LOCATION); - if (CollectionUtils.isNotEmpty(locationIds)) { - whereClause.append("AND S.MON_LOC_ID IN (").append(Daos.getInStatementFromIntegerCollection(locationIds)).append(")").append(LS); - } + } - List departmentIds = ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.DEPARTMENT); - if (CollectionUtils.isNotEmpty(departmentIds)) { - whereClause.append("AND S.REC_DEP_ID IN (").append(Daos.getInStatementFromIntegerCollection(departmentIds)).append(")").append(LS); - } + private void dropConcatDistinctFunction(String functionName) { - return whereClause.toString(); + extractionResultDao.queryUpdate("DROP FUNCTION CONCAT_DISTINCT_" + functionName + " IF EXISTS", null); } - private String trimAtLastSequence(String string, String sequence) { - return string.substring(0, string.lastIndexOf(sequence)); + private String getAliasedFields(Collection pmfmInfos, final String fieldName) { + return pmfmInfos.isEmpty() + ? "NULL" + : pmfmInfos.stream().map(pmfmInfo -> String.format("%s.%s", pmfmInfo.getAlias(), fieldName)).collect(Collectors.joining(",")); } private FilterDTO getPeriodFilter(ExtractionDTO extraction) { @@ -1302,8 +697,62 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService { return groupingType.getCode(); } + private String getNumericFormat(PmfmDTO pmfm) { + + // fixme: the pmfm definition is incomplete + return getDefaultNumericFormat(); + +// if (pmfm.getMaxDecimals() == null) { +// return getDefaultNumericFormat(); +// } +// +// // format with max decimals from pmfm definition (decimal 0 is appended) +// return "#." + StringUtils.repeat("0", pmfm.getMaxDecimals()); + } + private String getDefaultNumericFormat() { return "#." + StringUtils.repeat("#", 8); // 8 decimals should be enough by default (decimal 0 is erased) } + private XMLQuery createXMLQuery(String queryName) { + XMLQuery query = ReefDbServiceLocator.instance().getService("XMLQuery", XMLQuery.class); + query.setQuery(getXMLQueryFile(queryName)); + return query; + } + + private URL getXMLQueryFile(String queryName) { + URL fileURL = getClass().getClassLoader().getResource(XML_QUERY_PATH + "/" + queryName + ".xml"); + if (fileURL == null) + throw new ReefDbTechnicalException(String.format("query '%s' not found in resources", queryName)); + return fileURL; + } + + private void prepare(XMLQuery xmlQuery, Map fieldNamesByAlias, Map decimalFormats, Map dateFormats) { + + xmlQuery.getFirstQueryTag().getChildren(XMLQuery.TAG_SELECT).forEach(select -> { + + // Compute alias i18n key + String alias = select.getAttributeValue(XMLQuery.ATTR_ALIAS); + fieldNamesByAlias.putIfAbsent(alias, t("reefdb.service.extraction.fieldName." + alias)); + + String type = select.getAttributeValue(XMLQuery.ATTR_TYPE); + if (XMLQuery.TYPE_DATE.equalsIgnoreCase(type)) { + dateFormats.putIfAbsent(alias, "dd/MM/yyyy"); + } else if (XMLQuery.TYPE_NUMBER.equalsIgnoreCase(type)) { + decimalFormats.putIfAbsent(alias, getDefaultNumericFormat()); + } + + }); + } + + private int execute(XMLQuery xmlQuery) { + return extractionResultDao.queryUpdate(xmlQuery.getSQLQueryAsString()); + } + + private long countFrom(String tableName) { + XMLQuery xmlQuery = createXMLQuery("countFrom"); + xmlQuery.bind("tableName", tableName); + return extractionResultDao.queryCount(xmlQuery.getSQLQueryAsString()); + } + } diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceOldImpl.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceOldImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..481a48003ae9527857aed65cc6af8459fc2705cb --- /dev/null +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceOldImpl.java @@ -0,0 +1,1310 @@ +package fr.ifremer.reefdb.service.extraction; + +/*- + * #%L + * Reef DB :: Core + * %% + * Copyright (C) 2014 - 2019 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ +import com.google.common.base.Joiner; +import com.google.common.collect.Maps; +import fr.ifremer.quadrige3.core.ProgressionCoreModel; +import fr.ifremer.quadrige3.core.dao.technical.Assert; +import fr.ifremer.quadrige3.core.dao.technical.Dates; +import fr.ifremer.reefdb.config.ReefDbConfiguration; +import fr.ifremer.reefdb.dao.referential.pmfm.ReefDbPmfmDao; +import fr.ifremer.reefdb.dao.system.extraction.ReefDbExtractionResultDao; +import fr.ifremer.reefdb.dao.technical.Daos; +import fr.ifremer.reefdb.decorator.DecoratorService; +import fr.ifremer.reefdb.dto.ReefDbBeanFactory; +import fr.ifremer.reefdb.dto.ReefDbBeans; +import fr.ifremer.reefdb.dto.configuration.filter.FilterDTO; +import fr.ifremer.reefdb.dto.enums.ExtractionFilterValues; +import fr.ifremer.reefdb.dto.enums.ExtractionOutputType; +import fr.ifremer.reefdb.dto.referential.GroupingTypeDTO; +import fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO; +import fr.ifremer.reefdb.dto.system.extraction.ExtractionContextDTO; +import fr.ifremer.reefdb.dto.system.extraction.ExtractionDTO; +import fr.ifremer.reefdb.dto.system.extraction.ExtractionPeriodDTO; +import fr.ifremer.reefdb.dto.system.extraction.ExtractionPmfmInfoDTO; +import fr.ifremer.reefdb.service.ReefDbBusinessException; +import fr.ifremer.reefdb.service.ReefDbDataContext; +import fr.ifremer.reefdb.service.ReefDbServiceLocator; +import fr.ifremer.reefdb.service.ReefDbTechnicalException; +import fr.ifremer.reefdb.service.administration.program.ProgramStrategyService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.map.HashedMap; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.File; +import java.io.IOException; +import java.util.*; + +import static org.nuiton.i18n.I18n.t; + +/** + * @author peck7 on 14/05/2019. + */ +@Service("reefdbExtractionPerformServiceOld") +@Deprecated +public class ExtractionPerformServiceOldImpl implements ExtractionPerformService { + + private static final Log LOG = LogFactory.getLog(ExtractionPerformServiceOldImpl.class); + + private static final String EXTRACTION_START_DATE = "EXTRACTION_START_DATE"; + private static final String EXTRACTION_END_DATE = "EXTRACTION_END_DATE"; + + private static final String RAW_TABLE_NAME_PATTERN = "R%s"; + private static final String COMMON_TABLE_NAME_PATTERN = "C%s"; + private static final String SPLIT_TABLE_NAME_PATTERN = "S%s"; + private static final String PMFM_TABLE_NAME_PATTERN = "P%s_%s"; + + private static final String LS = System.lineSeparator(); + + @Resource + protected ReefDbConfiguration config; + + @Resource(name = "reefdbDataContext") + protected ReefDbDataContext dataContext; + + @Resource(name = "reefdbProgramStrategyService") + protected ProgramStrategyService programStrategyService; + + @Resource(name = "reefdbExtractionService") + protected ExtractionService extractionService; + + @Resource(name = "reefDbExtractionResultDao") + protected ReefDbExtractionResultDao extractionResultDao; + + @Resource(name = "reefDbPmfmDao") + protected ReefDbPmfmDao pmfmDao; + + @Override + public void performExtraction(ExtractionDTO extraction, ExtractionOutputType outputType, File outputFile, ProgressionCoreModel progressionModel) { + Assert.notNull(extraction); + Assert.notNull(extraction.getId()); + Assert.notEmpty(extraction.getFilters()); + Assert.notNull(ReefDbBeans.getFilterOfType(extraction, ExtractionFilterValues.PERIOD)); + Assert.notNull(ReefDbBeans.getFilterOfType(extraction, ExtractionFilterValues.ORDER_ITEM_TYPE)); + Assert.notNull(outputType); + Assert.notNull(outputFile); + + // ensure all filters are loaded + extractionService.loadFilteredElements(extraction); + progressionModel.setMessage(""); + progressionModel.setTotal(9); + + if (LOG.isInfoEnabled()) { + LOG.info(String.format("Beginning a %s extraction (id=%s) with:", outputType, extraction.getId())); + LOG.info(String.format("\t date ranges: %s", ReefDbBeans.toString(getPeriodFilter(extraction).getElements()))); + LOG.info(String.format("\tgeo grouping: %s", ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.ORDER_ITEM_TYPE))); + LOG.info(String.format("\t programs: %s", ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.PROGRAM))); + LOG.info(String.format("\t locations: %s", ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.LOCATION))); + LOG.info(String.format("\t departments: %s", ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.DEPARTMENT))); + LOG.info(String.format("\t taxons: %s", ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.TAXON))); + LOG.info(String.format("\ttaxon groups: %s", ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.TAXON_GROUP))); + LOG.info(String.format("\t pmfmu: %s", ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.PMFM))); + } + + try { + try { + + // count root data to extract + Long count = countRootData(extraction); + progressionModel.increments(1); + + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s surveys have to be extract", count)); + } + if (count == 0) { + throw new ReefDbBusinessException(t("reefdb.service.extraction.noData.error")); + } + + // create the concat functions used to concat distinct strings (ex: DEP_NM) + createConcatDistinctFunction("MEAS_CM", "VARCHAR(2000)"/*, " - "*/); + createConcatDistinctFunction("DEP_NM", "VARCHAR(255)"/*, ","*/); + createConcatDistinctFunction("MEAS_ID", "INTEGER"/*, "|"*/); + + // Extraction context + ExtractionContextDTO context = ReefDbBeanFactory.newExtractionContextDTO(); + context.setExtraction(extraction); + context.setUniqueId(System.currentTimeMillis()); + context.setRawTableName(String.format(RAW_TABLE_NAME_PATTERN, context.getUniqueId())); + context.setCommonTableName(String.format(COMMON_TABLE_NAME_PATTERN, context.getUniqueId())); + context.setResultTableName(String.format(SPLIT_TABLE_NAME_PATTERN, context.getUniqueId())); + + // create the first temp table + createRawTable(context, outputType); + + // insert raw data in temp table + int nbRowsInserted = insertRawData(context, outputType); + progressionModel.increments(1); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s rows of raw data inserted into %s", nbRowsInserted, context.getRawTableName())); + } + + // build pmfm metadata + List pmfmInfos = getPmfmInfo(context); + progressionModel.increments(1); + + // Mantis #29139: remove all individual measurement on survey + pmfmInfos = ReefDbBeans.filterCollection(pmfmInfos, input -> !(input.isSurvey() && input.isIndividual())); + + if (CollectionUtils.isEmpty(pmfmInfos)) { + throw new ReefDbBusinessException(t("reefdb.service.extraction.noPmfm.error")); + } + context.setPmfmInfos(pmfmInfos); + + // if a pmfm, taxon or taxon group filter is defined, will remove raw line not corresponding to filter (avoid blank cells in split table) + int nbRowsRemoved = cleanRawData(context, outputType); + progressionModel.increments(1); + + if (LOG.isDebugEnabled()) { + if (nbRowsRemoved > 0) { + LOG.debug(String.format("%s rows removed from raw data which not corresponding to PMFMU filter", nbRowsRemoved)); + } + LOG.debug(String.format("list of pmfmu ids to split : %s", ReefDbBeans.collectProperties(context.getPmfmInfos(), ExtractionPmfmInfoDTO.PROPERTY_PMFM_ID))); + } + + // Second clean operation: remove surveys from hermetic programs if user is not allowed (Mantis #47660) + int nbRowsRemoved2 = cleanHermeticData(context); + progressionModel.increments(1); + + if (LOG.isDebugEnabled() && nbRowsRemoved2 > 0) { + LOG.debug(String.format("%s rows removed from raw data which not corresponding to user rights (hermetic programs)", nbRowsRemoved2)); + } + + // if all the rows have been removed because of filters, there is no more data to extract + if (nbRowsRemoved + nbRowsRemoved2 == nbRowsInserted) { + throw new ReefDbBusinessException(t("reefdb.service.extraction.noPmfm.error")); + } + + // create pmfm tables + createPmfmTables(context, outputType); + + // insert raw data in pmfm tables + insertPmfmData(context, outputType); + progressionModel.increments(1); + + // create common table + createCommonTable(context, outputType); + + // insert common part of raw table into common table + nbRowsInserted = insertCommonData(context, outputType); + progressionModel.increments(1); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s rows of common raw data inserted into %s", nbRowsInserted, context.getCommonTableName())); + } + + // create split data table + createSplitTable(context, outputType); + + // insert data from raw table to result table = split pmfms in columns + nbRowsInserted = insertSplitData(context, outputType); + progressionModel.increments(1); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s rows of split data inserted into %s", nbRowsInserted, context.getResultTableName())); + } + + // final query and write to csv file + writeExtraction(context, outputType, outputFile); + progressionModel.increments(1); + + if (LOG.isInfoEnabled()) { + LOG.info(String.format("Extraction %s performed. result file is : %s", outputType, outputFile.getAbsolutePath())); + } + + } catch (Exception e) { + throw new ReefDbTechnicalException(t("reefdb.service.extraction.error"), e); + } + } finally { + + // drop concat functions + dropConcatDistinctFunction("MEAS_CM"); + dropConcatDistinctFunction("DEP_NM"); + dropConcatDistinctFunction("MEAS_ID"); + } + } + + private void createConcatDistinctFunction(String functionName, String valueType/*, String separator*/) { + + dropConcatDistinctFunction(functionName); + + // new function with external java method + String query = "CREATE FUNCTION CONCAT_DISTINCT_" + functionName + "(IN_ARRAY " + valueType + " ARRAY, SEPARATOR VARCHAR(10)) RETURNS LONGVARCHAR" + LS + + "LANGUAGE JAVA DETERMINISTIC NO SQL EXTERNAL NAME 'CLASSPATH:fr.ifremer.reefdb.dto.ReefDbBeans.getUnifiedSQLString';"; + + // old function with internal hsqldb method +// String query = "CREATE FUNCTION CONCAT_DISTINCT_" + functionName + "(IN_ARRAY " + valueType + " ARRAY) RETURNS LONGVARCHAR" + LS + +// "BEGIN ATOMIC" + LS + +// "DECLARE ARRAY_IT INTEGER DEFAULT 1;" + LS + +// "DECLARE VAR_ARRAY " + valueType + " ARRAY;" + LS + +// "SET VAR_ARRAY = IN_ARRAY;" + LS + +// "WHILE ARRAY_IT < CARDINALITY(VAR_ARRAY) DO" + LS + +// "IF POSITION_ARRAY(VAR_ARRAY[ARRAY_IT] IN VAR_ARRAY FROM ARRAY_IT + 1) != 0 THEN" + LS + +// "SET VAR_ARRAY[ARRAY_IT] = NULL;" + LS + +// "END IF;" + LS + +// "SET ARRAY_IT = ARRAY_IT + 1;" + LS + +// "END WHILE;" + LS + +// "RETURN (SELECT GROUP_CONCAT(RESULT.VALUE SEPARATOR '" + separator + "') FROM UNNEST(VAR_ARRAY) AS RESULT(VALUE));" + LS + +// "END;"; +// + extractionResultDao.queryUpdate(query, null); + + } + + private String getConcatDistinctFunction(String functionName) { + + return "CONCAT_DISTINCT_" + functionName; + } + + private void dropConcatDistinctFunction(String functionName) { + + extractionResultDao.queryUpdate("DROP FUNCTION CONCAT_DISTINCT_" + functionName + " IF EXISTS", null); + } + + private Long countRootData(ExtractionDTO extraction) { + + String countQuery = "SELECT COUNT(*)" + LS + + getFromClauseMinimal() + + getWhereClause(extraction); + + Map queryBindings = getQueryBindings(extraction); + + return extractionResultDao.queryCount(countQuery, queryBindings); + } + + private List getPmfmInfo(ExtractionContextDTO context) { + + // retrieve pmfm ids from filter + List pmfmIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.PMFM); + + // query the raw table to retrieve pmfm metadata + String pmfmQuery = "SELECT DISTINCT PMFM_ID, IS_SURVEY_MEAS, CASE WHEN MEAS_INDIV_ID IS NULL THEN FALSE ELSE TRUE END FROM " + context.getRawTableName(); + if (CollectionUtils.isNotEmpty(pmfmIds)) { + pmfmQuery += " WHERE PMFM_ID IN (" + Daos.getInStatementFromIntegerCollection(pmfmIds) + ")"; + } + + return extractionResultDao.query(pmfmQuery, null, (resultSet, i) -> { + ExtractionPmfmInfoDTO pmfmInfo = ReefDbBeanFactory.newExtractionPmfmInfoDTO(); + pmfmInfo.setPmfmId(resultSet.getInt(1)); + pmfmInfo.setSurvey(resultSet.getBoolean(2)); + pmfmInfo.setIndividual(resultSet.getBoolean(3)); + // compute alias + String safePmfmId = pmfmInfo.getPmfmId() < 0 ? "M" : "" + pmfmInfo.getPmfmId(); + pmfmInfo.setAlias((pmfmInfo.isSurvey() ? "SU" : "SO") + (pmfmInfo.isIndividual() ? "I" : "") + safePmfmId); + return pmfmInfo; + }); + } + + private void createRawTable(ExtractionContextDTO context, ExtractionOutputType outputType) { + + StringBuilder queryBuilder = new StringBuilder(); + + queryBuilder.append("DECLARE LOCAL TEMPORARY TABLE ").append(context.getRawTableName()).append(" ("); + queryBuilder.append("SURVEY_ID INTEGER, "); + queryBuilder.append("SURVEY_PROG_CD VARCHAR(40), "); + queryBuilder.append("REC_DEP_ID INTEGER, "); + queryBuilder.append("MON_LOC_NM VARCHAR(100), "); + queryBuilder.append("SURVEY_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_ID INTEGER, "); + queryBuilder.append("SAMPLING_OPER_LB VARCHAR(50), "); + queryBuilder.append("MON_LOC_ID INTEGER, "); + queryBuilder.append("MON_LOC_LB VARCHAR(50), "); + queryBuilder.append("ORDER_ITEM_NM VARCHAR(100), "); + queryBuilder.append("SURVEY_POSITION_LONG VARCHAR(20), "); + queryBuilder.append("SURVEY_POSITION_LAT VARCHAR(20), "); + queryBuilder.append("SAMPLING_EQUIPMENT_NM VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_DEP_NM VARCHAR(255), "); + if (outputType != ExtractionOutputType.PAMPA) { + queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); + } + queryBuilder.append("SURVEY_LB VARCHAR(50), "); + queryBuilder.append("SAMPLING_OPER_SIZE DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_SIZE_UNIT_SYMBOL VARCHAR(100), "); + + if (outputType == ExtractionOutputType.COMPLETE) { + queryBuilder.append("ORDER_ITEM_TYPE_NM VARCHAR(100), "); + queryBuilder.append("ORDER_ITEM_CD VARCHAR(40), "); + queryBuilder.append("MON_LOC_ORDER_ITEM_NUMBER DOUBLE, "); + queryBuilder.append("SURVEY_TIME DOUBLE, "); + queryBuilder.append("SURVEY_CM VARCHAR(2000), "); + queryBuilder.append("SURVEY_CONTROL_DT TIMESTAMP, "); + queryBuilder.append("SURVEY_VALID_DT TIMESTAMP, "); + queryBuilder.append("SURVEY_QUAL_FLAG VARCHAR(100), "); + queryBuilder.append("SURVEY_QUALIF_DT TIMESTAMP, "); + queryBuilder.append("SURVEY_QUALIF_CM VARCHAR(2000), "); + queryBuilder.append("SURVEY_INHERITED_POSITION VARCHAR(1), "); + queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); + queryBuilder.append("SAMPLING_OPER_DEPTH DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_MIN_DEPTH DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_MAX_DEPTH DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_INHERITED_POSITION VARCHAR(1), "); + queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT_SYMBOL VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_CM VARCHAR(2000), "); + queryBuilder.append("SAMPLING_EQUIPMENT_SIZE DOUBLE, "); + queryBuilder.append("SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_NUMBER_INDIV DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_CONTROL_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_VALID_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_QUAL_FLAG VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_QUALIF_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_QUALIF_CM VARCHAR(2000), "); + queryBuilder.append("SAMPLING_OPER_POSITION_LONG VARCHAR(20), "); + queryBuilder.append("SAMPLING_OPER_POSITION_LAT VARCHAR(20), "); + } else if (outputType == ExtractionOutputType.PAMPA) { + queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); + queryBuilder.append("SURVEY_BOTTOM_DEPTH DOUBLE, "); + queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); + } + + queryBuilder.append("MEAS_ID INTEGER, "); + queryBuilder.append("TAXON_MEAS_ID INTEGER, "); + queryBuilder.append("IS_SURVEY_MEAS BOOLEAN, "); + queryBuilder.append("MEAS_INDIV_ID INTEGER,"); + queryBuilder.append("PMFM_ID INTEGER, "); + queryBuilder.append("DEP_NM VARCHAR(255), "); + queryBuilder.append("MEAS_NUMER_VALUE DOUBLE, "); + queryBuilder.append("QUAL_VALUE_NM VARCHAR(100), "); + queryBuilder.append("TAXON_NAME_ID INTEGER, "); + queryBuilder.append("TAXON_NAME_NM VARCHAR(255), "); + queryBuilder.append("TAXON_GROUP_ID INTEGER, "); + queryBuilder.append("TAXON_GROUP_NM VARCHAR(100), "); + queryBuilder.append("MEAS_CM VARCHAR(2000), "); + + if (outputType == ExtractionOutputType.PAMPA) { + queryBuilder.append("TAXON_PAMPA VARCHAR(40), "); + } else { + queryBuilder.append("INPUT_TAXON_NAME_NM VARCHAR(255), "); + queryBuilder.append("INPUT_TAXON_NAME_ID INTEGER, "); + } + + String query = trimAtLastSequence(queryBuilder.toString(), ",").concat(")"); + + extractionResultDao.queryUpdate(query, null); + + } + + private void createPmfmTables(ExtractionContextDTO context, ExtractionOutputType outputType) { + + if (!context.isPmfmInfosEmpty()) { + for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { + + // Generate pmfm table name + String pmfmTableName = String.format(PMFM_TABLE_NAME_PATTERN, context.getUniqueId(), pmfmInfo.getAlias()); + pmfmInfo.setTableName(pmfmTableName); + + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("DECLARE LOCAL TEMPORARY TABLE ").append(pmfmTableName).append(" ("); + queryBuilder.append(pmfmInfo.isSurvey() ? "SURVEY_ID INTEGER, " : "SAMPLING_OPER_ID INTEGER, "); + queryBuilder.append("MEAS_ID INTEGER, "); + queryBuilder.append("TAXON_MEAS_ID INTEGER, "); + queryBuilder.append("IS_SURVEY_MEAS BOOLEAN, "); + queryBuilder.append("MEAS_INDIV_ID INTEGER, "); + queryBuilder.append("PMFM_ID INTEGER, "); + queryBuilder.append("DEP_NM VARCHAR(255), "); + queryBuilder.append("MEAS_NUMER_VALUE DOUBLE, "); + queryBuilder.append("QUAL_VALUE_NM VARCHAR(100), "); + queryBuilder.append("TAXON_NAME_NM VARCHAR(255), "); + queryBuilder.append("TAXON_GROUP_NM VARCHAR(100), "); + queryBuilder.append("MEAS_CM VARCHAR(2000), "); + + if (outputType == ExtractionOutputType.PAMPA) { + queryBuilder.append("TAXON_PAMPA VARCHAR(40), "); + } else { + queryBuilder.append("INPUT_TAXON_NAME_NM VARCHAR(255), "); + queryBuilder.append("INPUT_TAXON_NAME_ID INTEGER, "); + } + + String query = trimAtLastSequence(queryBuilder.toString(), ",").concat(")"); + extractionResultDao.queryUpdate(query, null); + } + } + } + + private void createCommonTable(ExtractionContextDTO context, ExtractionOutputType outputType) { + + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("DECLARE LOCAL TEMPORARY TABLE ").append(context.getCommonTableName()).append(" ("); + queryBuilder.append("SURVEY_ID INTEGER, "); + queryBuilder.append("SURVEY_PROG_CD VARCHAR(40), "); + queryBuilder.append("MON_LOC_NM VARCHAR(100), "); + queryBuilder.append("SURVEY_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_ID INTEGER, "); + queryBuilder.append("SAMPLING_OPER_LB VARCHAR(50), "); + queryBuilder.append("MON_LOC_ID INTEGER, "); + queryBuilder.append("MON_LOC_LB VARCHAR(50), "); + queryBuilder.append("ORDER_ITEM_NM VARCHAR(100), "); + queryBuilder.append("SURVEY_POSITION_LONG VARCHAR(20), "); + queryBuilder.append("SURVEY_POSITION_LAT VARCHAR(20), "); + queryBuilder.append("SAMPLING_EQUIPMENT_NM VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_DEP_NM VARCHAR(255), "); + if (outputType != ExtractionOutputType.PAMPA) { + queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); + } + queryBuilder.append("SURVEY_LB VARCHAR(50), "); + queryBuilder.append("SAMPLING_OPER_SIZE DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_SIZE_UNIT_SYMBOL VARCHAR(100), "); + if (outputType == ExtractionOutputType.COMPLETE) { + queryBuilder.append("ORDER_ITEM_TYPE_NM VARCHAR(100), "); + queryBuilder.append("ORDER_ITEM_CD VARCHAR(40), "); + queryBuilder.append("MON_LOC_ORDER_ITEM_NUMBER DOUBLE, "); + queryBuilder.append("SURVEY_TIME DOUBLE, "); + queryBuilder.append("SURVEY_CM VARCHAR(2000), "); + queryBuilder.append("SURVEY_CONTROL_DT TIMESTAMP, "); + queryBuilder.append("SURVEY_VALID_DT TIMESTAMP, "); + queryBuilder.append("SURVEY_QUAL_FLAG VARCHAR(100), "); + queryBuilder.append("SURVEY_QUALIF_DT TIMESTAMP, "); + queryBuilder.append("SURVEY_QUALIF_CM VARCHAR(2000), "); + queryBuilder.append("SURVEY_INHERITED_POSITION VARCHAR(1), "); + queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); + queryBuilder.append("SAMPLING_OPER_DEPTH DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_MIN_DEPTH DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_MAX_DEPTH DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_INHERITED_POSITION VARCHAR(1), "); + queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT_SYMBOL VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_CM VARCHAR(2000), "); + queryBuilder.append("SAMPLING_EQUIPMENT_SIZE DOUBLE, "); + queryBuilder.append("SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_NUMBER_INDIV DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_CONTROL_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_VALID_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_QUAL_FLAG VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_QUALIF_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_QUALIF_CM VARCHAR(2000), "); + queryBuilder.append("SAMPLING_OPER_POSITION_LONG VARCHAR(20), "); + queryBuilder.append("SAMPLING_OPER_POSITION_LAT VARCHAR(20), "); + } else if (outputType == ExtractionOutputType.PAMPA) { + queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); + queryBuilder.append("SURVEY_BOTTOM_DEPTH DOUBLE, "); + queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); + } + queryBuilder.append("MEAS_INDIV_ID INTEGER)"); + + extractionResultDao.queryUpdate(queryBuilder.toString(), null); + + } + + private void createSplitTable(ExtractionContextDTO context, ExtractionOutputType outputType) { + + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("DECLARE LOCAL TEMPORARY TABLE ").append(context.getResultTableName()).append(" ("); + queryBuilder.append("SURVEY_ID INTEGER, "); + queryBuilder.append("SURVEY_PROG_CD VARCHAR(40), "); + queryBuilder.append("MON_LOC_NM VARCHAR(100), "); + queryBuilder.append("SURVEY_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_ID INTEGER, "); + queryBuilder.append("SAMPLING_OPER_LB VARCHAR(50), "); + queryBuilder.append("MON_LOC_ID INTEGER, "); + queryBuilder.append("MON_LOC_LB VARCHAR(50), "); + queryBuilder.append("ORDER_ITEM_NM VARCHAR(100), "); + queryBuilder.append("SURVEY_POSITION_LONG VARCHAR(20), "); + queryBuilder.append("SURVEY_POSITION_LAT VARCHAR(20), "); + queryBuilder.append("SAMPLING_EQUIPMENT_NM VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_DEP_NM VARCHAR(255), "); + if (outputType != ExtractionOutputType.PAMPA) { + queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); + } + queryBuilder.append("SURVEY_LB VARCHAR(50), "); + queryBuilder.append("SAMPLING_OPER_SIZE DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_SIZE_UNIT_SYMBOL VARCHAR(100), "); + if (outputType == ExtractionOutputType.COMPLETE) { + queryBuilder.append("ORDER_ITEM_TYPE_NM VARCHAR(100), "); + queryBuilder.append("ORDER_ITEM_CD VARCHAR(40), "); + queryBuilder.append("MON_LOC_ORDER_ITEM_NUMBER DOUBLE, "); + queryBuilder.append("SURVEY_TIME DOUBLE, "); + queryBuilder.append("SURVEY_CM VARCHAR(2000), "); + queryBuilder.append("SURVEY_CONTROL_DT TIMESTAMP, "); + queryBuilder.append("SURVEY_VALID_DT TIMESTAMP, "); + queryBuilder.append("SURVEY_QUAL_FLAG VARCHAR(100), "); + queryBuilder.append("SURVEY_QUALIF_DT TIMESTAMP, "); + queryBuilder.append("SURVEY_QUALIF_CM VARCHAR(2000), "); + queryBuilder.append("SURVEY_INHERITED_POSITION VARCHAR(1), "); + queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); + queryBuilder.append("SAMPLING_OPER_DEPTH DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_MIN_DEPTH DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_MAX_DEPTH DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_INHERITED_POSITION VARCHAR(1), "); + queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT_SYMBOL VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_DEPTH_UNIT VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_CM VARCHAR(2000), "); + queryBuilder.append("SAMPLING_EQUIPMENT_SIZE DOUBLE, "); + queryBuilder.append("SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_NUMBER_INDIV DOUBLE, "); + queryBuilder.append("SAMPLING_OPER_CONTROL_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_VALID_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_QUAL_FLAG VARCHAR(100), "); + queryBuilder.append("SAMPLING_OPER_QUALIF_DT TIMESTAMP, "); + queryBuilder.append("SAMPLING_OPER_QUALIF_CM VARCHAR(2000), "); + queryBuilder.append("SAMPLING_OPER_POSITION_LONG VARCHAR(20), "); + queryBuilder.append("SAMPLING_OPER_POSITION_LAT VARCHAR(20), "); + } else if (outputType == ExtractionOutputType.PAMPA) { + queryBuilder.append("SAMPLING_OPER_TIME INTEGER, "); + queryBuilder.append("SURVEY_BOTTOM_DEPTH DOUBLE, "); + queryBuilder.append("SURVEY_QUSERS VARCHAR(1000), "); + } + queryBuilder.append("MEAS_INDIV_ID INTEGER, "); + + if (!context.isPmfmInfosEmpty()) { + for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { + + queryBuilder.append(pmfmInfo.getAlias()).append("_MEAS_ID INTEGER, "); + queryBuilder.append(pmfmInfo.getAlias()).append("_TAXON_MEAS_ID INTEGER, "); + queryBuilder.append(pmfmInfo.getAlias()).append("_MEAS_NUMER_VALUE DOUBLE, "); + queryBuilder.append(pmfmInfo.getAlias()).append("_QUAL_VALUE_NM VARCHAR(100), "); + queryBuilder.append(pmfmInfo.getAlias()).append("_DEP_NM VARCHAR(255), "); + if (pmfmInfo.isIndividual()) { + queryBuilder.append(pmfmInfo.getAlias()).append("_TAXON_NAME_NM VARCHAR(255), "); + queryBuilder.append(pmfmInfo.getAlias()).append("_TAXON_GROUP_NM VARCHAR(100), "); + queryBuilder.append(pmfmInfo.getAlias()).append("_MEAS_CM VARCHAR(2000), "); + if (outputType == ExtractionOutputType.PAMPA) { + queryBuilder.append(pmfmInfo.getAlias()).append("_TAXON_PAMPA VARCHAR(40), "); + } else { + queryBuilder.append(pmfmInfo.getAlias()).append("_INPUT_TAXON_NAME_NM VARCHAR(255), "); + queryBuilder.append(pmfmInfo.getAlias()).append("_INPUT_TAXON_NAME_ID INTEGER, "); + } + } + } + } + + String query = trimAtLastSequence(queryBuilder.toString(), ",").concat(")"); + + extractionResultDao.queryUpdate(query, null); + + } + + private int insertRawData(ExtractionContextDTO context, ExtractionOutputType outputType) { + + // Base select + StringBuilder baseSelectBuilder = new StringBuilder(); + baseSelectBuilder.append("SELECT BASE.SURVEY_ID, BASE.SURVEY_PROG_CD, BASE.REC_DEP_ID, BASE.MON_LOC_NM, BASE.SURVEY_DT, BASE.SAMPLING_OPER_ID, BASE.SAMPLING_OPER_LB, "); + baseSelectBuilder.append("BASE.MON_LOC_ID, BASE.MON_LOC_LB, MLOI.ORDER_ITEM_NM, BASE.SURVEY_POSITION_LONG, BASE.SURVEY_POSITION_LAT, "); + baseSelectBuilder.append("BASE.SAMPLING_EQUIPMENT_NM, BASE.SAMPLING_OPER_DEP_NM, "); + if (outputType != ExtractionOutputType.PAMPA) { + baseSelectBuilder.append("BASE.SURVEY_QUSERS, "); + } + baseSelectBuilder.append("BASE.SURVEY_LB, BASE.SAMPLING_OPER_SIZE, BASE.SAMPLING_OPER_SIZE_UNIT_SYMBOL, "); + + if (outputType == ExtractionOutputType.COMPLETE) { + baseSelectBuilder.append("MLOI.ORDER_ITEM_TYPE_NM, MLOI.ORDER_ITEM_CD, MLOI.MON_LOC_ORDER_ITEM_NUMBER, " + + "BASE.SURVEY_TIME, BASE.SURVEY_CM, BASE.SURVEY_CONTROL_DT, BASE.SURVEY_VALID_DT, BASE.SURVEY_QUAL_FLAG, " + + "BASE.SURVEY_QUALIF_DT, BASE.SURVEY_QUALIF_CM, BASE.SURVEY_INHERITED_POSITION, BASE.SAMPLING_OPER_TIME, " + + "BASE.SAMPLING_OPER_DEPTH, BASE.SAMPLING_OPER_MIN_DEPTH, BASE.SAMPLING_OPER_MAX_DEPTH, " + + "BASE.SAMPLING_OPER_INHERITED_POSITION, BASE.SAMPLING_OPER_DEPTH_UNIT_SYMBOL, BASE.SAMPLING_OPER_DEPTH_UNIT, " + + "BASE.SAMPLING_OPER_CM, BASE.SAMPLING_EQUIPMENT_SIZE, BASE.SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, BASE.SAMPLING_OPER_NUMBER_INDIV, " + + "BASE.SAMPLING_OPER_CONTROL_DT, BASE.SAMPLING_OPER_VALID_DT, BASE.SAMPLING_OPER_QUAL_FLAG, BASE.SAMPLING_OPER_QUALIF_DT, " + + "BASE.SAMPLING_OPER_QUALIF_CM, BASE.SAMPLING_OPER_POSITION_LONG, BASE.SAMPLING_OPER_POSITION_LAT, "); + } else if (outputType == ExtractionOutputType.PAMPA) { + baseSelectBuilder.append("BASE.SAMPLING_OPER_TIME, BASE.SURVEY_BOTTOM_DEPTH, BASE.SURVEY_QUSERS, "); + } + String baseSelect = baseSelectBuilder.toString(); + + // base sub query + StringBuilder insertQueryBuiler = new StringBuilder(); + insertQueryBuiler.append("INSERT INTO ").append(context.getRawTableName()).append(LS); + insertQueryBuiler.append("WITH BASE AS (").append(LS); + insertQueryBuiler.append("SELECT S.SURVEY_ID, PROG.PROG_CD AS SURVEY_PROG_CD, S.REC_DEP_ID, ML.MON_LOC_NM, S.SURVEY_DT,").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_ID, SO.SAMPLING_OPER_LB, ML.MON_LOC_ID, ML.MON_LOC_LB,").append(LS); + insertQueryBuiler.append("REGEXP_SUBSTRING(SP.SURVEY_POSITION, '[0-9.-]+') AS SURVEY_POSITION_LONG,").append(LS); + insertQueryBuiler.append("TRIM(TRAILING ')' FROM REGEXP_SUBSTRING(SP.SURVEY_POSITION, '[0-9.-]+\\)$')) AS SURVEY_POSITION_LAT,").append(LS); + insertQueryBuiler.append("SE.SAMPLING_EQUIPMENT_NM, DEP.DEP_NM AS SAMPLING_OPER_DEP_NM, ").append(LS); + if (outputType != ExtractionOutputType.PAMPA) { + insertQueryBuiler.append("GROUP_CONCAT(Q.QUSER_FIRST_NM || ' ' || Q.QUSER_LAST_NM || ' - ' || QD.DEP_NM separator '|') AS SURVEY_QUSERS,").append(LS); + } + insertQueryBuiler.append("S.SURVEY_LB,").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_SIZE, SU.UNIT_SYMBOL AS SAMPLING_OPER_SIZE_UNIT_SYMBOL").append(LS); + + if (outputType == ExtractionOutputType.COMPLETE) { + insertQueryBuiler.append(", S.SURVEY_TIME, S.SURVEY_CM, S.SURVEY_CONTROL_DT, S.SURVEY_VALID_DT, SQF.QUAL_FLAG_NM AS SURVEY_QUAL_FLAG, ").append(LS); + insertQueryBuiler.append("S.SURVEY_QUALIF_DT, S.SURVEY_QUALIF_CM, CASEWHEN(IFNULL(S.SURVEY_ACTUAL_POSITION,'0')='0','1','0') AS SURVEY_INHERITED_POSITION, SO.SAMPLING_OPER_TIME, ").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_DEPTH, SO.SAMPLING_OPER_MIN_DEPTH, SO.SAMPLING_OPER_MAX_DEPTH, CASEWHEN(IFNULL(SO.SAMPLING_OPER_ACTUAL_POSITION,'0')='0','1','0') AS.SAMPLING_OPER_INHERITED_POSITION, ").append(LS); + insertQueryBuiler.append("DU.UNIT_SYMBOL AS SAMPLING_OPER_DEPTH_UNIT_SYMBOL, DU.UNIT_NM AS SAMPLING_OPER_DEPTH_UNIT, SO.SAMPLING_OPER_CM, ").append(LS); + insertQueryBuiler.append("SE.SAMPLING_EQUIPMENT_SIZE, SEU.UNIT_SYMBOL AS SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, ").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_NUMBER_INDIV, SO.SAMPLING_OPER_CONTROL_DT, SO.SAMPLING_OPER_VALID_DT, SOQF.QUAL_FLAG_NM AS SAMPLING_OPER_QUAL_FLAG, ").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_QUALIF_DT, SO.SAMPLING_OPER_QUALIF_CM, ").append(LS); + insertQueryBuiler.append("REGEXP_SUBSTRING(SOP.SAMPLING_OPER_POSITION, '[0-9.-]+') AS SAMPLING_OPER_POSITION_LONG, ").append(LS); + insertQueryBuiler.append("TRIM(TRAILING ')' FROM REGEXP_SUBSTRING(SOP.SAMPLING_OPER_POSITION, '[0-9.-]+\\)$')) AS SAMPLING_OPER_POSITION_LAT").append(LS); + } else if (outputType == ExtractionOutputType.PAMPA) { + insertQueryBuiler.append(", SO.SAMPLING_OPER_TIME, S.SURVEY_BOTTOM_DEPTH, GROUP_CONCAT(Q.QUSER_FIRST_NM || ' ' || Q.QUSER_LAST_NM separator '|') AS SURVEY_QUSERS").append(LS); + } + + insertQueryBuiler.append(getFromClauseMinimal()); + insertQueryBuiler.append("LEFT OUTER JOIN SURVEY_POINT SP ON SP.SURVEY_ID = S.SURVEY_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN SAMPLING_OPERATION SO ON SO.SURVEY_ID = S.SURVEY_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN SAMPLING_EQUIPMENT SE ON SE.SAMPLING_EQUIPMENT_ID = SO.SAMPLING_EQUIPMENT_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT DEP ON DEP.DEP_ID = SO.DEP_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN UNIT SU ON SU.UNIT_ID = SO.SAMPLING_OPER_SIZE_UNIT_ID").append(LS); + if (outputType != ExtractionOutputType.PAMPA) { + insertQueryBuiler.append("LEFT OUTER JOIN SURVEY_QUSER SQ ON SQ.SURVEY_ID = S.SURVEY_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN QUSER Q ON Q.QUSER_ID = SQ.QUSER_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT QD ON QD.DEP_ID = Q.DEP_ID").append(LS); + } + + if (outputType == ExtractionOutputType.COMPLETE) { + insertQueryBuiler.append("LEFT OUTER JOIN QUALITY_FLAG SQF ON S.QUAL_FLAG_CD = SQF.QUAL_FLAG_CD").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN UNIT DU ON SO.SAMPLING_OPER_DEPTH_UNIT_ID = DU.UNIT_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN UNIT SEU ON SE.UNIT_ID = SEU.UNIT_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN QUALITY_FLAG SOQF ON SO.QUAL_FLAG_CD = SOQF.QUAL_FLAG_CD").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN SAMPLING_OPER_POINT SOP ON SO.SAMPLING_OPER_ID = SOP.SAMPLING_OPER_ID").append(LS); + } else if (outputType == ExtractionOutputType.PAMPA) { + insertQueryBuiler.append("LEFT OUTER JOIN SURVEY_QUSER SQ ON SQ.SURVEY_ID = S.SURVEY_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN QUSER Q ON SQ.QUSER_ID = Q.QUSER_ID").append(LS); + } + + insertQueryBuiler.append(getWhereClause(context.getExtraction())); + + // Add GROUP BY because of GROUP_CONCAT aggregation method + insertQueryBuiler.append("GROUP BY S.SURVEY_ID, PROG.PROG_CD, ML.MON_LOC_NM, S.SURVEY_DT,").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_ID, SO.SAMPLING_OPER_LB, ML.MON_LOC_ID, ML.MON_LOC_LB,").append(LS); + insertQueryBuiler.append("SURVEY_POSITION_LONG, SURVEY_POSITION_LAT,").append(LS); + insertQueryBuiler.append("SE.SAMPLING_EQUIPMENT_NM, DEP.DEP_NM, S.SURVEY_LB,").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_SIZE, SU.UNIT_SYMBOL").append(LS); + if (outputType == ExtractionOutputType.COMPLETE) { + insertQueryBuiler.append(", S.SURVEY_TIME, S.SURVEY_CM, S.SURVEY_CONTROL_DT, S.SURVEY_VALID_DT, SQF.QUAL_FLAG_NM,").append(LS); + insertQueryBuiler.append("S.SURVEY_QUALIF_DT, S.SURVEY_QUALIF_CM, CASEWHEN(IFNULL(S.SURVEY_ACTUAL_POSITION,'0')='0','1','0'), SO.SAMPLING_OPER_TIME,").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_DEPTH, SO.SAMPLING_OPER_MIN_DEPTH, SO.SAMPLING_OPER_MAX_DEPTH, CASEWHEN(IFNULL(SO.SAMPLING_OPER_ACTUAL_POSITION,'0')='0','1','0'),").append(LS); + insertQueryBuiler.append("DU.UNIT_SYMBOL, DU.UNIT_NM, SO.SAMPLING_OPER_CM, SE.SAMPLING_EQUIPMENT_SIZE, SEU.UNIT_SYMBOL, ").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_NUMBER_INDIV, SO.SAMPLING_OPER_CONTROL_DT, SO.SAMPLING_OPER_VALID_DT, SOQF.QUAL_FLAG_NM, ").append(LS); + insertQueryBuiler.append("SO.SAMPLING_OPER_QUALIF_DT, SO.SAMPLING_OPER_QUALIF_CM, ").append(LS); + insertQueryBuiler.append("REGEXP_SUBSTRING(SOP.SAMPLING_OPER_POSITION, '[0-9.-]+'), ").append(LS); + insertQueryBuiler.append("TRIM(TRAILING ')' FROM REGEXP_SUBSTRING(SOP.SAMPLING_OPER_POSITION, '[0-9.-]+\\)$'))").append(LS); + } else if (outputType == ExtractionOutputType.PAMPA) { + insertQueryBuiler.append(", SO.SAMPLING_OPER_TIME, S.SURVEY_BOTTOM_DEPTH").append(LS); + } + + insertQueryBuiler.append("ORDER BY S.SURVEY_ID)").append(LS); + // end of base sub query + + // order item on location query + insertQueryBuiler.append(", MLOI AS (").append(LS); + insertQueryBuiler.append("SELECT MLOI.MON_LOC_ID, OI.ORDER_ITEM_NM, OIT.ORDER_ITEM_TYPE_NM, OI.ORDER_ITEM_CD, MLOI.MON_LOC_ORDER_ITEM_NUMBER").append(LS); + insertQueryBuiler.append("FROM MON_LOC_ORDER_ITEM MLOI").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN ORDER_ITEM OI ON MLOI.ORDER_ITEM_ID = OI.ORDER_ITEM_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN ORDER_ITEM_TYPE OIT ON OI.ORDER_ITEM_TYPE_CD = OIT.ORDER_ITEM_TYPE_CD").append(LS); + insertQueryBuiler.append("WHERE OI.ORDER_ITEM_TYPE_CD = '").append(getOrderItemTypeCode(context.getExtraction())).append("')").append(LS); + + if (outputType == ExtractionOutputType.PAMPA) { + // alternative taxon for pampa + insertQueryBuiler.append(", ALT AS (").append(LS); + insertQueryBuiler.append("SELECT ALT.TAXON_NAME_ID, ALT.ALTERN_TAXON_CD FROM ALTERNATIVE_TAXON ALT").append(LS); + insertQueryBuiler.append("WHERE ALT.ALTERN_TAXON_ORIGIN_CD = '").append(config.getAlternativeTaxonOriginPAMPA()).append("')"); + } + + // SURVEY MEASUREMENTS + insertQueryBuiler.append(baseSelect).append(LS); + insertQueryBuiler.append("SM.REMOTE_ID AS MEAS_ID, NULL AS TAXON_MEAS_ID, 1 AS IS_SURVEY_MEAS, SM.MEAS_INDIV_ID, SM.PMFM_ID, D.DEP_NM, SM.MEAS_NUMER_VALUE, QV.QUAL_VALUE_NM,").append(LS); + insertQueryBuiler.append("NULL AS TAXON_NAME_ID, NULL AS TAXON_NAME_NM, NULL AS TAXON_GROUP_ID, NULL AS TAXON_GROUP_NM, SM.MEAS_CM"); + insertQueryBuiler.append(outputType == ExtractionOutputType.PAMPA ? ", NULL AS TAXON_PAMPA" : ", NULL AS INPUT_TAXON_NAME_NM, NULL AS INPUT_TAXON_NAME_ID").append(LS); + insertQueryBuiler.append("FROM BASE").append(LS); + insertQueryBuiler.append("INNER JOIN MEASUREMENT SM ON BASE.SURVEY_ID = SM.SURVEY_ID AND SM.SAMPLING_OPER_ID IS NULL").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT D ON SM.DEP_ID = D.DEP_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN QUALITATIVE_VALUE QV ON SM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN MLOI ON MLOI.MON_LOC_ID = BASE.MON_LOC_ID").append(LS); + insertQueryBuiler.append("UNION").append(LS); + + // SURVEY TAXON MEASUREMENTS + insertQueryBuiler.append(baseSelect).append(LS); + insertQueryBuiler.append("NULL AS MEAS_ID, STM.REMOTE_ID AS TAXON_MEAS_ID, 1 AS IS_SURVEY_MEAS, STM.TAXON_MEAS_INDIV_ID, STM.PMFM_ID, D.DEP_NM, STM.TAXON_MEAS_NUMER_VALUE, QV.QUAL_VALUE_NM,").append(LS); + insertQueryBuiler.append("TN.TAXON_NAME_ID, TN.TAXON_NAME_COMPLETE_NM AS TAXON_NAME_NM, TG.TAXON_GROUP_ID, TG.TAXON_GROUP_NM, STM.TAXON_MEAS_CM"); + insertQueryBuiler.append(outputType == ExtractionOutputType.PAMPA ? ", ALT.ALTERN_TAXON_CD AS TAXON_PAMPA" : ", STM.TAXON_NAME_NM AS INPUT_TAXON_NAME_NM, STM.TAXON_NAME_ID AS INPUT_TAXON_NAME_ID").append(LS); + insertQueryBuiler.append("FROM BASE").append(LS); + insertQueryBuiler.append("INNER JOIN TAXON_MEASUREMENT STM ON BASE.SURVEY_ID = STM.SURVEY_ID AND STM.SAMPLING_OPER_ID IS NULL").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT D ON STM.DEP_ID = D.DEP_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN QUALITATIVE_VALUE QV ON STM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN TAXON_NAME TN ON STM.REF_TAXON_ID = TN.REF_TAXON_ID AND TN.TAXON_NAME_IS_REFER = 1").append(LS); + if (outputType == ExtractionOutputType.PAMPA) { + insertQueryBuiler.append("LEFT OUTER JOIN ALT ON ALT.TAXON_NAME_ID = TN.TAXON_NAME_ID").append(LS); + } + insertQueryBuiler.append("LEFT OUTER JOIN TAXON_GROUP TG ON STM.TAXON_GROUP_ID = TG.TAXON_GROUP_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN MLOI ON MLOI.MON_LOC_ID = BASE.MON_LOC_ID").append(LS); + insertQueryBuiler.append("UNION").append(LS); + + // SAMPLING OPERATION MEASUREMENTS + insertQueryBuiler.append(baseSelect).append(LS); + insertQueryBuiler.append("SM.REMOTE_ID AS MEAS_ID, NULL AS TAXON_MEAS_ID, 0 AS IS_SURVEY_MEAS, SM.MEAS_INDIV_ID, SM.PMFM_ID, D.DEP_NM, SM.MEAS_NUMER_VALUE, QV.QUAL_VALUE_NM,").append(LS); + insertQueryBuiler.append("NULL AS TAXON_NAME_ID, NULL AS TAXON_NAME_NM, NULL AS TAXON_GROUP_ID, NULL AS TAXON_GROUP_NM, SM.MEAS_CM"); + insertQueryBuiler.append(outputType == ExtractionOutputType.PAMPA ? ", NULL AS TAXON_PAMPA" : ", NULL AS INPUT_TAXON_NAME_NM, NULL AS INPUT_TAXON_NAME_ID").append(LS); + insertQueryBuiler.append("FROM BASE").append(LS); + insertQueryBuiler.append("INNER JOIN MEASUREMENT SM ON BASE.SAMPLING_OPER_ID = SM.SAMPLING_OPER_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT D ON SM.DEP_ID = D.DEP_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN QUALITATIVE_VALUE QV ON SM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN MLOI ON MLOI.MON_LOC_ID = BASE.MON_LOC_ID").append(LS); + insertQueryBuiler.append("UNION").append(LS); + + // SAMPLING OPERATION TAXON MEASUREMENTS + insertQueryBuiler.append(baseSelect).append(LS); + insertQueryBuiler.append("NULL AS MEAS_ID, STM.REMOTE_ID AS TAXON_MEAS_ID, 0 AS IS_SURVEY_MEAS, STM.TAXON_MEAS_INDIV_ID, STM.PMFM_ID, D.DEP_NM, STM.TAXON_MEAS_NUMER_VALUE, QV.QUAL_VALUE_NM,").append(LS); + insertQueryBuiler.append("TN.TAXON_NAME_ID, TN.TAXON_NAME_COMPLETE_NM AS TAXON_NAME_NM, TG.TAXON_GROUP_ID, TG.TAXON_GROUP_NM, STM.TAXON_MEAS_CM"); + insertQueryBuiler.append(outputType == ExtractionOutputType.PAMPA ? ", ALT.ALTERN_TAXON_CD AS TAXON_PAMPA" : ", STM.TAXON_NAME_NM AS INPUT_TAXON_NAME_NM, STM.TAXON_NAME_ID AS INPUT_TAXON_NAME_ID").append(LS); + insertQueryBuiler.append("FROM BASE").append(LS); + insertQueryBuiler.append("INNER JOIN TAXON_MEASUREMENT STM ON BASE.SAMPLING_OPER_ID = STM.SAMPLING_OPER_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN DEPARTMENT D ON STM.DEP_ID = D.DEP_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN QUALITATIVE_VALUE QV ON STM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN TAXON_NAME TN ON STM.REF_TAXON_ID = TN.REF_TAXON_ID AND TN.TAXON_NAME_IS_REFER = 1").append(LS); + if (outputType == ExtractionOutputType.PAMPA) { + insertQueryBuiler.append("LEFT OUTER JOIN ALT ON ALT.TAXON_NAME_ID = TN.TAXON_NAME_ID").append(LS); + } + insertQueryBuiler.append("LEFT OUTER JOIN TAXON_GROUP TG ON STM.TAXON_GROUP_ID = TG.TAXON_GROUP_ID").append(LS); + insertQueryBuiler.append("LEFT OUTER JOIN MLOI ON MLOI.MON_LOC_ID = BASE.MON_LOC_ID").append(LS); + + return extractionResultDao.queryUpdate(insertQueryBuiler.toString(), getQueryBindings(context.getExtraction())); + + } + + private int cleanRawData(ExtractionContextDTO context, ExtractionOutputType outputType) { + + List pmfmIds = ReefDbBeans.collectProperties(context.getPmfmInfos(), ExtractionPmfmInfoDTO.PROPERTY_PMFM_ID); + List taxonNameIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.TAXON); + List taxonGroupIds = ReefDbBeans.getFilterElementsIds(context.getExtraction(), ExtractionFilterValues.TAXON_GROUP); + + // clause for taxon / taxon group filtering + StringBuilder taxonWhereClause = new StringBuilder(); + if (CollectionUtils.isNotEmpty(taxonGroupIds)) { + taxonWhereClause.append(" OR ((TAXON_GROUP_ID NOT IN (") + .append(Daos.getInStatementFromIntegerCollection(taxonGroupIds)) + .append(") OR TAXON_GROUP_ID IS NULL) AND MEAS_INDIV_ID IS NOT NULL)"); + } + if (CollectionUtils.isNotEmpty(taxonNameIds)) { + taxonWhereClause.append(" OR (((TAXON_NAME_ID NOT IN ") + .append("(").append(Daos.getInStatementFromIntegerCollection(taxonNameIds)).append(")"); + if (outputType != ExtractionOutputType.PAMPA) { + taxonWhereClause.append(" AND INPUT_TAXON_NAME_ID NOT IN ") + .append("(").append(Daos.getInStatementFromIntegerCollection(taxonNameIds)).append(")"); + } + taxonWhereClause.append(") OR TAXON_NAME_ID IS NULL) AND MEAS_INDIV_ID IS NOT NULL)"); + } + + String query = "DELETE FROM " + context.getRawTableName() + + " WHERE PMFM_ID NOT IN (" + Daos.getInStatementFromIntegerCollection(pmfmIds) + ")" + + taxonWhereClause.toString(); + + return extractionResultDao.queryUpdate(query, null); + + } + + private int cleanHermeticData(ExtractionContextDTO context) { + + // 1- first populate distinct programs from raw table + String query = "SELECT P.PROG_CD FROM PROGRAMME P WHERE P.IS_DEPARTMENT_HERMETIC = '1' AND P.PROG_CD IN " + + "(SELECT DISTINCT SURVEY_PROG_CD FROM " + context.getRawTableName() + ")"; + List hermeticPrograms = extractionResultDao.queryStringList(query, null); + + if (CollectionUtils.isEmpty(hermeticPrograms)) { + return 0; + } + + // 2- collect managed programs + int nbRemoves = 0; + Integer userId= dataContext.getRecorderPersonId(); + Assert.notNull(userId); + Integer recDepId = dataContext.getRecorderDepartmentId(); + Assert.notNull(recDepId); + Set managedProgramCodes = programStrategyService.getManagedProgramCodesByQuserId(userId); + + // 3- iterate hermetic programs and test with rec_dep_id if user is not manager + for (String hermeticProgram: hermeticPrograms) { + if (managedProgramCodes == null || !managedProgramCodes.contains(hermeticProgram)) { + query = "DELETE FROM " + context.getRawTableName() + " WHERE SURVEY_PROG_CD = '" + hermeticProgram + "' AND REC_DEP_ID != " + recDepId; + nbRemoves += extractionResultDao.queryUpdate(query, null); + } + } + + return nbRemoves; + } + + @SuppressWarnings("StringBufferReplaceableByString") + private void insertPmfmData(ExtractionContextDTO context, ExtractionOutputType outputType) { + + if (!context.isPmfmInfosEmpty()) { + for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { + + StringBuilder query = new StringBuilder(); + query.append("INSERT INTO ").append(pmfmInfo.getTableName()).append(LS); + query.append("SELECT DISTINCT "); + query.append(pmfmInfo.isSurvey() ? "SURVEY_ID," : "SAMPLING_OPER_ID, "); + query.append("MEAS_ID, TAXON_MEAS_ID, IS_SURVEY_MEAS, MEAS_INDIV_ID, "); + query.append("PMFM_ID, DEP_NM, MEAS_NUMER_VALUE, QUAL_VALUE_NM, TAXON_NAME_NM, TAXON_GROUP_NM, MEAS_CM"); + query.append(outputType == ExtractionOutputType.PAMPA ? ", TAXON_PAMPA" : ", INPUT_TAXON_NAME_NM, INPUT_TAXON_NAME_ID").append(LS); + query.append("FROM ").append(context.getRawTableName()).append(LS); + query.append("WHERE PMFM_ID = ").append(pmfmInfo.getPmfmId()).append(" AND IS_SURVEY_MEAS = ").append(pmfmInfo.isSurvey() ? "1" : "0").append(" "); + query.append("AND MEAS_INDIV_ID IS ").append(pmfmInfo.isIndividual() ? "NOT " : "").append("NULL"); + + int nbRowsInserted = extractionResultDao.queryUpdate(query.toString(), null); + + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s rows of pmfmu raw data inserted into %s", nbRowsInserted, pmfmInfo.getTableName())); + } + + } + } + } + + private int insertCommonData(ExtractionContextDTO context, ExtractionOutputType outputType) { + + StringBuilder query = new StringBuilder(); + query.append("INSERT INTO ").append(context.getCommonTableName()).append(LS); + query.append("SELECT DISTINCT SURVEY_ID, SURVEY_PROG_CD, MON_LOC_NM, SURVEY_DT, SAMPLING_OPER_ID, SAMPLING_OPER_LB, MON_LOC_ID, MON_LOC_LB, ORDER_ITEM_NM, "); + query.append("SURVEY_POSITION_LONG, SURVEY_POSITION_LAT, SAMPLING_EQUIPMENT_NM, SAMPLING_OPER_DEP_NM, "); + if (outputType != ExtractionOutputType.PAMPA) { + query.append("SURVEY_QUSERS, "); + } + query.append("SURVEY_LB, SAMPLING_OPER_SIZE, SAMPLING_OPER_SIZE_UNIT_SYMBOL, "); + if (outputType == ExtractionOutputType.COMPLETE) { + query.append("ORDER_ITEM_TYPE_NM, ORDER_ITEM_CD, MON_LOC_ORDER_ITEM_NUMBER, "); + query.append("SURVEY_TIME, SURVEY_CM, SURVEY_CONTROL_DT, SURVEY_VALID_DT, SURVEY_QUAL_FLAG, "); + query.append("SURVEY_QUALIF_DT, SURVEY_QUALIF_CM, SURVEY_INHERITED_POSITION, SAMPLING_OPER_TIME, "); + query.append("SAMPLING_OPER_DEPTH, SAMPLING_OPER_MIN_DEPTH, SAMPLING_OPER_MAX_DEPTH, "); + query.append("SAMPLING_OPER_INHERITED_POSITION, SAMPLING_OPER_DEPTH_UNIT_SYMBOL, SAMPLING_OPER_DEPTH_UNIT, "); + query.append("SAMPLING_OPER_CM, SAMPLING_EQUIPMENT_SIZE, SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, SAMPLING_OPER_NUMBER_INDIV, "); + query.append("SAMPLING_OPER_CONTROL_DT, SAMPLING_OPER_VALID_DT, SAMPLING_OPER_QUAL_FLAG, SAMPLING_OPER_QUALIF_DT, "); + query.append("SAMPLING_OPER_QUALIF_CM, SAMPLING_OPER_POSITION_LONG, SAMPLING_OPER_POSITION_LAT, "); + } else if (outputType == ExtractionOutputType.PAMPA) { + query.append("SAMPLING_OPER_TIME, SURVEY_BOTTOM_DEPTH, SURVEY_QUSERS, "); + } + query.append("MEAS_INDIV_ID FROM ").append(context.getRawTableName()); + + return extractionResultDao.queryUpdate(query.toString(), null); + } + + private int insertSplitData(ExtractionContextDTO context, ExtractionOutputType outputType) { + + // common part + StringBuilder insertPart = new StringBuilder(); + insertPart.append("INSERT INTO ").append(context.getResultTableName()).append(LS); + insertPart.append("SELECT COMMON.SURVEY_ID, COMMON.SURVEY_PROG_CD, COMMON.MON_LOC_NM, COMMON.SURVEY_DT, COMMON.SAMPLING_OPER_ID, COMMON.SAMPLING_OPER_LB, COMMON.MON_LOC_ID, "); + insertPart.append("COMMON.MON_LOC_LB, COMMON.ORDER_ITEM_NM, COMMON.SURVEY_POSITION_LONG, COMMON.SURVEY_POSITION_LAT, COMMON.SAMPLING_EQUIPMENT_NM, COMMON.SAMPLING_OPER_DEP_NM, "); + if (outputType != ExtractionOutputType.PAMPA) { + insertPart.append("COMMON.SURVEY_QUSERS, "); + } + insertPart.append("COMMON.SURVEY_LB, COMMON.SAMPLING_OPER_SIZE, COMMON.SAMPLING_OPER_SIZE_UNIT_SYMBOL, "); + if (outputType == ExtractionOutputType.COMPLETE) { + insertPart.append("COMMON.ORDER_ITEM_TYPE_NM, COMMON.ORDER_ITEM_CD, COMMON.MON_LOC_ORDER_ITEM_NUMBER, "); + insertPart.append("COMMON.SURVEY_TIME, COMMON.SURVEY_CM, COMMON.SURVEY_CONTROL_DT, COMMON.SURVEY_VALID_DT, COMMON.SURVEY_QUAL_FLAG, "); + insertPart.append("COMMON.SURVEY_QUALIF_DT, COMMON.SURVEY_QUALIF_CM, COMMON.SURVEY_INHERITED_POSITION, COMMON.SAMPLING_OPER_TIME, "); + insertPart.append("COMMON.SAMPLING_OPER_DEPTH, COMMON.SAMPLING_OPER_MIN_DEPTH, COMMON.SAMPLING_OPER_MAX_DEPTH, "); + insertPart.append("COMMON.SAMPLING_OPER_INHERITED_POSITION, COMMON.SAMPLING_OPER_DEPTH_UNIT_SYMBOL, COMMON.SAMPLING_OPER_DEPTH_UNIT, "); + insertPart.append("COMMON.SAMPLING_OPER_CM, COMMON.SAMPLING_EQUIPMENT_SIZE, COMMON.SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, COMMON.SAMPLING_OPER_NUMBER_INDIV, "); + insertPart.append("COMMON.SAMPLING_OPER_CONTROL_DT, COMMON.SAMPLING_OPER_VALID_DT, COMMON.SAMPLING_OPER_QUAL_FLAG, COMMON.SAMPLING_OPER_QUALIF_DT, "); + insertPart.append("COMMON.SAMPLING_OPER_QUALIF_CM, COMMON.SAMPLING_OPER_POSITION_LONG, COMMON.SAMPLING_OPER_POSITION_LAT, "); + } else if (outputType == ExtractionOutputType.PAMPA) { + insertPart.append("COMMON.SAMPLING_OPER_TIME, COMMON.SURVEY_BOTTOM_DEPTH, COMMON.SURVEY_QUSERS, "); + } + insertPart.append("COMMON.MEAS_INDIV_ID, "); + + StringBuilder query = new StringBuilder(insertPart); + + // all pmfm part + StringBuilder join = new StringBuilder(); + if (!context.isPmfmInfosEmpty()) { + for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { + query.append(pmfmInfo.getAlias()).append(".MEAS_ID, "); + query.append(pmfmInfo.getAlias()).append(".TAXON_MEAS_ID, "); + query.append(pmfmInfo.getAlias()).append(".MEAS_NUMER_VALUE, "); + query.append(pmfmInfo.getAlias()).append(".QUAL_VALUE_NM, "); + query.append(pmfmInfo.getAlias()).append(".DEP_NM, "); + if (pmfmInfo.isIndividual()) { + query.append(pmfmInfo.getAlias()).append(".TAXON_NAME_NM, "); + query.append(pmfmInfo.getAlias()).append(".TAXON_GROUP_NM, "); + query.append(pmfmInfo.getAlias()).append(".MEAS_CM, "); + if (outputType == ExtractionOutputType.PAMPA) { + query.append(pmfmInfo.getAlias()).append(".TAXON_PAMPA, "); + } else { + query.append(pmfmInfo.getAlias()).append(".INPUT_TAXON_NAME_NM, "); + query.append(pmfmInfo.getAlias()).append(".INPUT_TAXON_NAME_ID, "); + } + } + join.append("LEFT OUTER JOIN ").append(pmfmInfo.getTableName()).append(" ").append(pmfmInfo.getAlias()).append(" ON "); + join.append(pmfmInfo.isSurvey() ? "COMMON.SURVEY_ID = " + pmfmInfo.getAlias() + ".SURVEY_ID" : "COMMON.SAMPLING_OPER_ID = " + pmfmInfo.getAlias() + ".SAMPLING_OPER_ID"); + join.append(pmfmInfo.isIndividual() ? " AND COMMON.MEAS_INDIV_ID = " + pmfmInfo.getAlias() + ".MEAS_INDIV_ID" : ""); + join.append(LS); + } + } + + query = new StringBuilder(trimAtLastSequence(query.toString(), ",")).append(LS); + + // add from clause + query.append("FROM ").append(context.getCommonTableName()).append(" COMMON").append(LS); + // add all join tables + query.append(join); + // filter out non individual measurements + query.append("WHERE COMMON.MEAS_INDIV_ID IS NOT NULL"); + + int nbInsert = extractionResultDao.queryUpdate(query.toString(), null); + + // add rows from non individual measurements that are not already inserted + query = new StringBuilder(insertPart); + + // all pmfm part + // TODO maybe simplify joins : remove individual pmfms + join = new StringBuilder(); + if (!context.isPmfmInfosEmpty()) { + for (ExtractionPmfmInfoDTO pmfmInfo : context.getPmfmInfos()) { + query.append(pmfmInfo.getAlias()).append(".MEAS_ID, "); + query.append(pmfmInfo.getAlias()).append(".TAXON_MEAS_ID, "); + query.append(pmfmInfo.getAlias()).append(".MEAS_NUMER_VALUE, "); + query.append(pmfmInfo.getAlias()).append(".QUAL_VALUE_NM, "); + query.append(pmfmInfo.getAlias()).append(".DEP_NM, "); + if (pmfmInfo.isIndividual()) { + query.append(pmfmInfo.getAlias()).append(".TAXON_NAME_NM, "); + query.append(pmfmInfo.getAlias()).append(".TAXON_GROUP_NM, "); + query.append(pmfmInfo.getAlias()).append(".MEAS_CM, "); + if (outputType == ExtractionOutputType.PAMPA) { + query.append(pmfmInfo.getAlias()).append(".TAXON_PAMPA, "); + } else { + query.append(pmfmInfo.getAlias()).append(".INPUT_TAXON_NAME_NM, "); + query.append(pmfmInfo.getAlias()).append(".INPUT_TAXON_NAME_ID, "); + } + } + join.append("LEFT OUTER JOIN ").append(pmfmInfo.getTableName()).append(" ").append(pmfmInfo.getAlias()).append(" ON "); + join.append(pmfmInfo.isSurvey() ? "COMMON.SURVEY_ID = " + pmfmInfo.getAlias() + ".SURVEY_ID" : "COMMON.SAMPLING_OPER_ID = " + pmfmInfo.getAlias() + ".SAMPLING_OPER_ID"); + join.append(pmfmInfo.isIndividual() ? " AND COMMON.MEAS_INDIV_ID = " + pmfmInfo.getAlias() + ".MEAS_INDIV_ID" : ""); + join.append(LS); + } + } + + query = new StringBuilder(trimAtLastSequence(query.toString(), ",")).append(LS); + + // add from clause + query.append("FROM ").append(context.getCommonTableName()).append(" COMMON").append(LS); + // add all join tables + query.append(join); + // filter out already present individual measurements + query.append("WHERE COMMON.MEAS_INDIV_ID IS NULL AND NOT EXISTS (SELECT * FROM "); + query.append(context.getResultTableName()); + query.append(" SPLIT WHERE SPLIT.SURVEY_ID = COMMON.SURVEY_ID AND SPLIT.SAMPLING_OPER_ID = COMMON.SAMPLING_OPER_ID AND SPLIT.MEAS_INDIV_ID IS NOT NULL )"); + + nbInsert += extractionResultDao.queryUpdate(query.toString(), null); + + return nbInsert; + } + + private void writeExtraction(ExtractionContextDTO context, ExtractionOutputType outputType, File outputFile) throws IOException { + + Map fieldNamesByAlias = new HashMap<>(); + Map decimalFormats = new HashMap<>(); + + // taxon & taxon group fields + String taxonField = "NULL AS TAXON_NAME_NM, "; + String taxonGroupField = "NULL AS TAXON_GROUP_NM, "; + String taxonPampaField = "NULL AS TAXON_PAMPA, "; + String inputTaxonNameField = "NULL AS INPUT_TAXON_NAME_NM, "; + String inputTaxonIdField = "NULL AS INPUT_TAXON_NAME_ID, "; + String commentField = "NULL AS MEAS_CM, "; + + // get only individual pmfm info + List individualPmfmInfos = ReefDbBeans.filterCollection(context.getPmfmInfos(), ExtractionPmfmInfoDTO::isIndividual); + if (individualPmfmInfos.size() >= 2) { + + // must coalesce these fields + taxonField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "TAXON_NAME_NM") + ") AS TAXON_NAME_NM, "; + taxonGroupField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "TAXON_GROUP_NM") + ") AS TAXON_GROUP_NM, "; + if (outputType == ExtractionOutputType.PAMPA) { + taxonPampaField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "TAXON_PAMPA") + ") AS TAXON_PAMPA, "; + } else { + inputTaxonNameField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "INPUT_TAXON_NAME_NM") + ") AS INPUT_TAXON_NAME_NM, "; + inputTaxonIdField = "COALESCE(" + getAliasedFields(individualPmfmInfos, "INPUT_TAXON_NAME_ID") + ") AS INPUT_TAXON_NAME_ID, "; + } + + } else if (individualPmfmInfos.size() == 1) { + + // only 1 pmfm, no coalesce + ExtractionPmfmInfoDTO pmfmInfo = individualPmfmInfos.get(0); + taxonField = pmfmInfo.getAlias() + "_TAXON_NAME_NM AS TAXON_NAME_NM, "; + taxonGroupField = pmfmInfo.getAlias() + "_TAXON_GROUP_NM AS TAXON_GROUP_NM, "; + if (outputType == ExtractionOutputType.PAMPA) { + taxonPampaField = pmfmInfo.getAlias() + "_TAXON_PAMPA AS TAXON_PAMPA, "; + } else { + inputTaxonNameField = pmfmInfo.getAlias() + "_INPUT_TAXON_NAME_NM AS INPUT_TAXON_NAME_NM, "; + inputTaxonIdField = pmfmInfo.getAlias() + "_INPUT_TAXON_NAME_ID AS INPUT_TAXON_NAME_ID, "; + } + + } + + // use concat distinct function for comments + // Mantis #35443 : don't call the function when no individual pmfm infos + if (!individualPmfmInfos.isEmpty()) { + commentField = getConcatDistinctFunction("MEAS_CM") + "(ARRAY[" + getAliasedFields(individualPmfmInfos, "MEAS_CM") + "], ' - ') AS MEAS_CM, "; + } + + // measurements (individual first) + StringBuilder measurementFields = new StringBuilder(); + String departmentField = "NULL AS MEAS_DEP_NM, "; + String measIds = "NULL AS MEAS_IDS, "; + String taxonMeasIds = "NULL AS TAXON_MEAS_IDS, "; + + if (!context.isPmfmInfosEmpty()) { + + DecoratorService decoratorService = ReefDbServiceLocator.instance().getDecoratorService(); + + // Sort by individual measurements first + List sortedPmfmInfos = sortPmfmInfos(context.getPmfmInfos()); + for (ExtractionPmfmInfoDTO pmfmInfo : sortedPmfmInfos) { + + // decorate the PMFM to obtain field name + PmfmDTO pmfm = pmfmDao.getPmfmById(pmfmInfo.getPmfmId()); + String pmfmName = decoratorService.getDecoratorByType(PmfmDTO.class, DecoratorService.FOR_EXTRACTION).toString(pmfm); + + // add prefix + String formattedPmfmName = String.format("%s_%s", + pmfmInfo.isSurvey() ? t("reefdb.service.extraction.fieldNamePrefix.SURVEY") : t("reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER"), + pmfmName); + + measurementFields.append(pmfmInfo.getAlias()); + // get the correct value depending on parameter type + measurementFields.append(pmfm.getParameter().isQualitative() ? "_QUAL_VALUE_NM" : "_MEAS_NUMER_VALUE"); + measurementFields.append(" AS ").append(pmfmInfo.getAlias()).append("_VALUE, "); + + fieldNamesByAlias.put(pmfmInfo.getAlias() + "_VALUE", formattedPmfmName); + } + + // use concat_distinct for measIds & taxonMeasIds + measIds = getConcatDistinctFunction("MEAS_ID") + "(ARRAY[" + getAliasedFields(sortedPmfmInfos, "MEAS_ID") + "], '|') AS MEAS_IDS, "; + taxonMeasIds = getConcatDistinctFunction("MEAS_ID") + "(ARRAY[" + getAliasedFields(sortedPmfmInfos, "TAXON_MEAS_ID") + "], '|') AS TAXON_MEAS_IDS, "; + + // must use concat_distinct function for this field + departmentField = getConcatDistinctFunction("DEP_NM") + "(ARRAY[" + getAliasedFields(sortedPmfmInfos, "DEP_NM") + "], ',') AS MEAS_DEP_NM, "; + + } + + // common field names + fieldNamesByAlias.put("SURVEY_PROG_CD", t("reefdb.service.extraction.fieldName.SURVEY_PROG_CD")); + fieldNamesByAlias.put("MON_LOC_NM", t("reefdb.service.extraction.fieldName.MON_LOC_NM")); + fieldNamesByAlias.put("SURVEY_DT", t("reefdb.service.extraction.fieldName.SURVEY_DT")); + fieldNamesByAlias.put("SAMPLING_OPER_LB", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_LB")); + fieldNamesByAlias.put("MON_LOC_ID", t("reefdb.service.extraction.fieldName.MON_LOC_ID")); + fieldNamesByAlias.put("MON_LOC_LB", t("reefdb.service.extraction.fieldName.MON_LOC_LB")); + fieldNamesByAlias.put("ORDER_ITEM_NM", t("reefdb.service.extraction.fieldName.ORDER_ITEM_NM")); + fieldNamesByAlias.put("SURVEY_POSITION_LONG_MIN", t("reefdb.service.extraction.fieldName.SURVEY_POSITION_LONG_MIN")); + fieldNamesByAlias.put("SURVEY_POSITION_LONG_MAX", t("reefdb.service.extraction.fieldName.SURVEY_POSITION_LONG_MAX")); + fieldNamesByAlias.put("SURVEY_POSITION_LAT_MIN", t("reefdb.service.extraction.fieldName.SURVEY_POSITION_LAT_MIN")); + fieldNamesByAlias.put("SURVEY_POSITION_LAT_MAX", t("reefdb.service.extraction.fieldName.SURVEY_POSITION_LAT_MAX")); + fieldNamesByAlias.put("SAMPLING_EQUIPMENT_NM", t("reefdb.service.extraction.fieldName.SAMPLING_EQUIPMENT_NM")); + fieldNamesByAlias.put("SAMPLING_OPER_DEP_NM", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_DEP_NM")); + fieldNamesByAlias.put("SURVEY_QUSERS", t("reefdb.service.extraction.fieldName.SURVEY_QUSERS")); + fieldNamesByAlias.put("SURVEY_LB", t("reefdb.service.extraction.fieldName.SURVEY_LB")); + fieldNamesByAlias.put("SAMPLING_OPER_SIZE", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_SIZE")); + fieldNamesByAlias.put("SAMPLING_OPER_SIZE_UNIT_SYMBOL", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_SIZE_UNIT_SYMBOL")); + fieldNamesByAlias.put("TAXON_NAME_NM", t("reefdb.service.extraction.fieldName.TAXON_NAME_NM")); + fieldNamesByAlias.put("INPUT_TAXON_NAME_NM", t("reefdb.service.extraction.fieldName.INPUT_TAXON_NAME_NM")); + fieldNamesByAlias.put("INPUT_TAXON_NAME_ID", t("reefdb.service.extraction.fieldName.INPUT_TAXON_NAME_ID")); + fieldNamesByAlias.put("TAXON_GROUP_NM", t("reefdb.service.extraction.fieldName.TAXON_GROUP_NM")); + fieldNamesByAlias.put("MEAS_CM", t("reefdb.service.extraction.fieldName.MEAS_CM")); + fieldNamesByAlias.put("MEAS_DEP_NM", t("reefdb.service.extraction.fieldName.MEAS_DEP_NM")); + fieldNamesByAlias.put("MEAS_IDS", t("reefdb.service.extraction.fieldName.MEAS_IDS")); + fieldNamesByAlias.put("TAXON_MEAS_IDS", t("reefdb.service.extraction.fieldName.TAXON_MEAS_IDS")); + + // the final query + StringBuilder query = new StringBuilder(); + query.append("SELECT SURVEY_PROG_CD, MON_LOC_NM, SURVEY_DT, SAMPLING_OPER_LB, "); + query.append(taxonField); + query.append(taxonGroupField); + query.append(measurementFields); + query.append(departmentField); + query.append("MON_LOC_ID, MON_LOC_LB, ORDER_ITEM_NM, SURVEY_POSITION_LONG AS SURVEY_POSITION_LONG_MIN, SURVEY_POSITION_LONG AS SURVEY_POSITION_LONG_MAX, "); + query.append("SURVEY_POSITION_LAT AS SURVEY_POSITION_LAT_MIN, SURVEY_POSITION_LAT AS SURVEY_POSITION_LAT_MAX, SAMPLING_EQUIPMENT_NM, SAMPLING_OPER_DEP_NM, "); + if (outputType != ExtractionOutputType.PAMPA) { + query.append("SURVEY_QUSERS, "); + } + query.append("SURVEY_LB, SAMPLING_OPER_SIZE, SAMPLING_OPER_SIZE_UNIT_SYMBOL, "); + query.append(commentField); + + // Adaptation for PAMPA (see Mantis #32080) + if (outputType == ExtractionOutputType.PAMPA) { + query.append("SAMPLING_OPER_ID, TO_CHAR(TIMESTAMP(SAMPLING_OPER_TIME), 'HH24:MI:SS') AS SAMPLING_OPER_TIME, SURVEY_BOTTOM_DEPTH, SURVEY_QUSERS, "); + query.append(taxonPampaField); + + fieldNamesByAlias.put("SAMPLING_OPER_ID", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_ID")); + fieldNamesByAlias.put("SAMPLING_OPER_TIME", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_TIME")); + fieldNamesByAlias.put("SURVEY_BOTTOM_DEPTH", t("reefdb.service.extraction.fieldName.SURVEY_BOTTOM_DEPTH")); + decimalFormats.put("SURVEY_BOTTOM_DEPTH", getDefaultNumericFormat()); + fieldNamesByAlias.put("TAXON_PAMPA", t("reefdb.service.extraction.fieldName.TAXON_PAMPA")); + + } else { + + // Add input taxon + query.append(inputTaxonNameField); + query.append(inputTaxonIdField); + + // Add measId and taxonMeasId for other output types + query.append(measIds).append(taxonMeasIds); + } + + if (outputType == ExtractionOutputType.COMPLETE) { + query.append("ORDER_ITEM_TYPE_NM, ORDER_ITEM_CD, MON_LOC_ORDER_ITEM_NUMBER, "); + query.append("TO_CHAR(TIMESTAMP(SURVEY_TIME), 'HH24:MI:SS') AS SURVEY_TIME, SURVEY_CM, SURVEY_CONTROL_DT, SURVEY_VALID_DT, SURVEY_QUAL_FLAG, "); + query.append("SURVEY_QUALIF_DT, SURVEY_QUALIF_CM, SURVEY_INHERITED_POSITION, TO_CHAR(TIMESTAMP(SAMPLING_OPER_TIME), 'HH24:MI:SS') AS SAMPLING_OPER_TIME, "); + query.append("SAMPLING_OPER_DEPTH, SAMPLING_OPER_MIN_DEPTH, SAMPLING_OPER_MAX_DEPTH, "); + query.append("SAMPLING_OPER_INHERITED_POSITION, SAMPLING_OPER_DEPTH_UNIT_SYMBOL, SAMPLING_OPER_DEPTH_UNIT, "); + query.append("SAMPLING_OPER_CM, SAMPLING_EQUIPMENT_SIZE, SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL, SAMPLING_OPER_NUMBER_INDIV, "); + query.append("SAMPLING_OPER_CONTROL_DT, SAMPLING_OPER_VALID_DT, SAMPLING_OPER_QUAL_FLAG, SAMPLING_OPER_QUALIF_DT, "); + query.append("SAMPLING_OPER_QUALIF_CM, SAMPLING_OPER_POSITION_LONG AS SAMPLING_OPER_POSITION_LONG_MIN, SAMPLING_OPER_POSITION_LONG AS SAMPLING_OPER_POSITION_LONG_MAX, "); + query.append("SAMPLING_OPER_POSITION_LAT AS SAMPLING_OPER_POSITION_LAT_MIN, SAMPLING_OPER_POSITION_LAT AS SAMPLING_OPER_POSITION_LAT_MAX, MEAS_INDIV_ID, "); + + fieldNamesByAlias.put("ORDER_ITEM_TYPE_NM", t("reefdb.service.extraction.fieldName.ORDER_ITEM_TYPE_NM")); + fieldNamesByAlias.put("ORDER_ITEM_CD", t("reefdb.service.extraction.fieldName.ORDER_ITEM_CD")); + fieldNamesByAlias.put("MON_LOC_ORDER_ITEM_NUMBER", t("reefdb.service.extraction.fieldName.MON_LOC_ORDER_ITEM_NUMBER")); + fieldNamesByAlias.put("SURVEY_TIME", t("reefdb.service.extraction.fieldName.SURVEY_TIME")); + fieldNamesByAlias.put("SURVEY_CM", t("reefdb.service.extraction.fieldName.SURVEY_CM")); + fieldNamesByAlias.put("SURVEY_CONTROL_DT", t("reefdb.service.extraction.fieldName.SURVEY_CONTROL_DT")); + fieldNamesByAlias.put("SURVEY_VALID_DT", t("reefdb.service.extraction.fieldName.SURVEY_VALID_DT")); + fieldNamesByAlias.put("SURVEY_QUAL_FLAG", t("reefdb.service.extraction.fieldName.SURVEY_QUAL_FLAG")); + fieldNamesByAlias.put("SURVEY_QUALIF_DT", t("reefdb.service.extraction.fieldName.SURVEY_QUALIF_DT")); + fieldNamesByAlias.put("SURVEY_QUALIF_CM", t("reefdb.service.extraction.fieldName.SURVEY_QUALIF_CM")); + fieldNamesByAlias.put("SURVEY_INHERITED_POSITION", t("reefdb.service.extraction.fieldName.SURVEY_INHERITED_POSITION")); + fieldNamesByAlias.put("SAMPLING_OPER_TIME", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_TIME")); + fieldNamesByAlias.put("SAMPLING_OPER_DEPTH", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_DEPTH")); + fieldNamesByAlias.put("SAMPLING_OPER_MIN_DEPTH", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_MIN_DEPTH")); + fieldNamesByAlias.put("SAMPLING_OPER_MAX_DEPTH", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_MAX_DEPTH")); + fieldNamesByAlias.put("SAMPLING_OPER_INHERITED_POSITION", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_INHERITED_POSITION")); + fieldNamesByAlias.put("SAMPLING_OPER_DEPTH_UNIT_SYMBOL", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_DEPTH_UNIT_SYMBOL")); + fieldNamesByAlias.put("SAMPLING_OPER_DEPTH_UNIT", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_DEPTH_UNIT")); + fieldNamesByAlias.put("SAMPLING_OPER_CM", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_CM")); + fieldNamesByAlias.put("SAMPLING_EQUIPMENT_SIZE", t("reefdb.service.extraction.fieldName.SAMPLING_EQUIPMENT_SIZE")); + fieldNamesByAlias.put("SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL", t("reefdb.service.extraction.fieldName.SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL")); + fieldNamesByAlias.put("SAMPLING_OPER_NUMBER_INDIV", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_NUMBER_INDIV")); + fieldNamesByAlias.put("SAMPLING_OPER_CONTROL_DT", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_CONTROL_DT")); + fieldNamesByAlias.put("SAMPLING_OPER_VALID_DT", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_VALID_DT")); + fieldNamesByAlias.put("SAMPLING_OPER_QUAL_FLAG", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_QUAL_FLAG")); + fieldNamesByAlias.put("SAMPLING_OPER_QUALIF_DT", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_QUALIF_DT")); + fieldNamesByAlias.put("SAMPLING_OPER_QUALIF_CM", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_QUALIF_CM")); + fieldNamesByAlias.put("SAMPLING_OPER_POSITION_LONG_MIN", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LONG_MIN")); + fieldNamesByAlias.put("SAMPLING_OPER_POSITION_LONG_MAX", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LONG_MAX")); + fieldNamesByAlias.put("SAMPLING_OPER_POSITION_LAT_MIN", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LAT_MIN")); + fieldNamesByAlias.put("SAMPLING_OPER_POSITION_LAT_MAX", t("reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LAT_MAX")); + fieldNamesByAlias.put("MEAS_INDIV_ID", t("reefdb.service.extraction.fieldName.MEAS_INDIV_ID")); + } + + // remove last comma + query = new StringBuilder(trimAtLastSequence(query.toString(), ",")).append(LS); + + // add ordering clause + query.append("FROM "); + query.append(context.getResultTableName()); + query.append(" ORDER BY SURVEY_PROG_CD, MON_LOC_NM, SURVEY_DT, SAMPLING_OPER_LB, MEAS_INDIV_ID"); + + // some field formats + Map dateFormats = Maps.newHashMap(); + dateFormats.put("SURVEY_DT", "dd/MM/yyyy"); + + // write result + extractionResultDao.dumpQueryToCSV(outputFile, query.toString(), fieldNamesByAlias, dateFormats, decimalFormats, null); + + } + + private List sortPmfmInfos(Collection pmfmInfos) { + + List sorted = new ArrayList<>(pmfmInfos); + + sorted.sort((o1, o2) -> { + // individual first + int individualFirst = -Boolean.compare(o1.isIndividual(), o2.isIndividual()); + if (individualFirst == 0) { + // then sampling operation first + return Boolean.compare(o1.isSurvey(), o2.isSurvey()); + } + return individualFirst; + }); + + return sorted; + } + + private String getAliasedFields(List pmfmInfos, final String fieldName) { + + return Joiner.on(',').join(ReefDbBeans.transformCollection(pmfmInfos, pmfmInfo -> pmfmInfo.getAlias() + "_" + fieldName)); + } + + private Map getQueryBindings(ExtractionDTO extraction) { + Map bindings = new HashedMap<>(); + FilterDTO periodFilter = getPeriodFilter(extraction); + for (int i = 0; i < periodFilter.getElements().size(); i++) { + ExtractionPeriodDTO period = (ExtractionPeriodDTO) periodFilter.getElements().get(i); + bindings.put(EXTRACTION_START_DATE + i, Dates.convertToDate(period.getStartDate(), config.getDbTimezone())); + bindings.put(EXTRACTION_END_DATE + i, Dates.convertToDate(period.getEndDate(), config.getDbTimezone())); + } + return bindings; + } + + private String getFromClauseMinimal() { + + // generate the minimal from clause + return "FROM SURVEY S" + LS + + "INNER JOIN MONITORING_LOCATION ML ON ML.MON_LOC_ID = S.MON_LOC_ID" + LS + + "INNER JOIN SURVEY_PROG PROG ON PROG.SURVEY_ID = S.SURVEY_ID" + LS; + } + + private String getWhereClause(ExtractionDTO extraction) { + + // generate the main WHERE clause + StringBuilder whereClause = new StringBuilder("WHERE ("); + for (int i = 0; i < getPeriodFilter(extraction).getElements().size(); i++) { + whereClause.append("(S.SURVEY_DT >= :" + EXTRACTION_START_DATE).append(i); + whereClause.append(" AND S.SURVEY_DT <= :").append(EXTRACTION_END_DATE).append(i).append(") OR "); + } + whereClause = new StringBuilder(trimAtLastSequence(whereClause.toString(), " OR")).append(")").append(LS); + + List programCodes = ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.PROGRAM); + if (CollectionUtils.isNotEmpty(programCodes)) { + whereClause.append("AND PROG.PROG_CD IN (").append(Daos.getInStatementFromStringCollection(programCodes)).append(")").append(LS); + } + + List locationIds = ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.LOCATION); + if (CollectionUtils.isNotEmpty(locationIds)) { + whereClause.append("AND S.MON_LOC_ID IN (").append(Daos.getInStatementFromIntegerCollection(locationIds)).append(")").append(LS); + } + + List departmentIds = ReefDbBeans.getFilterElementsIds(extraction, ExtractionFilterValues.DEPARTMENT); + if (CollectionUtils.isNotEmpty(departmentIds)) { + whereClause.append("AND S.REC_DEP_ID IN (").append(Daos.getInStatementFromIntegerCollection(departmentIds)).append(")").append(LS); + } + + return whereClause.toString(); + } + + private String trimAtLastSequence(String string, String sequence) { + return string.substring(0, string.lastIndexOf(sequence)); + } + + private FilterDTO getPeriodFilter(ExtractionDTO extraction) { + FilterDTO periodFilter = ReefDbBeans.getFilterOfType(extraction, ExtractionFilterValues.PERIOD); + Assert.notNull(periodFilter); + Assert.notEmpty(periodFilter.getElements()); + return periodFilter; + } + + private String getOrderItemTypeCode(ExtractionDTO extraction) { + FilterDTO orderItemTypeFilter = ReefDbBeans.getFilterOfType(extraction, ExtractionFilterValues.ORDER_ITEM_TYPE); + Assert.notNull(orderItemTypeFilter); + Assert.notEmpty(orderItemTypeFilter.getElements()); + Assert.equals(orderItemTypeFilter.getElements().size(), 1); + + GroupingTypeDTO groupingType = (GroupingTypeDTO) orderItemTypeFilter.getElements().get(0); + Assert.notNull(groupingType); + Assert.notBlank(groupingType.getCode()); + return groupingType.getCode(); + } + + private String getDefaultNumericFormat() { + return "#." + StringUtils.repeat("#", 8); // 8 decimals should be enough by default (decimal 0 is erased) + } + +} diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/service/observation/ObservationServiceImpl.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/observation/ObservationServiceImpl.java index c334a1dc548ed3f70a6d2780f661c0ea3039b0fb..6aeb5dc797de749e5b044c598587f12306fd6e8c 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/service/observation/ObservationServiceImpl.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/observation/ObservationServiceImpl.java @@ -29,7 +29,6 @@ import fr.ifremer.quadrige3.core.ProgressionCoreModel; import fr.ifremer.quadrige3.core.dao.technical.Assert; import fr.ifremer.quadrige3.core.dao.technical.Dates; import fr.ifremer.quadrige3.core.dao.technical.Times; -import fr.ifremer.quadrige3.core.security.SecurityContextHelper; import fr.ifremer.quadrige3.ui.core.dto.referential.BaseReferentialDTO; import fr.ifremer.reefdb.config.ReefDbConfiguration; import fr.ifremer.reefdb.dao.administration.user.ReefDbDepartmentDao; @@ -177,7 +176,8 @@ public class ObservationServiceImpl implements ObservationInternalService { Collection programCodes; // if no filter on single program, force filter on writable programs if (StringUtils.isBlank(programCode)) { - programCodes = programStrategyService.getWritableProgramCodesByQuserId(SecurityContextHelper.getQuadrigeUserId()); + // get writable programs including locals (Mantis #49917) + programCodes = programStrategyService.getWritablePrograms().stream().map(ProgramDTO::getCode).collect(Collectors.toSet()); } else { programCodes = Collections.singleton(programCode); } @@ -438,6 +438,7 @@ public class ObservationServiceImpl implements ObservationInternalService { Assert.notNull(duplicateSurvey); // Remove ID duplicateSurvey.setId(null); + duplicateSurvey.setDirty(true); // duplicated data to keep: if (survey.isObserversEmpty() && survey.getId() != null) { @@ -599,8 +600,10 @@ public class ObservationServiceImpl implements ObservationInternalService { if (dataContext.isContextFiltered(FilterTypeValues.PROGRAM) && !forceNoContext) { result = contextService.getFilteredPrograms(dataContext.getContextId()); // context filtered programs can eventually out of user rights, filter them - Set writableProgramCodes = programStrategyService.getWritableProgramCodesByQuserId(dataContext.getPrincipalUserId()); - result = result.stream().filter(programDTO -> writableProgramCodes.contains(programDTO.getCode())).collect(Collectors.toList()); +// Set writableProgramCodes = programStrategyService.getWritableProgramCodesByQuserId(dataContext.getPrincipalUserId()); + // Get correct list of writable programs (Mantis #49913) + List writablePrograms = programStrategyService.getWritableProgramsByUserAndStatus(dataContext.getPrincipalUserId(), StatusFilter.ACTIVE); + result = result.stream().filter(writablePrograms::contains).collect(Collectors.toList()); } else if (campaignId != null) { result = programStrategyService.getWritableProgramsByCampaignId(campaignId); } else { diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/service/referential/ReferentialService.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/referential/ReferentialService.java index d04f2d0782df253b828d1e6fff5a10c60df9b053..e27c487b6b0b53054fe40dffaff684069ac989e3 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/service/referential/ReferentialService.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/referential/ReferentialService.java @@ -1215,4 +1215,9 @@ public interface ReferentialService { */ QualitativeValueDTO getQualitativeValue(int qualitativeValueId); - List getQualitativeValues(Collection qualitativeValueIds);} + List getQualitativeValues(Collection qualitativeValueIds); + + List getQualitativeValues(String parameterCode); +} + + diff --git a/reefdb-core/src/main/java/fr/ifremer/reefdb/service/referential/ReferentialServiceImpl.java b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/referential/ReferentialServiceImpl.java index df42b9ade149ef6a7825f9379734edb665b5e912..3ebcba90954e1cae1e352efc1e1572769f8475eb 100644 --- a/reefdb-core/src/main/java/fr/ifremer/reefdb/service/referential/ReferentialServiceImpl.java +++ b/reefdb-core/src/main/java/fr/ifremer/reefdb/service/referential/ReferentialServiceImpl.java @@ -1464,6 +1464,14 @@ public class ReferentialServiceImpl implements ReferentialService { return result; } + @Override + public List getQualitativeValues(String parameterCode) { + if (StringUtils.isBlank(parameterCode)) + return null; + + return qualitativeValueDao.getQualitativeValuesByParameterCode(parameterCode); + } + /** * {@inheritDoc} */ diff --git a/reefdb-core/src/main/resources/i18n/reefdb-core_en_GB.properties b/reefdb-core/src/main/resources/i18n/reefdb-core_en_GB.properties index 71dbf5e72535227df3dbe495fc254598a8068087..652659ad8fb229787838b72878f92ec12d09cbca 100644 --- a/reefdb-core/src/main/resources/i18n/reefdb-core_en_GB.properties +++ b/reefdb-core/src/main/resources/i18n/reefdb-core_en_GB.properties @@ -152,6 +152,7 @@ reefdb.config.option.synchro.useServer.description= reefdb.config.option.synchro.zipFile.prefix.description= reefdb.config.option.timezone.description= reefdb.config.option.tmp.directory.description= +reefdb.config.option.transcribingItemType.label.pmfmExtraction.description= reefdb.config.option.transcribingItemType.label.pmfmNm.description= reefdb.config.option.ui.autoPopupNumberEditor.description= reefdb.config.option.ui.color.alternateRow.description= diff --git a/reefdb-core/src/main/resources/i18n/reefdb-core_fr_FR.properties b/reefdb-core/src/main/resources/i18n/reefdb-core_fr_FR.properties index bc65fe83838e29d97b62a92f259f79794f523ef9..cffa2d1c425545db5f5b9229362c60c2be2ba7f3 100644 --- a/reefdb-core/src/main/resources/i18n/reefdb-core_fr_FR.properties +++ b/reefdb-core/src/main/resources/i18n/reefdb-core_fr_FR.properties @@ -118,7 +118,7 @@ reefdb.config.option.synchro.useServer.description= reefdb.config.option.synchro.zipFile.prefix.description= reefdb.config.option.timezone.description=Fuseau horaire du poste client reefdb.config.option.tmp.directory.description=Répertoire temporaire de l'application -reefdb.config.option.transcribingItemType.id.pmfmNm.description= +reefdb.config.option.transcribingItemType.label.pmfmExtraction.description=Libellé du type de transcodage pour les noms des PSFMU pour les extractions reefdb.config.option.transcribingItemType.label.pmfmNm.description=Libellé du type de transcodage pour les noms des PSFMU reefdb.config.option.ui.autoPopupNumberEditor.description=Ouvre automatiquement la calculette pour la saisie des nombres reefdb.config.option.ui.color.alternateRow.description=Couleur de fond des lignes paires (non sélectionnée) dans un tableau @@ -291,12 +291,17 @@ reefdb.service.common.progression=%s \: traitement de %s/%s reefdb.service.control=Contrôle reefdb.service.controlRule.invalid.message=La règle de contrôle '%s' n'est pas respectée reefdb.service.extraction.error=Une erreur s'est produite lors de l'extration. -reefdb.service.extraction.fieldName.INPUT_TAXON_NAME_ID=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Identifiant_interne_TAXON_NAME_ID -reefdb.service.extraction.fieldName.INPUT_TAXON_NAME_NM=Taxon_saisi +reefdb.service.extraction.fieldName.CAMPAIGN_NM=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Campagne +reefdb.service.extraction.fieldName.INPUT_TAXON_NAME_ID= +reefdb.service.extraction.fieldName.INPUT_TAXON_NAME_NM= +reefdb.service.extraction.fieldName.MEAS_ANALYST_NM=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Organisme_analyste reefdb.service.extraction.fieldName.MEAS_CM=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Commentaires -reefdb.service.extraction.fieldName.MEAS_DEP_NM=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Organisme_analyste +reefdb.service.extraction.fieldName.MEAS_DEP_NM= reefdb.service.extraction.fieldName.MEAS_IDS=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Identifiants_interne_MEAS_ID reefdb.service.extraction.fieldName.MEAS_INDIV_ID=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Numero_individu +reefdb.service.extraction.fieldName.MEAS_QUALIF_CM=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Commentaire_Qualif +reefdb.service.extraction.fieldName.MEAS_QUALIF_DT=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Date_Qualif +reefdb.service.extraction.fieldName.MEAS_QUAL_FLAG_NM=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Niveau_qualite reefdb.service.extraction.fieldName.MON_LOC_ID=${reefdb.service.extraction.fieldNamePrefix.MON_LOC}_Identifiant reefdb.service.extraction.fieldName.MON_LOC_LB=${reefdb.service.extraction.fieldNamePrefix.MON_LOC}_Mnemonique reefdb.service.extraction.fieldName.MON_LOC_NM=Station @@ -304,6 +309,7 @@ reefdb.service.extraction.fieldName.MON_LOC_ORDER_ITEM_NUMBER=${reefdb.service.e reefdb.service.extraction.fieldName.ORDER_ITEM_CD=${reefdb.service.extraction.fieldNamePrefix.MON_LOC}_Entite_classement_Identifiant reefdb.service.extraction.fieldName.ORDER_ITEM_NM=${reefdb.service.extraction.fieldNamePrefix.MON_LOC}_Entite_classement reefdb.service.extraction.fieldName.ORDER_ITEM_TYPE_NM=${reefdb.service.extraction.fieldNamePrefix.MON_LOC}_Entite_classement_Type +reefdb.service.extraction.fieldName.REF_TAXON_NM=Taxon reefdb.service.extraction.fieldName.SAMPLING_EQUIPMENT_NM=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Moyen_acquisition reefdb.service.extraction.fieldName.SAMPLING_EQUIPMENT_SIZE=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Moyen_acquisition_Taille reefdb.service.extraction.fieldName.SAMPLING_EQUIPMENT_SIZE_UNIT_SYMBOL=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Moyen_acquisition_Taille_Symbole_unite @@ -325,12 +331,14 @@ reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LONG_MAX=${reefdb.ser reefdb.service.extraction.fieldName.SAMPLING_OPER_POSITION_LONG_MIN=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Coordonnees_MINX reefdb.service.extraction.fieldName.SAMPLING_OPER_QUALIF_CM=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Commentaire_qualification reefdb.service.extraction.fieldName.SAMPLING_OPER_QUALIF_DT=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Date_qualification -reefdb.service.extraction.fieldName.SAMPLING_OPER_QUAL_FLAG=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Niveau_qualite +reefdb.service.extraction.fieldName.SAMPLING_OPER_QUAL_FLAG= +reefdb.service.extraction.fieldName.SAMPLING_OPER_QUAL_FLAG_NM=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Niveau_qualite reefdb.service.extraction.fieldName.SAMPLING_OPER_SIZE=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Taille reefdb.service.extraction.fieldName.SAMPLING_OPER_SIZE_UNIT_SYMBOL=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Unite reefdb.service.extraction.fieldName.SAMPLING_OPER_TIME=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Heure reefdb.service.extraction.fieldName.SAMPLING_OPER_VALID_DT=${reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER}_Date_validation reefdb.service.extraction.fieldName.SURVEY_BOTTOM_DEPTH=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Profondeur_precise +reefdb.service.extraction.fieldName.SURVEY_BOTTOM_DEPTH_UNIT_SYMBOL=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Profondeur_precise_Symbole_unite reefdb.service.extraction.fieldName.SURVEY_CM=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Commentaire reefdb.service.extraction.fieldName.SURVEY_CONTROL_DT=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Date_controle reefdb.service.extraction.fieldName.SURVEY_DT=Date @@ -343,13 +351,15 @@ reefdb.service.extraction.fieldName.SURVEY_POSITION_LONG_MIN=${reefdb.service.ex reefdb.service.extraction.fieldName.SURVEY_PROG_CD=Programme reefdb.service.extraction.fieldName.SURVEY_QUALIF_CM=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Commentaire_qualification reefdb.service.extraction.fieldName.SURVEY_QUALIF_DT=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Date_qualification -reefdb.service.extraction.fieldName.SURVEY_QUAL_FLAG=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Niveau_qualite +reefdb.service.extraction.fieldName.SURVEY_QUAL_FLAG= +reefdb.service.extraction.fieldName.SURVEY_QUAL_FLAG_NM=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Niveau_qualite reefdb.service.extraction.fieldName.SURVEY_QUSERS=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Observateurs reefdb.service.extraction.fieldName.SURVEY_TIME=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Heure reefdb.service.extraction.fieldName.SURVEY_VALID_DT=${reefdb.service.extraction.fieldNamePrefix.SURVEY}_Date_validation reefdb.service.extraction.fieldName.TAXON_GROUP_NM=Groupe_taxons reefdb.service.extraction.fieldName.TAXON_MEAS_IDS=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Identifiants_interne_TAXON_MEAS_ID -reefdb.service.extraction.fieldName.TAXON_NAME_NM=Taxon +reefdb.service.extraction.fieldName.TAXON_NAME_ID=${reefdb.service.extraction.fieldNamePrefix.MEAS}_Identifiant_interne_TAXON_NAME_ID +reefdb.service.extraction.fieldName.TAXON_NAME_NM=Taxon_saisi reefdb.service.extraction.fieldName.TAXON_PAMPA=Taxon_pampa reefdb.service.extraction.fieldNamePrefix.MEAS=MESURE reefdb.service.extraction.fieldNamePrefix.MON_LOC=STATION diff --git a/reefdb-core/src/main/resources/reefdb-db-enumerations.properties b/reefdb-core/src/main/resources/reefdb-db-enumerations.properties index fa132a479c7644c46e8e6956341136acdfeede89..72037ccdf62998798655413c8933f77d2d083578 100644 --- a/reefdb-core/src/main/resources/reefdb-db-enumerations.properties +++ b/reefdb-core/src/main/resources/reefdb-db-enumerations.properties @@ -43,6 +43,7 @@ pmfmId.PIT_ORIGIN=2326 UnitId.NO_UNIT=99 TranscribingItemTypeLb.REEFDB_PMFM_NM=REEFDB-PMFM.PMFM_NM +TranscribingItemTypeLb.REEFDB_PMFM_EXTRACTION=REEFDB-PMFM-EXTRACT.PMFM_NM ############################################ # Alternative Taxon Code # diff --git a/reefdb-core/src/main/resources/reefdb-queries.hbm.xml b/reefdb-core/src/main/resources/reefdb-queries.hbm.xml index d36a2bacdfaf9f4c7cfe35b9b9d6b55c86a3dcae..63c05e8a024db75775dd09e4af7034667dccabc6 100644 --- a/reefdb-core/src/main/resources/reefdb-queries.hbm.xml +++ b/reefdb-core/src/main/resources/reefdb-queries.hbm.xml @@ -1754,6 +1754,32 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/cleanTaxon.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/cleanTaxon.xml new file mode 100644 index 0000000000000000000000000000000000000000..943686b4e41813a9ff99e7711106e174b67e197c --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/cleanTaxon.xml @@ -0,0 +1,46 @@ + + + + + + + 1=2 + + TAXON_GROUP_ID IS NULL + + + + + + REF_TAXON_ID IS NULL + + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/countFrom.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/countFrom.xml new file mode 100644 index 0000000000000000000000000000000000000000..3c1833c67e82cc62b3f0792254575637ecd0e87b --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/countFrom.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/createBaseTable.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/createBaseTable.xml new file mode 100644 index 0000000000000000000000000000000000000000..f0f72278d6014df9de846b5981c6eaa6babf3d95 --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/createBaseTable.xml @@ -0,0 +1,211 @@ + + + + + + + + + + MLOI.MON_LOC_ID + OI.ORDER_ITEM_NM + OIT.ORDER_ITEM_TYPE_NM + OI.ORDER_ITEM_CD + MLOI.MON_LOC_ORDER_ITEM_NUMBER + + MON_LOC_ORDER_ITEM + LEFT OUTER JOIN ORDER_ITEM OI ON MLOI.ORDER_ITEM_ID = OI.ORDER_ITEM_ID + LEFT OUTER JOIN ORDER_ITEM_TYPE OIT ON OI.ORDER_ITEM_TYPE_CD = OIT.ORDER_ITEM_TYPE_CD + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SURVEY + INNER JOIN SURVEY_PROG PROG ON PROG.SURVEY_ID = S.SURVEY_ID + INNER JOIN MONITORING_LOCATION ML ON ML.MON_LOC_ID = S.MON_LOC_ID + LEFT OUTER JOIN SAMPLING_OPERATION SO ON SO.SURVEY_ID = S.SURVEY_ID + LEFT OUTER JOIN MLOI ON MLOI.MON_LOC_ID = S.MON_LOC_ID + LEFT OUTER JOIN SURVEY_POINT SP ON S.SURVEY_ID = SP.SURVEY_ID + LEFT OUTER JOIN CAMPAIGN C ON C.CAMPAIGN_ID = S.CAMPAIGN_ID + LEFT OUTER JOIN SAMPLING_EQUIPMENT SE ON SE.SAMPLING_EQUIPMENT_ID = SO.SAMPLING_EQUIPMENT_ID + LEFT OUTER JOIN DEPARTMENT SOD ON SOD.DEP_ID = SO.DEP_ID + LEFT OUTER JOIN QUALITY_FLAG SQF ON SQF.QUAL_FLAG_CD = S.QUAL_FLAG_CD + LEFT OUTER JOIN SURVEY_QUSER SQ ON SQ.SURVEY_ID = S.SURVEY_ID + LEFT OUTER JOIN QUSER Q ON Q.QUSER_ID = SQ.QUSER_ID + LEFT OUTER JOIN DEPARTMENT QD ON QD.DEP_ID = Q.DEP_ID + LEFT OUTER JOIN UNIT SOSU ON SOSU.UNIT_ID = SO.SAMPLING_OPER_SIZE_UNIT_ID + LEFT OUTER JOIN QUALITY_FLAG SOQF ON SOQF.QUAL_FLAG_CD = SO.QUAL_FLAG_CD + LEFT OUTER JOIN UNIT SEU ON SE.UNIT_ID = SEU.UNIT_ID + LEFT OUTER JOIN UNIT SODU ON SODU.UNIT_ID = SO.SAMPLING_OPER_DEPTH_UNIT_ID + LEFT OUTER JOIN UNIT SBDU ON SBDU.UNIT_ID = S.SURVEY_BOTTOM_DEPTH_UNIT_ID + LEFT OUTER JOIN SAMPLING_OPER_POINT SOP ON SOP.SAMPLING_OPER_ID = SO.SAMPLING_OPER_ID + + + + + + + + + + + + + + + + + + S.SURVEY_ID + S.SURVEY_LB + S.SURVEY_DT + PROG.PROG_CD + S.REC_DEP_ID + C.CAMPAIGN_NM + ML.MON_LOC_ID + ML.MON_LOC_LB + ML.MON_LOC_NM + MLOI.ORDER_ITEM_NM + SO.SAMPLING_OPER_ID + SO.SAMPLING_OPER_LB + SP.SURVEY_POSITION + SO.SAMPLING_OPER_SIZE + SOSU.UNIT_SYMBOL + SE.SAMPLING_EQUIPMENT_NM + SOD.DEP_NM + MLOI.ORDER_ITEM_TYPE_NM + MLOI.ORDER_ITEM_CD + MLOI.MON_LOC_ORDER_ITEM_NUMBER + S.SURVEY_TIME + S.SURVEY_CM + S.SURVEY_CONTROL_DT + S.SURVEY_VALID_DT + SQF.QUAL_FLAG_NM + S.SURVEY_QUALIF_DT + S.SURVEY_QUALIF_CM + S.SURVEY_ACTUAL_POSITION + S.SURVEY_BOTTOM_DEPTH + SBDU.UNIT_SYMBOL + SO.SAMPLING_OPER_TIME + S.SURVEY_BOTTOM_DEPTH + SO.SAMPLING_OPER_DEPTH + SO.SAMPLING_OPER_MIN_DEPTH + SO.SAMPLING_OPER_MAX_DEPTH + SO.SAMPLING_OPER_ACTUAL_POSITION + SODU.UNIT_SYMBOL + SODU.UNIT_NM + SO.SAMPLING_OPER_CM + SE.SAMPLING_EQUIPMENT_SIZE + SEU.UNIT_SYMBOL + SO.SAMPLING_OPER_NUMBER_INDIV + SO.SAMPLING_OPER_CONTROL_DT + SO.SAMPLING_OPER_VALID_DT + SOQF.QUAL_FLAG_NM + SO.SAMPLING_OPER_QUALIF_DT + SO.SAMPLING_OPER_QUALIF_CM + SOP.SAMPLING_OPER_POSITION + + S.SURVEY_ID + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/createCommonTable.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/createCommonTable.xml new file mode 100644 index 0000000000000000000000000000000000000000..129cb41a849639a5edb1b365db8ec6650880b28c --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/createCommonTable.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + RAW.SURVEY_ID + RAW.SAMPLING_OPER_ID + RAW.MEAS_INDIV_ID + RAW.REF_TAXON_NM + RAW.TAXON_NAME_ID + RAW.TAXON_NAME_NM + RAW.TAXON_PAMPA + RAW.TAXON_GROUP_NM + + + + + + + + + + + RAW.SURVEY_ID + RAW.SAMPLING_OPER_ID + RAW.MEAS_INDIV_ID + RAW.REF_TAXON_NM + RAW.TAXON_NAME_ID + RAW.TAXON_NAME_NM + RAW.TAXON_PAMPA + RAW.TAXON_GROUP_NM + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/createPmfmTable.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/createPmfmTable.xml new file mode 100644 index 0000000000000000000000000000000000000000..ef601963678c1460c551e144279746d8d0caa246 --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/createPmfmTable.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/createRawTable.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/createRawTable.xml new file mode 100644 index 0000000000000000000000000000000000000000..6895c1c4f230b4385f7b3f58bd429b9af9b9d066 --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/createRawTable.xml @@ -0,0 +1,178 @@ + + + + + + + + + + TAXON_NAME_ID + ALTERN_TAXON_CD + ALTERNATIVE_TAXON + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + INNER JOIN MEASUREMENT SM ON BASE.SURVEY_ID = SM.SURVEY_ID + LEFT OUTER JOIN DEPARTMENT D ON SM.DEP_ID = D.DEP_ID + LEFT OUTER JOIN QUALITATIVE_VALUE QV ON SM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID + LEFT OUTER JOIN QUALITY_FLAG QF ON QF.QUAL_FLAG_CD = SM.QUAL_FLAG_CD + + + + + BASE.SURVEY_ID + NULL + NULL + STM.REMOTE_ID + 1 + STM.TAXON_MEAS_INDIV_ID + TN.TAXON_NAME_ID + TN.TAXON_NAME_COMPLETE_NM + STM.TAXON_NAME_ID + STM.TAXON_NAME_NM + ALT.ALTERN_TAXON_CD + TG.TAXON_GROUP_ID + TG.TAXON_GROUP_NM + STM.PMFM_ID + STM.TAXON_MEAS_NUMER_VALUE + QV.QUAL_VALUE_ID + QV.QUAL_VALUE_NM + STM.TAXON_MEAS_CM + D.DEP_NM + QF.QUAL_FLAG_NM + STM.TAXON_MEAS_QUALIF_DT + STM.TAXON_MEAS_QUALIF_CM + + + INNER JOIN TAXON_MEASUREMENT STM ON BASE.SURVEY_ID = STM.SURVEY_ID + LEFT OUTER JOIN DEPARTMENT D ON STM.DEP_ID = D.DEP_ID + LEFT OUTER JOIN QUALITATIVE_VALUE QV ON STM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID + LEFT OUTER JOIN TAXON_GROUP TG ON STM.TAXON_GROUP_ID = TG.TAXON_GROUP_ID + LEFT OUTER JOIN TAXON_NAME TN ON STM.REF_TAXON_ID = TN.REF_TAXON_ID AND TN.TAXON_NAME_IS_REFER = 1 + LEFT OUTER JOIN QUALITY_FLAG QF ON QF.QUAL_FLAG_CD = STM.QUAL_FLAG_CD + LEFT OUTER JOIN ALT ON ALT.TAXON_NAME_ID = TN.TAXON_NAME_ID + + + + + + + BASE.SURVEY_ID + BASE.SAMPLING_OPER_ID + SOM.REMOTE_ID + NULL + 0 + SOM.MEAS_INDIV_ID + NULL + NULL + NULL + NULL + NULL + NULL + NULL + SOM.PMFM_ID + SOM.MEAS_NUMER_VALUE + QV.QUAL_VALUE_ID + QV.QUAL_VALUE_NM + SOM.MEAS_CM + D.DEP_NM + QF.QUAL_FLAG_NM + SOM.MEAS_QUALIF_DT + SOM.MEAS_QUALIF_CM + + + INNER JOIN MEASUREMENT SOM ON BASE.SAMPLING_OPER_ID = SOM.SAMPLING_OPER_ID + LEFT OUTER JOIN DEPARTMENT D ON SOM.DEP_ID = D.DEP_ID + LEFT OUTER JOIN QUALITATIVE_VALUE QV ON SOM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID + LEFT OUTER JOIN QUALITY_FLAG QF ON QF.QUAL_FLAG_CD = SOM.QUAL_FLAG_CD + + + + + + + + BASE.SURVEY_ID + BASE.SAMPLING_OPER_ID + NULL + SOTM.REMOTE_ID + 0 + SOTM.TAXON_MEAS_INDIV_ID + TN.TAXON_NAME_ID + TN.TAXON_NAME_COMPLETE_NM + SOTM.TAXON_NAME_ID + SOTM.TAXON_NAME_NM + ALT.ALTERN_TAXON_CD + TG.TAXON_GROUP_ID + TG.TAXON_GROUP_NM + SOTM.PMFM_ID + SOTM.TAXON_MEAS_NUMER_VALUE + QV.QUAL_VALUE_ID + QV.QUAL_VALUE_NM + SOTM.TAXON_MEAS_CM + D.DEP_NM + QF.QUAL_FLAG_NM + SOTM.TAXON_MEAS_QUALIF_DT + SOTM.TAXON_MEAS_QUALIF_CM + + + INNER JOIN TAXON_MEASUREMENT SOTM ON BASE.SAMPLING_OPER_ID = SOTM.SAMPLING_OPER_ID + LEFT OUTER JOIN DEPARTMENT D ON SOTM.DEP_ID = D.DEP_ID + LEFT OUTER JOIN QUALITATIVE_VALUE QV ON SOTM.QUAL_VALUE_ID = QV.QUAL_VALUE_ID + LEFT OUTER JOIN TAXON_GROUP TG ON SOTM.TAXON_GROUP_ID = TG.TAXON_GROUP_ID + LEFT OUTER JOIN TAXON_NAME TN ON SOTM.REF_TAXON_ID = TN.REF_TAXON_ID AND TN.TAXON_NAME_IS_REFER = 1 + LEFT OUTER JOIN QUALITY_FLAG QF ON QF.QUAL_FLAG_CD = SOTM.QUAL_FLAG_CD + LEFT OUTER JOIN ALT ON ALT.TAXON_NAME_ID = TN.TAXON_NAME_ID + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/createResultTable.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/createResultTable.xml new file mode 100644 index 0000000000000000000000000000000000000000..4197718f2a8725ff37681a6ad232f7335b20c0b3 --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/createResultTable.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/injectionPeriodFilter.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/injectionPeriodFilter.xml new file mode 100644 index 0000000000000000000000000000000000000000..56e3fa91b00bd8874cfc2a2439c93c87ca410d89 --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/injectionPeriodFilter.xml @@ -0,0 +1,23 @@ + + + += TO_DATE('&PERIOD_startDate','DD/MM/YYYY') AND S.SURVEY_DT <= TO_DATE('&PERIOD_endDate','DD/MM/YYYY'))]]> \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/injectionPmfm.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/injectionPmfm.xml new file mode 100644 index 0000000000000000000000000000000000000000..c2a0b0d43085897b4e6934952ab13bf35f6df25f --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/injectionPmfm.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/pmfmInfo.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/pmfmInfo.xml new file mode 100644 index 0000000000000000000000000000000000000000..2d32a68f55349199d94219c2da0673bcb69b7b6c --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/pmfmInfo.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/programCodes.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/programCodes.xml new file mode 100644 index 0000000000000000000000000000000000000000..10e1a15ccf3ac53a6c9c14232a4f48ed2c079dbf --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/programCodes.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/resources/xmlQuery/extraction/selectResultTable.xml b/reefdb-core/src/main/resources/xmlQuery/extraction/selectResultTable.xml new file mode 100644 index 0000000000000000000000000000000000000000..7e87939805fd0edff5fb59d04fcb1d8e50e71ad7 --- /dev/null +++ b/reefdb-core/src/main/resources/xmlQuery/extraction/selectResultTable.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + SURVEY_PROG_CD, MON_LOC_NM, SURVEY_DT, SURVEY_LB, SAMPLING_OPER_LB, MEAS_INDIV_ID + + + + \ No newline at end of file diff --git a/reefdb-core/src/main/xmi/reefdb.properties b/reefdb-core/src/main/xmi/reefdb.properties index 1ae1d1422b5019a3aee80a803f8796fc2bb5cf03..147985450934adad93a4a28c50b450c88136aede 100644 --- a/reefdb-core/src/main/xmi/reefdb.properties +++ b/reefdb-core/src/main/xmi/reefdb.properties @@ -54,6 +54,7 @@ fr.ifremer.reefdb.dto.referential.GroupingTypeDTO.attribute.grouping.stereotype= fr.ifremer.reefdb.dto.referential.TaxonGroupDTO.attribute.taxons.stereotype=ordered fr.ifremer.reefdb.dto.referential.TaxonDTO.attribute.taxonGroups.stereotype=ordered +fr.ifremer.reefdb.dto.referential.pmfm.ParameterDTO.attribute.qualitativeValues.stereotype=ordered fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO.attribute.qualitativeValues.stereotype=ordered fr.ifremer.reefdb.dto.referential.pmfm.MatrixDTO.attribute.fractions.stereotype=unique fr.ifremer.reefdb.dto.referential.pmfm.FractionDTO.attribute.matrixes.stereotype=unique diff --git a/reefdb-core/src/main/xmi/reefdb.zargo b/reefdb-core/src/main/xmi/reefdb.zargo index 961c17eb000652bc9f06732a9f39a4e76cce5a4c..3cca36eff1931afbc1fff9e15ff06c4690a39b28 100644 Binary files a/reefdb-core/src/main/xmi/reefdb.zargo and b/reefdb-core/src/main/xmi/reefdb.zargo differ diff --git a/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceRealTest.java b/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceRealTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7ecde3f43179d3cb53aea9f8d645b55554640542 --- /dev/null +++ b/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceRealTest.java @@ -0,0 +1,133 @@ +package fr.ifremer.reefdb.service.extraction; + +/* + * #%L + * Reef DB :: Core + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +import com.google.common.collect.ImmutableList; +import fr.ifremer.quadrige3.core.ProgressionCoreModel; +import fr.ifremer.reefdb.config.ReefDbConfiguration; +import fr.ifremer.reefdb.dao.ReefDbDatabaseResource; +import fr.ifremer.reefdb.dto.ReefDbBeanFactory; +import fr.ifremer.reefdb.dto.ReefDbBeans; +import fr.ifremer.reefdb.dto.configuration.filter.FilterDTO; +import fr.ifremer.reefdb.dto.enums.ExtractionFilterValues; +import fr.ifremer.reefdb.dto.enums.ExtractionOutputType; +import fr.ifremer.reefdb.dto.system.extraction.ExtractionDTO; +import fr.ifremer.reefdb.dto.system.extraction.ExtractionPeriodDTO; +import fr.ifremer.reefdb.service.ReefDbServiceLocator; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.*; + +import java.io.File; +import java.time.LocalDate; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Extraction Service Test Class + *

+ * Created by Ludovic on 03/12/2015. + */ +public class ExtractionPerformServiceRealTest { + + private static final Log LOG = LogFactory.getLog(ExtractionPerformServiceRealTest.class); + + @ClassRule +// public static final ReefDbDatabaseResource dbResource = ReefDbDatabaseResource.readDb("mantis49970", true); + public static final ReefDbDatabaseResource dbResource = new ReefDbDatabaseResource("mantis49970", true) { + @Override + public String getBuildEnvironment() { + return null; + } + }; + + private ExtractionService service; + + private ExtractionPerformService performService; + + private ReefDbConfiguration config; + + @Before + public void setUp() { + service = ReefDbServiceLocator.instance().getExtractionService(); + performService = ReefDbServiceLocator.instance().getExtractionPerformService(); + config = ReefDbConfiguration.getInstance(); + } + + @Ignore + @Test + public void testConfig() { + Assert.assertTrue(StringUtils.isNotBlank(config.getApplicationConfig().getOption("reefdb.core.test.extraction.path"))); + } + + @Ignore + @Test + public void performRealExtraction() { + + // load extraction + List extractions = service.getExtractions(2, null); + assertNotNull(extractions); + assertEquals(1, extractions.size()); + ExtractionDTO extraction = extractions.get(0); + assertNotNull(extraction); + + // limit some data + FilterDTO periodFilter = ReefDbBeans.getFilterOfType(extraction, ExtractionFilterValues.PERIOD); + if (periodFilter != null) { + extraction.removeFilters(periodFilter); + } + ExtractionPeriodDTO period = ReefDbBeanFactory.newExtractionPeriodDTO(); + period.setStartDate(LocalDate.of(2019, 2, 5)); + period.setEndDate(LocalDate.of(2019, 2, 5)); + ReefDbBeans.setFilterElements(extraction, ExtractionFilterValues.PERIOD, ImmutableList.of(period)); + + assertExtraction(extraction, ExtractionOutputType.SIMPLE); + assertExtraction(extraction, ExtractionOutputType.COMPLETE); +// assertExtraction(extraction, ExtractionOutputType.SINP); +// assertExtraction(extraction, ExtractionOutputType.PAMPA); + + + } + + private void assertExtraction(ExtractionDTO extraction, ExtractionOutputType outputType) { + + // get referent file + String refFileDir = config.getApplicationConfig().getOption("reefdb.core.test.extraction.path"); + String refFileName = config.getApplicationConfig().getOption(String.format("reefdb.core.test.extraction.%s.%s", extraction.getId(), outputType)); + File refFile = new File(refFileDir, refFileName); + + // perform extraction + File outputFile = new File(refFileDir, String.format("extraction-%s-%s-%s.csv", extraction.getId(), outputType, System.currentTimeMillis())); + performService.performExtraction(extraction, outputType, outputFile, new ProgressionCoreModel()); + + // compare files +// LOG.debug("comparing with " + refFile); +// FileAssert.assertEquals(refFile, outputFile); + + } + +} diff --git a/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceTest.java b/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9a67232f0d712ae3096e68d19c6728e20292bff4 --- /dev/null +++ b/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionPerformServiceTest.java @@ -0,0 +1,220 @@ +package fr.ifremer.reefdb.service.extraction; + +/* + * #%L + * Reef DB :: Core + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import fr.ifremer.quadrige3.core.ProgressionCoreModel; +import fr.ifremer.quadrige3.ui.core.dto.QuadrigeBean; +import fr.ifremer.reefdb.config.ReefDbConfiguration; +import fr.ifremer.reefdb.dao.ReefDbDatabaseResource; +import fr.ifremer.reefdb.dto.ReefDbBeanFactory; +import fr.ifremer.reefdb.dto.configuration.filter.FilterDTO; +import fr.ifremer.reefdb.dto.enums.ExtractionFilterValues; +import fr.ifremer.reefdb.dto.enums.ExtractionOutputType; +import fr.ifremer.reefdb.dto.system.extraction.ExtractionDTO; +import fr.ifremer.reefdb.dto.system.extraction.ExtractionPeriodDTO; +import fr.ifremer.reefdb.service.ReefDbServiceLocator; +import fr.ifremer.reefdb.service.StatusFilter; +import fr.ifremer.reefdb.service.administration.program.ProgramStrategyService; +import fr.ifremer.reefdb.service.referential.ReferentialService; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.time.LocalDate; +import java.util.Collections; + +import static org.junit.Assert.*; + +/** + * Extraction Service Test Class + *

+ * Created by Ludovic on 03/12/2015. + */ +public class ExtractionPerformServiceTest { + + @ClassRule + public static final ReefDbDatabaseResource dbResource = ReefDbDatabaseResource.writeDb(); + + private ExtractionPerformService performService; + + private ProgramStrategyService programStrategyService; + + private ReferentialService referentialService; + + private ReefDbConfiguration config; + + @Before + public void setUp() { + performService = ReefDbServiceLocator.instance().getExtractionPerformService(); + programStrategyService = ReefDbServiceLocator.instance().getProgramStrategyService(); + referentialService = ReefDbServiceLocator.instance().getReferentialService(); + config = ReefDbConfiguration.getInstance(); + } + + @Test + public void performExtraction() { + + // create extraction + ExtractionDTO extraction = ReefDbBeanFactory.newExtractionDTO(); + extraction.setName("extraction test"); + extraction.setId(1); + + // add periods + ExtractionPeriodDTO period = ReefDbBeanFactory.newExtractionPeriodDTO(); + period.setStartDate(LocalDate.of(2014,1,1)); + period.setEndDate(LocalDate.of(2016,1,1)); + FilterDTO periodFilter = ReefDbBeanFactory.newFilterDTO(); + periodFilter.setFilterTypeId(ExtractionFilterValues.PERIOD.getFilterTypeId()); + periodFilter.setElements(Collections.singletonList(period)); + extraction.addFilters(periodFilter); + + // add grouping + FilterDTO groupingFilter = ReefDbBeanFactory.newFilterDTO(); + groupingFilter.setFilterTypeId(ExtractionFilterValues.ORDER_ITEM_TYPE.getFilterTypeId()); + groupingFilter.setElements(Collections.singletonList(referentialService.getGroupingTypes().get(0))); + groupingFilter.setFilterLoaded(true); + extraction.addFilters(groupingFilter); + + // add filters + FilterDTO filter1 = ReefDbBeanFactory.newFilterDTO(); + filter1.setFilterTypeId(ExtractionFilterValues.PROGRAM.getFilterTypeId()); + filter1.setElements(ImmutableList.of(programStrategyService.getWritableProgramByCode("REMIS"))); + filter1.setFilterLoaded(true); + extraction.addFilters(filter1); + + // add another filter + FilterDTO filter2 = ReefDbBeanFactory.newFilterDTO(); + filter2.setFilterTypeId(ExtractionFilterValues.LOCATION.getFilterTypeId()); + filter2.setElements(referentialService.getLocations(StatusFilter.ALL)); + filter2.setFilterLoaded(true); + extraction.addFilters(filter2); + + File outputFile1 = new File(config.getTempDirectory(), "extraction1.csv"); + performService.performExtraction(extraction, ExtractionOutputType.SIMPLE, outputFile1, new ProgressionCoreModel()); + assertCsvFileNbLines(outputFile1, 6); // 1 header + 5 results + + // add pmfm filter + FilterDTO filter3 = ReefDbBeanFactory.newFilterDTO(); + filter3.setFilterTypeId(ExtractionFilterValues.PMFM.getFilterTypeId()); + filter3.setElements(Lists.newArrayList(referentialService.getPmfm(21))); // only 155 + filter3.setFilterLoaded(true); + extraction.addFilters(filter3); + + File outputFile2 = new File(config.getTempDirectory(), "extraction2.csv"); + performService.performExtraction(extraction, ExtractionOutputType.SIMPLE, outputFile2, new ProgressionCoreModel()); + assertCsvFileNbLines(outputFile2, 5); // 1 header + 4 results + + // add taxon group filter + FilterDTO filter4 = ReefDbBeanFactory.newFilterDTO(); + filter4.setFilterTypeId(ExtractionFilterValues.TAXON_GROUP.getFilterTypeId()); + filter4.setElements(Lists.newArrayList(referentialService.getTaxonGroup(1))); // only Groupe trophique benthos + filter4.setFilterLoaded(true); + extraction.addFilters(filter4); + + File outputFile3 = new File(config.getTempDirectory(), "extraction3.csv"); + performService.performExtraction(extraction, ExtractionOutputType.SIMPLE, outputFile3, new ProgressionCoreModel()); + assertCsvFileNbLines(outputFile3, 3); // 1 header + 2 results + + // add filter taxon + FilterDTO filter5 = ReefDbBeanFactory.newFilterDTO(); + filter5.setFilterTypeId(ExtractionFilterValues.TAXON.getFilterTypeId()); + filter5.setElements(Lists.newArrayList(referentialService.getTaxon(1))); // dummy taxon + filter5.setFilterLoaded(true); + extraction.addFilters(filter5); + + File outputFile4 = new File(config.getTempDirectory(), "extraction4.csv"); + try { + performService.performExtraction(extraction, ExtractionOutputType.SIMPLE, outputFile4, new ProgressionCoreModel()); + fail("should throw exception"); + } catch (Exception e) { + assertNotNull(e); + } + } + + @Test + public void performExtractionPAMPA() { + + // create extraction + ExtractionDTO extraction = ReefDbBeanFactory.newExtractionDTO(); + extraction.setName("extraction test"); + extraction.setId(1); + + // add periods + ExtractionPeriodDTO period = ReefDbBeanFactory.newExtractionPeriodDTO(); + period.setStartDate(LocalDate.of(2014,1,1)); + period.setEndDate(LocalDate.of(2016,1,1)); + FilterDTO periodFilter = ReefDbBeanFactory.newFilterDTO(); + periodFilter.setFilterTypeId(ExtractionFilterValues.PERIOD.getFilterTypeId()); + periodFilter.setElements(Collections.singletonList(period)); + extraction.addFilters(periodFilter); + + // add grouping + FilterDTO groupingFilter = ReefDbBeanFactory.newFilterDTO(); + groupingFilter.setFilterTypeId(ExtractionFilterValues.ORDER_ITEM_TYPE.getFilterTypeId()); + groupingFilter.setElements(Collections.singletonList(referentialService.getGroupingTypes().get(0))); + groupingFilter.setFilterLoaded(true); + extraction.addFilters(groupingFilter); + + // add filters + FilterDTO filter1 = ReefDbBeanFactory.newFilterDTO(); + filter1.setFilterTypeId(ExtractionFilterValues.PROGRAM.getFilterTypeId()); + filter1.setElements(ImmutableList.of(programStrategyService.getWritableProgramByCode("REMIS"))); + filter1.setFilterLoaded(true); + extraction.addFilters(filter1); + + // add another filter + FilterDTO filter2 = ReefDbBeanFactory.newFilterDTO(); + filter2.setFilterTypeId(ExtractionFilterValues.LOCATION.getFilterTypeId()); + filter2.setElements(referentialService.getLocations(StatusFilter.ALL)); + filter2.setFilterLoaded(true); + extraction.addFilters(filter2); + + File outputFile1 = new File(config.getTempDirectory(), "extractionPAMPA.csv"); + performService.performExtraction(extraction, ExtractionOutputType.PAMPA, outputFile1, new ProgressionCoreModel()); + assertCsvFileNbLines(outputFile1, 6); // 1 header + 5 results + } + + private void assertCsvFileNbLines(File csvFile, int expectedNbLines) { + + assertTrue(csvFile.canRead()); + try { + BufferedReader reader = new BufferedReader(new FileReader(csvFile.getCanonicalFile())); + int nbLines = 0; + while (reader.readLine() != null) { + nbLines++; + } + assertEquals(expectedNbLines, nbLines); + + } catch (IOException e) { + fail(e.getLocalizedMessage()); + } + } + +} diff --git a/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionServiceTest.java b/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionServiceTest.java index a04b9910ba87e649ab40055f917a73258fd16e99..c2367e64b8951c0b2f1a17cfea47ff3e68234af0 100644 --- a/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionServiceTest.java +++ b/reefdb-core/src/test/java/fr/ifremer/reefdb/service/extraction/ExtractionServiceTest.java @@ -25,15 +25,12 @@ package fr.ifremer.reefdb.service.extraction; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import fr.ifremer.quadrige3.core.ProgressionCoreModel; import fr.ifremer.quadrige3.ui.core.dto.QuadrigeBean; -import fr.ifremer.reefdb.config.ReefDbConfiguration; import fr.ifremer.reefdb.dao.ReefDbDatabaseResource; import fr.ifremer.reefdb.dto.ReefDbBeanFactory; import fr.ifremer.reefdb.dto.ReefDbBeans; import fr.ifremer.reefdb.dto.configuration.filter.FilterDTO; import fr.ifremer.reefdb.dto.enums.ExtractionFilterValues; -import fr.ifremer.reefdb.dto.enums.ExtractionOutputType; import fr.ifremer.reefdb.dto.system.extraction.ExtractionDTO; import fr.ifremer.reefdb.dto.system.extraction.ExtractionPeriodDTO; import fr.ifremer.reefdb.service.ReefDbServiceLocator; @@ -45,10 +42,6 @@ import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; import java.time.LocalDate; import java.util.*; @@ -65,21 +58,16 @@ public class ExtractionServiceTest { public static final ReefDbDatabaseResource dbResource = ReefDbDatabaseResource.writeDb(); private ExtractionService service; - private ExtractionPerformService performService; private ProgramStrategyService programStrategyService; private ReferentialService referentialService; - private ReefDbConfiguration config; - @Before public void setUp() { service = ReefDbServiceLocator.instance().getExtractionService(); - performService = ReefDbServiceLocator.instance().getExtractionPerformService(); programStrategyService = ReefDbServiceLocator.instance().getProgramStrategyService(); referentialService = ReefDbServiceLocator.instance().getReferentialService(); - config = ReefDbConfiguration.getInstance(); } @Test @@ -107,14 +95,14 @@ public class ExtractionServiceTest { groupingFilter.setFilterLoaded(true); extraction.addFilters(groupingFilter); - ExtractionDTO reloadedExtration = saveAndReload(extraction); - assertExtractionEquals(extraction, reloadedExtration); + ExtractionDTO reloadedExtraction = saveAndReload(extraction); + assertExtractionEquals(extraction, reloadedExtraction); // modify date range period1.setStartDate(LocalDate.of(2015,3,2)); period1.setEndDate(LocalDate.of(2015,8,28)); - reloadedExtration = saveAndReload(extraction); - assertExtractionEquals(extraction, reloadedExtration); + reloadedExtraction = saveAndReload(extraction); + assertExtractionEquals(extraction, reloadedExtraction); // add filters FilterDTO filter1 = ReefDbBeanFactory.newFilterDTO(); @@ -123,11 +111,11 @@ public class ExtractionServiceTest { filter1.setFilterLoaded(true); extraction.addFilters(filter1); - reloadedExtration = saveAndReload(extraction); + reloadedExtraction = saveAndReload(extraction); // load elements - service.loadFilteredElements(reloadedExtration); - assertExtractionEquals(extraction, reloadedExtration); + service.loadFilteredElements(reloadedExtraction); + assertExtractionEquals(extraction, reloadedExtraction); // add another filter FilterDTO filter2 = ReefDbBeanFactory.newFilterDTO(); @@ -136,163 +124,24 @@ public class ExtractionServiceTest { filter2.setFilterLoaded(true); extraction.addFilters(filter2); - reloadedExtration = saveAndReload(extraction); + reloadedExtraction = saveAndReload(extraction); // load elements - service.loadFilteredElements(reloadedExtration); - assertExtractionEquals(extraction, reloadedExtration); + service.loadFilteredElements(reloadedExtraction); + assertExtractionEquals(extraction, reloadedExtraction); // remove first filter extraction.removeFilters(filter1); - reloadedExtration = saveAndReload(extraction); + reloadedExtraction = saveAndReload(extraction); // load elements - service.loadFilteredElements(reloadedExtration); - assertExtractionEquals(extraction, reloadedExtration); + service.loadFilteredElements(reloadedExtraction); + assertExtractionEquals(extraction, reloadedExtraction); // delete extraction service.deleteExtractions(Lists.newArrayList(extraction.getId())); } - @Test - public void performExtraction() { - - // create extraction - ExtractionDTO extraction = ReefDbBeanFactory.newExtractionDTO(); - extraction.setName("extraction test"); - extraction.setId(1); - - // add periods - ExtractionPeriodDTO period = ReefDbBeanFactory.newExtractionPeriodDTO(); - period.setStartDate(LocalDate.of(2014,1,1)); - period.setEndDate(LocalDate.of(2016,1,1)); - FilterDTO periodFilter = ReefDbBeanFactory.newFilterDTO(); - periodFilter.setFilterTypeId(ExtractionFilterValues.PERIOD.getFilterTypeId()); - periodFilter.setElements(Collections.singletonList(period)); - extraction.addFilters(periodFilter); - - // add grouping - FilterDTO groupingFilter = ReefDbBeanFactory.newFilterDTO(); - groupingFilter.setFilterTypeId(ExtractionFilterValues.ORDER_ITEM_TYPE.getFilterTypeId()); - groupingFilter.setElements(Collections.singletonList(referentialService.getGroupingTypes().get(0))); - groupingFilter.setFilterLoaded(true); - extraction.addFilters(groupingFilter); - - // add filters - FilterDTO filter1 = ReefDbBeanFactory.newFilterDTO(); - filter1.setFilterTypeId(ExtractionFilterValues.PROGRAM.getFilterTypeId()); - filter1.setElements(ImmutableList.of(programStrategyService.getWritableProgramByCode("REMIS"))); - filter1.setFilterLoaded(true); - extraction.addFilters(filter1); - - // add another filter - FilterDTO filter2 = ReefDbBeanFactory.newFilterDTO(); - filter2.setFilterTypeId(ExtractionFilterValues.LOCATION.getFilterTypeId()); - filter2.setElements(referentialService.getLocations(StatusFilter.ALL)); - filter2.setFilterLoaded(true); - extraction.addFilters(filter2); - - File outputFile1 = new File(config.getTempDirectory(), "extraction1.csv"); - performService.performExtraction(extraction, ExtractionOutputType.SIMPLE, outputFile1, new ProgressionCoreModel()); - assertCsvFileNbLines(outputFile1, 6); // 1 header + 5 results - - // add pmfm filter - FilterDTO filter3 = ReefDbBeanFactory.newFilterDTO(); - filter3.setFilterTypeId(ExtractionFilterValues.PMFM.getFilterTypeId()); - filter3.setElements(Lists.newArrayList(referentialService.getPmfm(21))); // only 155 - filter3.setFilterLoaded(true); - extraction.addFilters(filter3); - - File outputFile2 = new File(config.getTempDirectory(), "extraction2.csv"); - performService.performExtraction(extraction, ExtractionOutputType.SIMPLE, outputFile2, new ProgressionCoreModel()); - assertCsvFileNbLines(outputFile2, 5); // 1 header + 4 results - - // add taxon group filter - FilterDTO filter4 = ReefDbBeanFactory.newFilterDTO(); - filter4.setFilterTypeId(ExtractionFilterValues.TAXON_GROUP.getFilterTypeId()); - filter4.setElements(Lists.newArrayList(referentialService.getTaxonGroup(1))); // only Groupe trophique benthos - filter4.setFilterLoaded(true); - extraction.addFilters(filter4); - - File outputFile3 = new File(config.getTempDirectory(), "extraction3.csv"); - performService.performExtraction(extraction, ExtractionOutputType.SIMPLE, outputFile3, new ProgressionCoreModel()); - assertCsvFileNbLines(outputFile3, 3); // 1 header + 2 results - - // add filter taxon - FilterDTO filter5 = ReefDbBeanFactory.newFilterDTO(); - filter5.setFilterTypeId(ExtractionFilterValues.TAXON.getFilterTypeId()); - filter5.setElements(Lists.newArrayList(referentialService.getTaxon(1))); // dummy taxon - filter5.setFilterLoaded(true); - extraction.addFilters(filter5); - - File outputFile4 = new File(config.getTempDirectory(), "extraction4.csv"); - try { - performService.performExtraction(extraction, ExtractionOutputType.SIMPLE, outputFile4, new ProgressionCoreModel()); - fail("should throw exception"); - } catch (Exception e) { - assertNotNull(e); - } - } - - @Test - public void performExtractionPAMPA() { - - // create extraction - ExtractionDTO extraction = ReefDbBeanFactory.newExtractionDTO(); - extraction.setName("extraction test"); - extraction.setId(1); - - // add periods - ExtractionPeriodDTO period = ReefDbBeanFactory.newExtractionPeriodDTO(); - period.setStartDate(LocalDate.of(2014,1,1)); - period.setEndDate(LocalDate.of(2016,1,1)); - FilterDTO periodFilter = ReefDbBeanFactory.newFilterDTO(); - periodFilter.setFilterTypeId(ExtractionFilterValues.PERIOD.getFilterTypeId()); - periodFilter.setElements(Collections.singletonList(period)); - extraction.addFilters(periodFilter); - - // add grouping - FilterDTO groupingFilter = ReefDbBeanFactory.newFilterDTO(); - groupingFilter.setFilterTypeId(ExtractionFilterValues.ORDER_ITEM_TYPE.getFilterTypeId()); - groupingFilter.setElements(Collections.singletonList(referentialService.getGroupingTypes().get(0))); - groupingFilter.setFilterLoaded(true); - extraction.addFilters(groupingFilter); - - // add filters - FilterDTO filter1 = ReefDbBeanFactory.newFilterDTO(); - filter1.setFilterTypeId(ExtractionFilterValues.PROGRAM.getFilterTypeId()); - filter1.setElements(ImmutableList.of(programStrategyService.getWritableProgramByCode("REMIS"))); - filter1.setFilterLoaded(true); - extraction.addFilters(filter1); - - // add another filter - FilterDTO filter2 = ReefDbBeanFactory.newFilterDTO(); - filter2.setFilterTypeId(ExtractionFilterValues.LOCATION.getFilterTypeId()); - filter2.setElements(referentialService.getLocations(StatusFilter.ALL)); - filter2.setFilterLoaded(true); - extraction.addFilters(filter2); - - File outputFile1 = new File(config.getTempDirectory(), "extractionPAMPA.csv"); - performService.performExtraction(extraction, ExtractionOutputType.PAMPA, outputFile1, new ProgressionCoreModel()); - assertCsvFileNbLines(outputFile1, 6); // 1 header + 5 results - } - - private void assertCsvFileNbLines(File csvFile, int expectedNbLines) { - - assertTrue(csvFile.canRead()); - try { - BufferedReader reader = new BufferedReader(new FileReader(csvFile.getCanonicalFile())); - int nbLines = 0; - while (reader.readLine() != null) { - nbLines++; - } - assertEquals(expectedNbLines, nbLines); - - } catch (IOException e) { - fail(e.getLocalizedMessage()); - } - } - private ExtractionDTO saveAndReload(ExtractionDTO extraction) { extraction.setDirty(true); service.saveExtractions(Lists.newArrayList(extraction)); diff --git a/reefdb-core/src/test/resources/log4j.properties b/reefdb-core/src/test/resources/log4j.properties index 300c0eb0997eab54eb0c8f8e97e7bb865c6797da..9d3f52f8d91fd6f3fff15d9a201a740476534d78 100644 --- a/reefdb-core/src/test/resources/log4j.properties +++ b/reefdb-core/src/test/resources/log4j.properties @@ -76,7 +76,7 @@ log4j.logger.fr.ifremer.reefdb.security.ReefDbUserDetailsServiceImpl=WARN log4j.logger.fr.ifremer.reefdb.service.persistence.PersistenceServiceImpl=WARN log4j.logger.fr.ifremer.reefdb.config=WARN log4j.logger.fr.ifremer.quadrige3.config=WARN -log4j.logger.fr.ifremer.quadrige3.core=WARN +log4j.logger.fr.ifremer.quadrige3.core=DEBUG #log4j.logger.fr.ifremer.quadrige3.core.test.DatabaseResource=WARN #log4j.logger.fr.ifremer.quadrige3.core.dao=DEBUG #log4j.logger.fr.ifremer.quadrige3.core.dao.technical.hibernate=INFO diff --git a/reefdb-core/src/test/resources/reefdb-core-test-read.properties b/reefdb-core/src/test/resources/reefdb-core-test-read.properties index a9baa161749638772a4402f2d281a9da360a8780..e2bcd0805a024b219dc9fceedc9ccdaf1adf811f 100644 --- a/reefdb-core/src/test/resources/reefdb-core-test-read.properties +++ b/reefdb-core/src/test/resources/reefdb-core-test-read.properties @@ -54,7 +54,7 @@ reefdb.persistence.checkConstants.enable=true #quadrige3.persistence.jdbc.batch-size=10000 #quadrige3.persistence.hibernate.showSql=true -synchro.import.jdbc.url=jdbc:oracle:thin:@192.168.0.6:1521:ORCL +synchro.import.jdbc.url=jdbc:oracle:thin:@EIS-FIXE2:1521:ORCL #synchro.import.jdbc.url=jdbc:oracle:thin:@server.e-is.pro:1521:xe synchro.import.jdbc.username=Q2_TU synchro.import.jdbc.password=${synchro.import.jdbc.username} diff --git a/reefdb-core/src/test/resources/reefdb-core-test-write-mantis49970.properties b/reefdb-core/src/test/resources/reefdb-core-test-write-mantis49970.properties new file mode 100644 index 0000000000000000000000000000000000000000..5e4dbc678231d453301a818c6f53085a7bbfcbb5 --- /dev/null +++ b/reefdb-core/src/test/resources/reefdb-core-test-write-mantis49970.properties @@ -0,0 +1,68 @@ +### +# #%L +# Reef DB :: Core +# $Id:$ +# $HeadURL:$ +# %% +# Copyright (C) 2014 - 2015 Ifremer +# %% +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License +# along with this program. If not, see . +# #L% +### +### +#-------------------------------------------------------------------------- +# +# WARNING : For UNIT TEST ONLY +# -------------- +# Configuration file for quadrige3-core-client +# +# project : ${project.name} +# version : ${project.version} for ${pom.env} +# env : ${pom.env} - ${pom.profil} +# date : ${pom.date.fr} +# +# Copyright Ifremer 2014 +# +# 12/11/2014 BL Creation +#-------------------------------------------------------------------------- + +# Uncomment to use Hsqldb server: +# !! for DEV ONLY !! +quadrige3.persistence.jdbc.url=jdbc:hsqldb:file:C:/dev/reefdb/_src/reefdb/.local/extraction/data/db/quadrige3 +#quadrige3.persistence.jdbc.batch-size=1 +#quadrige3.persistence.jdbc.batch-size=10000 +#quadrige3.persistence.hibernate.showSql=true +#quadrige3.persistence.hibernate.formatSql=true +#quadrige3.persistence.hibernate.load.debug=true + +reefdb.core.test.extraction.path=C:/dev/reefdb/_src/reefdb/.local/extraction/extraction +reefdb.core.test.extraction.1.SIMPLE=reefdb-extraction-simple-FRANGEANT-MAYOTTE-PHOTOQUADRAT-BENTHOS-2020-01-28-141843.csv +reefdb.core.test.extraction.1.COMPLETE=reefdb-extraction-complet-FRANGEANT-MAYOTTE-PHOTOQUADRAT-BENTHOS-2020-01-28-142119.csv +reefdb.core.test.extraction.1.SINP=reefdb-extraction-SINP-FRANGEANT-MAYOTTE-PHOTOQUADRAT-BENTHOS-2020-01-28-142417.csv +reefdb.core.test.extraction.1.PAMPA=reefdb-extraction-PAMPA-FRANGEANT-MAYOTTE-PHOTOQUADRAT-BENTHOS-2020-01-28-142717.csv +reefdb.core.test.extraction.2.SIMPLE=reefdb-extraction-simple-GCRMN_LAREUNION_LIT_BENTHOS-2020-01-28-143131.csv +reefdb.core.test.extraction.2.COMPLETE=reefdb-extraction-complet-GCRMN_LAREUNION_LIT_BENTHOS-2020-01-28-143240.csv +reefdb.core.test.extraction.2.SINP=reefdb-extraction-SINP-GCRMN_LAREUNION_LIT_BENTHOS-2020-01-28-143354.csv +reefdb.core.test.extraction.2.PAMPA=reefdb-extraction-PAMPA-GCRMN_LAREUNION_LIT_BENTHOS-2020-01-28-143507.csv + +# Enumeration +#reefdb.persistence.db.enumeration.path=${reefdb.persistence.db.enumeration.resource} +#reefdb.persistence.db.enumeration.resource=classpath*:reefdb-db-enumerations.properties +#reefdb.persistence.checkConstants.enable=true + +# test dataset xml file to load in InitTests +quadrige3.core.test.dataset.common=datas-hsqldb-common.xml +quadrige3.core.test.dataset.additional=datas-hsqldb-pendings.xml + + diff --git a/reefdb-core/src/test/resources/reefdb-core-test-write.properties b/reefdb-core/src/test/resources/reefdb-core-test-write.properties index 02aa40b6ff7d694c021b94cc7652813a40cdae57..ab7571c08a393c93f5a8133299d1bfca8bc700d0 100644 --- a/reefdb-core/src/test/resources/reefdb-core-test-write.properties +++ b/reefdb-core/src/test/resources/reefdb-core-test-write.properties @@ -59,7 +59,7 @@ quadrige3.core.test.dataset.additional=datas-hsqldb-pendings.xml #quadrige3.persistence.jdbc.batch-size=10000 #quadrige3.persistence.hibernate.showSql=true -synchro.import.jdbc.url=jdbc:oracle:thin:@192.168.0.6:1521:ORCL +synchro.import.jdbc.url=jdbc:oracle:thin:@EIS-FIXE2:1521:ORCL #synchro.import.jdbc.url=jdbc:oracle:thin:@server.e-is.pro:1521:xe synchro.import.jdbc.username=Q2_TU synchro.import.jdbc.password=${synchro.import.jdbc.username} diff --git a/reefdb-ui-swing-launcher/pom.xml b/reefdb-ui-swing-launcher/pom.xml index a22fcc23ba86710efa4ea04363a0e44353134d29..d3dbb00387c6901b35afb5a5dd7c05326c920d7d 100644 --- a/reefdb-ui-swing-launcher/pom.xml +++ b/reefdb-ui-swing-launcher/pom.xml @@ -5,7 +5,7 @@ fr.ifremer.common common-parent - 3.0.6 + 3.0.9 fr.ifremer.reefdb @@ -225,12 +225,12 @@ eis-nexus-deploy - http://server.e-is.pro/nexus/content/repositories/reefdb-releases + https://nexus.e-is.pro/nexus/content/repositories/reefdb-releases eis-nexus-deploy - http://server.e-is.pro/nexus/content/repositories/reefdb-snapshots + https://nexus.e-is.pro/nexus/content/repositories/reefdb-snapshots - http://server.e-is.pro/nexus/content/groups/public + https://nexus.e-is.pro/nexus/content/groups/public diff --git a/reefdb-ui-swing/pom.xml b/reefdb-ui-swing/pom.xml index 86f6a5844330472c46a4f696da25846da4a3aa70..ef47f4838af4150573bf73f101afc9855744f64f 100644 --- a/reefdb-ui-swing/pom.xml +++ b/reefdb-ui-swing/pom.xml @@ -4,7 +4,7 @@ fr.ifremer.reefdb reefdb - 3.8.4-SNAPSHOT + 3.9.5-SNAPSHOT reefdb-ui-swing diff --git a/reefdb-ui-swing/src/license/THIRD-PARTY.properties b/reefdb-ui-swing/src/license/THIRD-PARTY.properties index b3ebbae1db097969db66e62d66741c08157f8e52..80434fcaba4d3fd54150c9e5a33d42c96677d988 100644 --- a/reefdb-ui-swing/src/license/THIRD-PARTY.properties +++ b/reefdb-ui-swing/src/license/THIRD-PARTY.properties @@ -43,7 +43,7 @@ # Please fill the missing licenses for dependencies : # # -#Tue Jan 21 15:10:29 CET 2020 +#Wed Jan 22 09:26:52 CET 2020 com.oracle--ojdbc7--12.1.0.2.0=OTN license commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0 dom4j--dom4j--1.6.1=BSD License diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/ReefDbUIContext.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/ReefDbUIContext.java index 7b3cec0fe5454dcd7b2c52b1939ab4247454a6b5..28973475196039cdc2f179d968307b5c836c0eaf 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/ReefDbUIContext.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/ReefDbUIContext.java @@ -1255,6 +1255,9 @@ public class ReefDbUIContext extends ApplicationUIContext implements JAXXHelpUIH // set to data context (for service use) dataContext.setContext(selectedContext); firePropertyChange(PROPERTY_SELECTED_CONTEXT_ID, null, contextId); + + // Change title to reflect context change (Mantis #49551) + getMainUI().getHandler().changeTitle(); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/action/ExportSynchroAction.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/action/ExportSynchroAction.java index 6dce103761876b8fbd7dc4b8c79f21341fa0da37..a1ac19b2299498741b149bd30abbaabe84e0951c 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/action/ExportSynchroAction.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/action/ExportSynchroAction.java @@ -277,7 +277,8 @@ public class ExportSynchroAction extends AbstractReloadCurrentScreenAction { catch (SynchroException se) { serverJobRunning = false; serverFailed = true; - throw se; + throw se; // TODO Dont throw here because the result file has to be downloaded from server + // needDownloadResultAndFinish = true; } } else { needDownloadResultAndFinish = true; diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/action/ImportSynchroAction.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/action/ImportSynchroAction.java index b35fccaa3f65161f7b4135bc7990e6bfefef588f..ad422bcd97476843ace3057dd6fc64e943dc0d6f 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/action/ImportSynchroAction.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/action/ImportSynchroAction.java @@ -179,8 +179,10 @@ public class ImportSynchroAction extends AbstractReefDbMainUIAction { // If no programs selected (or user cancelled): only import referential if (CollectionUtils.isEmpty(programs)) { - getSynchroUIContext().setImportData(false); - referentialOnly = true; +// getSynchroUIContext().setImportData(false); +// referentialOnly = true; + // If user cancel the program selection, then cancel synchro (Mantis #46164) + return; } // Transform selected programs into a code list diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/CloseAction.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/CloseAction.java index a46be458902490a99517e32d2070958c084cbb54..e7ffc321ff0b4992e71d1a666c8333794fb30632 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/CloseAction.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/CloseAction.java @@ -68,7 +68,8 @@ public class CloseAction extends AbstractCheckBeforeChangeScreenAction null, null); + // Listener on remove filter on campaigns + getUI().getCampaignCombo().setActionListener(e -> { + if (!askBefore(t("reefdb.common.unfilter"), t("reefdb.common.unfilter.confirmation"))) { + return; + } + getUI().getCampaignCombo().setActionEnabled(false); + getModel().setForceNoCampaignFilter(true); + applyContext(); + }); + // Initailisation des programmes initBeanFilterableComboBox( getUI().getProgramCombo(), @@ -192,16 +202,6 @@ public class HomeUIHandler extends AbstractReefDbUIHandler */ private void initListeners() { - // Listener on remove filter on campaigns - getUI().getCampaignCombo().setActionListener(e -> { - if (!askBefore(t("reefdb.common.unfilter"), t("reefdb.common.unfilter.confirmation"))) { - return; - } - getUI().getCampaignCombo().setActionEnabled(false); - getModel().setForceNoCampaignFilter(true); - applyContext(); - }); - // Listener sur la selection du programme getModel().addPropertyChangeListener(HomeUIModel.PROPERTY_PROGRAM, evt -> { // update locations diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel.java index 579a0661528e3958bd756483b8d8889ab0aee95e..5382aad851b01e5b325c4c444c8331b16b450782 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel.java @@ -12,24 +12,27 @@ package fr.ifremer.reefdb.ui.swing.content.home; * it under the terms of the GNU Affero 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 Affero General Public License * along with this program. If not, see . * #L% */ import fr.ifremer.quadrige3.ui.swing.model.AbstractEmptyUIModel; +import fr.ifremer.reefdb.dto.ReefDbBeans; import fr.ifremer.reefdb.dto.SearchDateDTO; import fr.ifremer.reefdb.dto.StateDTO; import fr.ifremer.reefdb.dto.SynchronizationStatusDTO; import fr.ifremer.reefdb.dto.configuration.context.ContextDTO; import fr.ifremer.reefdb.dto.configuration.programStrategy.ProgramDTO; +import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationDTO; import fr.ifremer.reefdb.dto.data.survey.CampaignDTO; +import fr.ifremer.reefdb.dto.data.survey.SurveyDTO; import fr.ifremer.reefdb.dto.referential.LocationDTO; import fr.ifremer.reefdb.ui.swing.content.home.operation.OperationsTableUIModel; import fr.ifremer.reefdb.ui.swing.content.home.survey.SurveysTableRowModel; @@ -85,6 +88,36 @@ public class HomeUIModel extends AbstractEmptyUIModel { private OperationsTableUIModel operationsTableUIModel; private SurveysTableRowModel selectedSurvey; + /** + * Check if there is real error (if not, means control is valid, then the save is enabled) (Mantis #50538) + * + * @return true if already valid or there is only control errors + */ + public boolean isControlValid() { + if (isValid()) + return true; + if (getSurveysTableUIModel() == null) + return false; + + boolean controlValid = true; + for (SurveyDTO survey : getSurveysTableUIModel().getBeans()) { + if (ReefDbBeans.isSurveyValidated(survey)) + continue; + if (!ReefDbBeans.getErrors(survey, false).isEmpty()) { + controlValid = false; + break; + } else { + for (SamplingOperationDTO operation : survey.getSamplingOperations()) { + if (!ReefDbBeans.getErrors(operation, false).isEmpty()) { + controlValid = false; + break; + } + } + } + } + return controlValid; + } + /** *

isAdjusting.

* diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/SaveAction.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/SaveAction.java index ad900287b2e497aaae72126e093ad63bafb48ad1..dde44ffe7971f5d2fa800c3ce55a6f618bd9ff36 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/SaveAction.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/home/SaveAction.java @@ -110,7 +110,8 @@ public class SaveAction extends AbstractReefDbSaveAction { - /** - * Row. - */ - private SurveysTableRowModel newRow; + private SurveyDTO duplicatedObservation; private boolean fullDuplication; private boolean duplicateCoordinate; @@ -61,18 +58,15 @@ public class DuplicateSurveyAction extends AbstractReefDbAction { if (getModel().getSelectedRows().size() == 1) { - getUI().getEditCombobox().setEnabled(!getModel().getSelectedRows().iterator().next().isLocal()); + ProgramsTableRowModel selected = getModel().getSelectedRows().iterator().next(); + getUI().getEditCombobox().setEnabled(selected.getStatus() != null && !selected.isLocal()); } else { getUI().getEditCombobox().setEnabled(false); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/local/PmfmsLocalUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/local/PmfmsLocalUIHandler.java index 959065341cf7ecb4c0f70c0ec5df218540980297..8706e80efc48a63230df929df84da6819fa88c3b 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/local/PmfmsLocalUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/local/PmfmsLocalUIHandler.java @@ -169,7 +169,6 @@ public class PmfmsLocalUIHandler extends AbstractReefDbTableUIHandler getTableModel() { diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/parameter/table/ParameterTableRowModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/parameter/table/ParameterTableRowModel.java index afa3631721eb6c72c65e9c45578725faf46e368e..8080e10238f3c6e1b4533d99149051e2302c3121 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/parameter/table/ParameterTableRowModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/parameter/table/ParameterTableRowModel.java @@ -181,13 +181,13 @@ public class ParameterTableRowModel extends AbstractReefDbRowUIModel getQualitativeValues() { + public List getQualitativeValues() { return delegateObject.getQualitativeValues(); } /** {@inheritDoc} */ @Override - public void setQualitativeValues(Collection QualitativeValues) { + public void setQualitativeValues(List QualitativeValues) { delegateObject.setQualitativeValues(QualitativeValues); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/qualitativevalue/QualitativeValueUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/qualitativevalue/QualitativeValueUIHandler.java index 502d95d2d8acc5a93dda4953ac7d70c8a2e9de22..9d99e1e97cb0e8a080c6729b8df5a5e23375639e 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/qualitativevalue/QualitativeValueUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/referential/pmfm/qualitativevalue/QualitativeValueUIHandler.java @@ -26,6 +26,7 @@ package fr.ifremer.reefdb.ui.swing.content.manage.referential.pmfm.qualitativeva import com.google.common.base.Predicate; import com.google.common.collect.Lists; import fr.ifremer.quadrige3.core.dao.referential.StatusCode; +import fr.ifremer.quadrige3.ui.core.dto.referential.BaseReferentialDTO; import fr.ifremer.quadrige3.ui.swing.table.SwingTable; import fr.ifremer.reefdb.dao.technical.Daos; import fr.ifremer.reefdb.dto.ReefDbBeans; @@ -42,7 +43,7 @@ import org.apache.commons.logging.LogFactory; import org.jdesktop.swingx.table.TableColumnExt; import org.nuiton.jaxx.application.swing.util.Cancelable; -import java.util.Collection; +import java.util.Comparator; import java.util.List; /** @@ -86,8 +87,13 @@ public class QualitativeValueUIHandler extends AbstractReefDbTableUIHandler universeValues = null; if (pmfm.getParameter() != null) { + // gather qualitative values from service (Mantis #49916,49708) + List qualitativeValues = getContext().getReferentialService().getQualitativeValues(pmfm.getParameter().getCode()); // filter active qualitative values only - universeValues = ReefDbBeans.filterCollection(pmfm.getParameter().getQualitativeValues(), (Predicate) input -> input != null && input.getStatus() != null && StatusFilter.ACTIVE.toStatusCodes().contains(input.getStatus().getCode())); + universeValues = ReefDbBeans.filterCollection(qualitativeValues, (Predicate) input -> + input != null && input.getStatus() != null && StatusFilter.ACTIVE.toStatusCodes().contains(input.getStatus().getCode())); + // sort by label + universeValues.sort(Comparator.comparing(BaseReferentialDTO::getName)); } List selectedValues = Lists.newArrayList(pmfm.getQualitativeValues()); @@ -96,7 +102,11 @@ public class QualitativeValueUIHandler extends AbstractReefDbTableUIHandler qualitativeValues = getQualitativeValuesFromRow(getModel().getParentRowModel()); + if (qualitativeValues != null) { + qualitativeValues.sort(Comparator.comparing(BaseReferentialDTO::getName)); + } + getModel().setBeans(qualitativeValues); getUI().getListPanelLayout().setSelected(TABLE); } }); @@ -142,7 +152,7 @@ public class QualitativeValueUIHandler extends AbstractReefDbTableUIHandler getQualitativeValuesFromRow(AbstractReefDbRowUIModel rowModel) { + private List getQualitativeValuesFromRow(AbstractReefDbRowUIModel rowModel) { if (ParameterDTO.class.isAssignableFrom(rowModel.getClass())) { return ((ParameterDTO) rowModel).getQualitativeValues(); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/SaveAction.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/SaveAction.java index 55703ca349ade4cd86aceb5c404484ac6afd8fec..3715d1119d7b5f30fc65f8f0b2c09b38fb877add 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/SaveAction.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/SaveAction.java @@ -59,6 +59,14 @@ public class SaveAction extends AbstractReefDbRemoteSaveAction 0) { + getModel().getControlRuleUIModel().getRows().forEach(controlRuleRowModel -> controlRuleRowModel.setNewCode(false)); + } + + // reload ComboBox + getUI().getRulesMenuUI().getHandler().reloadComboBox(); + getActionEngine().runInternalAction(getUI().getRulesMenuUI().getHandler(), SearchAction.class); } @@ -91,24 +99,4 @@ public class SaveAction extends AbstractReefDbRemoteSaveAction 0) { - getModel().getControlRuleUIModel().getRows().forEach(controlRuleRowModel -> controlRuleRowModel.setNewCode(false)); - } - - // reload ComboBox - getUI().getRulesMenuUI().getHandler().reloadComboBox(); - } - } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/ControlRuleTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/ControlRuleTableUIHandler.java index 9d0e20f17c99009f55ce5c70fa7ea2f49129d6ed..01b87e2d0505b49982cb94933856350a0aeed946 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/ControlRuleTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/ControlRuleTableUIHandler.java @@ -643,6 +643,9 @@ public class ControlRuleTableUIHandler extends */ public void loadControlRules(final Collection controlRules) { + // Stop table edition to avoid rendering exception (Mantis #49268) + getTable().editingStopped(null); + // Load les controlRule dans le model getModel().setBeans(controlRules); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/precondition/numerical/RulePrecondNumUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/precondition/numerical/RulePrecondNumUIHandler.java index 2f4158a3d9d044cec50e7e4f1a5c3ec53ab508cc..825d542d69f75cbc57fa9a7cf927dc54ce2760ea 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/precondition/numerical/RulePrecondNumUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/precondition/numerical/RulePrecondNumUIHandler.java @@ -23,8 +23,8 @@ package fr.ifremer.reefdb.ui.swing.content.manage.rule.controlrule.precondition. * #L% */ -import fr.ifremer.quadrige3.core.dao.technical.AlphanumericComparator; import fr.ifremer.quadrige3.core.dao.technical.Assert; +import fr.ifremer.quadrige3.ui.core.dto.referential.ReferentialNameAlphanumericComparator; import fr.ifremer.quadrige3.ui.swing.table.AbstractTableModel; import fr.ifremer.quadrige3.ui.swing.table.SwingTable; import fr.ifremer.reefdb.decorator.DecoratorService; @@ -83,7 +83,7 @@ public class RulePrecondNumUIHandler null, newTableCellRender(RulePrecondNumTableModel.QUALITATIVE_VALUE), RulePrecondNumTableModel.QUALITATIVE_VALUE); -// qvCol.setSortable(true); + qvCol.setSortable(true); qvCol.setEditable(false); addColumn( @@ -101,7 +101,7 @@ public class RulePrecondNumUIHandler initTable(getTable(), true); // Mantis #42541 Allow Qualitative value name sorting with enhanced sorting comparator - getSortController().setComparator(qvCol.getModelIndex(), new AlphanumericComparator()); + getSortController().setComparator(qvCol.getModelIndex(), ReferentialNameAlphanumericComparator.instance()); getTable().setSortOrder(RulePrecondNumTableModel.QUALITATIVE_VALUE, SortOrder.ASCENDING); getTable().setHorizontalScrollEnabled(false); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/precondition/qualitative/RulePrecondQualUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/precondition/qualitative/RulePrecondQualUIHandler.java index 9a684721fcce2c62edb9f55c3df67a813c90709b..595699489bfa87642022ea1be453b84b7ce70934 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/precondition/qualitative/RulePrecondQualUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/controlrule/precondition/qualitative/RulePrecondQualUIHandler.java @@ -23,7 +23,6 @@ package fr.ifremer.reefdb.ui.swing.content.manage.rule.controlrule.precondition. * #L% */ -import fr.ifremer.quadrige3.core.dao.technical.AlphanumericComparator; import fr.ifremer.quadrige3.ui.swing.table.AbstractTableModel; import fr.ifremer.quadrige3.ui.swing.table.SwingTable; import fr.ifremer.reefdb.decorator.DecoratorService; @@ -62,7 +61,8 @@ public class RulePrecondQualUIHandler initTable(); - initBeanList(rulePrecondQualUI.getUsedRuleQVDoubleList(), null, new ArrayList<>()); + // adjust double list size (Mantis #51128) + initBeanList(rulePrecondQualUI.getUsedRuleQVDoubleList(), null, new ArrayList<>(), 100); rulePrecondQualUI.getUsedRuleQVDoubleList().getHandler().addAdditionalControls(); initListeners(); @@ -81,8 +81,6 @@ public class RulePrecondQualUIHandler initTable(getTable(), true); - // Mantis #42541 Allow Qualitative value name sorting with enhanced sorting comparator - getSortController().setComparator(nameCol.getModelIndex(), new AlphanumericComparator()); getTable().setSortOrder(RulePrecondQualTableModel.NAME, SortOrder.ASCENDING); getTable().setHorizontalScrollEnabled(false); getTable().setEditable(false); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/menu/RulesMenuUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/menu/RulesMenuUIHandler.java index 56223ee4bbbcc9ff83d31fb745327c6a89123177..62ab7b4ef871fbbdcd3908413fee7db01e582c10 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/menu/RulesMenuUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/manage/rule/menu/RulesMenuUIHandler.java @@ -99,18 +99,18 @@ public class RulesMenuUIHandler extends AbstractReefDbUIHandlerreloadComboBox.

*/ - @SuppressWarnings("unchecked") public void reloadComboBox() { getModel().setLoading(true); - BeanFilterableComboBox cb = getUI().getRuleListComboBox(); + BeanFilterableComboBox cb = getUI().getRuleListComboBox(); cb.setData(null); List ruleLists = getContext().getRuleListService().getRuleLists(); - cb.setData(ruleLists); -// if (cb.getSelectedItem() != null) { -// RulesUI parentUI = (RulesUI) ReefDbUIs.getParentUI(getUI()); -// cb.setSelectedItem(parentUI.getModel().getRuleListUIModel().getSingleSelectedRow()); -// } + + // clear selected item if not present in list (Mantis #50537) + if (cb.getSelectedItem() instanceof RuleListDTO && !ruleLists.contains(cb.getSelectedItem())) { + cb.setSelectedItem(null); + } + getModel().setLoading(false); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/ObservationUI.jaxx b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/ObservationUI.jaxx index e0421c801a408f5d793267e70d9331296bc6d3d2..727fd445ccbd40193b70eb83ba2166fd9274266f 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/ObservationUI.jaxx +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/ObservationUI.jaxx @@ -30,7 +30,7 @@ fr.ifremer.reefdb.ui.swing.content.ReefDbMainUI fr.ifremer.quadrige3.ui.swing.ApplicationUI fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil - fr.ifremer.quadrige3.ui.swing.plaf.WaitBlockingLayerUI + fr.ifremer.quadrige3.ui.swing.plaf.ComponentBlockingLayerUI fr.ifremer.reefdb.ui.swing.content.observation.survey.SurveyDetailsTabUI fr.ifremer.reefdb.ui.swing.content.observation.survey.measurement.SurveyMeasurementsTabUI @@ -54,7 +54,7 @@ - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/multiedit/OperationMeasurementsMultiEditUI.jcss b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/multiedit/OperationMeasurementsMultiEditUI.jcss new file mode 100644 index 0000000000000000000000000000000000000000..b3c7de30f8c34be821096f16403d5a0d0ee4d2e6 --- /dev/null +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/multiedit/OperationMeasurementsMultiEditUI.jcss @@ -0,0 +1,44 @@ +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +#operationMeasurementsMultiEditUI { + modal: true; + resizable: false; + title: "reefdb.measurement.grouped.multiEdit.title"; +} + + +#cancelButton { + actionIcon: cancel; + text: "reefdb.common.cancel"; + toolTipText: "reefdb.common.cancel"; + i18nMnemonic: "reefdb.common.cancel.mnemonic"; +} + +#validButton { + actionIcon: accept; + text: "reefdb.common.validate"; + toolTipText: "reefdb.common.validate"; + i18nMnemonic: "reefdb.common.validate.mnemonic"; + enabled: {model.isValid() && model.isModify()}; +} \ No newline at end of file diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/multiedit/OperationMeasurementsMultiEditUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/multiedit/OperationMeasurementsMultiEditUIHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..64f922fed2c2daa85a6cefca87abf633457f526a --- /dev/null +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/multiedit/OperationMeasurementsMultiEditUIHandler.java @@ -0,0 +1,130 @@ +package fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.grouped.multiedit; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +import fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil; +import fr.ifremer.quadrige3.ui.swing.table.ColumnIdentifier; +import fr.ifremer.quadrige3.ui.swing.table.SwingTable; +import fr.ifremer.reefdb.dto.data.measurement.MeasurementAware; +import fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedRowModel; +import fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedTableModel; +import fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedTableUI; +import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsGroupedTableModel; +import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsMultiEditUIHandler; +import org.jdesktop.swingx.table.TableColumnExt; +import org.nuiton.jaxx.application.swing.util.Cancelable; + +/** + * Controleur pour les mesures de l'observation. + */ +public class OperationMeasurementsMultiEditUIHandler + extends AbstractMeasurementsMultiEditUIHandler + implements Cancelable { + + /** + *

Constructor for OperationMeasurementsMultiEditUIHandler.

+ */ + public OperationMeasurementsMultiEditUIHandler() { + super(); + } + + /** + * {@inheritDoc} + */ + @Override + public AbstractMeasurementsGroupedTableModel getTableModel() { + return (OperationMeasurementsGroupedTableModel) getTable().getModel(); + } + + @Override + protected OperationMeasurementsMultiEditUIModel createNewModel() { + return new OperationMeasurementsMultiEditUIModel(); + } + + @Override + protected OperationMeasurementsGroupedRowModel createNewRow(boolean readOnly, MeasurementAware parentBean) { + return new OperationMeasurementsGroupedRowModel(readOnly); + } + + /** + * {@inheritDoc} + */ + @Override + public SwingTable getTable() { + return getUI().getOperationGroupedMeasurementMultiEditTable(); + } + + @Override + protected SwingTable getReferentTable() { + return ((OperationMeasurementsGroupedTableUI) ApplicationUIUtil.getParentUI(getUI())).getOperationGroupedMeasurementTable(); + } + + /** + * Initialisation du tableau. + */ + @Override + protected void initTable() { + + final TableColumnExt samplingCol = addColumn(OperationMeasurementsGroupedTableModel.SAMPLING); + samplingCol.setEditable(false); + + // Colonne groupe taxon + addColumn( + taxonGroupCellEditor, + newTableCellRender(OperationMeasurementsGroupedTableModel.TAXON_GROUP), + OperationMeasurementsGroupedTableModel.TAXON_GROUP); + + // Colonne taxon + addColumn( + taxonCellEditor, + newTableCellRender(OperationMeasurementsGroupedTableModel.TAXON), + OperationMeasurementsGroupedTableModel.TAXON); + + // Colonne taxon saisi + final TableColumnExt colInputTaxon = addColumn(OperationMeasurementsGroupedTableModel.INPUT_TAXON_NAME); + colInputTaxon.setEditable(false); + + // Colonne analyste + addColumn( + departmentCellEditor, + newTableCellRender(AbstractMeasurementsGroupedTableModel.ANALYST), + (ColumnIdentifier) AbstractMeasurementsGroupedTableModel.ANALYST); + + // No comment column because comment editor is also a JDialog +// final TableColumnExt colComment = addCommentColumn(OperationMeasurementsGroupedTableModel.COMMENT); + + // Modele de la table + final OperationMeasurementsGroupedTableModel tableModel = new OperationMeasurementsGroupedTableModel(getTable().getColumnModel(), false); + tableModel.setNoneEditableCols(); + getTable().setModel(tableModel); + + // Initialisation de la table + initTable(getTable()); + + // border + addEditionPanelBorder(); + } + + +} diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/multiedit/OperationMeasurementsMultiEditUIModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/multiedit/OperationMeasurementsMultiEditUIModel.java new file mode 100644 index 0000000000000000000000000000000000000000..6f0587703dd08fa57ed514df1e17d82920b4ea2f --- /dev/null +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/grouped/multiedit/OperationMeasurementsMultiEditUIModel.java @@ -0,0 +1,49 @@ +package fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.grouped.multiedit; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +import com.google.common.collect.ImmutableSet; +import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; +import fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedRowModel; +import fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedTableModel; +import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsGroupedTableModel; +import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsMultiEditUIModel; +import fr.ifremer.reefdb.ui.swing.util.table.ReefDbColumnIdentifier; + +import java.util.Set; + +public class OperationMeasurementsMultiEditUIModel + extends AbstractMeasurementsMultiEditUIModel { + + @Override + public Set> getIdentifiersToCheck() { + return ImmutableSet.of( + OperationMeasurementsGroupedTableModel.SAMPLING, + OperationMeasurementsGroupedTableModel.TAXON_GROUP, + OperationMeasurementsGroupedTableModel.TAXON, + OperationMeasurementsGroupedTableModel.INPUT_TAXON_NAME, + (ReefDbColumnIdentifier) AbstractMeasurementsGroupedTableModel.ANALYST + ); + } +} diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIHandler.java index bcf66ede6e370d8dec60aa905163738db99cb05a..569b76954ec8fd25012286d62f1ee066b2f48e8f 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIHandler.java @@ -23,7 +23,6 @@ package fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.ung * #L% */ -import fr.ifremer.quadrige3.core.dao.technical.AlphanumericComparator; import fr.ifremer.quadrige3.ui.swing.table.SwingTable; import fr.ifremer.quadrige3.ui.swing.table.editor.ExtendedComboBoxCellEditor; import fr.ifremer.reefdb.decorator.DecoratorService; @@ -174,7 +173,9 @@ public class OperationMeasurementsUngroupedTableUIHandler extends AbstractReefDb getContext().restoreComponentFromSwingSession(getTable()); // hide analyst if no pmfm - forceColumnVisibleAtLastPosition(OperationMeasurementsUngroupedTableModel.ANALYST, notEmpty); +// forceColumnVisibleAtLastPosition(OperationMeasurementsUngroupedTableModel.ANALYST, notEmpty); + // Don't force position (Mantis #49537) + forceColumnVisible(OperationMeasurementsUngroupedTableModel.ANALYST, notEmpty); // set columns with errors visible (Mantis #40752) ensureColumnsWithErrorAreVisible(getModel().getRows()); @@ -284,17 +285,6 @@ public class OperationMeasurementsUngroupedTableUIHandler extends AbstractReefDb addEditionPanelBorder(); } - @Override - protected void installSortController() { - super.installSortController(); - - getSortController().setComparator( - getTable().getColumnModel().getColumnExt(OperationMeasurementsUngroupedTableModel.NAME).getModelIndex(), - new AlphanumericComparator() - ); - - } - /** * {@inheritDoc} */ diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIModel.java index 4d492a095e9bdd00552af3aa2092f371fcf9d96b..6e830aba2ebdc61c5b69771ddc8a8df6e8b08d34 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/ungrouped/OperationMeasurementsUngroupedTableUIModel.java @@ -42,6 +42,7 @@ public class OperationMeasurementsUngroupedTableUIModel extends AbstractReefDbTa private ObservationUIModel survey; private SamplingOperationDTO samplingFilter; + private Integer calculatedLengthStartPositionPmfmId; /** * Constructor. @@ -113,6 +114,14 @@ public class OperationMeasurementsUngroupedTableUIModel extends AbstractReefDbTa return measurements; } + public Integer getCalculatedLengthStartPositionPmfmId() { + return calculatedLengthStartPositionPmfmId; + } + + public void setCalculatedLengthStartPositionPmfmId(Integer calculatedLengthStartPositionPmfmId) { + this.calculatedLengthStartPositionPmfmId = calculatedLengthStartPositionPmfmId; + } + public void fireMeasurementsLoaded() { firePropertyChange(EVENT_MEASUREMENTS_LOADED, null, null); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/photo/ImportAction.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/photo/ImportAction.java index f1817c836376672021eab9ad11040d39ec430d80..b18416a3460a8b9c49794d6f0e9584db4df3b66a 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/photo/ImportAction.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/photo/ImportAction.java @@ -12,12 +12,12 @@ package fr.ifremer.reefdb.ui.swing.content.observation.photo; * it under the terms of the GNU Affero 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 Affero General Public License * along with this program. If not, see . * #L% @@ -29,9 +29,12 @@ import fr.ifremer.reefdb.dto.ReefDbBeanFactory; import fr.ifremer.reefdb.dto.data.photo.PhotoDTO; import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationDTO; import fr.ifremer.reefdb.ui.swing.action.AbstractReefDbAction; +import org.apache.commons.collections4.CollectionUtils; import java.io.File; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.Objects; import static org.nuiton.i18n.I18n.t; @@ -41,8 +44,8 @@ import static org.nuiton.i18n.I18n.t; */ public class ImportAction extends AbstractReefDbAction { - private File originalImage; - private PhotoDTO newPhoto; + private List originalImages; + private List newPhotos; /** * Constructor. @@ -53,80 +56,110 @@ public class ImportAction extends AbstractReefDbAction 0 && originalImage.length() > maxSize) { + if (maxSize > 0 && originalImages.stream().anyMatch(file -> file.length() > maxSize)) { displayErrorMessage(getActionDescription(), - t("reefdb.action.photo.import.fileTooLarge.message", maxSize, Files.byteCountToDisplaySize(maxSize))); - originalImage = null; + t("reefdb.action.photo.import.fileTooLarge.message", maxSize, Files.byteCountToDisplaySize(maxSize))); + return false; } - } - return originalImage != null; + return true; + + } else { + + // no selection + return false; + } } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public void doAction() { getModel().setLoading(true); - - File tempFile = Images.importAndPrepareImageFile(originalImage, getConfig().getTempDirectory()); - - newPhoto = ReefDbBeanFactory.newPhotoDTO(); - newPhoto.setDirty(true); - newPhoto.setDate(new Date()); - newPhoto.setName(originalImage.getName()); - // set path file to null - newPhoto.setPath(null); - newPhoto.setFullPath(tempFile.getAbsolutePath()); - - // set sampling operation - if (getContext().getSelectedSamplingOperationId() != null){ - for (SamplingOperationDTO samplingOperation : getModel().getObservationModel().getSamplingOperations()) { - if (Objects.equals(samplingOperation.getId(), getContext().getSelectedSamplingOperationId())) { - newPhoto.setSamplingOperation(samplingOperation); - break; + newPhotos = new ArrayList<>(); + + originalImages.forEach(originalImage -> { + + File tempFile = Images.importAndPrepareImageFile(originalImage, getConfig().getTempDirectory()); + + PhotoDTO newPhoto = ReefDbBeanFactory.newPhotoDTO(); + newPhoto.setDirty(true); + newPhoto.setDate(new Date()); + newPhoto.setName(originalImage.getName()); + // set path file to null + newPhoto.setPath(null); + newPhoto.setFullPath(tempFile.getAbsolutePath()); + + // set sampling operation + if (getContext().getSelectedSamplingOperationId() != null) { + for (SamplingOperationDTO samplingOperation : getModel().getObservationModel().getSamplingOperations()) { + if (Objects.equals(samplingOperation.getId(), getContext().getSelectedSamplingOperationId())) { + newPhoto.setSamplingOperation(samplingOperation); + break; + } } } - } + + newPhotos.add(newPhoto); + + }); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public void postSuccessAction() { super.postSuccessAction(); - if (newPhoto != null) { - getHandler().setFocusOnCell(getModel().addNewRow(newPhoto)); + if (CollectionUtils.isNotEmpty(newPhotos)) { + + PhotosTableRowModel firstRow = null; + for (PhotoDTO newPhoto : newPhotos) { + PhotosTableRowModel newRow = getModel().addNewRow(newPhoto); + if (firstRow == null) + firstRow = newRow; + } + if (firstRow != null) + getHandler().setFocusOnCell(firstRow); + getModel().setModify(true); } } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override protected void releaseAction() { super.releaseAction(); - originalImage = null; - newPhoto = null; + originalImages = null; + newPhotos = null; getModel().setLoading(false); } } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedRowModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedRowModel.java index 2fe3a0c9c00ff7593b0d593953557fe487a1d719..3227c3e215f981abc964a225f61eba194febd306 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedRowModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedRowModel.java @@ -26,7 +26,7 @@ package fr.ifremer.reefdb.ui.swing.content.observation.shared; import com.google.common.collect.Lists; import fr.ifremer.quadrige3.core.dao.technical.factorization.pmfm.AllowedQualitativeValuesMap; import fr.ifremer.quadrige3.ui.core.dto.CommentAware; -import fr.ifremer.quadrige3.ui.core.dto.QuadrigeBean; +import fr.ifremer.quadrige3.ui.swing.table.ColumnIdentifier; import fr.ifremer.reefdb.dto.ErrorAware; import fr.ifremer.reefdb.dto.ErrorDTO; import fr.ifremer.reefdb.dto.ReefDbBeans; @@ -38,17 +38,14 @@ import fr.ifremer.reefdb.dto.referential.TaxonGroupDTO; import fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO; import fr.ifremer.reefdb.ui.swing.util.table.AbstractReefDbRowUIModel; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; /** * @author peck7 on 08/01/2019. */ -public abstract class AbstractMeasurementsGroupedRowModel> +public abstract class AbstractMeasurementsGroupedRowModel> extends AbstractReefDbRowUIModel implements CommentAware, MeasurementAware, ErrorAware { public static String PROPERTY_INDIVIDUAL_ID = "individualId"; @@ -77,15 +74,21 @@ public abstract class AbstractMeasurementsGroupedRowModel preconditionErrors; + // used with multi edit model + private List> multipleValuesOnIdentifier; + private List multipleValuesOnPmfmIds; + /** *

Constructor for AbstractReefDbRowUIModel.

*/ public AbstractMeasurementsGroupedRowModel(boolean readOnly) { super(null, null); - this.individualMeasurements = Lists.newArrayList(); - this.errors = Lists.newArrayList(); - this.preconditionErrors = Lists.newArrayList(); + this.individualMeasurements = new ArrayList<>(); + this.errors = new ArrayList<>(); + this.preconditionErrors = new ArrayList<>(); this.allowedQualitativeValuesMap = new AllowedQualitativeValuesMap(); + this.multipleValuesOnIdentifier = new ArrayList<>(); + this.multipleValuesOnPmfmIds = new ArrayList<>(); this.readOnly = readOnly; } @@ -291,6 +294,22 @@ public abstract class AbstractMeasurementsGroupedRowModel> getMultipleValuesOnIdentifier() { + return multipleValuesOnIdentifier; + } + + public void addMultipleValuesOnIdentifier(ColumnIdentifier identifier) { + multipleValuesOnIdentifier.add(identifier); + } + + public List getMultipleValuesOnPmfmIds() { + return multipleValuesOnPmfmIds; + } + + public void addMultipleValuesOnPmfmId(Integer pmfmId) { + multipleValuesOnPmfmIds.add(pmfmId); + } + public boolean isSameRow(AbstractMeasurementsGroupedRowModel that) { return Objects.equals(this.getTaxonGroup(), that.getTaxonGroup()) && Objects.equals(this.getTaxon(), that.getTaxon()); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableModel.java index 2c678f3f095b358d3df8b7487ee565688a53aadf..6ca7cc38f382c65b64bc3b412ecf6068eac04e00 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableModel.java @@ -23,6 +23,7 @@ package fr.ifremer.reefdb.ui.swing.content.observation.shared; * #L% */ +import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; import fr.ifremer.reefdb.dto.referential.DepartmentDTO; import fr.ifremer.reefdb.ui.swing.util.table.AbstractReefDbTableModel; import fr.ifremer.reefdb.ui.swing.util.table.ReefDbColumnIdentifier; @@ -33,19 +34,19 @@ import static org.nuiton.i18n.I18n.n; /** * @author peck7 on 08/01/2019. */ -public abstract class AbstractMeasurementsGroupedTableModel> +public abstract class AbstractMeasurementsGroupedTableModel> extends AbstractReefDbTableModel { /** * Identifiant pour la colonne analyst. */ - public static final ReefDbColumnIdentifier ANALYST = ReefDbColumnIdentifier.newId( + public static final ReefDbColumnIdentifier> ANALYST = ReefDbColumnIdentifier.newId( AbstractMeasurementsGroupedRowModel.PROPERTY_ANALYST, n("reefdb.property.analyst"), n("reefdb.measurement.analyst.tip"), DepartmentDTO.class); - public static final ReefDbColumnIdentifier INDIVIDUAL_ID = ReefDbColumnIdentifier.newReadOnlyId( + public static final ReefDbColumnIdentifier> INDIVIDUAL_ID = ReefDbColumnIdentifier.newReadOnlyId( AbstractMeasurementsGroupedRowModel.PROPERTY_INDIVIDUAL_ID, n("reefdb.property.individualId"), n("reefdb.property.individualId"), @@ -56,8 +57,8 @@ public abstract class AbstractMeasurementsGroupedTableModel getPmfmInsertPosition(); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIHandler.java index 18641b829e5731513dcb6e9867b327a406144ba7..1a229dd2576eb3e81d82fc9a7aed548f2248467f 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIHandler.java @@ -49,6 +49,7 @@ import fr.ifremer.reefdb.dto.referential.TaxonDTO; import fr.ifremer.reefdb.dto.referential.TaxonGroupDTO; import fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO; import fr.ifremer.reefdb.dto.referential.pmfm.QualitativeValueDTO; +import fr.ifremer.reefdb.ui.swing.content.observation.operation.measurement.grouped.OperationMeasurementsGroupedRowModel; import fr.ifremer.reefdb.ui.swing.util.ReefDbUI; import fr.ifremer.reefdb.ui.swing.util.table.AbstractReefDbTableUIHandler; import fr.ifremer.reefdb.ui.swing.util.table.PmfmTableColumn; @@ -59,7 +60,12 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JScrollPane; import javax.swing.SwingUtilities; +import java.awt.Dimension; +import java.awt.Insets; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; @@ -71,8 +77,8 @@ import static org.nuiton.i18n.I18n.t; * @author peck7 on 08/01/2019. */ public abstract class AbstractMeasurementsGroupedTableUIHandler< - R extends AbstractMeasurementsGroupedRowModel, - M extends AbstractMeasurementsGroupedTableUIModel, + R extends AbstractMeasurementsGroupedRowModel, + M extends AbstractMeasurementsGroupedTableUIModel, UI extends ReefDbUI> extends AbstractReefDbTableUIHandler { @@ -102,7 +108,6 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< @Override public void afterInit(UI ui) { - // Initialiser l UI initUI(ui); createTaxonGroupCellEditor(); @@ -285,8 +290,10 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< // restore table from swing session getContext().restoreComponentFromSwingSession(getTable()); - // hide analyst if no pmfm TODO - forceColumnVisibleAtLastPosition(AbstractMeasurementsGroupedTableModel.ANALYST, notEmpty); + // hide analyst if no pmfm +// forceColumnVisibleAtLastPosition(AbstractMeasurementsGroupedTableModel.ANALYST, notEmpty); + // Don't force position (Mantis #49537) + forceColumnVisible(AbstractMeasurementsGroupedTableModel.ANALYST, notEmpty); // set columns with errors visible (Mantis #40752) ensureColumnsWithErrorAreVisible(getModel().getRows()); @@ -299,7 +306,7 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< } - private List buildRows(boolean readOnly) { + protected List buildRows(boolean readOnly) { List rows = new ArrayList<>(); @@ -610,6 +617,10 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< } + private void setDirty(Object bean) { + if (bean instanceof DirtyAware) ((DirtyAware) bean).setDirty(true); + } + protected void updateMeasurementFromRow(MeasurementDTO measurement, R row) { measurement.setIndividualId(row.getIndividualId()); measurement.setTaxonGroup(row.getTaxonGroup()); @@ -670,6 +681,18 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< protected boolean isRowValid(R row) { boolean valid = super.isRowValid(row); + if (!valid && !row.isMandatoryValid()) { + // check invalid mandatory errors + new ArrayList<>(row.getInvalidMandatoryIdentifiers()).forEach(invalidIdentifier -> { + if (row.getMultipleValuesOnIdentifier().contains(invalidIdentifier)) { + // if this identifier has multiple value, remove error + row.getErrors().removeIf(error -> error.getPropertyName().size() == 1 && error.getPropertyName().contains(invalidIdentifier.getPropertyName())); + row.getInvalidMandatoryIdentifiers().remove(invalidIdentifier); + } + }); + valid = row.isMandatoryValid(); + } + boolean noUnicityDuplicates = hasNoUnicityDuplicates(row); boolean noPreconditionErrors = hasNoPreconditionErrors(row); boolean noGroupedRuleErrors = hasNoGroupedRuleErrors(row); @@ -679,7 +702,8 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< } protected boolean hasAnalyst(R row) { - if (row.getAnalyst() == null && row.getIndividualMeasurements().stream().anyMatch(this::isMeasurementNotEmpty)) { + if (!row.getMultipleValuesOnIdentifier().contains(AbstractMeasurementsGroupedTableModel.ANALYST) + && row.getAnalyst() == null && row.getIndividualMeasurements().stream().anyMatch(this::isMeasurementNotEmpty)) { ReefDbBeans.addError(row, t("reefdb.validator.error.analyst.required"), AbstractMeasurementsGroupedRowModel.PROPERTY_ANALYST); @@ -1099,12 +1123,92 @@ public abstract class AbstractMeasurementsGroupedTableUIHandler< } } - - /* - Private methods + /** + * Open the multiline edit dialog (Mantis #49615) + * + * @param dialog the dialog to open */ + protected void editSelectedMeasurements(JDialog dialog) { + // save current table state to be able to restore it in dialog's table + saveTableInSwingSession(); + + Assert.isInstanceOf(ReefDbUI.class, dialog); + ReefDbUI multiEditUI = (ReefDbUI) dialog; + Assert.isInstanceOf(AbstractMeasurementsMultiEditUIModel.class, multiEditUI.getModel()); + AbstractMeasurementsMultiEditUIModel multiEditModel = (AbstractMeasurementsMultiEditUIModel) multiEditUI.getModel(); + multiEditModel.setObservationHandler(getModel().getObservationUIHandler()); + multiEditModel.setRowsToEdit(getModel().getSelectedRows()); + multiEditModel.setPmfms(getModel().getPmfms()); + multiEditModel.setSurvey(getModel().getSurvey()); + + // get parent component for dialog centering + JComponent parent = getUI().getParentContainer(getTable(), JScrollPane.class); + Insets borderInsets = parent.getBorder().getBorderInsets(parent); + openDialog(dialog, new Dimension(parent.getWidth() + borderInsets.left + borderInsets.right, 160), true, parent); + + // if dialog is valid + if (multiEditModel.isValid()) { + + // affect all non multiple column values to selected rows + R multiEditRow = multiEditModel.getRows().get(0); + + for (R row : getModel().getSelectedRows()) { + + // affect column values + for (ReefDbColumnIdentifier identifier : multiEditModel.getIdentifiersToCheck()) { + // be sure that sampling operation value can not be changed + if (identifier.getPropertyName().equals(OperationMeasurementsGroupedRowModel.PROPERTY_SAMPLING_OPERATION)) + continue; - private void setDirty(Object bean) { - if (bean instanceof DirtyAware) ((DirtyAware) bean).setDirty(true); + // get values + Object multiValue = identifier.getValue(multiEditRow); + Object currentValue = identifier.getValue(row); + boolean isMultiple = multiEditRow.getMultipleValuesOnIdentifier().contains(identifier); + // affect value if a multiple value has been replaced, or modification has been made + if ((!isMultiple || multiValue != null) && !Objects.equals(multiValue, currentValue)) { + identifier.setValue(row, multiValue); + // special case for INPUT_TAXON_NAME + if (identifier.getPropertyName().equals(AbstractMeasurementsGroupedRowModel.PROPERTY_INPUT_TAXON_NAME)) { + // affect also INPUT_TAXON_ID + row.setInputTaxonId(multiEditRow.getInputTaxonId()); + } + } + } + + // for measurement columns + for (PmfmDTO pmfm : getModel().getPmfms()) { + MeasurementDTO multiMeasurement = ReefDbBeans.getIndividualMeasurementByPmfmId(multiEditRow, pmfm.getId()); + if (multiMeasurement == null) { + // can happened if user pass on on a cel without setting a value + multiMeasurement = ReefDbBeanFactory.newMeasurementDTO(); + } + boolean isMultiple = multiEditRow.getMultipleValuesOnPmfmIds().contains(pmfm.getId()); + // affect value if a multiple value has been replaced, or modification has been made + if (!isMultiple || !ReefDbBeans.isMeasurementEmpty(multiMeasurement)) { + MeasurementDTO measurement = ReefDbBeans.getIndividualMeasurementByPmfmId(row, pmfm.getId()); + if (measurement == null) { + // create and add the measurement if not exists + measurement = ReefDbBeanFactory.newMeasurementDTO(); + measurement.setPmfm(pmfm); + measurement.setIndividualId(row.getIndividualId()); + row.getIndividualMeasurements().add(measurement); + } + // affect value (either numeric or qualitative) + if (!ReefDbBeans.measurementValuesEquals(multiMeasurement, measurement)) { + measurement.setNumericalValue(multiMeasurement.getNumericalValue()); + measurement.setQualitativeValue(multiMeasurement.getQualitativeValue()); + } + } + } + + // save modifications + saveMeasurementsInModel(row); + } + + // done + getModel().setModify(true); + getTable().repaint(); + } } + } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIModel.java index 15b24bab9ead4b50539e0f955dc650624f8bfb40..f8fbca9d4b3a9cae849d5dbefedaacebb6fe2154 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsGroupedTableUIModel.java @@ -25,10 +25,10 @@ package fr.ifremer.reefdb.ui.swing.content.observation.shared; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; -import fr.ifremer.quadrige3.ui.core.dto.QuadrigeBean; import fr.ifremer.reefdb.dto.configuration.control.ControlRuleDTO; import fr.ifremer.reefdb.dto.configuration.control.PreconditionRuleDTO; import fr.ifremer.reefdb.dto.configuration.control.RuleGroupDTO; +import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationDTO; import fr.ifremer.reefdb.dto.referential.TaxonDTO; import fr.ifremer.reefdb.dto.referential.TaxonGroupDTO; @@ -46,7 +46,7 @@ import java.util.Map; * @author peck7 on 08/01/2019. */ public abstract class AbstractMeasurementsGroupedTableUIModel< - B extends QuadrigeBean, + B extends MeasurementDTO, R extends AbstractMeasurementsGroupedRowModel, M extends AbstractMeasurementsGroupedTableUIModel> extends AbstractReefDbTableUIModel { diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..ca251614895e28b17960dc3d31fb7a153e9fd631 --- /dev/null +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIHandler.java @@ -0,0 +1,239 @@ +package fr.ifremer.reefdb.ui.swing.content.observation.shared; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +import com.google.common.collect.ImmutableList; +import fr.ifremer.quadrige3.core.dao.technical.Assert; +import fr.ifremer.quadrige3.ui.swing.table.SwingTable; +import fr.ifremer.quadrige3.ui.swing.table.state.SwingTableSessionState; +import fr.ifremer.reefdb.dto.ReefDbBeanFactory; +import fr.ifremer.reefdb.dto.ReefDbBeans; +import fr.ifremer.reefdb.dto.data.measurement.MeasurementAware; +import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; +import fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO; +import fr.ifremer.reefdb.ui.swing.util.ReefDbUI; +import fr.ifremer.reefdb.ui.swing.util.table.ReefDbColumnIdentifier; +import fr.ifremer.reefdb.ui.swing.util.table.renderer.MultipleValueCellRenderer; +import jaxx.runtime.swing.session.State; +import org.nuiton.jaxx.application.swing.util.Cancelable; + +import javax.swing.table.TableColumn; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * abstract handler for multiline edition + */ +public abstract class AbstractMeasurementsMultiEditUIHandler< + R extends AbstractMeasurementsGroupedRowModel, + M extends AbstractMeasurementsMultiEditUIModel, + UI extends ReefDbUI + > + extends AbstractMeasurementsGroupedTableUIHandler + implements Cancelable { + + /** + *

Constructor for AbstractMeasurementsMultiEditUIHandler.

+ */ + public AbstractMeasurementsMultiEditUIHandler() { + super(R.PROPERTY_TAXON_GROUP, + R.PROPERTY_TAXON, + R.PROPERTY_INDIVIDUAL_PMFMS, + R.PROPERTY_COMMENT); + } + + /** + * get the referent table for columns adjustments + * + * @return the referent table + */ + protected abstract SwingTable getReferentTable(); + + /** + * Don't really build rows but create a multi edit row + * + * @param readOnly readOnly + * @return rows from model + */ + @Override + protected List buildRows(boolean readOnly) { + + if (getModel().getRowsToEdit().isEmpty()) + return null; + + // Create a ghost row without parent + R multiEditRow = createNewRow(readOnly, null); + multiEditRow.setIndividualPmfms(new ArrayList<>(getModel().getPmfms())); + ReefDbBeans.createEmptyMeasurements(multiEditRow); + + boolean firstRow = true; + for (R row : getModel().getRowsToEdit()) { + + // find multiple value on each known columns + findMultipleValueOnIdentifier(row, multiEditRow, firstRow); + + // find multiple value on each measurement + findMultipleValueOnPmfmIdentifier(row, multiEditRow, firstRow); + + firstRow = false; + } + + overrideColumnRenderersAndEditors(multiEditRow); + + overrideColumnWidthAndPosition(); + + return ImmutableList.of(multiEditRow); + } + + // detect multiple values on each column + private void findMultipleValueOnIdentifier(R row, R multiEditRow, boolean firstRow) { + + for (ReefDbColumnIdentifier identifier : getModel().getIdentifiersToCheck()) { + if (!multiEditRow.getMultipleValuesOnIdentifier().contains(identifier)) { + if (!Objects.equals(identifier.getValue(row), identifier.getValue(multiEditRow))) { + if (firstRow) { + // on first row, consider a unique value + identifier.setValue(multiEditRow, identifier.getValue(row)); + } else { + // on other rows, if the value differs, set it as multiple + identifier.setValue(multiEditRow, null); + multiEditRow.addMultipleValuesOnIdentifier(identifier); + } + } + } + } + } + + // detect multiple values on each pmfm column + private void findMultipleValueOnPmfmIdentifier(R row, R multiEditRow, boolean firstRow) { + + for (PmfmDTO pmfm : getModel().getPmfms()) { + if (!multiEditRow.getMultipleValuesOnPmfmIds().contains(pmfm.getId())) { + MeasurementDTO multiMeasurement = ReefDbBeans.getIndividualMeasurementByPmfmId(multiEditRow, pmfm.getId()); + Assert.notNull(multiMeasurement, "should be already present"); + MeasurementDTO measurement = ReefDbBeans.getIndividualMeasurementByPmfmId(row, pmfm.getId()); + if (measurement == null) { + // create ghost measurement + measurement = ReefDbBeanFactory.newMeasurementDTO(); + measurement.setPmfm(pmfm); + } + + if (!ReefDbBeans.measurementValuesEquals(multiMeasurement, measurement)) { + if (firstRow) { + // on first row, consider a unique value + multiMeasurement.setNumericalValue(measurement.getNumericalValue()); + multiMeasurement.setQualitativeValue(measurement.getQualitativeValue()); + } else { + // on other rows, if the value differs, set it as multiple + multiMeasurement.setNumericalValue(null); + multiMeasurement.setQualitativeValue(null); + multiEditRow.addMultipleValuesOnPmfmId(pmfm.getId()); + } + } + } + } + } + + /** + * Override all column renderers with specific behavior if multiple values is found + * + * @param multiEditRow + */ + private void overrideColumnRenderersAndEditors(R multiEditRow) { + + multiEditRow.getMultipleValuesOnIdentifier().forEach(identifier -> { + TableColumn col = getTable().getColumnExt(identifier); + // override the renderer + col.setCellRenderer(new MultipleValueCellRenderer(col.getCellRenderer())); + }); + multiEditRow.getMultipleValuesOnPmfmIds().forEach(pmfmId -> + getModel().getPmfmColumns().stream().filter(pmfmTableColumn -> pmfmTableColumn.getPmfmId() == pmfmId).findFirst() + .ifPresent(pmfmTableColumn -> { + // override the renderer + pmfmTableColumn.setCellRenderer(new MultipleValueCellRenderer(pmfmTableColumn.getCellRenderer())); + // and set not editable if the pmfm is set as read-only + if (getModel().getReadOnlyPmfmIds().contains(pmfmId)) + pmfmTableColumn.setEditable(false); + } + )); + } + + private void overrideColumnWidthAndPosition() { + + // get the state of the referent table + State referentState = getContext().getSwingSession().findStateByComponentName(".*" + getReferentTable().getName()); + + // apply this state to the current table + if (referentState instanceof SwingTableSessionState) { + referentState.setState(getTable(), referentState); + } + } + + @Override + protected void onRowsAdded(List addedRows) { + // Don't call super method because the row is already initialized in buildRows() +// super.onRowsAdded(addedRows); + } + + @Override + public void saveMeasurementsInModel(R row) { + // Don't call super method; the selected rows will be saved after multi-line validation +// super.saveMeasurementsInModel(row); + } + + @Override + protected List getMeasurementAwareModels() { + // nothing to return, this handler don't save model + return null; + } + + @Override + protected MeasurementAware getMeasurementAwareModelForRow(R row) { + // nothing to return, this handler don't save model + return null; + } + + @Override + protected void filterMeasurements() { + } + + @Override + protected void removeIndividualMeasurements(List measurementToDelete) { + } + + public void valid() { + if (getModel().isValid()) { + closeDialog(); + } + } + + @Override + public void cancel() { + stopListenValidatorValid(getValidator()); + getModel().setValid(false); + closeDialog(); + } + +} diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIModel.java new file mode 100644 index 0000000000000000000000000000000000000000..379426413e30372f3d52377f8122b5df45c32320 --- /dev/null +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/shared/AbstractMeasurementsMultiEditUIModel.java @@ -0,0 +1,71 @@ +package fr.ifremer.reefdb.ui.swing.content.observation.shared; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; +import fr.ifremer.reefdb.ui.swing.util.table.ReefDbColumnIdentifier; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Modele pour les mesures de l'observation. + */ +public abstract class AbstractMeasurementsMultiEditUIModel< + B extends MeasurementDTO, + R extends AbstractMeasurementsGroupedRowModel, + M extends AbstractMeasurementsMultiEditUIModel> + extends AbstractMeasurementsGroupedTableUIModel { + + // rows selected by caller + Set rowsToEdit; + + // pmfm ids as read-only + List readOnlyPmfmIds; + + public Set getRowsToEdit() { + if (rowsToEdit == null) + rowsToEdit = new HashSet<>(); + return rowsToEdit; + } + + public void setRowsToEdit(Set rowsToEdit) { + this.rowsToEdit = rowsToEdit; + } + + public List getReadOnlyPmfmIds() { + if (readOnlyPmfmIds == null) + readOnlyPmfmIds = new ArrayList<>(); + return readOnlyPmfmIds; + } + + public void setReadOnlyPmfmIds(List readOnlyPmfmIds) { + this.readOnlyPmfmIds = readOnlyPmfmIds; + } + + public abstract Set> getIdentifiersToCheck(); + +} diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIHandler.java index 7388ec0ba6289ce63244f44deec8241d991d618a..08e6cf1ba56a0d0957bac24fb04b33c83abb81bd 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIHandler.java @@ -60,6 +60,8 @@ public class SurveyMeasurementsTabUIHandler extends AbstractReefDbUIHandler pmfmIdsToIgnore = ImmutableList.of(getConfig().getDepthValuesPmfmId()); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedRowModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedRowModel.java index c8de4905f84f4817c9101671ebc67823a843310a..89783e1d96205c7d4c1a4a0f8715392fb48d0cd5 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedRowModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedRowModel.java @@ -36,7 +36,7 @@ public class SurveyMeasurementsGroupedRowModel extends AbstractMeasurementsGroup * * @param readOnly a boolean. */ - SurveyMeasurementsGroupedRowModel(boolean readOnly) { + public SurveyMeasurementsGroupedRowModel(boolean readOnly) { super(readOnly); } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableModel.java index fd7ce8c27675c8ea3e35072fe4131fc2a3ef29e6..6624eec2029e7aa8bf14d2d04d0e565e98fdbd62 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableModel.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableModel.java @@ -28,6 +28,7 @@ import fr.ifremer.reefdb.dto.data.survey.SurveyDTO; import fr.ifremer.reefdb.dto.referential.TaxonDTO; import fr.ifremer.reefdb.dto.referential.TaxonGroupDTO; import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsGroupedTableModel; +import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsGroupedTableUIModel; import fr.ifremer.reefdb.ui.swing.util.table.ReefDbColumnIdentifier; import org.jdesktop.swingx.table.TableColumnModelExt; @@ -42,47 +43,46 @@ public class SurveyMeasurementsGroupedTableModel extends AbstractMeasurementsGro * Identifiant pour la colonne groupe taxon. */ public static final ReefDbColumnIdentifier TAXON_GROUP = ReefDbColumnIdentifier.newId( - SurveyMeasurementsGroupedRowModel.PROPERTY_TAXON_GROUP, - n("reefdb.property.taxonGroup.short"), - n("reefdb.survey.measurement.grouped.taxonGroup.tip"), - TaxonGroupDTO.class); + SurveyMeasurementsGroupedRowModel.PROPERTY_TAXON_GROUP, + n("reefdb.property.taxonGroup.short"), + n("reefdb.survey.measurement.grouped.taxonGroup.tip"), + TaxonGroupDTO.class); /** * Identifiant pour la colonne taxon. */ public static final ReefDbColumnIdentifier TAXON = ReefDbColumnIdentifier.newId( - SurveyMeasurementsGroupedRowModel.PROPERTY_TAXON, - n("reefdb.property.taxon"), - n("reefdb.survey.measurement.grouped.taxon.tip"), - TaxonDTO.class, - DecoratorService.WITH_CITATION); + SurveyMeasurementsGroupedRowModel.PROPERTY_TAXON, + n("reefdb.property.taxon"), + n("reefdb.survey.measurement.grouped.taxon.tip"), + TaxonDTO.class, + DecoratorService.WITH_CITATION); /** * Identifiant pour la colonne taxon saisi. */ - public static final ReefDbColumnIdentifier INPUT_TAXON_NAME = ReefDbColumnIdentifier.newReadOnlyId( - SurveyMeasurementsGroupedRowModel.PROPERTY_INPUT_TAXON_NAME, - n("reefdb.property.inputTaxon"), - n("reefdb.survey.measurement.grouped.inputTaxon.tip"), - String.class); + public static final ReefDbColumnIdentifier INPUT_TAXON_NAME = ReefDbColumnIdentifier.newId( + SurveyMeasurementsGroupedRowModel.PROPERTY_INPUT_TAXON_NAME, + n("reefdb.property.inputTaxon"), + n("reefdb.survey.measurement.grouped.inputTaxon.tip"), + String.class); /** * Identifiant pour la colonne valeur. */ public static final ReefDbColumnIdentifier COMMENT = ReefDbColumnIdentifier.newId( - SurveyMeasurementsGroupedRowModel.PROPERTY_COMMENT, - n("reefdb.property.comment"), - n("reefdb.survey.measurement.grouped.comment.tip"), - String.class); - + SurveyMeasurementsGroupedRowModel.PROPERTY_COMMENT, + n("reefdb.property.comment"), + n("reefdb.survey.measurement.grouped.comment.tip"), + String.class); /** * Constructor. * * @param columnModel Le modele pour les colonnes */ - public SurveyMeasurementsGroupedTableModel(final TableColumnModelExt columnModel) { - super(columnModel); + public SurveyMeasurementsGroupedTableModel(final TableColumnModelExt columnModel, boolean createNewRow) { + super(columnModel, createNewRow); } /** @@ -110,8 +110,8 @@ public class SurveyMeasurementsGroupedTableModel extends AbstractMeasurementsGro * {@inheritDoc} */ @Override - public SurveyMeasurementsGroupedTableUIModel getTableUIModel() { - return (SurveyMeasurementsGroupedTableUIModel) super.getTableUIModel(); + public AbstractMeasurementsGroupedTableUIModel getTableUIModel() { + return (AbstractMeasurementsGroupedTableUIModel) super.getTableUIModel(); } /** @@ -122,8 +122,8 @@ public class SurveyMeasurementsGroupedTableModel extends AbstractMeasurementsGro if (getTableUIModel().getSurvey() != null && getTableUIModel().getSurvey().getProgram() != null) { return SurveyMeasurementsGroupedTableUIModel.PROPERTY_SURVEY + '_' - + SurveyDTO.PROPERTY_INDIVIDUAL_PMFMS + '_' - + getTableUIModel().getSurvey().getProgram().getCode(); + + SurveyDTO.PROPERTY_INDIVIDUAL_PMFMS + '_' + + getTableUIModel().getSurvey().getProgram().getCode(); } return super.getStateContext(); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUI.jaxx b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUI.jaxx index 714c8e48a1f1a44867b2af65ee99f17e03ce1f49..9cad090d4c7f228a430dea9e5f478132997f1bd5 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUI.jaxx +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUI.jaxx @@ -59,9 +59,10 @@ - - - + + + + diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUI.jcss b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUI.jcss index aa03aac507d704e1be05ca47493a19206c9222d9..b105be5b3167db835b1dd0a9397eb9ec9c5745ed 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUI.jcss +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUI.jcss @@ -34,21 +34,21 @@ toggledToolTipText: {t("reefdb.table.view.unFullScreen.tip")}; } -#tableauBasNouveauBouton { +#newButton { actionIcon: add; text: "reefdb.common.new"; toolTipText: "reefdb.survey.measurement.grouped.new.tip"; enabled: {model.getSurvey().isEditable() && !model.getPmfms().isEmpty()}; } -#tableauBasSupprimerBouton { +#deleteButton { actionIcon: delete; text: "reefdb.common.delete"; toolTipText: "reefdb.survey.measurement.grouped.delete.tip"; enabled: {model.getSurvey().isEditable() && !model.getSelectedRows().isEmpty() && !model.getPmfms().isEmpty()}; } -#tableauBasDupliquerBouton { +#duplicateButton { actionIcon: copy; text: "reefdb.action.duplicate.label"; toolTipText: "reefdb.action.duplicate.measurement.tip"; @@ -56,6 +56,13 @@ enabled: {model.getSurvey().isEditable() && !model.getSelectedRows().isEmpty() && (model.getSelectedRows().size() == 1) && !model.getPmfms().isEmpty()}; } +#multiEditButton { + actionIcon: edit; + text: "reefdb.common.edit"; + toolTipText: "reefdb.measurement.grouped.multiEdit.tip"; + enabled: {model.getSurvey().isEditable() && !model.getSelectedRows().isEmpty() && (model.getSelectedRows().size() >= 2) && !model.getPmfms().isEmpty()}; +} + #tableBlockLayer { blockingColor: {handler.getConfig().getColorBlockingLayer()}; block:{model.isLoading()}; diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUIHandler.java index 813381e1f4cf66ca4ebd239e1469118087f8cca5..66732d7381b6cdef309f0b44621e2dd61fb68db6 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/SurveyMeasurementsGroupedTableUIHandler.java @@ -30,6 +30,7 @@ import fr.ifremer.reefdb.dto.data.measurement.MeasurementAware; import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsGroupedTableModel; import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsGroupedTableUIHandler; +import fr.ifremer.reefdb.ui.swing.content.observation.survey.measurement.grouped.multiedit.SurveyMeasurementsMultiEditUI; import jaxx.runtime.SwingUtil; import org.jdesktop.swingx.table.TableColumnExt; @@ -89,8 +90,8 @@ public class SurveyMeasurementsGroupedTableUIHandler super.afterInit(ui); // Les boutons sont desactives - getUI().getTableauBasSupprimerBouton().setEnabled(false); - getUI().getTableauBasDupliquerBouton().setEnabled(false); + getUI().getDeleteButton().setEnabled(false); + getUI().getDuplicateButton().setEnabled(false); SwingUtil.setLayerUI(ui.getTableauBasScrollPane(), ui.getTableBlockLayer()); // Keep initial border @@ -193,10 +194,9 @@ public class SurveyMeasurementsGroupedTableUIHandler // Colonne commentaire final TableColumnExt colComment = addCommentColumn(SurveyMeasurementsGroupedTableModel.COMMENT); - setDefaultColumnMinWidth(colComment); // Modele de la table - final SurveyMeasurementsGroupedTableModel tableModel = new SurveyMeasurementsGroupedTableModel(getTable().getColumnModel()); + final SurveyMeasurementsGroupedTableModel tableModel = new SurveyMeasurementsGroupedTableModel(getTable().getColumnModel(), true); tableModel.setNoneEditableCols(); getTable().setModel(tableModel); @@ -221,4 +221,10 @@ public class SurveyMeasurementsGroupedTableUIHandler getModel().setModify(true); } + + public void editSelectedMeasurements() { + + editSelectedMeasurements(new SurveyMeasurementsMultiEditUI(getUI())); + + } } diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUI.jaxx b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUI.jaxx new file mode 100644 index 0000000000000000000000000000000000000000..d6316f7b061d13ff30583815e35eb4900274156e --- /dev/null +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUI.jaxx @@ -0,0 +1,61 @@ + + + + fr.ifremer.reefdb.ui.swing.ReefDbHelpBroker + fr.ifremer.reefdb.ui.swing.ReefDbUIContext + fr.ifremer.reefdb.ui.swing.util.ReefDbUI + fr.ifremer.quadrige3.ui.swing.ApplicationUI + fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil + + java.awt.FlowLayout + javax.swing.Box + javax.swing.BoxLayout + java.awt.BorderLayout + + fr.ifremer.quadrige3.ui.swing.table.SwingTable + + static org.nuiton.i18n.I18n.* + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUI.jcss b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUI.jcss new file mode 100644 index 0000000000000000000000000000000000000000..69d088d271d06879982def8b24403244e6fef019 --- /dev/null +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUI.jcss @@ -0,0 +1,44 @@ +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +#surveyMeasurementsMultiEditUI { + modal: true; + resizable: false; + title: "reefdb.measurement.grouped.multiEdit.title"; +} + + +#cancelButton { + actionIcon: cancel; + text: "reefdb.common.cancel"; + toolTipText: "reefdb.common.cancel"; + i18nMnemonic: "reefdb.common.cancel.mnemonic"; +} + +#validButton { + actionIcon: accept; + text: "reefdb.common.validate"; + toolTipText: "reefdb.common.validate"; + i18nMnemonic: "reefdb.common.validate.mnemonic"; + enabled: {model.isValid() && model.isModify()}; +} \ No newline at end of file diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUIHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..1803d22563ea13706e98ee4633f3b8fff94ce677 --- /dev/null +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUIHandler.java @@ -0,0 +1,127 @@ +package fr.ifremer.reefdb.ui.swing.content.observation.survey.measurement.grouped.multiedit; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +import fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil; +import fr.ifremer.quadrige3.ui.swing.table.ColumnIdentifier; +import fr.ifremer.quadrige3.ui.swing.table.SwingTable; +import fr.ifremer.reefdb.dto.data.measurement.MeasurementAware; +import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsGroupedTableModel; +import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsMultiEditUIHandler; +import fr.ifremer.reefdb.ui.swing.content.observation.survey.measurement.grouped.SurveyMeasurementsGroupedRowModel; +import fr.ifremer.reefdb.ui.swing.content.observation.survey.measurement.grouped.SurveyMeasurementsGroupedTableModel; +import fr.ifremer.reefdb.ui.swing.content.observation.survey.measurement.grouped.SurveyMeasurementsGroupedTableUI; +import org.jdesktop.swingx.table.TableColumnExt; +import org.nuiton.jaxx.application.swing.util.Cancelable; + +/** + * Controleur pour les mesures de l'observation. + */ +public class SurveyMeasurementsMultiEditUIHandler + extends AbstractMeasurementsMultiEditUIHandler + implements Cancelable { + + /** + *

Constructor for SurveyMeasurementsMultiEditUIHandler.

+ */ + public SurveyMeasurementsMultiEditUIHandler() { + super(); + } + + /** + * {@inheritDoc} + */ + @Override + public AbstractMeasurementsGroupedTableModel getTableModel() { + return (SurveyMeasurementsGroupedTableModel) getTable().getModel(); + } + + @Override + protected SurveyMeasurementsMultiEditUIModel createNewModel() { + return new SurveyMeasurementsMultiEditUIModel(); + } + + @Override + protected SurveyMeasurementsGroupedRowModel createNewRow(boolean readOnly, MeasurementAware parentBean) { + return new SurveyMeasurementsGroupedRowModel(readOnly); + } + + /** + * {@inheritDoc} + */ + @Override + public SwingTable getTable() { + return getUI().getSurveyGroupedMeasurementMultiEditTable(); + } + + @Override + protected SwingTable getReferentTable() { + return ((SurveyMeasurementsGroupedTableUI) ApplicationUIUtil.getParentUI(getUI())).getSurveyGroupedMeasurementTable(); + } + + /** + * Initialisation du tableau. + */ + @Override + protected void initTable() { + + // Colonne groupe taxon + addColumn( + taxonGroupCellEditor, + newTableCellRender(SurveyMeasurementsGroupedTableModel.TAXON_GROUP), + SurveyMeasurementsGroupedTableModel.TAXON_GROUP); + + // Colonne taxon + addColumn( + taxonCellEditor, + newTableCellRender(SurveyMeasurementsGroupedTableModel.TAXON), + SurveyMeasurementsGroupedTableModel.TAXON); + + // Colonne taxon saisi + final TableColumnExt colInputTaxon = addColumn(SurveyMeasurementsGroupedTableModel.INPUT_TAXON_NAME); + colInputTaxon.setEditable(false); + + // Colonne analyste + addColumn( + departmentCellEditor, + newTableCellRender(AbstractMeasurementsGroupedTableModel.ANALYST), + (ColumnIdentifier) AbstractMeasurementsGroupedTableModel.ANALYST); + + // No comment column because comment editor is also a JDialog +// final TableColumnExt colComment = addCommentColumn(SurveyMeasurementsGroupedTableModel.COMMENT); + + // Modele de la table + final SurveyMeasurementsGroupedTableModel tableModel = new SurveyMeasurementsGroupedTableModel(getTable().getColumnModel(), false); + tableModel.setNoneEditableCols(); + getTable().setModel(tableModel); + + // Initialisation de la table + initTable(getTable()); + + // border + addEditionPanelBorder(); + } + + +} diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUIModel.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUIModel.java new file mode 100644 index 0000000000000000000000000000000000000000..b184008a96e2e43b24057c8d5d7ef9cc6dd8ad7b --- /dev/null +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/grouped/multiedit/SurveyMeasurementsMultiEditUIModel.java @@ -0,0 +1,48 @@ +package fr.ifremer.reefdb.ui.swing.content.observation.survey.measurement.grouped.multiedit; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see . + * #L% + */ + +import com.google.common.collect.ImmutableSet; +import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO; +import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsGroupedTableModel; +import fr.ifremer.reefdb.ui.swing.content.observation.shared.AbstractMeasurementsMultiEditUIModel; +import fr.ifremer.reefdb.ui.swing.content.observation.survey.measurement.grouped.SurveyMeasurementsGroupedRowModel; +import fr.ifremer.reefdb.ui.swing.content.observation.survey.measurement.grouped.SurveyMeasurementsGroupedTableModel; +import fr.ifremer.reefdb.ui.swing.util.table.ReefDbColumnIdentifier; + +import java.util.Set; + +public class SurveyMeasurementsMultiEditUIModel + extends AbstractMeasurementsMultiEditUIModel { + + @Override + public Set> getIdentifiersToCheck() { + return ImmutableSet.of( + SurveyMeasurementsGroupedTableModel.TAXON_GROUP, + SurveyMeasurementsGroupedTableModel.TAXON, + SurveyMeasurementsGroupedTableModel.INPUT_TAXON_NAME, + (ReefDbColumnIdentifier) AbstractMeasurementsGroupedTableModel.ANALYST + ); + } +} diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/ungrouped/SurveyMeasurementsUngroupedTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/ungrouped/SurveyMeasurementsUngroupedTableUIHandler.java index 0ae103fe921285e34d879a8d9cef01539fc9df09..092b7a83c9ef513b99f3175e09074c0d88b84c85 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/ungrouped/SurveyMeasurementsUngroupedTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/ungrouped/SurveyMeasurementsUngroupedTableUIHandler.java @@ -175,7 +175,9 @@ public class SurveyMeasurementsUngroupedTableUIHandler getContext().restoreComponentFromSwingSession(getTable()); // hide analyst if no pmfm - forceColumnVisibleAtLastPosition(SurveyMeasurementsUngroupedTableModel.ANALYST, notEmpty); +// forceColumnVisibleAtLastPosition(SurveyMeasurementsUngroupedTableModel.ANALYST, notEmpty); + // Don't force position (Mantis #49537) + forceColumnVisible(SurveyMeasurementsUngroupedTableModel.ANALYST, notEmpty); // Install save state listener installSaveTableStateListener(); diff --git a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/table/AbstractReefDbTableUIHandler.java b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/table/AbstractReefDbTableUIHandler.java index c96767e34cbd030a8f86a855791ee2f2e05113c5..951a01d2d3ae5b6dfcd2d963b112898455063035 100644 --- a/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/table/AbstractReefDbTableUIHandler.java +++ b/reefdb-ui-swing/src/main/java/fr/ifremer/reefdb/ui/swing/util/table/AbstractReefDbTableUIHandler.java @@ -27,6 +27,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import fr.ifremer.quadrige3.core.dao.technical.Assert; import fr.ifremer.quadrige3.ui.swing.table.AbstractTableUIHandler; +import fr.ifremer.quadrige3.ui.swing.table.ColumnIdentifier; +import fr.ifremer.quadrige3.ui.swing.table.HiddenColumn; import fr.ifremer.quadrige3.ui.swing.table.SwingTable; import fr.ifremer.quadrige3.ui.swing.table.action.AdditionalTableActions; import fr.ifremer.quadrige3.ui.swing.table.renderer.ColorCheckBoxRenderer; @@ -296,12 +298,26 @@ public abstract class AbstractReefDbTableUIHandler beans) { if (CollectionUtils.isNotEmpty(beans)) { // Get all columns - List columns = getTable().getColumns(true).stream().filter(Objects::nonNull).map(TableColumnExt.class::cast).collect(Collectors.toList()); + List columns = getTable().getColumns(true).stream() + .filter(Objects::nonNull).filter(tableColumn -> !(tableColumn instanceof HiddenColumn)) + .map(TableColumnExt.class::cast).collect(Collectors.toList()); // Build map of columns indexed by property name Map map = Maps.uniqueIndex(columns, column -> { Assert.notNull(column); @@ -329,7 +348,7 @@ public abstract class AbstractReefDbTableUIHandler. + * #L% + */ + +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.TableCellRenderer; +import java.awt.Component; + +import static org.nuiton.i18n.I18n.t; + +/** + * @author peck7 on 24/01/2020. + */ +public class MultipleValueCellRenderer implements TableCellRenderer { + + private final TableCellRenderer delegate; + private final JLabel multiValueLabel; + + public MultipleValueCellRenderer(TableCellRenderer delegate) { + this.delegate = delegate; + multiValueLabel = createMultiValueLabel(); + } + + private JLabel createMultiValueLabel() { + JLabel label = new JLabel(t("reefdb.measurement.grouped.multiEdit.multiValueLabel")); + label.setOpaque(true); + return label; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + return value == null + ? multiValueLabel + : delegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + } +} diff --git a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel-error-validation.xml b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel-error-validation.xml index 23c350619085cde3bf6d91b01c35ddefa07b8bd0..a0139bdf84cb30dea64d8e1cfe13263d7789f198 100644 --- a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel-error-validation.xml +++ b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel-error-validation.xml @@ -35,7 +35,7 @@ error - none + error @@ -46,7 +46,7 @@ error - none + error diff --git a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel-warning-validation.xml b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel-warning-validation.xml index b85618514843c93029c584d09f0bfcff1ad4525b..869662646dbf85bcf31a9770dbb0ba075001b619 100644 --- a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel-warning-validation.xml +++ b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/home/HomeUIModel-warning-validation.xml @@ -31,14 +31,14 @@ warning - all + warning warning - all + warning diff --git a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIModel-error-validation.xml b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIModel-error-validation.xml index b0720251132cd49e5bd3e07dccf7791652f10dca..20aecfe354646da12dc1ce1d5320f0cd8a10215d 100644 --- a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIModel-error-validation.xml +++ b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIModel-error-validation.xml @@ -35,7 +35,7 @@ error - none + error @@ -46,7 +46,7 @@ error - none + error diff --git a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIModel-warning-validation.xml b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIModel-warning-validation.xml index e6f549fc753d26dfdacf3693ba8fa65829473f2c..71fcd454babd48a95a0f35663759e84fd384d587 100644 --- a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIModel-warning-validation.xml +++ b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/operation/measurement/OperationMeasurementsTabUIModel-warning-validation.xml @@ -31,14 +31,14 @@ warning - all + warning warning - all + warning diff --git a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIModel-error-validation.xml b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIModel-error-validation.xml index c628cf9aed4e61604bfe04283efbcc746678cfbb..62eb7196378d80e03e6d6312980d9436fb2d3002 100644 --- a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIModel-error-validation.xml +++ b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIModel-error-validation.xml @@ -35,7 +35,7 @@ error - none + error @@ -46,7 +46,7 @@ error - none + error diff --git a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIModel-warning-validation.xml b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIModel-warning-validation.xml index 5b13df23efee5918128fd4ad000b13a9490ae88b..4eceb89fbd4df45439e9eace23a417eac0a3ddcd 100644 --- a/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIModel-warning-validation.xml +++ b/reefdb-ui-swing/src/main/resources/fr/ifremer/reefdb/ui/swing/content/observation/survey/measurement/SurveyMeasurementsTabUIModel-warning-validation.xml @@ -30,11 +30,15 @@ + warning + warning + warning + warning diff --git a/reefdb-ui-swing/src/main/resources/i18n/reefdb-ui-swing_en_GB.properties b/reefdb-ui-swing/src/main/resources/i18n/reefdb-ui-swing_en_GB.properties index 2de25c0aab3dfeb454a968ba9f38279a4d974212..a739c8e900a10da02b3dbdae47202f432051c3e5 100644 --- a/reefdb-ui-swing/src/main/resources/i18n/reefdb-ui-swing_en_GB.properties +++ b/reefdb-ui-swing/src/main/resources/i18n/reefdb-ui-swing_en_GB.properties @@ -873,6 +873,9 @@ reefdb.measurement.grouped.duplicates= reefdb.measurement.grouped.duplicates.taxonUnique= reefdb.measurement.grouped.incoherentQualitativeAndNumericalValues= reefdb.measurement.grouped.invalidGroupedRule= +reefdb.measurement.grouped.multiEdit.multiValueLabel= +reefdb.measurement.grouped.multiEdit.tip= +reefdb.measurement.grouped.multiEdit.title= reefdb.observation.label= reefdb.observation.onglet.prelevement.general.bouton.effacer.tip= reefdb.observation.onglet.prelevement.general.selection.commentaire.label= diff --git a/reefdb-ui-swing/src/main/resources/i18n/reefdb-ui-swing_fr_FR.properties b/reefdb-ui-swing/src/main/resources/i18n/reefdb-ui-swing_fr_FR.properties index f1050ce548a3fb0da8b4c75b7ca388383aa32f8a..cdb2485ff1741535a3bb10e68f73109d6d57eba8 100644 --- a/reefdb-ui-swing/src/main/resources/i18n/reefdb-ui-swing_fr_FR.properties +++ b/reefdb-ui-swing/src/main/resources/i18n/reefdb-ui-swing_fr_FR.properties @@ -161,9 +161,9 @@ reefdb.action.photo.export.chooseDirectory.buttonLabel=Exporter reefdb.action.photo.export.chooseDirectory.title=Sélection du répertoire pour l'exportation des photos reefdb.action.photo.export.done=Exportation réussie dans le répertoire\:
%s reefdb.action.photo.export.title=Exportation des photos -reefdb.action.photo.import.chooseFile.buttonLabel=Sélectionnez une photo +reefdb.action.photo.import.chooseFile.buttonLabel=Sélectionnez des photos reefdb.action.photo.import.chooseFile.filterDescription=Fichier %s uniquement -reefdb.action.photo.import.chooseFile.title=Sélection de la photo à importer +reefdb.action.photo.import.chooseFile.title=Sélection des photos à importer reefdb.action.photo.import.fileTooLarge.message=La taille de l’image est trop importante pour être téléchargée par le système.
Taille maximum autorisée\: %d octets (soit %s) reefdb.action.photo.loading=Chargement de la photo reefdb.action.save.analysisInstruments=Sauvegarde des engins d'analyse @@ -672,10 +672,8 @@ reefdb.home.samplingOperation.title=3/ Liste des réplicats reefdb.home.survey.changeStatus=Changer Etat reefdb.home.survey.control=Contrôler reefdb.home.survey.duplicate.coordinate=Dupliquer les coordonnées -reefdb.home.survey.duplicate.help=Simple \: Seul l'observation sera dupliquée
Complète \: L'observation et ses réplicats seront dupliqués -reefdb.home.survey.duplicate.message=Sélectionner le type de duplication souhaité -reefdb.home.survey.duplicate.option.full=Duplication complète -reefdb.home.survey.duplicate.option.simple=Duplication simple +reefdb.home.survey.duplicate.option.full=Observation + réplicats +reefdb.home.survey.duplicate.option.simple=Observation seule reefdb.home.survey.duplicate.surveyMeasurements=Dupliquer les mesures de l'observation reefdb.home.survey.duplicate.title=Choix du type de duplication reefdb.home.survey.edit=Général @@ -891,6 +889,9 @@ reefdb.measurement.grouped.duplicates=Un taxon ou un groupe de taxon est présen reefdb.measurement.grouped.duplicates.taxonUnique=Un taxon ou un groupe de taxon est présent plusieurs fois pour une même valeur du mesures \:
%s reefdb.measurement.grouped.incoherentQualitativeAndNumericalValues=La valeur du paramètre '%s' n'est pas cohérente avec la valeur du paramètre '%s'. Vérifiez votre saisie. reefdb.measurement.grouped.invalidGroupedRule=Au moins une ces valeurs doit être renseignées\: %s +reefdb.measurement.grouped.multiEdit.multiValueLabel=\#\#\#\#\#\#\#\# +reefdb.measurement.grouped.multiEdit.tip=Modification des lignes sélectionnées +reefdb.measurement.grouped.multiEdit.title=Modification des lignes sélectionnées reefdb.observation.label=Observation \: reefdb.observation.onglet.prelevement.general.bouton.effacer.tip=Effacer toutes les valeurs 'profondeur précise' reefdb.observation.onglet.prelevement.general.selection.commentaire.label=Commentaire diff --git a/src/changes/changes.xml b/src/changes/changes.xml index ccdd2fb6033a0ae5d7b1789c3daa5e3bf02862d1..fcd947530e74fe9d9d7eb4c3119113f115712931 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -31,6 +31,107 @@ + + + RulePrecondQualUIHandler: adjust preconditioned qualitative values double list size + + + Report of issue #50455 + + + Change reefdb.transcribingItemType.label.pmfmExtraction default value to REEFDB-PMFM-EXTRACT.PMFM_NM + + + Upgrade quadrige3-core to version 3.6.10 + + + Extraction: use measurements REMOTE_ID instead of local id + + + + + + Change reefdb.transcribingItemType.label.pmfmExtraction default value to REEFDB-PMFM-EXTRACTION.PMFM_NM + + + Photo import can select multiple files + + + Extraction: fix createCommonTable query + + + Observation save: Postpone model modify state + + + + + + New extraction perform service using xmlQuery (version 1.1+) + + + Pmfmu labels are transcribed with specific label for extraction, if exists, or with "screen" label + + + DuplicateSurveyAction: postpone duplicate line insertion in Swing thread + + + Empty result won't crash on referential search + + + MultiEdit: sampling operation is detected correctly and pmfm ids for transition length calculated are read-only + + + + + + Change EIS nexus url + + + Add multiline edition dialog for survey's and operation's grouped measurement tables + + + RuleControl: The model can be valid if control is valid + + + + + + Opening qualitative values modal from PMFMU will now load correctly the qualitative values from selected parameter + + + Delete a rule list which is selected in selection combobox will be removed before reload + + + Recompute rows valid state when a sampling operation is removed + + + HomeUI: default program filter now includes local programs + + + Update title on context change + Taxon group and taxon filters in measurement screens are initialized once and avoid circular effect + + + Don't force the analyst column at the last column + + + ControlRuleTable: Stop table edition to avoid rendering exception + + + ImportSynchroAction: If user cancel the program selection, then cancel synchro + + + Set default pmfm column min width + + + DuplicateSurveyAction: Change message and buttons + + + RuleControl: The model can be valid if control is valid + For now, only HomeUI is done... + + + Upgrade quadrige3-core version 3.6.3.2