001/* 002 * Copyright 2010 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.calendar.enumerators; 017 018import java.util.Collection; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.Map; 022import java.util.Set; 023 024import org.apache.avalon.framework.configuration.Configuration; 025import org.apache.avalon.framework.configuration.ConfigurationException; 026import org.apache.commons.collections.CollectionUtils; 027import org.apache.commons.collections.Predicate; 028import org.apache.commons.lang.StringUtils; 029 030import org.ametys.cms.contenttype.ContentType; 031import org.ametys.cms.contenttype.ContentTypeEnumerator; 032import org.ametys.cms.contenttype.MetadataType; 033import org.ametys.runtime.i18n.I18nizableText; 034 035/** 036 * Enumerator on {@link ContentType} for the Agenda service. 037 * Restrict content types to thoses who have all the metadatas referenced by the <code>_metadataNames</code> list. 038 */ 039public class CalendarContentTypesEnumerator extends ContentTypeEnumerator 040{ 041 /** Map of mandatory metadata names and their type. */ 042 protected Map<String, Set<MetadataType>> _mandatoryMetadata; 043 044 @Override 045 public void configure(Configuration configuration) throws ConfigurationException 046 { 047 super.configure(configuration); 048 049 Configuration mandatoryMetadataConf = configuration.getChild("enumeration").getChild("custom-enumerator").getChild("mandatory-metadata", false); 050 if (mandatoryMetadataConf == null) 051 { 052 _mandatoryMetadata = null; 053 } 054 else 055 { 056 _mandatoryMetadata = new HashMap<>(); 057 058 Configuration[] metadataRefConfs = mandatoryMetadataConf.getChildren("metadata-ref"); 059 for (Configuration metadataRefConf : metadataRefConfs) 060 { 061 String name = metadataRefConf.getValue(null); 062 063 String[] types = StringUtils.split(metadataRefConf.getAttribute("type", "string"), ','); 064 065 Set<MetadataType> metaTypes = new HashSet<>(types.length); 066 for (String type : types) 067 { 068 metaTypes.add(MetadataType.valueOf(type.trim().toUpperCase())); 069 } 070 071 _mandatoryMetadata.put(name, metaTypes); 072 } 073 _mandatoryMetadata.remove(null); 074 } 075 } 076 077 @Override 078 public Map<Object, I18nizableText> getEntries() throws Exception 079 { 080 Map<Object, I18nizableText> entries = new HashMap<>(); 081 Set<String> cTypeIds = getCTypeIds(); 082 083 for (String cTypeId : cTypeIds) 084 { 085 ContentType cType = _cTypeExtPt.getExtension(cTypeId); 086 087 // Build a Set containing the rejected mandatory metadata. 088 // This means either the metadata does not exists for this content type, or the metadata type is not matching the expectations. 089 Collection<String> rejectedMetadata = CollectionUtils.selectRejected(_mandatoryMetadata.keySet(), new MandatoryMetadataPredicate(cType)); 090 091 if (rejectedMetadata.isEmpty()) 092 { 093 entries.put(cTypeId, cType.getLabel()); 094 } 095 } 096 097 // All contents 098 _handleAllOptionEntry(entries); 099 100 return entries; 101 } 102 103 /** 104 * Predicate that test if the requested metadata is in the content type and if its type is correct. 105 */ 106 public class MandatoryMetadataPredicate implements Predicate 107 { 108 private ContentType _cType; 109 110 /** 111 * Build a {@code MandatoryMetadataPredicate} 112 * @param cType The ContentType to check against. 113 */ 114 protected MandatoryMetadataPredicate(ContentType cType) 115 { 116 _cType = cType; 117 } 118 119 @Override 120 public boolean evaluate(Object object) 121 { 122 String metadataName = (String) object; 123 return _isDefined(metadataName) && _isTypeCorrect(metadataName); 124 } 125 126 private boolean _isDefined(String metadataName) 127 { 128 return _cType.getMetadataNames().contains(metadataName); 129 } 130 131 private boolean _isTypeCorrect(String metadataName) 132 { 133 return _mandatoryMetadata.get(metadataName).contains(_cType.getMetadataDefinition(metadataName).getType()); 134 } 135 } 136}