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.cms.tag; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023 024import org.apache.avalon.framework.configuration.Configuration; 025import org.apache.avalon.framework.configuration.ConfigurationException; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.avalon.framework.service.Serviceable; 029 030import org.ametys.cms.tag.CMSTag.TagVisibility; 031import org.ametys.runtime.i18n.I18nizableText; 032 033 034/** 035 * Class representing a static tag provider. 036 */ 037public class StaticTagProvider extends AbstractTagProvider<CMSTag> implements Serviceable 038{ 039 /** List of statically defined ids */ 040 protected List<String> _localIds; 041 042 /** The tags */ 043 protected Map<String, CMSTag> _tags; 044 045 /** Target types */ 046 protected TagTargetTypeExtensionPoint _targetTypeEP; 047 048 @Override 049 public void service(ServiceManager smanager) throws ServiceException 050 { 051 _targetTypeEP = (TagTargetTypeExtensionPoint) smanager.lookup(TagTargetTypeExtensionPoint.ROLE); 052 } 053 054 @Override 055 public void configure(Configuration configuration) throws ConfigurationException 056 { 057 super.configure(configuration); 058 059 _localIds = new ArrayList<>(); 060 _tags = configureTags(configuration, null, "plugin." + _pluginName); 061 } 062 063 /** 064 * Returns the list of statically defined ids 065 * @return the list of statically defined ids 066 */ 067 public List<String> getLocalIds() 068 { 069 return _localIds; 070 } 071 072 @Override 073 public Map<String, CMSTag> getTags(Map<String, Object> contextualParameters) 074 { 075 return _tags; 076 } 077 078 @Override 079 public boolean hasTag(String tagID, Map<String, Object> contextualParameters) 080 { 081 return getTag(tagID, contextualParameters) != null; 082 } 083 084 @Override 085 public CMSTag getTag(String tagID, Map<String, Object> contextualParameters) 086 { 087 Map<String, CMSTag> tags = getTags(contextualParameters); 088 return tags != null ? _recursiveSearchTags(tags, tagID) : null; 089 } 090 091 private CMSTag _recursiveSearchTags(Map<String, CMSTag> tags, String tagID) 092 { 093 if (tags.containsKey(tagID)) 094 { 095 return tags.get(tagID); 096 } 097 098 for (CMSTag child : tags.values()) 099 { 100 CMSTag tag = _recursiveSearchTags(child.getTags(), tagID); 101 if (tag != null) 102 { 103 return tag; 104 } 105 } 106 107 return null; 108 } 109 110 @Override 111 public Collection<CMSTag> getTags(String tagID, Map<String, Object> contextualParameters) 112 { 113 CMSTag tag = getTag(tagID, contextualParameters); 114 return tag != null ? tag.getTags().values() : null; 115 } 116 117 /** 118 * Configure tag from the passed configuration 119 * @param configuration The configuration 120 * @param parent The parent tag if any 121 * @param defaultCatalogue The default catalogue for i18n 122 * @return a Set of {@link Tag} 123 * @throws ConfigurationException If an error occurred 124 */ 125 protected Map<String, CMSTag> configureTags (Configuration configuration, CMSTag parent, String defaultCatalogue) throws ConfigurationException 126 { 127 Map<String, CMSTag> tags = new HashMap<>(); 128 129 Configuration[] tagsConfiguration = configuration.getChildren("tag"); 130 for (Configuration tagConfiguration : tagsConfiguration) 131 { 132 String id = tagConfiguration.getAttribute("id"); 133 if (!Tag.NAME_PATTERN.matcher(id).matches()) 134 { 135 throw new ConfigurationException("Invalid tag ID '" + id + "': it must match the pattern " + Tag.NAME_PATTERN.toString(), configuration); 136 } 137 if (_localIds.contains(id)) 138 { 139 throw new ConfigurationException("A tag with the id '" + id + "' already exists", configuration); 140 } 141 _localIds.add(id); 142 143 TagVisibility visibility = TagVisibility.PUBLIC; 144 if (tagConfiguration.getAttribute("private", "").equals("true")) 145 { 146 visibility = TagVisibility.PRIVATE; 147 } 148 149 String typeName = tagConfiguration.getAttribute("target", "CONTENT"); 150 TagTargetType targetType = _targetTypeEP.getTagTargetType(typeName); 151 152 I18nizableText label = configureLabel (tagConfiguration, defaultCatalogue); 153 I18nizableText description = configureDescription (tagConfiguration, defaultCatalogue); 154 CMSTag tag = new CMSTag(id, id, parent, label, description, visibility, targetType); 155 tags.put(id, tag); 156 157 // Recursive configuration 158 Map<String, CMSTag> childTags = configureTags(tagConfiguration, tag, defaultCatalogue); 159 tag.setTags(childTags); 160 } 161 162 return tags; 163 } 164}