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}