001/*
002 *  Copyright 2020 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.odfpilotage.validator;
017
018import java.util.HashMap;
019import java.util.HashSet;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import org.ametys.cms.contenttype.validation.AbstractContentValidator;
025import org.ametys.cms.data.ContentValue;
026import org.ametys.cms.repository.Content;
027import org.ametys.plugins.repository.data.holder.group.impl.ModelAwareRepeater;
028import org.ametys.plugins.repository.data.holder.group.impl.ModelAwareRepeaterEntry;
029import org.ametys.plugins.repository.data.holder.impl.DataHolderHelper;
030import org.ametys.plugins.repository.data.holder.values.SynchronizableRepeater;
031import org.ametys.runtime.i18n.I18nizableText;
032import org.ametys.runtime.i18n.I18nizableTextParameter;
033import org.ametys.runtime.model.View;
034import org.ametys.runtime.parameter.Errors;
035
036/**
037 * Global validator for content.
038 * Check that every instance of the repeater {@link #getRepeaterName()} have a different value in {@link #getContentDataName()}.
039 */
040public abstract class AbstractRepeaterWithUniqueContentValidator extends AbstractContentValidator
041{
042    @Override
043    public void validate(Content content, Errors errors)
044    {
045        if (content.hasValue(getRepeaterName()))
046        {
047            Set<String> itemIds = new HashSet<>();
048            
049            ModelAwareRepeater repeater = content.getRepeater(getRepeaterName());
050            for (ModelAwareRepeaterEntry entry : repeater.getEntries())
051            {
052                ContentValue item = entry.getValue(getContentDataName());
053                
054                if (item != null && !itemIds.add(item.getContentId()))
055                {
056                    String title = item.getContentIfExists()
057                            .map(Content::getTitle)
058                            .orElse(item.getContentId());
059                    
060                    Map<String, I18nizableTextParameter> i18nParams = new HashMap<>();
061                    i18nParams.put("contentTitle", new I18nizableText(content.getTitle()));
062                    i18nParams.put("dataValueTitle", new I18nizableText(title));
063                    errors.addError(new I18nizableText("plugin.odf-pilotage", getErrorKey(), i18nParams));
064                }
065            }
066        }
067    }
068    
069    @Override
070    public void validate(Content content, Map<String, Object> values, View view, Errors errors)
071    {
072        Set<String> itemIds = new HashSet<>();
073        Object repeater = values.get(getRepeaterName());
074        
075        @SuppressWarnings("unchecked")
076        List<Map<String, Object>> repeaterValues = repeater instanceof SynchronizableRepeater ? ((SynchronizableRepeater) repeater).getEntries() : (List<Map<String, Object>>) repeater;
077        if (repeaterValues != null)
078        {
079            for (Map<String, Object> entry : repeaterValues)
080            {
081                Object value = entry.get(getContentDataName());
082                ContentValue contentValue = (ContentValue) DataHolderHelper.getValueToValidate(value);
083                if (contentValue != null)
084                {
085                    Content repeaterContent = contentValue.getContent();
086                    
087                    if (!itemIds.add(repeaterContent.getId()))
088                    {
089                        Map<String, I18nizableTextParameter> i18nParams = new HashMap<>();
090                        i18nParams.put("contentTitle", new I18nizableText(content.getTitle()));
091                        i18nParams.put("dataValueTitle", new I18nizableText(repeaterContent.getTitle()));
092                        errors.addError(new I18nizableText("plugin.odf-pilotage", getErrorKey(), i18nParams));
093                    }
094                }
095            }
096        }
097    }
098    
099    /**
100     * Get the repeater name.
101     * @return The repeater name.
102     */
103    protected abstract String getRepeaterName();
104    
105    /**
106     * Get the content data name.
107     * @return The content data name.
108     */
109    protected abstract String getContentDataName();
110    
111    /**
112     * Get the error I18N key (parameterizable with "contentTitle" and "dataValueTitle").
113     * @return The error 18N key.
114     */
115    protected abstract String getErrorKey();
116}