Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe Commits: 6684283f by Tony Chemit at 2022-11-16T02:11:22+01:00 Rapport Liste des captures de faune accessoire selon le type de banc, filtrées par groupe - Closes #2532 - - - - - 18379b3e by Tony Chemit at 2022-11-16T02:11:22+01:00 GUI - use resetEdit state when reset entry on content table - - - - - 12dfe7b6 by Tony Chemit at 2022-11-16T02:11:22+01:00 GUI - Sur échantillons PS observations saisis par lots, migrés vers 9.0, valeurs étranges sur le champ poids individuel - Closes #2503 - - - - - 46e605b6 by Tony Chemit at 2022-11-16T02:11:22+01:00 Report API - Add TimeLog in DefaultReportRequestExecutor - - - - - 34b3dec6 by Tony Chemit at 2022-11-16T02:11:22+01:00 Report API - Clean ReportRequest code - - - - - 0ac163ca by Tony Chemit at 2022-11-16T02:11:22+01:00 Report API - Improve executeReportRequest method (one for simple request and one for request with repeat) - - - - - 5694c752 by Tony Chemit at 2022-11-16T02:11:22+01:00 Report API - Improve Sum operations (can now set x and y and better round of double) - - - - - 357f447c by Tony Chemit at 2022-11-16T02:11:22+01:00 Report API - add safe guard tests (to be able to copy partial matrix) - - - - - 6295fc29 by Tony Chemit at 2022-11-16T02:11:22+01:00 Report API - Be able to order variables and repeat variables - - - - - bacdc4d1 by Tony Chemit at 2022-11-16T02:11:22+01:00 Tck Report - columnHeaders can be null Tck Report - Improve when to deliver asserts - - - - - be74c546 by Tony Chemit at 2022-11-16T02:11:22+01:00 Report GUI - Manage report with no columns and row headers (everything is coming from the report result to be able to manage dynamic columns) - - - - - 81146b7a by Tony Chemit at 2022-11-16T02:11:22+01:00 Report GUI - Respect report variables order in Report model - - - - - c0fab2d0 by Tony Chemit at 2022-11-16T02:11:22+01:00 Report API - Improve ReportVariable (add isEmpty and computeIndexList methods) - - - - - f0e84c38 by Tony Chemit at 2022-11-16T02:11:22+01:00 Report API - Add new neutral operations - - - - - 24 changed files: - client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/report/ReportModel.java - client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/report/ResultTableModel.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/table/actions/entry/ResetEntry.java - client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/observation/SampleUIHandler.java - core/api/dto/src/main/resources/observe-reports.properties - − core/services/local/src/test/java/fr/ird/observe/services/local/service/ReportServiceLocalReadTest.java - core/services/test/src/main/java/fr/ird/observe/services/service/ReportFixture.java - core/services/test/src/main/java/fr/ird/observe/services/service/report/ps/PsObservationAccessoryCatchReportFixture.java → core/services/test/src/main/java/fr/ird/observe/services/service/report/ps/PsObservationCatchReportFixture.java - core/services/test/src/main/resources/fixtures/fr/ird/observe/services/service/ReportService-psObservationAccessoryCatch.properties → core/services/test/src/main/resources/fixtures/fr/ird/observe/services/service/ReportService-psObservationCatch.properties - toolkit/api/src/main/java/fr/ird/observe/dto/report/DataMatrix.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportBuilder.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportRequest.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportRequestExecutor.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportVariable.java - + toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/ComputeDynamicHeader.java - + toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/CopyRepeatVariableToFirstColumn.java - + toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/ExecuteRequestAndReorganizeCountByRepeatVariable.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/ExecuteRequests.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumColumn.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumFloatColumn.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumIntColumn.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumIntRow.java - toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumRow.java - toolkit/persistence/src/main/java/fr/ird/observe/spi/report/DefaultReportRequestExecutor.java Changes: ===================================== client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/report/ReportModel.java ===================================== @@ -43,10 +43,10 @@ import java.net.URL; import java.nio.file.Files; import java.util.Collections; import java.util.Date; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.TreeMap; import java.util.stream.Collectors; /** @@ -81,7 +81,7 @@ public class ReportModel extends AdminActionModel { /** * les variables utilisées pour le report. */ - protected final Map<String, Object> variables; + protected final Map<String, Object> variables = new LinkedHashMap<>(); /** * la fichier contenant la définition des reports. */ @@ -128,7 +128,6 @@ public class ReportModel extends AdminActionModel { public ReportModel() { super(AdminStep.REPORT); - variables = new TreeMap<>(); // quand le type de modèle change, on mets à jour les rapports disponibles addPropertyChangeListener(REPORT_FILE_PROPERTY_NAME, evt -> updateReports()); } ===================================== client/datasource/actions/src/main/java/fr/ird/observe/client/datasource/actions/report/ResultTableModel.java ===================================== @@ -149,12 +149,11 @@ public class ResultTableModel extends AbstractTableModel { rowNames.addAll(Arrays.asList(report.getRowHeaders())); } - withColumnHeader = !columnNames.isEmpty(); - withRowHeader = !rowNames.isEmpty(); - table.setTableHeader(!withColumnHeader ? null : tableHeader); - table.createDefaultColumnsFromModel(); int nbRows = incomingData.getHeight(); int nbCols = incomingData.getWidth(); + + withColumnHeader = !columnNames.isEmpty(); + withRowHeader = !rowNames.isEmpty(); if (withRowHeader) { // on ajoute une première colonne aux données nbCols += 1; @@ -162,6 +161,22 @@ public class ResultTableModel extends AbstractTableModel { incomingData.setX(1); } + if (!withColumnHeader && !withRowHeader) { + // let's say we always use columns from incomingData + table.setTableHeader(tableHeader); + for (int i = 0; i < nbCols; i++) { + columnNames.add((String) incomingData.getValue(i, 0)); + } + incomingData.setY(-1); + withColumnHeader = true; + nbRows--; + + } else { + table.setTableHeader(!withColumnHeader ? null : tableHeader); + } + table.createDefaultColumnsFromModel(); + + data.setHeight(nbRows); data.setWidth(nbCols); @@ -185,7 +200,9 @@ public class ResultTableModel extends AbstractTableModel { } else if (withColumnHeader) { } - data.copyData(incomingData); + if (nbCols > 0) { + data.copyData(incomingData); + } fireTableStructureChanged(); table.revalidate(); table.repaint(); @@ -220,7 +237,7 @@ public class ResultTableModel extends AbstractTableModel { } public String getClipboardContent(boolean copyRowHeaders, boolean copyColumnHeaders) { - return getDataContent(copyRowHeaders, copyColumnHeaders, true,'\t'); + return getDataContent(copyRowHeaders, copyColumnHeaders, true, '\t'); } public String getCsvContent() { ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/table/actions/entry/ResetEntry.java ===================================== @@ -59,7 +59,12 @@ public final class ResetEntry extends ContentTableUIActionSupport<ContentTableUI } } else { // reset existing entry - tableModel.resetEditBean(); + ui.getStates().setResetEdit(true); + try { + tableModel.resetEditBean(); + } finally { + ui.getStates().setResetEdit(false); + } } } ===================================== client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/observation/SampleUIHandler.java ===================================== @@ -72,12 +72,11 @@ public class SampleUIHandler extends GeneratedSampleUIHandler { private final PropertyChangeListener speciesChanged; public SampleUIHandler() { - weightChanged = evt -> onWeightChanged((Float) evt.getNewValue()); - lengthChanged = evt -> onLengthChanged((Float) evt.getNewValue()); + weightChanged = evt -> onWeightChanged((Float) evt.getNewValue(), !ui.getStates().isResetEdit()); + lengthChanged = evt -> onLengthChanged((Float) evt.getNewValue(), !ui.getStates().isResetEdit()); speciesChanged = evt -> onSpeciesChanged((SpeciesReference) evt.getNewValue()); } - @Override public void onInit(SampleUI ui) { super.onInit(ui); @@ -97,8 +96,8 @@ public class SampleUIHandler extends GeneratedSampleUIHandler { public void onSelectedRowChanged(SampleMeasureDto tableEditBean, SampleMeasureDto previousRowBean, boolean notPersisted, boolean newRow) { - onLengthChanged(tableEditBean.getLength()); - onWeightChanged(tableEditBean.getWeight()); + onLengthChanged(tableEditBean.getLength(), false); + onWeightChanged(tableEditBean.getWeight(), false); SampleUIModel sampleModel = getModel(); @@ -209,6 +208,9 @@ public class SampleUIHandler extends GeneratedSampleUIHandler { } public void startEditTableEditBean(SampleMeasureDto tableEditBean) { + tableEditBean.removePropertyChangeListener(SampleMeasureDto.PROPERTY_WEIGHT, weightChanged); + tableEditBean.removePropertyChangeListener(SampleMeasureDto.PROPERTY_LENGTH, lengthChanged); + tableEditBean.removePropertyChangeListener(SampleMeasureDto.PROPERTY_SPECIES, speciesChanged); tableEditBean.addPropertyChangeListener(SampleMeasureDto.PROPERTY_WEIGHT, weightChanged); tableEditBean.addPropertyChangeListener(SampleMeasureDto.PROPERTY_LENGTH, lengthChanged); tableEditBean.addPropertyChangeListener(SampleMeasureDto.PROPERTY_SPECIES, speciesChanged); @@ -249,9 +251,9 @@ public class SampleUIHandler extends GeneratedSampleUIHandler { acquisitionModeGroup.setSelectedValue(acquisitionMode); } - protected void onWeightChanged(Float newValue) { + protected void onWeightChanged(Float newValue, boolean realChange) { SampleMeasureDto tableEditBean = ui.getModel().getStates().getTableEditBean(); - if (tableEditBean.getAcquisitionMode() == 1) { + if (realChange && tableEditBean.getAcquisitionMode() == 1) { tableEditBean.setIsWeightComputed(false); } if (newValue == null) { @@ -259,9 +261,11 @@ public class SampleUIHandler extends GeneratedSampleUIHandler { } } - protected void onLengthChanged(Float newValue) { + protected void onLengthChanged(Float newValue, boolean realChange) { SampleMeasureDto tableEditBean = ui.getModel().getStates().getTableEditBean(); - tableEditBean.setIsLengthComputed(false); + if (realChange) { + tableEditBean.setIsLengthComputed(false); + } if (newValue == null) { tableEditBean.setLengthMeasureMethod(null); } ===================================== core/api/dto/src/main/resources/observe-reports.properties ===================================== @@ -697,26 +697,26 @@ report.psObservationTargetDiscardedByAssociation.request.19=0,3|row|\ and os.topiaId = 'fr.ird.referential.ps.common.ObservedSystem#1239832686428#0.9217864901728908' \ and os not in elements(a.observedSystem) ################################################################################ -## Captures accessoires observées +## Captures observées ################################################################################ -report.psObservationAccessoryCatch.modelType=PS -report.psObservationAccessoryCatch.name=Observations - Liste des captures accessoires selon le type de banc, filtrées par groupe -report.psObservationAccessoryCatch.description=Afficher les captures accessoires par groupe d'espèce\nLes poids sont exprimés en tonnes. -report.psObservationAccessoryCatch.columns=Espèce, Banc libre, Banc objet -report.psObservationAccessoryCatch.variable.speciesGroup=fr.ird.observe.dto.referential.common.SpeciesGroupDto|From SpeciesGroupImpl ge Order By ge.code -report.psObservationAccessoryCatch.repeatVariable.speciesId=java.lang.String|\ +report.psObservationCatch.modelType=PS +report.psObservationCatch.name=Observations - Liste des captures selon le type de banc, filtrées par groupe +report.psObservationCatch.description=Afficher les captures par groupe d'espèce\nLes poids sont exprimés en tonnes. +report.psObservationCatch.columns=Espèce, Banc libre, Banc objet +report.psObservationCatch.variable.speciesGroup=fr.ird.observe.dto.referential.common.SpeciesGroupDto|From SpeciesGroupImpl ge Order By ge.code +report.psObservationCatch.repeatVariable.speciesId=java.lang.String|\ Select e.id From SpeciesImpl e \ Where e.speciesGroup.id = :speciesGroup \ Order By e.homeId -report.psObservationAccessoryCatch.request.1=0,0|row|\ +report.psObservationCatch.request.1=0,0|row|\ Select \ concat('[FAO]', (case when e.faoCode is not null then e.faoCode else '-' end), \ ' [sc]', (case when e.scientificLabel is not null then e.scientificLabel else '-' end), \ ' [fr]', (case when e.label2 is not null then e.label2 else '-' end)) \ From SpeciesImpl e \ Where e.id = :speciesId -report.psObservationAccessoryCatch.request.1.repeat=speciesId|column -report.psObservationAccessoryCatch.request.2=1,0|row|\ +report.psObservationCatch.request.1.repeat=speciesId|column +report.psObservationCatch.request.2=1,0|row|\ Select \ case when Count(ca) > 0 then \ concat('+', \ @@ -731,8 +731,8 @@ report.psObservationAccessoryCatch.request.2=1,0|row|\ Join c.catches ca \ with ca.species.id = :speciesId \ Where m.id In :tripId -report.psObservationAccessoryCatch.request.2.repeat=speciesId|column -report.psObservationAccessoryCatch.request.3=2,0|row|\ +report.psObservationCatch.request.2.repeat=speciesId|column +report.psObservationCatch.request.3=2,0|row|\ Select \ case when Count(ca) > 0 then \ concat('+', \ @@ -747,7 +747,7 @@ report.psObservationAccessoryCatch.request.3=2,0|row|\ Join c.catches ca \ with ca.species.id = :speciesId \ Where m.id In :tripId -report.psObservationAccessoryCatch.request.3.repeat=speciesId|column +report.psObservationCatch.request.3.repeat=speciesId|column ################################################################################ ## Captures accessoires par speciesGroup d'espèces ################################################################################ ===================================== core/services/local/src/test/java/fr/ird/observe/services/local/service/ReportServiceLocalReadTest.java deleted ===================================== @@ -1,38 +0,0 @@ -package fr.ird.observe.services.local.service; - -/*- - * #%L - * ObServe Core :: Services :: Local - * %% - * Copyright (C) 2008 - 2022 IRD, Ultreia.io - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import fr.ird.observe.services.service.ReportServiceFixtures; -import org.junit.AfterClass; - -public class ReportServiceLocalReadTest extends GeneratedReportServiceLocalReadTest { - - @AfterClass - public static void afterClass() { - if (!ReportServiceFixtures.WITH_ASSERT) { - System.out.println("New asserts:\n" + String.join("\n", ReportServiceFixtures.getAsserts())); - ReportServiceFixtures.getAsserts().clear(); - } - } - -} ===================================== core/services/test/src/main/java/fr/ird/observe/services/service/ReportFixture.java ===================================== @@ -76,6 +76,7 @@ public abstract class ReportFixture { } public final DataMatrix execute(ReportService service, Report report) { + log.warn("Starting report {}", report.getName()); return service.executeReport(report, getTripIds()); } @@ -127,6 +128,8 @@ public abstract class ReportFixture { for (int i = 0; i < rows; i++) { ReportServiceFixtures.writeArrayAssert(String.format("result.%d", i), actual.getData()[i]); } + System.out.println("New asserts:\n" + String.join("\n", ReportServiceFixtures.getAsserts())); + ReportServiceFixtures.getAsserts().clear(); } } @@ -159,7 +162,11 @@ public abstract class ReportFixture { Assert.assertEquals(rows, report.getRows()); Assert.assertEquals(columns, report.getColumns()); - Assert.assertArrayEquals(columnsHeader, report.getColumnHeaders()); + if (report.getColumnHeaders() == null) { + Assert.assertEquals(0, columnsHeader.length); + } else { + Assert.assertArrayEquals(columnsHeader, report.getColumnHeaders()); + } if (report.getRowHeaders() == null) { Assert.assertEquals(0, rowsHeader.length); } else { @@ -168,7 +175,11 @@ public abstract class ReportFixture { } else { ReportServiceFixtures.addAssert("syntax.rows", report.getRows()); ReportServiceFixtures.addAssert("syntax.columns", report.getColumns()); - ReportServiceFixtures.writeArrayAssert("syntax.columnsHeader", (Object[]) report.getColumnHeaders()); + if (report.getRowHeaders() == null) { + ReportServiceFixtures.writeArrayAssert("syntax.columnsHeader"); + } else { + ReportServiceFixtures.writeArrayAssert("syntax.columnsHeader", (Object[]) report.getColumnHeaders()); + } if (report.getRowHeaders() == null) { ReportServiceFixtures.writeArrayAssert("syntax.rowsHeader"); } else { ===================================== core/services/test/src/main/java/fr/ird/observe/services/service/report/ps/PsObservationAccessoryCatchReportFixture.java → core/services/test/src/main/java/fr/ird/observe/services/service/report/ps/PsObservationCatchReportFixture.java ===================================== @@ -36,7 +36,7 @@ import java.util.Iterator; * @since 1.9 */ @AutoService(ReportFixture.class) -public class PsObservationAccessoryCatchReportFixture extends ReportFixture { +public class PsObservationCatchReportFixture extends ReportFixture { @Override public void assertSyntax(Report report) { ===================================== core/services/test/src/main/resources/fixtures/fr/ird/observe/services/service/ReportService-psObservationAccessoryCatch.properties → core/services/test/src/main/resources/fixtures/fr/ird/observe/services/service/ReportService-psObservationCatch.properties ===================================== @@ -19,8 +19,24 @@ # <http://www.gnu.org/licenses/gpl-3.0.html>. # #L% ### +syntax.name=Observations - Liste des captures selon le type de banc, filtrées par groupe +syntax.description=Afficher les captures par groupe d'espèce-Les poids sont exprimés en tonnes. +syntax.columns=3 +syntax.rows=-1 +syntax.columnsHeader=Espèce^Banc libre^Banc objet +syntax.nbRequests=3 +result.columns=3 +result.rows=49 result.0=[FAO]CCB [sc]Carcharhinus brevipinna [fr]Requin tisserand^-^- result.1=[FAO]ALS [sc]Carcharhinus albimarginatus [fr]Requin pointe blanche^-^- +result.2=[FAO]AML [sc]Carcharhinus amblyrhynchos [fr]Grey reef shark^-^- +result.3=[FAO]PTH [sc]Alopias pelagicus [fr]Renard pélagique^-^- +result.4=[FAO]BTH [sc]Alopias superciliosus [fr]Renard à gros yeux^-^- +result.5=[FAO]ALV [sc]Alopias vulpinus [fr]Renard^-^+ Effectif : 3 Poids total (t) : 12.0 +result.6=[FAO]BLR [sc]Carcharhinus melanopterus [fr]Requin pointes noires^-^- +result.7=[FAO]BRO [sc]Carcharhinus brachyurus [fr]Requin cuivre^-^- +result.8=[FAO]WSH [sc]Carcharodon carcharias [fr]Grand requin blanc^-^- +result.9=[FAO]CCE [sc]Carcharhinus leucas [fr]Requin bouledogue^-^- result.10=[FAO]CCL [sc]Carcharhinus limbatus [fr]Requin bordé^-^- result.11=[FAO]CCP [sc]Carcharhinus plumbeus [fr]Requin gris^-^- result.12=[FAO]FAL [sc]Carcharhinus falciformis [fr]Requin soyeux^-^- @@ -28,10 +44,9 @@ result.13=[FAO]OCS [sc]Carcharhinus longimanus [fr]Requin océanique^-^- result.14=[FAO]CWZ [sc]Carcharhinus spp [fr]Requins Carcharhinus nca^-^- result.15=[FAO]DUS [sc]Carcharhinus obscurus [fr]Requin sombre^-^- result.16=[FAO]SHL [sc]Etmopterus spp [fr]Genre Etmopterus^-^- -result.17=[FAO]THR [sc]Alopias spp [fr]Renards de mer nca ^-^- +result.17=[FAO]THR [sc]Alopias spp [fr]Renards de mer nca^-^- result.18=[FAO]RSK [sc]Carcharhinidae spp [fr]Famille Carcharhinidae^-^- result.19=[FAO]MSK [sc]Lamnidae [fr]Famille Lamnidae^-^- -result.2=[FAO]AML [sc]Carcharhinus amblyrhynchos [fr]Grey reef shark^-^- result.20=[FAO]2FOD [sc]Odontaspididae [fr]Odontaspididae^-^- result.21=[FAO]2FRH [sc]Rhincodontidae [fr]Famille Rhincodontidae^-^- result.22=[FAO]SPY [sc]Sphyrnidae [fr]Famille Sphyrnidae^-^- @@ -42,18 +57,16 @@ result.26=[FAO]LMA [sc]Isurus paucus [fr]Petite taupe, Mako^-^- result.27=[FAO]MAK [sc]Isurus spp [fr]Taupes^-^- result.28=[FAO]LMP [sc]Megachasma pelagios [fr]Requin grande gueule^-^- result.29=[FAO]CVX [sc]Carcharhiniformes [fr]Ordre Carcharhiniformes^-^- -result.3=[FAO]PTH [sc]Alopias pelagicus [fr]Renard pélagique^-^- result.30=[FAO]HDQ [sc]Heterodontiformes [fr]Ordre Heterodontiformes^-^- result.31=[FAO]HXW [sc]Hexanchiformes [fr]Ordre Hexanchiformes^-^- result.32=[FAO]LMZ [sc]Lamniformes [fr]Ordre Lamniformes^-^- result.33=[FAO]OCX [sc]Orectolobiformes [fr]Ordre Orectolobiformes^-^- -result.34=[FAO]PWS [sc]Pristiophorus spp [fr]Requins-scies nca ^-^- +result.34=[FAO]PWS [sc]Pristiophorus spp [fr]Requins-scies nca^-^- result.35=[FAO]OSF [sc]Stegostoma fasciatum [fr]Requin zèbre^-^- result.36=[FAO]SHX [sc]Squaliformes [fr]Ordre Squaliformes^-^- -result.37=[FAO]ASK [sc]Squatinidae [fr]Anges de mer nca ^-^- +result.37=[FAO]ASK [sc]Squatinidae [fr]Anges de mer nca^-^- result.38=[FAO]BSH [sc]Prionace glauca [fr]Peau bleue^-^- result.39=[FAO]POR [sc]Lamna nasus [fr]Requin taupe commun^-^- -result.4=[FAO]BTH [sc]Alopias superciliosus [fr]Renard à gros yeux^-^- result.40=[FAO]PSK [sc]Pseudocarcharias kamoharai [fr]Requin crocodile^-^- result.41=[FAO]2REX [sc]Requin non identifié [fr]Requin non identifié^-^- result.42=[FAO]BSK [sc]Cetorhinus maximus [fr]Requin pèlerin^-^- @@ -63,17 +76,3 @@ result.45=[FAO]SPL [sc]Sphyrna lewini [fr]Requin marteau halicorne^-^- result.46=[FAO]SPK [sc]Sphyrna mokarran [fr]Grand requin marteau^-^- result.47=[FAO]SPN [sc]Sphyrna spp [fr]Requins marteau nca^-^- result.48=[FAO]SPZ [sc]Sphyrna zygaena [fr]Requin marteau commun^-^- -result.5=[FAO]ALV [sc]Alopias vulpinus [fr]Renard^-^+ Effectif : 3 Poids total (t) : 12.0 -result.6=[FAO]BLR [sc]Carcharhinus melanopterus [fr]Requin pointes noires^-^- -result.7=[FAO]BRO [sc]Carcharhinus brachyurus [fr]Requin cuivre^-^- -result.8=[FAO]WSH [sc]Carcharodon carcharias [fr]Grand requin blanc^-^- -result.9=[FAO]CCE [sc]Carcharhinus leucas [fr]Requin bouledogue^-^- -result.columns=3 -result.rows=49 -syntax.columns=3 -syntax.columnsHeader=Espèce^Banc libre^Banc objet -syntax.description=Afficher les captures accessoires par groupe d'espèce-Les poids sont exprimés en tonnes. -syntax.name=Observations - Liste des captures accessoires selon le type de banc, filtrées par groupe -syntax.nbRequests=3 -syntax.rows=-1 -syntax.rowsHeader= ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/DataMatrix.java ===================================== @@ -159,7 +159,13 @@ public class DataMatrix implements JsonAware { log.debug(String.format("copying incoming matrix (dim: %s, location: %s)", incoming.getDimension(), incoming.getLocation())); for (int i = 0; i < width; i++) { + if (x + i < 0) { + continue; + } for (int j = 0; j < height; j++) { + if (y + j < 0) { + continue; + } Serializable value = incoming.getValue(i, j); setValue(x + i, y + j, value); } ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportBuilder.java ===================================== @@ -319,12 +319,14 @@ public class ReportBuilder { Map.Entry<String, String> entry = itr.next(); String key = entry.getKey(); if (!key.startsWith(VARIABLE_PREFIX)) { - continue; } String operations = entry.getValue(); String id = key.substring(VARIABLE_PREFIX.length()); - + int indexOf = id.indexOf("."); + if (indexOf > -1) { + id = id.substring(indexOf + 1); + } // on interdit la surcharge d'une variable déjà trouvée pour le report if (ids.contains(id)) { throw new IllegalArgumentException("La variable " + id + " est déjà définie pour le report " + reportName); @@ -359,12 +361,14 @@ public class ReportBuilder { Map.Entry<String, String> entry = itr.next(); String key = entry.getKey(); if (!key.startsWith(REPEAT_VARIABLE_PREFIX)) { - continue; } String operations = entry.getValue(); String id = key.substring(REPEAT_VARIABLE_PREFIX.length()); - + int indexOf = id.indexOf("."); + if (indexOf > -1) { + id = id.substring(indexOf + 1); + } // on interdit la surcharge d'une variable déjà trouvée pour le report if (ids.contains(id)) { throw new IllegalArgumentException("La variable de répétition " + id + " est déjà définie pour le report " + reportName); ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportRequest.java ===================================== @@ -27,9 +27,9 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import java.awt.Point; import java.io.Serializable; -import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.TreeMap; /** * Pour caractériser une requète à lancer dans un report. @@ -90,46 +90,17 @@ public class ReportRequest implements Serializable, JsonAware { } public static Map<String, Object> extractParams(Report report, Set<String> tripId) { - - Map<String, Object> params = new HashMap<>(); - + Map<String, Object> params = new TreeMap<>(); params.put(TRIP_ID_VARIABLE, tripId); - for (ReportVariable<?> variable : report.getVariables()) { - String name = variable.getName(); - Object value = variable.getSelectedValue(); - params.put(name, value); - } return params; } -// public static Object[] getParams(String request, Map<String, Object> params) { -// -// // on parcourt la liste de tous les paramètres pour savoir si on doit -// // les inclure pour la requête donnée : -// List<String> namesToUsed = new ArrayList<>(); -// for (String paramName : params.keySet()) { -// if (request.contains(":" + paramName)) { -// namesToUsed.add(paramName); -// } -// } -// Object[] datas = new Object[namesToUsed.size() * 2]; -// int index = 0; -// for (String name : namesToUsed) { -// Object value = params.get(name); -// datas[index * 2] = name; -// datas[index * 2 + 1] = value; -// index++; -// } -// namesToUsed.clear(); -// return datas; -// } - public ReportRequest(RequestLayout layout, int x, int y, ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportRequestExecutor.java ===================================== @@ -29,6 +29,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeMap; /** * To execute a request. @@ -49,11 +50,20 @@ public interface ReportRequestExecutor { <V> void populateVariable(ReportVariable<V> variable, Map<String, Object> vars); - default DataMatrix executeReportRequest(ReportRequest request, Report report, Set<String> dataId, ReportVariable<?> repeatValues) { + default DataMatrix executeReportRequest(ReportRequest request, Report report, Set<String> dataId) { Map<String, Object> params = ReportRequest.extractParams(report, dataId); - if (repeatValues == null) { - return executeReportRequest(request, params); + String hql = request.getRequest(); + for (ReportVariable<?> repeatVariable : report.getRepeatVariables()) { + if (hql.contains(":" + repeatVariable.getName() + " ")) { + // add this repeat variable values to parameters + params.put(repeatVariable.getName(), repeatVariable.computeIndexList()); + } } + return executeReportRequest(request, params); + } + + default DataMatrix executeReportRequest(ReportRequest request, Report report, Set<String> dataId, ReportVariable<?> repeatValues) { + Map<String, Object> params = ReportRequest.extractParams(report, dataId); DataMatrix result = new DataMatrix(); for (Object repeatValue : repeatValues.getValues()) { params.put(request.getRepeat().getVariableName(), repeatValue); @@ -97,15 +107,27 @@ public interface ReportRequestExecutor { return result; } - @SuppressWarnings("unchecked") default void doPopulateRepeatVariables(Report report, Set<String> tripId) { Map<String, Object> vars = ReportRequest.extractParams(report, tripId); - for (@SuppressWarnings("rawtypes") ReportVariable variable : report.getRepeatVariables()) { - String hql = variable.getRequest(); - List<Object> universe = executeRequest(hql, vars); - LinkedHashSet<Object> values = new LinkedHashSet<>(universe); - variable.setValues(values); + for (ReportVariable<?> variable : report.getRepeatVariables()) { + doPopulateRepeatVariable(report, tripId, new TreeMap<>(vars), variable); + } + } + + default <R> void doPopulateRepeatVariable(Report report, Set<String> tripId, Map<String, Object> vars, ReportVariable<R> variable) { + String hql = variable.getRequest(); + for (ReportVariable<?> repeatVariable : report.getRepeatVariables()) { + if (variable.equals(repeatVariable)) { + continue; + } + if (hql.contains(":" + repeatVariable.getName() + " ")) { + // add this repeat variable values to parameters + vars.put(repeatVariable.getName(), repeatVariable.computeIndexList()); + } } + List<R> universe = executeRequest(hql, vars); + LinkedHashSet<R> values = new LinkedHashSet<>(universe); + variable.setValues(values); } private DataMatrixDimension computeDimension(ReportRequest request, List<?> list) { ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/ReportVariable.java ===================================== @@ -22,10 +22,15 @@ package fr.ird.observe.dto.report; * #L% */ +import fr.ird.observe.dto.ToolkitId; import io.ultreia.java4all.util.json.JsonAware; import java.io.Serializable; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; /** * La définition d'une variable utilisable dans un report. @@ -90,4 +95,31 @@ public class ReportVariable<V> implements Serializable, JsonAware { public void setSelectedValue(V selectedValue) { this.selectedValue = selectedValue; } + + public List<String> computeIndexList() { + Set<V> tmp = new LinkedHashSet<>(values); + boolean useNullValue = tmp.remove(null); + List<String> result = tmp.stream().map(s -> s instanceof ToolkitId ? ((ToolkitId) s).getId() : String.valueOf(s)).collect(Collectors.toList()); + if (useNullValue) { + result.add("null"); + } + return result; + } + + public boolean isEmpty() { + return values == null || values.isEmpty(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ReportVariable)) return false; + ReportVariable<?> that = (ReportVariable<?>) o; + return Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } } ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/ComputeDynamicHeader.java ===================================== @@ -0,0 +1,84 @@ +package fr.ird.observe.dto.report.operations; + +/*- + * #%L + * ObServe Toolkit :: API + * %% + * Copyright (C) 2008 - 2022 IRD, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.auto.service.AutoService; +import fr.ird.observe.dto.referential.WithI18n; +import fr.ird.observe.dto.report.DataMatrix; +import fr.ird.observe.dto.report.Report; +import fr.ird.observe.dto.report.ReportOperationConsumer; +import fr.ird.observe.dto.report.ReportRequestExecutor; + +import java.util.Set; + +/** + * To compute dynamic headers (for report with no column headers defined). + * <p> + * You can set as parameters an array of fixed column names + a repeat variable to complete the header. + * <p> + * Example: + * <code>Col1,Col2,Col3|repeatVariableName</code> + * <p> + * Created on 15/11/2022. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.0.17 + */ +@AutoService(ReportOperationConsumer.class) +public class ComputeDynamicHeader implements ReportOperationConsumer { + @Override + public DataMatrix consume(String parameters, ReportRequestExecutor requestExecutor, Report report, Set<String> tripId, DataMatrix incoming) { + if (parameters.isEmpty()) { + throw new IllegalStateException(String.format("parameters of operation %s can't not be null (format: col1,col2,...|repeatVariableName)", getClass().getName())); + } + String[] split = parameters.split("\\|"); + if (split.length != 2) { + throw new IllegalStateException(String.format("parameters of operation %s (value %s) has bad format (format: col1,col2,...|repeatVariableName)", getClass().getName(), parameters)); + } + String[] fixedColumnNames = split[0].split("\\s*,\\s*"); + String repeatVariableName = split[1].trim(); + Set<?> repeatVariableValues = report.getRepeatVariable(repeatVariableName).getValues(); + int columnIndex = 0; + DataMatrix tmpMatrix = createTmpMatrix(0, 0, incoming.getWidth(), 1); + boolean useNullRepeatVariableValue = false; + for (String beginHeader : fixedColumnNames) { + tmpMatrix.setValue(columnIndex++, 0, beginHeader); + } + for (Object repeatVariable : repeatVariableValues) { + if (repeatVariable == null) { + useNullRepeatVariableValue = true; + } else { + if (repeatVariable instanceof WithI18n) { + tmpMatrix.setValue(columnIndex++, 0, ((WithI18n) repeatVariable).getLabel2()); + } else { + tmpMatrix.setValue(columnIndex++, 0, repeatVariable.toString()); + } + } + } + if (useNullRepeatVariableValue) { + tmpMatrix.setValue(columnIndex, 0, "Aucun"); + } + incoming.setY(1); + return DataMatrix.merge(incoming, tmpMatrix); + } +} ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/CopyRepeatVariableToFirstColumn.java ===================================== @@ -0,0 +1,66 @@ +package fr.ird.observe.dto.report.operations; + +/*- + * #%L + * ObServe Toolkit :: API + * %% + * Copyright (C) 2008 - 2022 IRD, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.auto.service.AutoService; +import fr.ird.observe.dto.referential.WithI18n; +import fr.ird.observe.dto.report.DataMatrix; +import fr.ird.observe.dto.report.Report; +import fr.ird.observe.dto.report.ReportOperationConsumer; +import fr.ird.observe.dto.report.ReportRequestExecutor; + +import java.util.Set; + +/** + * To copy all values of a repeat variable to the first column. + * <p> + * If repeat variables values are {@link WithI18n}, then will use the {@link WithI18n#getLabel2()}. + * <p> + * TODO: Be able to use the correct locale to translate with correct label. + * <p> + * Created on 15/11/2022. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.0.17 + */ +@AutoService(ReportOperationConsumer.class) +public class CopyRepeatVariableToFirstColumn implements ReportOperationConsumer { + @Override + public DataMatrix consume(String parameters, ReportRequestExecutor requestExecutor, Report report, Set<String> tripId, DataMatrix incoming) { + if (parameters.isEmpty()) { + throw new IllegalStateException(String.format("parameters of operation %s can't not be null (format: repeatVariableName)", getClass().getName())); + } + String repeatVariableName = parameters.trim(); + Set<?> repeatVariableValues = report.getRepeatVariable(repeatVariableName).getValues(); + DataMatrix tmpMatrix = createTmpMatrix(0, 0, 1 + incoming.getWidth(), repeatVariableValues.size()); + int index = 0; + for (Object value : repeatVariableValues) { + if (value instanceof WithI18n) { + value = ((WithI18n) value).getLabel2(); + } + tmpMatrix.setValue(0, index++, value); + } + incoming.setX(1); + return DataMatrix.merge(incoming, tmpMatrix); + } +} ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/ExecuteRequestAndReorganizeCountByRepeatVariable.java ===================================== @@ -0,0 +1,120 @@ +package fr.ird.observe.dto.report.operations; + +/*- + * #%L + * ObServe Toolkit :: API + * %% + * Copyright (C) 2008 - 2022 IRD, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.auto.service.AutoService; +import fr.ird.observe.dto.report.DataMatrix; +import fr.ird.observe.dto.report.Report; +import fr.ird.observe.dto.report.ReportOperationConsumer; +import fr.ird.observe.dto.report.ReportRequest; +import fr.ird.observe.dto.report.ReportRequestExecutor; +import fr.ird.observe.dto.report.ReportVariable; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * To execute a query and then reorganize it using repeat variables position (on x axis and y axis). + * <p> + * Created on 15/11/2022. + * <p> + * Parameters format is + * <code>repeatVariableForRow|repeatVariableFormColum|request</code> + * + * @author Tony Chemit - dev@tchemit.fr + * @since 9.0.17 + */ +@AutoService(ReportOperationConsumer.class) +public class ExecuteRequestAndReorganizeCountByRepeatVariable implements ReportOperationConsumer { + + @Override + public DataMatrix consume(String parameters, ReportRequestExecutor requestExecutor, Report report, Set<String> tripId, DataMatrix incoming) { + if (parameters.isEmpty()) { + throw new IllegalStateException(String.format("parameters of operation %s can't not be null (format: repeatVariableForRow|repeatVariableFormColum|request)", getClass().getName())); + } + String[] split = parameters.split("\\|"); + if (split.length != 3) { + throw new IllegalStateException(String.format("parameters of operation %s (value %s) has bad format (format: repeatVariableForRow|repeatVariableFormColum|request)", getClass().getName(), parameters)); + } + String repeatVariableForColumName = split[1].trim(); + ReportVariable<?> repeatVariableForColumn = report.getRepeatVariable(repeatVariableForColumName); + if (repeatVariableForColumn.isEmpty()) { + return incoming; + } + String repeatVariableForRowName = split[0].trim(); + ReportVariable<?> repeatVariableForRow = report.getRepeatVariable(repeatVariableForRowName); + if (repeatVariableForRow.isEmpty()) { + return incoming; + } + String request = split[2].trim(); + + List<String> columnIdList = repeatVariableForColumn.computeIndexList(); + List<String> rowIdList = repeatVariableForRow.computeIndexList(); + + Map<String, Object> queryParameters = computeQueryParameters(report, + tripId, + request, + repeatVariableForRowName, + rowIdList, + repeatVariableForColumName, + columnIdList); + + DataMatrix result = createTmpMatrix(incoming.getWidth(), 0, columnIdList.size(), rowIdList.size()); + + List<Object[]> rows = requestExecutor.executeRequest(request, queryParameters); + reorganize(result, rows, rowIdList, columnIdList); + return DataMatrix.merge(incoming, result); + } + + private Map<String, Object> computeQueryParameters(Report report, + Set<String> tripId, + String request, + String repeatVariableForRow, + List<String> rowIdList, + String repeatVariableFormColum, + List<String> columnIdList) { + Map<String, Object> queryParameters = ReportRequest.extractParams(report, tripId); + + if (request.contains(":" + repeatVariableForRow + " ")) { + // add this variable to queryParameters + queryParameters.put(repeatVariableForRow, rowIdList); + } + if (request.contains(":" + repeatVariableFormColum + " ")) { + // add this variable to queryParameters + queryParameters.put(repeatVariableFormColum, columnIdList); + } + return queryParameters; + } + + private void reorganize(DataMatrix result, List<Object[]> rows, List<String> rowIdList, List<String> columnIdList) { + for (Object[] row : rows) { + String rowId = String.valueOf(row[0]); + int rowIndex = rowIdList.indexOf(rowId); + String columnId = String.valueOf(row[1]); + int columnIndex = columnIdList.indexOf(columnId); + Number count = (Number) row[2]; + result.setValue(columnIndex, rowIndex, count); + } + } +} ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/ExecuteRequests.java ===================================== @@ -53,7 +53,7 @@ public class ExecuteRequests implements ReportOperationConsumer { DataMatrix result; if (repeatVariable == null) { // requête simple sans repetition - result = requestExecutor.executeReportRequest(request, report, tripId, null); + result = requestExecutor.executeReportRequest(request, report, tripId); } else { // on a une requête avec repetition String repeatVariableName = repeatVariable.getVariableName(); ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumColumn.java ===================================== @@ -27,6 +27,7 @@ import fr.ird.observe.dto.report.DataMatrix; import fr.ird.observe.dto.report.Report; import fr.ird.observe.dto.report.ReportOperationConsumer; import fr.ird.observe.dto.report.ReportRequestExecutor; +import io.ultreia.java4all.lang.Numbers; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -45,19 +46,37 @@ public class SumColumn implements ReportOperationConsumer { @Override public DataMatrix consume(String parameters, ReportRequestExecutor requestExecutor, Report report, Set<String> tripId, DataMatrix incoming) { - DataMatrix tmpMatrix = createTmpMatrix(0, incoming.getHeight(), incoming.getWidth(), 1); - for (int column = 0, nbColumns = incoming.getWidth(); column < nbColumns; column++) { - Object sumColumn = getSumColumn(column, incoming); + int x = 0; + int y = 0; + int height = incoming.getHeight(); + int width = incoming.getWidth(); + if (!parameters.isEmpty()) { + String[] split = parameters.split("\\|"); + x = Integer.parseInt(split[0]); + y = Integer.parseInt(split[1]); + if (x + 1 >= height) { + // only one row in column to sum, so skip operation + return incoming; + } + } + + DataMatrix tmpMatrix = createTmpMatrix(0, height, width, 1); + for (int column = y; column < width; column++) { + Object sumColumn = getSumColumn(column, x, incoming); tmpMatrix.setValue(column, 0, sumColumn); } - return DataMatrix.merge(incoming, tmpMatrix); + DataMatrix merge = DataMatrix.merge(incoming, tmpMatrix); + if (report.getColumnHeaders() == null) { + merge.setValue(0, height, "Total"); + } + return merge; } - protected Object getSumColumn(int column, DataMatrix incoming) { - double result = 0d; + protected Object getSumColumn(int column, int x, DataMatrix incoming) { + float result = 0f; int nbRows = incoming.getHeight(); - for (int row = 0; row < nbRows; row++) { + for (int row = x; row < nbRows; row++) { Serializable o = incoming.getValue(column, row); if (o == null || "null".equals(o)) { o = 0; @@ -71,6 +90,6 @@ public class SumColumn implements ReportOperationConsumer { } result += d; } - return result; + return Numbers.roundFourDigits(result); } } ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumFloatColumn.java ===================================== @@ -41,7 +41,7 @@ public class SumFloatColumn extends SumColumn implements ReportOperationConsumer private static final Logger log = LogManager.getLogger(SumFloatColumn.class); @Override - protected Object getSumColumn(int column, DataMatrix incoming) { + protected Object getSumColumn(int column, int x, DataMatrix incoming) { double result = 0d; int nbRows = incoming.getHeight(); for (int row = 0; row < nbRows; row++) { ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumIntColumn.java ===================================== @@ -36,8 +36,8 @@ import fr.ird.observe.dto.report.ReportOperationConsumer; public class SumIntColumn extends SumColumn implements ReportOperationConsumer { @Override - protected Object getSumColumn(int column, DataMatrix incoming) { - Object sumColumn = super.getSumColumn(column, incoming); + protected Object getSumColumn(int column, int x, DataMatrix incoming) { + Object sumColumn = super.getSumColumn(column, x, incoming); return sumColumn instanceof Number ? ((Number) sumColumn).intValue() : sumColumn; } } ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumIntRow.java ===================================== @@ -35,8 +35,8 @@ import fr.ird.observe.dto.report.ReportOperationConsumer; @AutoService(ReportOperationConsumer.class) public class SumIntRow extends SumRow implements ReportOperationConsumer { @Override - protected Object getSumRow(int row, DataMatrix incoming) { - Object sumColumn = super.getSumRow(row, incoming); + protected Object getSumRow(int row, int y, DataMatrix incoming) { + Object sumColumn = super.getSumRow(row, y, incoming); return sumColumn instanceof Number ? ((Number) sumColumn).intValue() : sumColumn; } } ===================================== toolkit/api/src/main/java/fr/ird/observe/dto/report/operations/SumRow.java ===================================== @@ -27,6 +27,7 @@ import fr.ird.observe.dto.report.DataMatrix; import fr.ird.observe.dto.report.Report; import fr.ird.observe.dto.report.ReportOperationConsumer; import fr.ird.observe.dto.report.ReportRequestExecutor; +import io.ultreia.java4all.lang.Numbers; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -45,18 +46,37 @@ public class SumRow implements ReportOperationConsumer { @Override public DataMatrix consume(String parameters, ReportRequestExecutor requestExecutor, Report report, Set<String> tripId, DataMatrix incoming) { - DataMatrix tmpMatrix = createTmpMatrix(incoming.getWidth(), 0, 1, incoming.getHeight()); - for (int row = 0, nbRows = incoming.getHeight(); row < nbRows; row++) { - Object sumRow = getSumRow(row, incoming); + int x = 0; + int y = 0; + int width = incoming.getWidth(); + int height = incoming.getHeight(); + + + if (!parameters.isEmpty()) { + String[] split = parameters.split("\\|"); + x = Integer.parseInt(split[0]); + y = Integer.parseInt(split[1]); + if (y + 1 >= width) { + // only one column in row to sum, so skip operation + return incoming; + } + } + DataMatrix tmpMatrix = createTmpMatrix(width, 0, 1, height); + for (int row = x; row < height; row++) { + Object sumRow = getSumRow(row, y, incoming); tmpMatrix.setValue(0, row, sumRow); } - return DataMatrix.merge(incoming, tmpMatrix); + DataMatrix merge = DataMatrix.merge(incoming, tmpMatrix); + if (report.getRowHeaders() == null) { + merge.setValue(width, 0, "Total"); + } + return merge; } - protected Object getSumRow(int row, DataMatrix incoming) { - double result = 0d; + protected Object getSumRow(int row, int y, DataMatrix incoming) { + float result = 0f; int nbColumns = incoming.getWidth(); - for (int col = 0; col < nbColumns; col++) { + for (int col = y; col < nbColumns; col++) { Serializable o = incoming.getValue(col, row); if (o == null || "null".equals(o)) { o = 0; @@ -71,6 +91,6 @@ public class SumRow implements ReportOperationConsumer { } result += d; } - return result; + return Numbers.roundFourDigits(result); } } ===================================== toolkit/persistence/src/main/java/fr/ird/observe/spi/report/DefaultReportRequestExecutor.java ===================================== @@ -36,6 +36,7 @@ import fr.ird.observe.dto.report.ReportRequestExecutor; import fr.ird.observe.dto.report.ReportVariable; import fr.ird.observe.dto.report.operations.ExecuteRequests; import fr.ird.observe.spi.PersistenceBusinessProject; +import io.ultreia.java4all.util.TimeLog; import org.nuiton.topia.persistence.TopiaDao; import java.util.Collection; @@ -57,6 +58,7 @@ import java.util.function.Supplier; @SuppressWarnings("SpellCheckingInspection") public abstract class DefaultReportRequestExecutor implements ReportRequestExecutor { + public static final TimeLog TIME_LOG = new TimeLog(DefaultReportRequestExecutor.class, 500, 1000); private final Supplier<? extends TopiaDao<?>> daoSupplier; private final ReferentialLocale referentialLocale; @@ -67,11 +69,15 @@ public abstract class DefaultReportRequestExecutor implements ReportRequestExecu @Override public Report populateVariables(Report report, Set<String> tripIds) { + long t00 = TimeLog.getTime(); Map<String, Object> vars = new TreeMap<>(); vars.put(ReportRequest.TRIP_ID_VARIABLE, tripIds); for (ReportVariable<?> variable : report.getVariables()) { + long t0 = TimeLog.getTime(); populateVariable(variable, vars); + TIME_LOG.log(t0, "populate variable", variable.getName()); } + TIME_LOG.log(t00, "populate variables"); return report; } @@ -103,14 +109,29 @@ public abstract class DefaultReportRequestExecutor implements ReportRequestExecu return result; } + @Override + public void doPopulateRepeatVariables(Report report, Set<String> tripId) { + long t0 = TimeLog.getTime(); + ReportRequestExecutor.super.doPopulateRepeatVariables(report, tripId); + TIME_LOG.log(t0, "populate repeat variables"); + } + + @Override + public <R> void doPopulateRepeatVariable(Report report, Set<String> tripId, Map<String, Object> vars, ReportVariable<R> variable) { + long t0 = TimeLog.getTime(); + ReportRequestExecutor.super.doPopulateRepeatVariable(report, tripId, vars, variable); + TIME_LOG.log(t0, "populate repeat variable", variable.getName()); + } + @Override public <R> List<R> executeRequest(String request, Map<String, Object> params) { + long t0 = TimeLog.getTime(); // si il y a des references de DTO dans les valeurs des paramètres on les remplace par leur id // on copie pour ne pas modifier le paramètre de la méthode Map<String, Object> paramsFixes = new HashMap<>(); for (Map.Entry<String, Object> entry : params.entrySet()) { String name = entry.getKey(); - if (request.contains(":" + name)) { + if (request.contains(":" + name + " ") || request.endsWith(":" + name)) { Object value = entry.getValue(); if (value instanceof DtoReference) { DtoReference referenceDto = (DtoReference) value; @@ -120,7 +141,11 @@ public abstract class DefaultReportRequestExecutor implements ReportRequestExecu } } log.debug(String.format("Request: %s, params: %s", request, paramsFixes)); - return daoSupplier.get().findAll(request, paramsFixes); + try { + return daoSupplier.get().findAll(request, paramsFixes); + } finally { + TIME_LOG.log(t0, "execute request", request); + } } @SuppressWarnings("unchecked") View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/b8a08b6b41646e5e148525dc2... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/b8a08b6b41646e5e148525dc2... You're receiving this email because of your account on gitlab.com.
participants (1)
-
Tony CHEMIT (@tchemit)