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("plugin." + pluginName, rightConfiguration, "Declared by plugin '" + pluginName + "'"); 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 defaultCatalog The default catalog. 084 * @param configuration The configuration of the extension 085 * @param message Declaration origin (for debug purpose) 086 * @return The created right 087 * @throws ConfigurationException if configuration if not complete 088 */ 089 protected Right addRight(String defaultCatalog, Configuration configuration, String message) throws ConfigurationException 090 { 091 String id = configuration.getAttribute("id", ""); 092 if (id.length() == 0) 093 { 094 throw new ConfigurationException("Right declaration is incorrect since no 'Id' attribute is specified (or may be empty)", configuration); 095 } 096 097 I18nizableText i18nLabel = I18nizableText.parseI18nizableText(configuration.getChild("label", false), defaultCatalog); 098 if (i18nLabel == null) 099 { 100 throw new ConfigurationException("Right declaration is incorrect since no 'label' element is specified (or may be empty)", configuration); 101 } 102 103 I18nizableText i18nDescription = I18nizableText.parseI18nizableText(configuration.getChild("description", false), defaultCatalog); 104 if (i18nDescription == null) 105 { 106 throw new ConfigurationException("Right declaration is incorrect since no 'description' element is specified (or may be empty)", configuration); 107 } 108 109 I18nizableText i18nCategory = I18nizableText.parseI18nizableText(configuration.getChild("category", false), defaultCatalog); 110 if (i18nCategory == null) 111 { 112 throw new ConfigurationException("Right declaration is incorrect since no 'category' element is specified (or may be empty)", configuration); 113 } 114 115 if (_rights.containsKey(id)) 116 { 117 Right right = _rights.get(id); 118 throw new ConfigurationException("Right with id '" + id + "' is already declared : '" + right.getDeclaration() + "'. This second declaration is ignored.", configuration); 119 } 120 121 if (getLogger().isDebugEnabled()) 122 { 123 getLogger().debug("Adding right ID : " + id); 124 } 125 126 Right right = new Right(id, i18nLabel, i18nDescription, i18nCategory, message); 127 if (_rights.containsKey(id)) 128 { 129 Right oldright = _rights.get(id); 130 throw new IllegalArgumentException("Right with id '" + id + "' is already declared : '" + oldright.getDeclaration() + "'. This second declaration is ignored."); 131 } 132 _rights.put(id, right); 133 134 return right; 135 } 136 137 /** 138 * Declare a new right as used. Use this method to add a right programmatically. 139 * @param defaultCatalog The default catalog. 140 * @param configuration The configuration of the extension 141 * @return The created right 142 */ 143 public Right addRight(String defaultCatalog, Configuration configuration) throws ConfigurationException 144 { 145 return addRight(defaultCatalog, configuration, "Declared by API"); 146 } 147 148 /** 149 * Declare a new right as used. Use this method to add a right programmatically. 150 * @param id The id of the right (not null or empty) 151 * @param labelKey The label of the right (i18n key) (not null or empty) 152 * @param descriptionKey The description of the right (i18n key) (not null or empty) 153 * @param categoryKey The category of the right (i18n key) (not null or empty) 154 * @return The created right 155 * @throws IllegalArgumentException if the id is already declared 156 */ 157 public Right addRight(String id, I18nizableText labelKey, I18nizableText descriptionKey, I18nizableText categoryKey) throws IllegalArgumentException 158 { 159 if (getLogger().isDebugEnabled()) 160 { 161 getLogger().debug("Adding right from API with ID : " + id); 162 } 163 164 if (_rights.containsKey(id)) 165 { 166 Right right = _rights.get(id); 167 throw new IllegalArgumentException("Right with id '" + id + "' is already declared : '" + right.getDeclaration() + "'. The application cannot be run."); 168 } 169 170 Right right = new Right(id, labelKey, descriptionKey, categoryKey, "Declared by API"); 171 _rights.put(id, right); 172 173 return right; 174 } 175 176 /** 177 * Remove a right from the list of used rights 178 * @param id id of the right to remove 179 */ 180 public void removeRight(String id) 181 { 182 if (getLogger().isDebugEnabled()) 183 { 184 getLogger().debug("Removing right with ID : " + id + "from API"); 185 } 186 187 _rights.remove(id); 188 } 189 190 public Right getExtension(String id) 191 { 192 return _rights.get(id); 193 } 194 195 public Set<String> getExtensionsIds() 196 { 197 return new HashSet<>(_rights.keySet()); 198 } 199 200 public void initializeExtensions() throws Exception 201 { 202 // empty 203 } 204 205 /** 206 * SAX all managed rights 207 * 208 * @param handler the handler receiving SAX events 209 * @throws SAXException if something wrong occurs 210 */ 211 public void toSAX (ContentHandler handler) throws SAXException 212 { 213 for (String id : _rights.keySet()) 214 { 215 Right right = _rights.get(id); 216 right.toSAX(handler); 217 } 218 } 219}