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.userpref; 017 018import java.util.ArrayList; 019import java.util.Collections; 020import java.util.Comparator; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024import java.util.Map.Entry; 025import java.util.TreeMap; 026 027import org.apache.commons.lang3.StringUtils; 028 029import org.ametys.runtime.i18n.I18nizableText; 030import org.ametys.runtime.parameter.ParameterHelper; 031import org.ametys.runtime.parameter.ValidationResult; 032import org.ametys.runtime.parameter.Validator; 033import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint; 034 035/** 036 * Extension point holding all {@link UserPreference} definitions. 037 */ 038public class UserPreferencesExtensionPoint extends AbstractThreadSafeComponentExtensionPoint<UserPreferenceProvider> 039{ 040 041 /** Avalon Role */ 042 public static final String ROLE = UserPreferencesExtensionPoint.class.getName(); 043 044 /** User preference parser. */ 045 private UserPrefOrderComparator _comparator; 046 047 @Override 048 public void initialize() throws Exception 049 { 050 super.initialize(); 051 052 _comparator = new UserPrefOrderComparator(); 053 } 054 055 /** 056 * Get all the declared user preferences. 057 * @param contextVars The context variables including environment elements 058 * @param id The preference id 059 * @return the user preferences (read-only collection). 060 */ 061 public UserPreference getUserPreference(Map<String, String> contextVars, String id) 062 { 063 for (String extensionId : getExtensionsIds()) 064 { 065 UserPreferenceProvider provider = getExtension(extensionId); 066 067 for (UserPreference preference : provider.getPreferences(contextVars)) 068 { 069 if (preference.getId().equals(id)) 070 { 071 return preference; 072 } 073 } 074 } 075 076 return null; 077 } 078 079 /** 080 * Get all the declared user preferences. 081 * @param contextVars The context variables including environment elements 082 * @return the user preferences (read-only collection). 083 */ 084 public Map<String, UserPreference> getUserPreferences(Map<String, String> contextVars) 085 { 086 return Collections.unmodifiableMap(getPreferencesMap(contextVars)); 087 } 088 089 /** 090 * Get all the preferences, classified by group and ordered. 091 * @param contextVars The context variables including environment elements 092 * @return the preferences classified by group and ordered. 093 */ 094 public Map<I18nizableText, List<UserPreference>> getCategorizedPreferences(Map<String, String> contextVars) 095 { 096 return Collections.unmodifiableMap(getCategorizedPreferencesMap(contextVars)); 097 } 098 099 /** 100 * Validate preference values. 101 * @param contextVars The context variables including environment elements 102 * @param values the values. 103 * @param errors the errors object to fill in. 104 */ 105 public void validatePreferences(Map<String, String> contextVars, Map<String, String> values, UserPreferencesErrors errors) 106 { 107 Map<String, UserPreference> preferences = getPreferencesMap(contextVars); 108 109 for (Entry<String, String> entry : values.entrySet()) 110 { 111 UserPreference pref = preferences.get(entry.getKey()); 112 if (pref != null) 113 { 114 String value = entry.getValue(); 115 116 Object castValue = ParameterHelper.castValue(value, pref.getType()); 117 if (StringUtils.isNotEmpty(value) && castValue == null) 118 { 119 errors.addError(pref.getId(), new I18nizableText("plugin.core", "PLUGINS_CORE_UI_USER_PREFERENCES_INVALID_TYPE")); 120 } 121 else 122 { 123 Validator validator = pref.getValidator(); 124 if (validator != null) 125 { 126 ValidationResult validationResult = pref.getValidator().validate(castValue == null ? value : castValue); 127 128 if (validationResult.hasErrors()) 129 { 130 errors.addErrors(pref.getId(), validationResult.getErrors()); 131 } 132 } 133 } 134 } 135 } 136 } 137 138 /** 139 * Compute the preferences map. 140 * @param contextVars The context variables including environment elements 141 * @return the preferences map. 142 */ 143 protected Map<String, UserPreference> getPreferencesMap(Map<String, String> contextVars) 144 { 145 Map<String, UserPreference> preferences = new HashMap<>(); 146 147 for (String extensionId : getExtensionsIds()) 148 { 149 UserPreferenceProvider provider = getExtension(extensionId); 150 151 for (UserPreference preference : provider.getPreferences(contextVars)) 152 { 153 preferences.put(preference.getId(), preference); 154 } 155 } 156 157 return preferences; 158 } 159 160 /** 161 * Compute the grouped preferences map. 162 * @param contextVars The context variables including environment elements 163 * @return the grouped preferences map. 164 */ 165 protected Map<I18nizableText, List<UserPreference>> getCategorizedPreferencesMap(Map<String, String> contextVars) 166 { 167 Map<I18nizableText, List<UserPreference>> preferences = new TreeMap<>(new I18nizableTextComparator()); 168 169 for (String extensionId : getExtensionsIds()) 170 { 171 UserPreferenceProvider provider = getExtension(extensionId); 172 173 for (UserPreference preference : provider.getPreferences(contextVars)) 174 { 175 I18nizableText groupName = preference.getDisplayGroup(); 176 177 // Get the map of preferences of the group. 178 List<UserPreference> group = preferences.get(groupName); 179 if (group == null) 180 { 181 group = new ArrayList<>(); 182 preferences.put(groupName, group); 183 } 184 185 group.add(preference); 186 } 187 } 188 189 // Sort all groups. 190 for (List<UserPreference> group : preferences.values()) 191 { 192 Collections.sort(group, _comparator); 193 } 194 195 return preferences; 196 } 197 198 /** 199 * Compares user preferences on their "order" attribute. 200 */ 201 class UserPrefOrderComparator implements Comparator<UserPreference> 202 { 203 @Override 204 public int compare(UserPreference pref1, UserPreference pref2) 205 { 206 return pref1.getOrder() - pref2.getOrder(); 207 } 208 } 209 210 class I18nizableTextComparator implements Comparator<I18nizableText> 211 { 212 @Override 213 public int compare(I18nizableText t1, I18nizableText t2) 214 { 215 return t1.toString().compareTo(t2.toString()); 216 } 217 } 218 219}