Skip to content

Commit

Permalink
Merge branch 'master' into DHIS2-18239
Browse files Browse the repository at this point in the history
  • Loading branch information
larshelge committed Nov 1, 2024
2 parents c4a685b + 5b66ac7 commit 0715fd8
Show file tree
Hide file tree
Showing 408 changed files with 9,280 additions and 3,861 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/analyse-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ concurrency:
cancel-in-progress: true
jobs:
sonarqube:
if: github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -38,13 +39,13 @@ jobs:
BASE_BRANCH: ${{ github.base_ref }}
BRANCH: ${{ github.ref }}
PR: ${{ github.event.number }}
if: github.event_name == 'pull_request'
if: github.event.pull_request.user.login != 'dependabot[bot]' && github.event_name == 'pull_request'
run: |
mvn -f dhis-2/pom.xml clean install --threads 2C --batch-mode --update-snapshots --no-transfer-progress -DskipTests
mvn -f dhis-2/pom.xml sonar:sonar -Dsonar.internal.analysis.dbd=false --batch-mode --no-transfer-progress -Dsonar.scm.revision=${{ github.event.pull_request.head.sha }} -Dsonar.projectKey=dhis2_dhis2-core
- name: Analyse long-living branch
if: github.event_name != 'pull_request'
if: github.event.pull_request.user.login != 'dependabot[bot]' && github.event_name != 'pull_request'
run: |
mvn -f dhis-2/pom.xml clean install --threads 2C --batch-mode --update-snapshots --no-transfer-progress -DskipTests
mvn -f dhis-2/pom.xml sonar:sonar -Dsonar.internal.analysis.dbd=false --batch-mode --no-transfer-progress -Dsonar.branch.name=${GITHUB_REF#refs/heads/} -Dsonar.projectKey=dhis2_dhis2-core
9 changes: 5 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ on:
branches:
- master
schedule:
- cron: '0 12 * * *'
- cron: "0 12 * * *"
concurrency:
group: ${{ github.workflow}}-${{ github.ref }}
cancel-in-progress: true
group: ${{ github.workflow}}-${{ github.ref }}
cancel-in-progress: true
jobs:
analyze:
if: github.actor != 'dependabot[bot]'
name: Analyze
runs-on: ubuntu-latest

Expand All @@ -27,7 +28,7 @@ jobs:
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
language: [ 'java' ]
language: ["java"]
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2004-2024, 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.analytics;

import java.util.Collection;
import java.util.List;
import org.hisp.dhis.category.CategoryDimension;
import org.hisp.dhis.category.CategoryOption;
import org.hisp.dhis.common.GenericStore;

/**
* @author david mackessy
*/
public interface CategoryDimensionStore extends GenericStore<CategoryDimension> {

/**
* Gets all {@link CategoryDimension}s that reference any of the supplied {@link CategoryOption}s
*
* @param categoryOptions to search for
* @return matching {@link CategoryDimension}s
*/
List<CategoryDimension> getByCategoryOption(Collection<String> categoryOptions);
}
95 changes: 95 additions & 0 deletions dhis-2/dhis-api/src/main/java/org/hisp/dhis/cache/SoftCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2004-2024, 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.cache;

import java.lang.ref.SoftReference;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Supplier;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

/**
* A soft cache uses a concurrent map with {@link java.lang.ref.SoftReference} boxed values.
*
* <p>This means the values might get GC-ed if the JVM needs memory. Therefore, when accessing a
* value by key, a {@link java.util.function.Supplier} needs to be passed in case the value needs
* re-computing.
*
* @author Jan Bernitt
* @since 2.42
*/
public final class SoftCache<T> {

private final ConcurrentMap<String, SoftReference<T>> cache = new ConcurrentHashMap<>();

/**
* Access a cached value by key.
*
* @param key the key to get from the cache, when null the value is computed and not cached
* @param onMiss a function to compute the value on a cache miss; the function must not return
* null
* @return the cached or computed value
*/
@Nonnull
public T get(@CheckForNull String key, @Nonnull Supplier<T> onMiss) {
if (key == null) return onMiss.get();
Supplier<T> memOnMiss = memorize(onMiss);
T res =
cache
.compute(
key,
(k, v) -> {
if (v == null) return new SoftReference<>(memOnMiss.get());
if (v.get() != null) return v;
return new SoftReference<>(memOnMiss.get());
})
.get();
// in theory the get() of the SoftReference can become null
// just when it is returned from the map
// in which case the res is taken directly from the supplier
// since this should mean the JVM is low on memory
return res == null ? memOnMiss.get() : res;
}

/**
* @param onMiss assumed expensive to compute
* @return a supplier that will memorize the result once it has been computed
*/
private Supplier<T> memorize(Supplier<T> onMiss) {
Object[] memorize = new Object[1];
return () -> {
@SuppressWarnings("unchecked")
T v = (T) memorize[0];
if (v != null) return v;
v = onMiss.get();
memorize[0] = v;
return v;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -92,6 +93,10 @@ public void removeCategoryOption(CategoryOption categoryOption) {
categoryOption.getCategories().remove(this);
}

public void removeCategoryOptions(Collection<CategoryOption> categoryOptions) {
categoryOptions.forEach(this::removeCategoryOption);
}

public void removeAllCategoryOptions() {
for (CategoryOption categoryOption : categoryOptions) {
categoryOption.getCategories().remove(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nonnull;
import org.hisp.dhis.common.BaseIdentifiableObject;
import org.hisp.dhis.common.DimensionalEmbeddedObject;
import org.hisp.dhis.common.DxfNamespaces;
Expand Down Expand Up @@ -83,6 +85,18 @@ public void setItems(List<CategoryOption> items) {
this.items = items;
}

public void addItem(CategoryOption item) {
this.getItems().add(item);
}

public void removeItem(CategoryOption item) {
this.getItems().remove(item);
}

public void removeItems(@Nonnull Collection<CategoryOption> items) {
items.forEach(this::removeItem);
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("CategoryDimension{");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -116,11 +117,19 @@ public void addCategoryOptionCombo(CategoryOptionCombo dataElementCategoryOption
dataElementCategoryOptionCombo.getCategoryOptions().add(this);
}

public void addCategoryOptionCombos(Collection<CategoryOptionCombo> categoryOptionCombos) {
categoryOptionCombos.forEach(this::addCategoryOptionCombo);
}

public void removeCategoryOptionCombo(CategoryOptionCombo dataElementCategoryOptionCombo) {
categoryOptionCombos.remove(dataElementCategoryOptionCombo);
dataElementCategoryOptionCombo.getCategoryOptions().remove(this);
}

public void removeCategoryOptionCombos(Collection<CategoryOptionCombo> categoryOptionCombos) {
categoryOptionCombos.forEach(this::removeCategoryOptionCombo);
}

public void addOrganisationUnit(OrganisationUnit organisationUnit) {
organisationUnits.add(organisationUnit);
organisationUnit.getCategoryOptions().add(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -151,6 +152,10 @@ public void removeCategoryOption(CategoryOption dataElementCategoryOption) {
dataElementCategoryOption.getCategoryOptionCombos().remove(this);
}

public void removeCategoryOptions(Collection<CategoryOption> categoryOptions) {
categoryOptions.forEach(this::removeCategoryOption);
}

public void removeAllCategoryOptions() {
categoryOptions.clear();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
*/
package org.hisp.dhis.category;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.hisp.dhis.common.IdentifiableObjectStore;
Expand Down Expand Up @@ -56,4 +57,13 @@ CategoryOptionCombo getCategoryOptionCombo(
* @return a List of {@link CategoryOptionCombo} or empty List
*/
List<CategoryOptionCombo> getCategoryOptionCombosByGroupUid(String groupId, String dataElementId);

/**
* Retrieves all CategoryOptionCombos with a ref to any of the CategoryOptions passed in.
*
* @param categoryOptions refs to search for
* @return categoryOptionCombos with refs to categoryOptions
*/
List<CategoryOptionCombo> getCategoryOptionCombosByCategoryOption(
Collection<String> categoryOptions);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.hisp.dhis.common.BaseDimensionalItemObject;
Expand Down Expand Up @@ -128,4 +129,8 @@ public void removeCategoryOption(CategoryOption categoryOption) {
members.remove(categoryOption);
categoryOption.getGroups().remove(this);
}

public void removeCategoryOptions(Collection<CategoryOption> categoryOptions) {
categoryOptions.forEach(this::removeCategoryOption);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@
*/
package org.hisp.dhis.category;

import java.util.Collection;
import java.util.List;
import org.hisp.dhis.common.IdentifiableObjectStore;

public interface CategoryOptionGroupStore extends IdentifiableObjectStore<CategoryOptionGroup> {
List<CategoryOptionGroup> getCategoryOptionGroups(CategoryOptionGroupSet groupSet);

List<CategoryOptionGroup> getByCategoryOption(Collection<String> categoryOptions);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.Set;
import org.apache.commons.collections4.SetValuedMap;
import org.hisp.dhis.common.IdScheme;
import org.hisp.dhis.common.UID;
import org.hisp.dhis.dataelement.DataElement;
import org.hisp.dhis.dataelement.DataElementOperand;
import org.hisp.dhis.dataset.DataSet;
Expand Down Expand Up @@ -145,6 +146,14 @@ public interface CategoryService {
*/
List<Category> getAttributeDataDimensionCategoriesNoAcl();

/**
* Retrieves all Categories with a ref to any of the CategoryOptions passed in.
*
* @param categoryOptions refs to search for
* @return categories with refs to categoryOptions
*/
List<Category> getCategoriesByCategoryOption(Collection<UID> categoryOptions);

// -------------------------------------------------------------------------
// CategoryOption
// -------------------------------------------------------------------------
Expand Down Expand Up @@ -461,6 +470,15 @@ CategoryOptionCombo getCategoryOptionCombo(
/** Updates the name property of all category option combinations. */
void updateCategoryOptionComboNames();

/**
* Retrieves all CategoryOptionCombos with a ref to any of the CategoryOptions passed in.
*
* @param categoryOptions refs to search for
* @return categoryOptionCombos with refs to categoryOptions
*/
List<CategoryOptionCombo> getCategoryOptionCombosByCategoryOption(
Collection<UID> categoryOptions);

// -------------------------------------------------------------------------
// DataElementOperand
// -------------------------------------------------------------------------
Expand Down Expand Up @@ -509,6 +527,8 @@ CategoryOptionCombo getCategoryOptionCombo(

List<CategoryOptionGroup> getCategoryOptionGroups(CategoryOptionGroupSet groupSet);

List<CategoryOptionGroup> getCategoryOptionGroupByCategoryOption(Collection<UID> categoryOptions);

/**
* Returns a set of CategoryOptionGroups that may be seen by the current user, if the current user
* has any CategoryOptionGroupSet constraint(s).
Expand Down Expand Up @@ -541,4 +561,6 @@ CategoryOptionCombo getCategoryOptionCombo(
CategoryOption getDefaultCategoryOption();

Category getDefaultCategory();

List<CategoryOption> getCategoryOptionsByUid(List<String> catOptionUids);
}
Loading

0 comments on commit 0715fd8

Please sign in to comment.