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.lang.StringUtils; 028 029import org.ametys.runtime.i18n.I18nizableText; 030import org.ametys.runtime.parameter.Errors; 031import org.ametys.runtime.parameter.ParameterHelper; 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 Errors fieldErrors = new Errors(); 127 pref.getValidator().validate(castValue == null ? value : castValue, fieldErrors); 128 129 if (fieldErrors.hasErrors()) 130 { 131 errors.addErrors(pref.getId(), fieldErrors.getErrors()); 132 } 133 } 134 } 135 } 136 } 137 } 138 139 /** 140 * Compute the preferences map. 141 * @param contextVars The context variables including environment elements 142 * @return the preferences map. 143 */ 144 protected Map<String, UserPreference> getPreferencesMap(Map<String, String> contextVars) 145 { 146 Map<String, UserPreference> preferences = new HashMap<>(); 147 148 for (String extensionId : getExtensionsIds()) 149 { 150 UserPreferenceProvider provider = getExtension(extensionId); 151 152 for (UserPreference preference : provider.getPreferences(contextVars)) 153 { 154 preferences.put(preference.getId(), preference); 155 } 156 } 157 158 return preferences; 159 } 160 161 /** 162 * Compute the grouped preferences map. 163 * @param contextVars The context variables including environment elements 164 * @return the grouped preferences map. 165 */ 166 protected Map<I18nizableText, List<UserPreference>> getCategorizedPreferencesMap(Map<String, String> contextVars) 167 { 168 Map<I18nizableText, List<UserPreference>> preferences = new TreeMap<>(new I18nizableTextComparator()); 169 170 for (String extensionId : getExtensionsIds()) 171 { 172 UserPreferenceProvider provider = getExtension(extensionId); 173 174 for (UserPreference preference : provider.getPreferences(contextVars)) 175 { 176 I18nizableText groupName = preference.getDisplayGroup(); 177 178 // Get the map of preferences of the group. 179 List<UserPreference> group = preferences.get(groupName); 180 if (group == null) 181 { 182 group = new ArrayList<>(); 183 preferences.put(groupName, group); 184 } 185 186 group.add(preference); 187 } 188 } 189 190 // Sort all groups. 191 for (List<UserPreference> group : preferences.values()) 192 { 193 Collections.sort(group, _comparator); 194 } 195 196 return preferences; 197 } 198 199 /** 200 * Compares user preferences on their "order" attribute. 201 */ 202 class UserPrefOrderComparator implements Comparator<UserPreference> 203 { 204 @Override 205 public int compare(UserPreference pref1, UserPreference pref2) 206 { 207 return pref1.getOrder() - pref2.getOrder(); 208 } 209 } 210 211 class I18nizableTextComparator implements Comparator<I18nizableText> 212 { 213 @Override 214 public int compare(I18nizableText t1, I18nizableText t2) 215 { 216 return t1.toString().compareTo(t2.toString()); 217 } 218 } 219 220}