Skip to content

Commit

Permalink
Merge branch 'master' into DHIS2-18117-changelog-migration
Browse files Browse the repository at this point in the history
  • Loading branch information
muilpp authored Nov 4, 2024
2 parents a52f726 + 8540aca commit 2ecf039
Show file tree
Hide file tree
Showing 118 changed files with 4,484 additions and 851 deletions.
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);
}
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 org.hisp.dhis.common.DataDimensionType;
import org.hisp.dhis.common.GenericDimensionalObjectStore;
Expand All @@ -40,4 +41,6 @@ public interface CategoryStore extends GenericDimensionalObjectStore<Category> {
List<Category> getCategories(DataDimensionType dataDimensionType, boolean dataDimension);

List<Category> getCategoriesNoAcl(DataDimensionType dataDimensionType, boolean dataDimension);

List<Category> getCategoriesByCategoryOption(Collection<String> categoryOptions);
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ enum Access {
* @return the class that represents the domain for the annotated controller {@link Class} or
* endpoint {@link java.lang.reflect.Method}.
*/
// TODO make this metadataEntity() ? => always point out the most related metadata object to
// categorise a controller by?
Class<?> entity() default EntityType.class;

/**
Expand Down
5 changes: 5 additions & 0 deletions dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/UID.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,9 @@ public static Set<String> toValueSet(Collection<UID> uids) {
public static List<String> toValueList(Collection<UID> uids) {
return uids.stream().map(UID::getValue).toList();
}

public static <T extends BaseIdentifiableObject> Set<String> toUidValueSet(
@Nonnull Collection<T> elements) {
return elements.stream().map(BaseIdentifiableObject::getUid).collect(toUnmodifiableSet());
}
}
Loading

0 comments on commit 2ecf039

Please sign in to comment.