All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sdl.dxa.modules.context.content.ContextExpressionEntityEvaluator Maven / Gradle / Ivy

package com.sdl.dxa.modules.context.content;

import com.sdl.dxa.modules.context.model.Conditions;
import com.sdl.webapp.common.api.content.ConditionalEntityEvaluator;
import com.sdl.webapp.common.api.contextengine.ContextClaims;
import com.sdl.webapp.common.api.contextengine.ContextClaimsProvider;
import com.sdl.webapp.common.api.model.EntityModel;
import com.sdl.webapp.common.api.model.ViewModel;
import com.sdl.webapp.common.exceptions.DxaException;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Implementation of {@link ConditionalEntityEvaluator} that analyzes Context Expression Conditions
 * set as {@link ViewModel#getExtensionData()}.
 */
@Component
@Slf4j
public class ContextExpressionEntityEvaluator implements ConditionalEntityEvaluator {

    @Autowired
    private ContextClaimsProvider contextClaimsProvider;

    @Value("${dxa.modules.contextexpr.extension_data_map_key}")
    private String contextExpressionsKey = "ContextExpressions";

    /**
     * {@inheritDoc}
     * 

Determines whether a given Entity Model should be included * based on the conditions specified on the Entity Model and the context.

*/ @Override public boolean includeEntity(@NonNull EntityModel entity) { if (entity.getExtensionData() == null || !entity.getExtensionData().containsKey(contextExpressionsKey)) { log.debug("Entity {} is included because there is no extension data with a key {}", entity, contextExpressionsKey); return true; } Conditions conditions = (Conditions) entity.getExtensionData().get(contextExpressionsKey); if (conditions == null || conditions.isEmpty()) { log.warn("Found conditions, but they are null or empty, that looks like an error!"); return true; } try { Map contextClaims = contextClaimsProvider.getContextClaims(null); boolean isExcludedNoIncludes = false, isExcludedAnyExclude = false; if (shouldBeExcluded(conditions.getIncludes(), contextClaims, Mode.INCLUDE)) { isExcludedNoIncludes = true; } if (!isExcludedNoIncludes && shouldBeExcluded(conditions.getExcludes(), contextClaims, Mode.EXCLUDE)) { isExcludedAnyExclude = true; } if (isExcludedNoIncludes || isExcludedAnyExclude) { log.debug("suppressing entity because of {} Context Expression conditions; entity {}", isExcludedNoIncludes ? "Include" : "Exclude", entity); return false; } } catch (DxaException e) { log.warn("Exception while requesting context claims, including entity", e); return true; } log.debug("All include/exclude context conditions are satisfied, including Entity"); return true; } private boolean shouldBeExcluded(@Nullable Set cxs, @NonNull Map contextClaims, @NonNull Mode mode) { //if set is null, then we don't process, and return FALSE for "excluded" if (cxs == null || cxs.isEmpty()) { log.debug("Context expression set is empty or null, ignoring"); return false; } //ignore any unknown claims Set filtered = filterCxsByClaims(cxs, contextClaims); if (filtered.isEmpty()) { log.debug("Filtered context expressions set is empty, meaning expressions are not in context claims"); //if set is empty, then we don't process, and return FALSE for "excluded" return false; } //if this is INCLUDE, then any include means FALSE for "excluded" //if this is EXCLUDE, then any exclude means TRUE for "excluded" return (mode == Mode.INCLUDE) != anyCxIsTrue(filtered, contextClaims); } @NotNull private Set filterCxsByClaims(@NonNull Set contextExpressions, @NonNull Map contextClaims) { Set filtered = new HashSet<>(); for (String claimName : contextExpressions) { if (contextClaims.containsKey(claimName)) { filtered.add(claimName); } } return filtered; } private boolean anyCxIsTrue(@NonNull Set contextExpressions, @NonNull Map contextClaims) { //also covers if set is empty, then we don't iterate for (String claimName : contextExpressions) { Boolean claimValue = ContextClaims.castClaim(contextClaims.get(claimName), Boolean.class); if (claimValue != null && claimValue) { return true; } } //set is empty or all conditions are not satisfied return false; } private enum Mode { /** * This is include condition. */ INCLUDE, /** * This is exclude condition. */ EXCLUDE } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy