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}