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.plugins.repository.data.holder.values.SynchronizableValue;
032import org.ametys.runtime.i18n.I18nizableText;
033import org.ametys.runtime.i18n.I18nizableTextParameter;
034import org.ametys.runtime.model.View;
035import org.ametys.runtime.parameter.Errors;
036
037/**
038 * Global validator for content.
039 * Check that every instance of the repeater {@link #getRepeaterName()} have a different value in {@link #getContentDataName()}.
040 */
041public abstract class AbstractRepeaterWithUniqueContentValidator extends AbstractContentValidator
042{
043    @Override
044    public void validate(Content content, Errors errors)
045    {
046        if (content.hasValue(getRepeaterName()))
047        {
048            Set<String> itemIds = new HashSet<>();
049            
050            ModelAwareRepeater repeater = content.getRepeater(getRepeaterName());
051            for (ModelAwareRepeaterEntry entry : repeater.getEntries())
052            {
053                ContentValue item = entry.getValue(getContentDataName());
054                
055                if (item != null && !itemIds.add(item.getContentId()))
056                {
057                    String title = item.getContentIfExists()
058                            .map(Content::getTitle)
059                            .orElse(item.getContentId());
060                    
061                    Map<String, I18nizableTextParameter> i18nParams = new HashMap<>();
062                    i18nParams.put("contentTitle", new I18nizableText(content.getTitle()));
063                    i18nParams.put("dataValueTitle", new I18nizableText(title));
064                    errors.addError(new I18nizableText("plugin.odf-pilotage", getErrorKey(), i18nParams));
065                }
066            }
067        }
068    }
069    
070    @Override
071    public void validate(Content content, Map<String, Object> values, View view, Errors errors)
072    {
073        Set<String> itemIds = new HashSet<>();
074        Object repeater = values.get(getRepeaterName());
075        
076        @SuppressWarnings("unchecked")
077        List<Map<String, Object>> repeaterValues = repeater instanceof SynchronizableRepeater ? ((SynchronizableRepeater) repeater).getEntries() : (List<Map<String, Object>>) repeater;
078        if (repeaterValues != null)
079        {
080            for (Map<String, Object> entry : repeaterValues)
081            {
082                Object value = entry.get(getContentDataName());
083                ContentValue contentValue = (ContentValue) DataHolderHelper.getValueToValidate(value);
084                if (contentValue != null)
085                {
086                    Content repeaterContent = contentValue.getContent();
087                    
088                    if (!itemIds.add(repeaterContent.getId()))
089                    {
090                        Map<String, I18nizableTextParameter> i18nParams = new HashMap<>();
091                        i18nParams.put("contentTitle", new I18nizableText(content.getTitle()));
092                        i18nParams.put("dataValueTitle", new I18nizableText(repeaterContent.getTitle()));
093                        errors.addError(new I18nizableText("plugin.odf-pilotage", getErrorKey(), i18nParams));
094                    }
095                }
096            }
097        }
098    }
099    
100    /**
101     * Get the repeater name.
102     * @return The repeater name.
103     */
104    protected abstract String getRepeaterName();
105    
106    /**
107     * Get the content data name.
108     * @return The content data name.
109     */
110    protected abstract String getContentDataName();
111    
112    /**
113     * Get the error I18N key (parameterizable with "contentTitle" and "dataValueTitle").
114     * @return The error 18N key.
115     */
116    protected abstract String getErrorKey();
117}