Skip to content

Commit

Permalink
Merge branch 'master' of github.com:dhis2/dhis2-core into DHIS2-18370…
Browse files Browse the repository at this point in the history
…_2.42
  • Loading branch information
maikelarabori committed Jan 20, 2025
2 parents 9c151b8 + f007409 commit 6aacc33
Show file tree
Hide file tree
Showing 63 changed files with 2,132 additions and 1,860 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
*/
package org.hisp.dhis.datadimensionitem;

import java.util.Collection;
import java.util.List;
import org.hisp.dhis.common.DataDimensionItem;
import org.hisp.dhis.common.GenericStore;
Expand All @@ -47,4 +48,14 @@ public interface DataDimensionItemStore extends GenericStore<DataDimensionItem>
List<DataDimensionItem> getIndicatorDataDimensionItems(List<Indicator> indicators);

List<DataDimensionItem> getDataElementDataDimensionItems(List<DataElement> dataElements);

/**
* Update the entities with refs to the category option combo ids passed in, with the new category
* option combo id passed in.
*
* @param cocIds category option combo ids to be used to update linked data dimension items
* @param newCocId new category option combo id to use
* @return number of entities updated
*/
int updateDeoCategoryOptionCombo(Collection<Long> cocIds, long newCocId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2004-2025, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the HISP project nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hisp.dhis.expression;

import org.hisp.dhis.common.GenericStore;

/**
* @author david mackessy
*/
public interface ExpressionStore extends GenericStore<Expression> {

/**
* Update all expressions whose expression property contains the 'find' value. When updating, it
* replaces all occurrences of 'find' with 'replace'.
*
* @param find text to search for
* @param replace text used to replace 'find'
* @return number of entities updated
*/
int updateExpressionContaining(String find, String replace);
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,15 @@ public interface IndicatorStore extends IdentifiableObjectStore<Indicator> {
List<Indicator> getIndicatorsWithNumeratorContaining(String search);

List<Indicator> getIndicatorsWithDenominatorContaining(String search);

/**
* Updates any indicator that has the 'find' param in either its numerator or denominator. The
* update involves updating numerator and denominator, replacing all occurrences of 'find' with
* 'replace'.
*
* @param find text to search for
* @param replace text used to replace
* @return number of rows updated
*/
int updateNumeratorDenominatorContaining(String find, String replace);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@
import java.util.List;
import org.hisp.dhis.common.AnalyticalObjectStore;
import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
import org.hisp.dhis.program.Program;

/**
* @author Morten Olav Hansen <[email protected]>
*/
public interface MapViewStore extends AnalyticalObjectStore<MapView> {
List<MapView> getByOrganisationUnitGroupSet(OrganisationUnitGroupSet groupSet);

List<MapView> findByProgram(Program program);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.List;
import org.hisp.dhis.common.AnalyticalObjectService;
import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
import org.hisp.dhis.program.Program;

/**
* @author Jan Henrik Overland
Expand Down Expand Up @@ -91,6 +92,8 @@ public interface MappingService extends AnalyticalObjectService<MapView> {

int countMapViewMaps(MapView mapView);

List<MapView> findByProgram(Program program);

// -------------------------------------------------------------------------
// ExternalMapLayer
// -------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion dhis-2/dhis-services/dhis-service-administration/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>1.5.4</version>
<version>1.5.5</version>
<exclusions>
<exclusion>
<groupId>org.apache.commons</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ private void initMergeHandlers() {
metadataMergeHandler::handlePredictors,
metadataMergeHandler::handleDataElementOperands,
metadataMergeHandler::handleMinMaxDataElements,
metadataMergeHandler::handleSmsCodes);
metadataMergeHandler::handleSmsCodes,
metadataMergeHandler::handleIndicators,
metadataMergeHandler::handleExpressions);

dataMergeHandlers =
List.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
package org.hisp.dhis.merge.category.optioncombo;

import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hisp.dhis.category.CategoryCombo;
Expand All @@ -37,8 +38,11 @@
import org.hisp.dhis.category.CategoryOptionStore;
import org.hisp.dhis.common.BaseIdentifiableObject;
import org.hisp.dhis.common.UID;
import org.hisp.dhis.datadimensionitem.DataDimensionItemStore;
import org.hisp.dhis.dataelement.DataElementOperand;
import org.hisp.dhis.dataelement.DataElementOperandStore;
import org.hisp.dhis.expression.ExpressionStore;
import org.hisp.dhis.indicator.IndicatorStore;
import org.hisp.dhis.minmax.MinMaxDataElement;
import org.hisp.dhis.minmax.MinMaxDataElementStore;
import org.hisp.dhis.predictor.Predictor;
Expand All @@ -60,9 +64,12 @@ public class MetadataCategoryOptionComboMergeHandler {
private final CategoryOptionStore categoryOptionStore;
private final CategoryComboStore categoryComboStore;
private final DataElementOperandStore dataElementOperandStore;
private final DataDimensionItemStore dataDimensionItemStore;
private final MinMaxDataElementStore minMaxDataElementStore;
private final PredictorStore predictorStore;
private final SMSCommandStore smsCommandStore;
private final IndicatorStore indicatorStore;
private final ExpressionStore expressionStore;

/**
* Remove sources from {@link CategoryOption} and add target to {@link CategoryOption}
Expand Down Expand Up @@ -116,6 +123,17 @@ public void handleDataElementOperands(
UID.of(sources.stream().map(BaseIdentifiableObject::getUid).toList()));

dataElementOperands.forEach(deo -> deo.setCategoryOptionCombo(target));

// A data element operand is also a data dimension item.
// The above update does not cascade the reference change though.
// The Data dimension item table also needs updating
int dataDimensionItemsUpdated =
dataDimensionItemStore.updateDeoCategoryOptionCombo(
sources.stream().map(BaseIdentifiableObject::getId).collect(Collectors.toSet()),
target.getId());
log.info(
"{} data dimension items updated as part of category option combo merge",
dataDimensionItemsUpdated);
}

/**
Expand Down Expand Up @@ -163,4 +181,38 @@ public void handleSmsCodes(List<CategoryOptionCombo> sources, CategoryOptionComb

smsCodes.forEach(smsCode -> smsCode.setOptionId(target));
}

/**
* Update each Indicator numerator and denominator values, replacing any source ref with the
* target ref.
*
* @param sources to be replaced
* @param target to replace source refs
*/
public void handleIndicators(List<CategoryOptionCombo> sources, CategoryOptionCombo target) {
log.info("Merging source indicators");
int totalUpdates = 0;
for (CategoryOptionCombo source : sources) {
totalUpdates +=
indicatorStore.updateNumeratorDenominatorContaining(source.getUid(), target.getUid());
}

log.info("{} indicators updated", totalUpdates);
}

/**
* Update each Expression expression value, replacing any source ref with the target ref.
*
* @param sources to be replaced
* @param target to replace source refs
*/
public void handleExpressions(List<CategoryOptionCombo> sources, CategoryOptionCombo target) {
log.info("Merging source expressions");
int totalUpdates = 0;
for (CategoryOptionCombo source : sources) {
totalUpdates += expressionStore.updateExpressionContaining(source.getUid(), target.getUid());
}

log.info("{} expressions updated", totalUpdates);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
package org.hisp.dhis.datadimensionitem.hibernate;

import jakarta.persistence.EntityManager;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.hisp.dhis.common.DataDimensionItem;
import org.hisp.dhis.dataelement.DataElement;
import org.hisp.dhis.hibernate.HibernateGenericStore;
Expand Down Expand Up @@ -69,4 +72,19 @@ public List<DataDimensionItem> getDataElementDataDimensionItems(List<DataElement
.setParameter("dataElements", dataElements)
.getResultList();
}

@Override
public int updateDeoCategoryOptionCombo(@Nonnull Collection<Long> cocIds, long newCocId) {
if (cocIds.isEmpty()) return 0;

String sql =
"""
update datadimensionitem
set dataelementoperand_categoryoptioncomboid = %s
where dataelementoperand_categoryoptioncomboid in (%s)
"""
.formatted(
newCocId, cocIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
return jdbcTemplate.update(sql);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2004-2023, University of Oslo
* Copyright (c) 2004-2024, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand All @@ -25,36 +25,35 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hisp.dhis.security;
package org.hisp.dhis.expression;

import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hisp.dhis.external.conf.ConfigurationKey;
import org.hisp.dhis.external.conf.DhisConfigurationProvider;
import org.springframework.context.event.EventListener;
import org.springframework.security.web.session.HttpSessionCreatedEvent;
import org.springframework.stereotype.Component;
import jakarta.persistence.EntityManager;
import org.hisp.dhis.hibernate.HibernateGenericStore;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

/**
* @author Morten Svanæs <[email protected]>
* @author david mackessy
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class DhisHttpSessionEventListener {
private final DhisConfigurationProvider config;
@Repository
public class HibernateExpressionStore extends HibernateGenericStore<Expression>
implements org.hisp.dhis.expression.ExpressionStore {

@EventListener
public void sessionCreated(HttpSessionCreatedEvent event) {
HttpSession session = event.getSession();
try {
String property = config.getProperty(ConfigurationKey.SYSTEM_SESSION_TIMEOUT);
session.setMaxInactiveInterval(Integer.parseInt(property));
} catch (Exception e) {
session.setMaxInactiveInterval(
Integer.parseInt(ConfigurationKey.SYSTEM_SESSION_TIMEOUT.getDefaultValue()));
log.error("Could not read session timeout value from config", e);
}
public HibernateExpressionStore(
EntityManager entityManager, JdbcTemplate jdbcTemplate, ApplicationEventPublisher publisher) {
super(entityManager, jdbcTemplate, publisher, Expression.class, false);
}

@Override
public int updateExpressionContaining(String find, String replace) {
String sql =
"""
update expression
set expression = replace(expression, '%s', '%s')
where expression like '%s';
"""
.formatted(find, replace, "%" + find + "%");
return jdbcTemplate.update(sql);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,18 @@ public List<Indicator> getIndicatorsWithDenominatorContaining(String search) {
.setParameter("search", "%" + search + "%")
.getResultList();
}

@Override
public int updateNumeratorDenominatorContaining(String find, String replace) {
String sql =
"""
update indicator
set numerator = replace(numerator, '%s', '%s'),
denominator = replace(denominator, '%s', '%s')
where numerator like '%s'
or denominator like '%s';
"""
.formatted(find, replace, find, replace, "%" + find + "%", "%" + find + "%");
return jdbcTemplate.update(sql);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.hisp.dhis.period.Period;
import org.hisp.dhis.period.PeriodService;
import org.hisp.dhis.period.RelativePeriods;
import org.hisp.dhis.program.Program;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -185,6 +186,12 @@ public int countMapViewMaps(MapView mapView) {
return mapStore.countMapViewMaps(mapView);
}

@Override
@Transactional(readOnly = true)
public List<MapView> findByProgram(Program program) {
return mapViewStore.findByProgram(program);
}

// -------------------------------------------------------------------------
// ExternalMapLayer
// -------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 6aacc33

Please sign in to comment.