Commit fda6869f authored by PECQUOT's avatar PECQUOT

[fix] Extraction: delete empty file when no data to extract (Mantis #51225)

[enh] Extraction: hide import and export filter buttons (Mantis #51226)
[fix] Rules: auto loading of single selection reworked (Mantis #51270)
[enh] Extraction: use specific function for MEAS_QUAL_FLAG_NM and MEAS_QUALIF_CM to get unique value or a default value if not unique (Mantis #51297)
Signed-off-by: PECQUOT's avatarlp1ee9d <ludovic.pecquot@e-is.pro>
parent f6d1059a
## Sprint 88 - v3.9.5
- Pas de mise à jour de modèle
## Sprint 87 - v3.9.4
- Pas de mise à jour de modèle
......
......@@ -120,6 +120,10 @@ public class ReefDbBeans extends QuadrigeBeans {
return addressBuilder.toString();
}
public static String toQuotedString(String string) {
return "'" + string.replaceAll("'", "''") + "'";
}
/**
* <p>toString.</p>
*
......@@ -535,6 +539,38 @@ public class ReefDbBeans extends QuadrigeBeans {
return getUnifiedString(comments, DEFAULT_STRING_SEPARATOR);
}
/**
* Method used as external function for HSQLDB
* see fr.ifremer.reefdb.service.extraction.ExtractionPerformServiceImpl#createDistinctFunction(java.lang.String, java.lang.String, java.lang.String)
*
* @param array the input array (any type)
* @param nonDistinctResult the result text if the array contains non distinct values
* @return the unified string
*/
@SuppressWarnings(value = "unused")
public static String getDistinctSQLString(Array array, String nonDistinctResult) {
try {
Set<String> strings = new HashSet<>();
for (Object object : (Object[]) array.getArray()) {
if (object != null) {
strings.add(object.toString());
}
}
return strings.isEmpty()
? ""
: strings.size() == 1
? strings.stream().findFirst().get()
: nonDistinctResult;
} catch (SQLException e) {
return "";
}
}
/**
* Method used as external function for HSQLDB
* see fr.ifremer.reefdb.service.extraction.ExtractionServiceImpl#createConcatDistinctFunction(java.lang.String, java.lang.String, java.lang.String)
......
......@@ -87,8 +87,6 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService {
private static final String XML_QUERY_PATH = "xmlQuery/extraction";
private static final String LS = System.lineSeparator();
@Resource
protected ReefDbConfiguration config;
......@@ -155,6 +153,9 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService {
// create the concat functions used to concat distinct strings (ex: DEP_NM)
createConcatDistinctFunction("STRING", "VARCHAR(2000)");
createConcatDistinctFunction("INTEGER", "INTEGER");
// create the distinct functions used for quality informations (Mantis #51297)
createDistinctFunction("MEAS_QUAL_FLAG_NM", "VARCHAR(2000)");
createDistinctFunction("MEAS_QUALIF_CM", "VARCHAR(2000)");
// STEP 1 : Create the base table
long nbRowsInserted = createBaseTable(context, outputType);
......@@ -595,12 +596,14 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService {
// add measurement quality flags
xmlQuery.bind("measQualFlagFields", getAliasedFields(pmfmInfos, "MEAS_QUAL_FLAG_NM"));
xmlQuery.bind("measQualFlagDefault", ReefDbBeans.toQuotedString(t("reefdb.service.extraction.notDistinct.MEAS_QUAL_FLAG_NM")));
// add measurement qualification dates
xmlQuery.bind("measQualifDtFields", getAliasedFields(pmfmInfos, "MEAS_QUALIF_DT"));
// add measurement qualification comments
xmlQuery.bind("measQualifCmFields", getAliasedFields(pmfmInfos, "MEAS_QUALIF_CM"));
xmlQuery.bind("measQualifCmDefault", ReefDbBeans.toQuotedString(t("reefdb.service.extraction.notDistinct.MEAS_QUALIF_CM")));
// add measurement and taxon measurement ids
xmlQuery.bind("measIdFields", getAliasedFields(pmfmInfos, "MEAS_ID"));
......@@ -660,7 +663,7 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService {
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 +
String query = "CREATE FUNCTION CONCAT_DISTINCT_" + functionName + "(IN_ARRAY " + valueType + " ARRAY, SEPARATOR VARCHAR(10)) RETURNS LONGVARCHAR " +
"LANGUAGE JAVA DETERMINISTIC NO SQL EXTERNAL NAME 'CLASSPATH:fr.ifremer.reefdb.dto.ReefDbBeans.getUnifiedSQLString';";
extractionResultDao.queryUpdate(query, null);
......@@ -672,6 +675,24 @@ public class ExtractionPerformServiceImpl implements ExtractionPerformService {
extractionResultDao.queryUpdate("DROP FUNCTION CONCAT_DISTINCT_" + functionName + " IF EXISTS", null);
}
private void createDistinctFunction(String functionName, String valueType) {
dropDistinctFunction(functionName);
// new function with external java method
String query = "CREATE FUNCTION DISTINCT_" + functionName + "(" +
"IN_ARRAY " + valueType + " ARRAY, NON_DISTINCT_RESULT LONGVARCHAR) RETURNS LONGVARCHAR " +
"LANGUAGE JAVA DETERMINISTIC NO SQL EXTERNAL NAME 'CLASSPATH:fr.ifremer.reefdb.dto.ReefDbBeans.getDistinctSQLString';";
extractionResultDao.queryUpdate(query, null);
}
private void dropDistinctFunction(String functionName) {
extractionResultDao.queryUpdate("DROP FUNCTION DISTINCT_" + functionName + " IF EXISTS", null);
}
private String getAliasedFields(Collection<ExtractionPmfmInfoDTO> pmfmInfos, final String fieldName) {
return pmfmInfos.isEmpty()
? "NULL"
......
......@@ -371,6 +371,8 @@ reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER=
reefdb.service.extraction.fieldNamePrefix.SURVEY=
reefdb.service.extraction.noData.error=
reefdb.service.extraction.noPmfm.error=
reefdb.service.extraction.notDistinct.MEAS_QUALIF_CM=
reefdb.service.extraction.notDistinct.MEAS_QUAL_FLAG_NM=
reefdb.service.observation.duplicate.measurementComment=
reefdb.service.observation.unvalidation.progression=
reefdb.service.observation.validation.progression=
......
......@@ -367,6 +367,8 @@ reefdb.service.extraction.fieldNamePrefix.SAMPLING_OPER=REPLICAT
reefdb.service.extraction.fieldNamePrefix.SURVEY=OBSERVATION
reefdb.service.extraction.noData.error=Aucune observation ne correspond aux critères d'extraction.
reefdb.service.extraction.noPmfm.error=Aucune mesure ne correspond aux critères d'extraction.
reefdb.service.extraction.notDistinct.MEAS_QUALIF_CM=Qualifications différentes selon les résultats - non affichables dans ce format d'export
reefdb.service.extraction.notDistinct.MEAS_QUAL_FLAG_NM=Niveaux multiples
reefdb.service.observation.duplicate.measurementComment=Résultat dupliqué le %s depuis l'observation %s
reefdb.service.observation.save=Sauvegarde
reefdb.service.observation.unvalidation.progression=Dévalidation de %s observation(s) [%s-%s]
......
......@@ -35,6 +35,27 @@
<from alias="RAW"><![CDATA[&rawTableName]]></from>
<where><![CDATA[RAW.MEAS_INDIV_ID IS NOT NULL]]></where>
<!-- FIXME: only if old data have to be extract: ie. GCRMN_LAREUNION_LIT_BENTHOS 07/03/2012 data have measurements and taxon_measurements for same meas_indiv_id
to avoid blank duplicated lines replace first query by:
SELECT
RAW.SURVEY_ID "SURVEY_ID",
RAW.SAMPLING_OPER_ID "SAMPLING_OPER_ID",
RAW.MEAS_INDIV_ID "MEAS_INDIV_ID",
max(RAW.REF_TAXON_NM) "REF_TAXON_NM",
max(RAW.TAXON_NAME_ID) "TAXON_NAME_ID",
max(RAW.TAXON_NAME_NM) "TAXON_NAME_NM",
max(RAW.TAXON_GROUP_NM) "TAXON_GROUP_NM"
FROM
EXT_R1583421502786 RAW
WHERE
RAW.MEAS_INDIV_ID IS NOT NULL
group by RAW.SURVEY_ID, RAW.SAMPLING_OPER_ID, RAW.MEAS_INDIV_ID
order by RAW.SURVEY_ID, RAW.SAMPLING_OPER_ID, RAW.MEAS_INDIV_ID;
-->
<union>
<!-- add non individual measurements from sampling operations -->
<subquery option="DISTINCT">
......
......@@ -64,9 +64,9 @@
<select alias="TAXON_NAME_NM" type="text" group="simple,complete,sinp">C.TAXON_NAME_NM</select>
<select alias="MEAS_QUAL_FLAG_NM" type="text"><![CDATA[CONCAT_DISTINCT_STRING(ARRAY[&measQualFlagFields],',')]]></select>
<select alias="MEAS_QUAL_FLAG_NM" type="text"><![CDATA[DISTINCT_MEAS_QUAL_FLAG_NM(ARRAY[&measQualFlagFields],&measQualFlagDefault)]]></select>
<select alias="MEAS_QUALIF_DT" type="text"><![CDATA[CONCAT_DISTINCT_STRING(ARRAY[&measQualifDtFields],',')]]></select>
<select alias="MEAS_QUALIF_CM" type="text"><![CDATA[CONCAT_DISTINCT_STRING(ARRAY[&measQualifCmFields],' - ')]]></select>
<select alias="MEAS_QUALIF_CM" type="text"><![CDATA[DISTINCT_MEAS_QUALIF_CM(ARRAY[&measQualifCmFields],&measQualifCmDefault)]]></select>
<select alias="TAXON_NAME_ID" type="number" group="simple,complete,sinp">C.TAXON_NAME_ID</select>
......
......@@ -230,6 +230,17 @@ public abstract class AbstractExtractAction extends AbstractCheckModelAction<Ext
super.postSuccessAction();
}
@Override
public void postFailedAction(Throwable error) {
// Delete empty file (Mantis #51225)
if (getOutputFile() != null && getOutputFile().exists() && getOutputFile().length() == 0) {
getOutputFile().delete();
}
super.postFailedAction(error);
}
/**
* {@inheritDoc}
*/
......
......@@ -52,7 +52,7 @@
text: "reefdb.common.import";
toolTipText: "reefdb.extraction.list.import.tip";
/*_applicationAction: {ImportExtractionAction.class};*/
enabled: false;
visible: false;
}
#exportButton {
......@@ -61,7 +61,7 @@
toolTipText: "reefdb.extraction.list.export.tip";
/*enabled: {!model.getSelectedRows().isEmpty()};*/
/*_applicationAction: {ExportExtractionAction.class};*/
enabled: false;
visible: false;
}
#extractCombo {
......
......@@ -23,19 +23,18 @@ package fr.ifremer.reefdb.ui.swing.content.manage.rule;
* #L%
*/
import com.google.common.collect.Lists;
import fr.ifremer.quadrige3.synchro.vo.SynchroProgressionStatus;
import fr.ifremer.quadrige3.ui.swing.synchro.action.ImportSynchroCheckAction;
import fr.ifremer.reefdb.dto.configuration.control.ControlRuleDTO;
import fr.ifremer.reefdb.dto.configuration.control.RuleListDTO;
import fr.ifremer.reefdb.ui.swing.action.QuitScreenAction;
import fr.ifremer.reefdb.ui.swing.content.manage.rule.menu.RulesMenuUIModel;
import fr.ifremer.reefdb.ui.swing.content.manage.rule.rulelist.RuleListRowModel;
import fr.ifremer.reefdb.ui.swing.content.manage.rule.rulelist.RuleListUI;
import fr.ifremer.reefdb.ui.swing.util.AbstractReefDbBeanUIModel;
import fr.ifremer.reefdb.ui.swing.util.AbstractReefDbUIHandler;
import jaxx.runtime.SwingUtil;
import jaxx.runtime.validator.swing.SwingValidator;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.jaxx.application.swing.util.CloseableUI;
......@@ -104,6 +103,11 @@ public class RulesUIHandler extends AbstractReefDbUIHandler<RulesUIModel, RulesU
private void initListeners() {
// Listen search results
getUI().getRulesMenuUI().getModel().addPropertyChangeListener(RulesMenuUIModel.PROPERTY_RESULTS, evt ->
getUI().getRuleListUI().getHandler().loadRuleLists((List<RuleListDTO>) evt.getNewValue())
);
// Listen modify property and set dirty to the selected rule list
listenModelModify(getModel().getRuleListUIModel());
PropertyChangeListener modifyListener = evt -> {
......@@ -204,32 +208,6 @@ public class RulesUIHandler extends AbstractReefDbUIHandler<RulesUIModel, RulesU
}
/**
* Load la regle.
*
* @param ruleListCode L identifiant de la regle a load
* @param programCode
*/
public void loadRuleLists(final String ruleListCode, String programCode) {
// Recuperation de la liste des regles
List<RuleListDTO> ruleLists;
if (StringUtils.isNotBlank(ruleListCode)) {
ruleLists = Lists.newArrayList(getContext().getRuleListService().getRuleList(ruleListCode));
} else if (StringUtils.isNotBlank(programCode)) {
ruleLists = Lists.newArrayList(getContext().getRuleListService().getRuleListsForProgram(programCode));
} else {
ruleLists = getContext().getRuleListService().getRuleLists();
}
getUI().getRuleListUI().getHandler().loadRuleLists(ruleLists);
getUI().getControlProgramTableUI().getHandler().clearTable();
getUI().getControlDepartmentTableUI().getHandler().clearTable();
getUI().getControlRuleTableUI().getHandler().clearTable();
getUI().getControlPmfmTableUI().getHandler().clearTable();
getUI().getControlRuleTableUI().getHandler().clearControlRuleInformation();
}
/** {@inheritDoc} */
@Override
@SuppressWarnings("unchecked")
......
......@@ -12,12 +12,12 @@ package fr.ifremer.reefdb.ui.swing.content.manage.rule.menu;
* 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 <http://www.gnu.org/licenses/>.
* #L%
......@@ -44,32 +44,39 @@ public class ClearAction extends AbstractCheckModelAction<RulesMenuUIModel, Rule
super(handler, false);
}
/** {@inheritDoc} */
/**
* {@inheritDoc}
*/
@Override
public void doAction() {
// Suppression choix de regle
getUI().getRuleListComboBox().getHandler().reset();
getUI().getProgramComboBox().getHandler().reset();
getModel().clear();
RulesUI rulesUI = getUI().getParentContainer(RulesUI.class);
rulesUI.getRuleListUI().getHandler().clearTable();
}
/** {@inheritDoc} */
/**
* {@inheritDoc}
*/
@Override
protected Class<? extends AbstractReefDbSaveAction> getSaveActionClass() {
return SaveAction.class;
}
/** {@inheritDoc} */
/**
* {@inheritDoc}
*/
@Override
protected boolean isModelModify() {
final RulesUIModel model = getLocalModel();
return model != null && model.isModify();
}
/** {@inheritDoc} */
/**
* {@inheritDoc}
*/
@Override
protected void setModelModify(boolean modelModify) {
final RulesUIModel model = getLocalModel();
......@@ -78,14 +85,18 @@ public class ClearAction extends AbstractCheckModelAction<RulesMenuUIModel, Rule
}
}
/** {@inheritDoc} */
/**
* {@inheritDoc}
*/
@Override
protected boolean isModelValid() {
final RulesUIModel model = getLocalModel();
return model == null || model.isValid();
}
/** {@inheritDoc} */
/**
* {@inheritDoc}
*/
@Override
protected AbstractApplicationUIHandler<?, ?> getSaveHandler() {
final RulesUI rulesUI = getUI().getParentContainer(RulesUI.class);
......
......@@ -20,7 +20,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
#L%
-->
<JPanel decorator='help' implements='fr.ifremer.reefdb.ui.swing.util.ReefDbUI&lt;RulesMenuUIModel, RulesMenuUIHandler&gt;'>
<JPanel decorator='help' implements='fr.ifremer.reefdb.ui.swing.content.manage.referential.menu.ReferentialMenuUI&lt;RulesMenuUIModel, RulesMenuUIHandler&gt;'>
<import>
fr.ifremer.reefdb.ui.swing.ReefDbHelpBroker
fr.ifremer.reefdb.ui.swing.ReefDbUIContext
......
......@@ -24,6 +24,7 @@ ExtendedComboBox {
showReset: false;
filterable: true;
showDecorator: false;
bean: {model};
}
#menuPanel {
......@@ -35,11 +36,22 @@ ExtendedComboBox {
labelFor: {ruleListComboBox};
}
#ruleListComboBox {
property: ruleList;
selectedItem: {model.getRuleList()};
}
#programLabel {
text: "reefdb.rule.ruleList.program";
labelFor: {programComboBox};
}
#programComboBox {
property: program;
selectedItem: {model.getProgram()};
enabled: {ruleListComboBox.getSelectedItem() == null};
}
#clearButton{
actionIcon: reset;
text: "reefdb.action.search.clear.label";
......
......@@ -25,18 +25,21 @@ package fr.ifremer.reefdb.ui.swing.content.manage.rule.menu;
import fr.ifremer.quadrige3.core.security.SecurityContextHelper;
import fr.ifremer.reefdb.dto.configuration.control.RuleListDTO;
import fr.ifremer.reefdb.dto.configuration.filter.FilterDTO;
import fr.ifremer.reefdb.service.StatusFilter;
import fr.ifremer.reefdb.ui.swing.util.AbstractReefDbUIHandler;
import fr.ifremer.reefdb.ui.swing.content.manage.filter.element.menu.ApplyFilterUI;
import fr.ifremer.reefdb.ui.swing.content.manage.referential.menu.ReferentialMenuUIHandler;
import fr.ifremer.reefdb.ui.swing.util.ReefDbUIs;
import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import java.util.List;
/**
* Controlleur du menu de l'onglet prelevements mesures.
*/
public class RulesMenuUIHandler extends AbstractReefDbUIHandler<RulesMenuUIModel, RulesMenuUI> {
public class RulesMenuUIHandler extends ReferentialMenuUIHandler<RulesMenuUIModel, RulesMenuUI> {
/**
* {@inheritDoc}
......@@ -57,8 +60,8 @@ public class RulesMenuUIHandler extends AbstractReefDbUIHandler<RulesMenuUIModel
public void afterInit(final RulesMenuUI ui) {
initUI(ui);
// Initialiser les combobox
initComboBox();
initListeners();
}
/**
......@@ -66,34 +69,22 @@ public class RulesMenuUIHandler extends AbstractReefDbUIHandler<RulesMenuUIModel
*/
private void initComboBox() {
// Initialisation des groupe de taxons pere
initBeanFilterableComboBox(
getUI().getRuleListComboBox(),
getContext().getRuleListService().getRuleLists(),
null);
getUI().getRuleListComboBox(),
getContext().getRuleListService().getRuleLists(),
null);
initBeanFilterableComboBox(
getUI().getProgramComboBox(),
getContext().getProgramStrategyService().getManagedProgramsByUserAndStatus(
SecurityContextHelper.getQuadrigeUserId(),
StatusFilter.ACTIVE
),
null
getUI().getProgramComboBox(),
getContext().getProgramStrategyService().getManagedProgramsByUserAndStatus(
SecurityContextHelper.getQuadrigeUserId(),
StatusFilter.ACTIVE
),
null
);
ReefDbUIs.forceComponentSize(getUI().getRuleListComboBox());
ReefDbUIs.forceComponentSize(getUI().getProgramComboBox());
getUI().getRuleListComboBox().getComboBoxModel().addWillChangeSelectedItemListener(event -> {
if (getModel().isLoading()) return;
if (event.getNextSelectedItem() != null) {
getUI().getProgramComboBox().getHandler().reset();
getUI().getProgramComboBox().setEnabled(false);
SwingUtilities.invokeLater(() -> getUI().getSearchButton().getAction().actionPerformed(null));
} else {
getUI().getProgramComboBox().setEnabled(true);
}
});
}
/**
......@@ -114,4 +105,34 @@ public class RulesMenuUIHandler extends AbstractReefDbUIHandler<RulesMenuUIModel
getModel().setLoading(false);
}
private void initListeners() {
getModel().addPropertyChangeListener(RulesMenuUIModel.PROPERTY_RULE_LIST, evt -> {
if (getModel().isLoading()) return;
if (getModel().getRuleList() != null) {
getModel().setProgram(null);
SwingUtilities.invokeLater(() -> getUI().getSearchButton().getAction().actionPerformed(null));
}
});
}
@Override
public void enableSearch(boolean enabled) {
}
@Override
public List<FilterDTO> getFilters() {
return null;
}
@Override
public ApplyFilterUI getApplyFilterUI() {
return null;
}
@Override
public JComponent getLocalFilterPanel() {
return null;
}
}
......@@ -12,22 +12,61 @@ package fr.ifremer.reefdb.ui.swing.content.manage.rule.menu;
* 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 <http://www.gnu.org/licenses/>.
* #L%
*/
import fr.ifremer.quadrige3.ui.swing.model.AbstractEmptyUIModel;
import fr.ifremer.reefdb.dto.configuration.control.RuleListDTO;
import fr.ifremer.reefdb.dto.configuration.programStrategy.ProgramDTO;
import fr.ifremer.reefdb.ui.swing.content.manage.referential.menu.DefaultReferentialMenuUIModel;
/**
* Modele du menu de l onglet prelevements mesures.
* Model for RuleLists
*/
public class RulesMenuUIModel extends AbstractEmptyUIModel<RulesMenuUIModel> {
public class RulesMenuUIModel extends DefaultReferentialMenuUIModel {
public static final String PROPERTY_RULE_LIST = "ruleList";
public static final String PROPERTY_PROGRAM = "program";
private RuleListDTO ruleList;
private ProgramDTO program;
public RuleListDTO getRuleList() {
return ruleList;
}
public void setRuleList(RuleListDTO ruleList) {
this.ruleList = ruleList;
firePropertyChange(PROPERTY_RULE_LIST, null, ruleList);
}
public String getRuleListCode() {
return getRuleList() != null ? getRuleList().getCode() : null;
}
public ProgramDTO getProgram() {
return program;
}
public String getProgramCode() {
return getProgram() != null ? getProgram().getCode() : null;
}
public void setProgram(ProgramDTO program) {
this.program = program;
firePropertyChange(PROPERTY_PROGRAM, null, program);
}
@Override
public void clear() {
super.clear();
setRuleList(null);
setProgram(null);
}
}
......@@ -12,25 +12,26 @@ package fr.ifremer.reefdb.ui.swing.content.manage.rule.menu;
* 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