001/* 002 * Copyright 2012 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.core.right; 017 018import java.util.HashMap; 019import java.util.HashSet; 020import java.util.Map; 021import java.util.Set; 022 023import org.apache.avalon.framework.activity.Initializable; 024import org.apache.avalon.framework.component.Component; 025import org.apache.avalon.framework.configuration.Configuration; 026import org.apache.avalon.framework.configuration.ConfigurationException; 027import org.apache.avalon.framework.logger.AbstractLogEnabled; 028import org.apache.avalon.framework.thread.ThreadSafe; 029import org.xml.sax.ContentHandler; 030import org.xml.sax.SAXException; 031 032import org.ametys.runtime.i18n.I18nizableText; 033import org.ametys.runtime.plugin.ExtensionPoint; 034 035 036/** 037 * This extension point handle a list of rights handled by the plugins or the application. 038 */ 039public class RightsExtensionPoint extends AbstractLogEnabled implements ExtensionPoint<Right>, Initializable, ThreadSafe, Component 040{ 041 /** The avalon role */ 042 public static final String ROLE = RightsExtensionPoint.class.getName(); 043 044 /** The map of rightId, Right of declared rights */ 045 protected Map<String, Right> _rights; 046 047 public void initialize() throws Exception 048 { 049 _rights = new HashMap<>(); 050 } 051 052 public boolean hasExtension(String id) 053 { 054 return _rights.containsKey(id); 055 } 056 057 public void addExtension(String id, String pluginName, String pluginId, Configuration configuration) throws ConfigurationException 058 { 059 if (getLogger().isDebugEnabled()) 060 { 061 getLogger().debug("Adding rights from plugin " + pluginName + "/" + pluginId); 062 } 063 064 Configuration[] rightsConfigurations = configuration.getChildren("right"); 065 for (Configuration rightConfiguration : rightsConfigurations) 066 { 067 try 068 { 069 addRight(pluginName, rightConfiguration); 070 } 071 catch (ConfigurationException e) 072 { 073 if (getLogger().isWarnEnabled()) 074 { 075 getLogger().warn("The plugin '" + pluginName + "." + pluginId + "' has a rights extension but has an incorrect configuration", e); 076 } 077 } 078 } 079 } 080 081 /** 082 * Declare a new right (not as used) 083 * @param pluginName The name of the plugin declaring the extension 084 * @param configuration The configuration of the extension 085 * @throws ConfigurationException if configuration if not complete 086 */ 087 protected void addRight(String pluginName, Configuration configuration) throws ConfigurationException 088 { 089 String id = configuration.getAttribute("id", ""); 090 if (id.length() == 0) 091 { 092 throw new ConfigurationException("Right declaration is incorrect since no 'Id' attribute is specified (or may be empty)", configuration); 093 } 094 095 String label = configuration.getChild("label").getValue(""); 096 if (label.length() == 0) 097 { 098 throw new ConfigurationException("Right declaration is incorrect since no 'label' element is specified (or may be empty)", configuration); 099 } 100 I18nizableText i18nLabel = new I18nizableText("plugin." + pluginName, label); 101 102 String description = configuration.getChild("description").getValue(""); 103 if (description.length() == 0) 104 { 105 throw new ConfigurationException("Right declaration is incorrect since no 'description' element is specified (or may be empty)", configuration); 106 } 107 I18nizableText i18nDescription = new I18nizableText("plugin." + pluginName, description); 108 109 String category = configuration.getChild("category").getValue(""); 110 if (category.length() == 0) 111 { 112 throw new ConfigurationException("Right declaration is incorrect since no 'category' element is specified (or may be empty)", configuration); 113 } 114 I18nizableText i18nCategory = new I18nizableText("plugin." + pluginName, category); 115 116 if (_rights.containsKey(id)) 117 { 118 Right right = _rights.get(id); 119 throw new ConfigurationException("Right with id '" + id + "' is already declared : '" + right.getDeclaration() + "'. This second declaration is ignored.", configuration); 120 } 121 122 if (getLogger().isDebugEnabled()) 123 { 124 getLogger().debug("Adding right ID : " + id); 125 } 126 127 Right right = new Right(id, i18nLabel, i18nDescription, i18nCategory, "Declared by plugin '" + pluginName + "'"); 128 if (_rights.containsKey(id)) 129 { 130 Right oldright = _rights.get(id); 131 throw new IllegalArgumentException("Right with id '" + id + "' is already declared : '" + oldright.getDeclaration() + "'. This second declaration is ignored."); 132 } 133 _rights.put(id, right); 134 } 135 136 /** 137 * Declare a new right as used. Use this method to add a right programmatically. 138 * @param id The id of the right (not null or empty) 139 * @param labelKey The label of the right (i18n key) (not null or empty) 140 * @param descriptionKey The description of the right (i18n key) (not null or empty) 141 * @param categoryKey The category of the right (i18n key) (not null or empty) 142 * @throws IllegalArgumentException if the id is already declared 143 */ 144 public void addRight(String id, I18nizableText labelKey, I18nizableText descriptionKey, I18nizableText categoryKey) throws IllegalArgumentException 145 { 146 if (getLogger().isDebugEnabled()) 147 { 148 getLogger().debug("Adding right from API with ID : " + id); 149 } 150 151 if (_rights.containsKey(id)) 152 { 153 Right right = _rights.get(id); 154 throw new IllegalArgumentException("Right with id '" + id + "' is already declared : '" + right.getDeclaration() + "'. The application cannot be run."); 155 } 156 157 Right right = new Right(id, labelKey, descriptionKey, categoryKey, "Declared by API"); 158 _rights.put(id, right); 159 } 160 161 /** 162 * Remove a right from the list of used rights 163 * @param id id of the right to remove 164 */ 165 public void removeRight(String id) 166 { 167 if (getLogger().isDebugEnabled()) 168 { 169 getLogger().debug("Removing right with ID : " + id + "from API"); 170 } 171 172 _rights.remove(id); 173 } 174 175 public Right getExtension(String id) 176 { 177 return _rights.get(id); 178 } 179 180 public Set<String> getExtensionsIds() 181 { 182 return new HashSet<>(_rights.keySet()); 183 } 184 185 public void initializeExtensions() throws Exception 186 { 187 // empty 188 } 189 190 /** 191 * SAX all managed rights 192 * 193 * @param handler the handler receiving SAX events 194 * @throws SAXException if something wrong occurs 195 */ 196 public void toSAX (ContentHandler handler) throws SAXException 197 { 198 for (String id : _rights.keySet()) 199 { 200 Right right = _rights.get(id); 201 right.toSAX(handler); 202 } 203 } 204}