com.sdl.dxa.tridion.mapping.impl.DefaultSemanticFieldDataProvider Maven / Gradle / Ivy
The newest version!
package com.sdl.dxa.tridion.mapping.impl;
import com.sdl.dxa.api.datamodel.model.ContentModelData;
import com.sdl.dxa.api.datamodel.model.EntityModelData;
import com.sdl.dxa.api.datamodel.model.KeywordModelData;
import com.sdl.dxa.api.datamodel.model.ViewModelData;
import com.sdl.dxa.api.datamodel.model.util.CanWrapContentAndMetadata;
import com.sdl.dxa.api.datamodel.model.util.ListWrapper;
import com.sdl.dxa.api.datamodel.model.util.ModelDataWrapper;
import com.sdl.dxa.tridion.mapping.ModelBuilderPipeline;
import com.sdl.dxa.tridion.mapping.converter.GenericSemanticModelDataConverter;
import com.sdl.webapp.common.api.WebRequestContext;
import com.sdl.webapp.common.api.mapping.semantic.FieldData;
import com.sdl.webapp.common.api.mapping.semantic.SemanticFieldDataProvider;
import com.sdl.webapp.common.api.mapping.semantic.SemanticMappingException;
import com.sdl.webapp.common.api.mapping.semantic.config.FieldPath;
import com.sdl.webapp.common.api.mapping.semantic.config.SemanticField;
import com.sdl.webapp.common.api.mapping.semantic.config.SemanticSchema;
import com.sdl.webapp.common.api.model.KeywordModel;
import com.sdl.webapp.common.api.model.entity.Link;
import com.sdl.webapp.common.api.model.entity.MediaItem;
import com.sdl.webapp.common.exceptions.DxaException;
import com.sdl.webapp.common.util.TcmUtils;
import com.sdl.webapp.tridion.fields.exceptions.FieldConverterException;
import com.sdl.webapp.tridion.fields.exceptions.UnsupportedTargetTypeException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.core.convert.TypeDescriptor;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.sdl.webapp.common.util.ApplicationContextHolder.getContext;
@Slf4j
public class DefaultSemanticFieldDataProvider implements SemanticFieldDataProvider {
private ModelDataWrapper dataWrapper;
@Getter
private SemanticSchema semanticSchema;
private GenericSemanticModelDataConverter genericSemanticModelDataConverter;
private ModelBuilderPipeline pipeline;
private int embeddingLevel = 0;
private int iteration = 0;
private String context = null;
private DefaultSemanticFieldDataProvider(ModelDataWrapper dataWrapper, SemanticSchema semanticSchema) {
this.dataWrapper = dataWrapper;
this.semanticSchema = semanticSchema;
this.genericSemanticModelDataConverter = getContext().getBean(GenericSemanticModelDataConverter.class);
this.pipeline = getContext().getBean(ModelBuilderPipeline.class);
}
@Nullable
public static DefaultSemanticFieldDataProvider getFor(ViewModelData model, SemanticSchema semanticSchema) {
return getFor((Object) model, semanticSchema);
}
@Nullable
private static DefaultSemanticFieldDataProvider getFor(@NotNull Object model, SemanticSchema semanticSchema) {
if (!(model instanceof CanWrapContentAndMetadata)) {
log.debug("Type {} is not supported by embedded SemanticFieldDataProvider", model.getClass());
return null;
}
return new DefaultSemanticFieldDataProvider(((CanWrapContentAndMetadata) model).getDataWrapper(), semanticSchema);
}
/**
* Shifts the context of this data provider to the given index for the given mode. It is used to iterate over lists of values and to save XPath context.
*
* @param model current item in the list
* @param semanticField current parent semantic field inside which we iterate
* @param index current item index in a list
* @return data provider shifted to the given index
*/
@Nullable
public DefaultSemanticFieldDataProvider iteration(Object model, SemanticField semanticField, int index) {
DefaultSemanticFieldDataProvider provider = getFor(model, semanticSchema);
if (provider != null) {
provider.embeddingLevel = this.embeddingLevel;
provider.iteration = index + 1;
provider.context = semanticField.getXPath(this.context) + "[" + provider.iteration + "]";
log.trace("Iterating over some list, current index = {}, item = {}, embedding level = {}, context = {}",
index, model, this.embeddingLevel, provider.context);
}
return provider;
}
/**
* Increases the embedding level of the data provider saving the current XPath context. It is used to go inside the nested maps.
*
* @param value current value in the map
* @return data provider embedded to the next elvel
*/
@Nullable
public DefaultSemanticFieldDataProvider embedded(Object value) {
DefaultSemanticFieldDataProvider provider = getFor(value, this.semanticSchema);
if (provider != null) {
provider.iteration = this.iteration;
provider.context = this.context;
provider.embeddingLevel = this.embeddingLevel + 1;
log.trace("Embedding into embedding level = {}, index = {}, item = {}, context = {}",
provider.iteration, value, this.embeddingLevel, provider.context);
}
return provider;
}
@Override
public FieldData getFieldData(SemanticField semanticField, TypeDescriptor targetType) throws SemanticMappingException {
log.trace("semanticField: {}, targetType: {}", semanticField, targetType);
ContentModelData data = semanticField.getPath().isMetadata() ? dataWrapper.getMetadata() : dataWrapper.getContent();
FieldPath path = getCurrentPath(semanticField);
if (path == null) {
log.warn("Path is null for semantic field {}, embedding level {}", semanticField, embeddingLevel);
return null;
}
Optional
© 2015 - 2024 Weber Informatics LLC | Privacy Policy