001/* 002 * Copyright 2015 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.plugins.core.user; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.Collections; 021import java.util.HashMap; 022import java.util.HashSet; 023import java.util.List; 024import java.util.Map; 025import java.util.Objects; 026import java.util.Optional; 027import java.util.Set; 028import java.util.stream.Collectors; 029 030import org.apache.avalon.framework.component.Component; 031import org.apache.avalon.framework.context.Context; 032import org.apache.avalon.framework.context.ContextException; 033import org.apache.avalon.framework.context.Contextualizable; 034import org.apache.avalon.framework.service.ServiceException; 035import org.apache.avalon.framework.service.ServiceManager; 036import org.apache.avalon.framework.service.Serviceable; 037import org.apache.cocoon.components.ContextHelper; 038import org.apache.cocoon.environment.Request; 039import org.apache.cocoon.xml.AttributesImpl; 040import org.apache.cocoon.xml.XMLUtils; 041import org.xml.sax.ContentHandler; 042import org.xml.sax.SAXException; 043 044import org.ametys.core.user.User; 045import org.ametys.core.user.UserIdentity; 046import org.ametys.core.user.UserManager; 047import org.ametys.core.user.directory.UserDirectoryFactory; 048import org.ametys.core.user.population.UserPopulationDAO; 049 050/** 051 * Simple user helper, for common function working on {@link User} 052 */ 053public class UserHelper implements Component, Serviceable, Contextualizable 054{ 055 /** The Avalon role */ 056 public static final String ROLE = UserHelper.class.getName(); 057 058 private static final String __USER_CACHE_REQUEST_ATTR = UserHelper.class.getName() + "$userCache"; 059 060 /** The user population DAO */ 061 private UserPopulationDAO _userPopulationDAO; 062 063 /** The user directory factory */ 064 private UserDirectoryFactory _userDirectoryFactory; 065 066 private UserManager _userManager; 067 068 private Context _context; 069 070 @Override 071 public void service(ServiceManager smanager) throws ServiceException 072 { 073 _userManager = (UserManager) smanager.lookup(UserManager.ROLE); 074 _userPopulationDAO = (UserPopulationDAO) smanager.lookup(UserPopulationDAO.ROLE); 075 _userDirectoryFactory = (UserDirectoryFactory) smanager.lookup(UserDirectoryFactory.ROLE); 076 } 077 078 @Override 079 public void contextualize(Context context) throws ContextException 080 { 081 _context = context; 082 } 083 084 /** 085 * Get the user's full name handling request cache 086 * @param userIdentity The user identity 087 * @return user's full name or null if user does not exist 088 */ 089 public String getUserFullName (UserIdentity userIdentity) 090 { 091 User user = getUser(userIdentity); 092 return user != null ? user.getFullName() : null; 093 } 094 095 /** 096 * Get the user's sortable name handling request cache 097 * @param userIdentity The user identity 098 * @return user's full name or null if user does not exist 099 */ 100 public String getUserSortableName (UserIdentity userIdentity) 101 { 102 User user = getUser(userIdentity); 103 return user != null ? user.getSortableName() : null; 104 } 105 106 /** 107 * Populate a list of map, where each map representing an user. 108 * @param users The list of users 109 * @return The list of map. 110 */ 111 public List<Map<String, Object>> userIdentities2json(Collection<UserIdentity> users) 112 { 113 return users.stream().map(identity -> getUser(identity)).filter(Objects::nonNull).map(user -> user2json(user)).collect(Collectors.toList()); 114 } 115 116 117 /** 118 * Populate a list of map, where each map representing an user. 119 * @param users The list of users 120 * @return The list of map. 121 */ 122 public List<Map<String, Object>> users2json(Collection<User> users) 123 { 124 return users2json(users, false); 125 } 126 127 /** 128 * Populate a list of map, where each map representing an user. 129 * @param users The list of users 130 * @param full Set to <code>true</code> to get full information on user 131 * @return The list of map. 132 */ 133 public List<Map<String, Object>> users2json(Collection<User> users, boolean full) 134 { 135 List<Map<String, Object>> userList = new ArrayList<>(); 136 137 Set<User> distinctUsers = new HashSet<>(users); 138 for (User user : distinctUsers) 139 { 140 userList.add(user2json(user, full)); 141 } 142 143 return userList; 144 } 145 146 /** 147 * Get the JSON object representing a user 148 * @param userIdentity The user identity 149 * @return The user as JSON object 150 */ 151 public Map<String, Object> user2json (UserIdentity userIdentity) 152 { 153 return user2json(userIdentity, false); 154 } 155 156 /** 157 * Get the JSON object representing a user 158 * @param userIdentity The user identity 159 * @param full Set to <code>true</code> to get full information on user 160 * @return The user as JSON object 161 */ 162 public Map<String, Object> user2json (UserIdentity userIdentity, boolean full) 163 { 164 User user = getUser(userIdentity); 165 if (user != null) 166 { 167 return user2json(user, full); 168 } 169 return Collections.EMPTY_MAP; 170 } 171 172 /** 173 * Get the JSON object representing a user 174 * @param user The user 175 * @return The user as JSON object 176 */ 177 public Map<String, Object> user2json(User user) 178 { 179 return _user2json(user, false); 180 } 181 182 /** 183 * Get the JSON object representing a user 184 * @param user The user 185 * @param full Set to <code>true</code> to get full information on user 186 * @return The user as JSON object 187 */ 188 public Map<String, Object> user2json(User user, boolean full) 189 { 190 return _user2json(user, full); 191 } 192 193 private Map<String, Object> _user2json(User user, boolean full) 194 { 195 Map<String, Object> userInfos = new HashMap<>(); 196 197 userInfos.put("login", user.getIdentity().getLogin()); 198 199 String populationId = user.getIdentity().getPopulationId(); 200 userInfos.put("populationId", populationId); 201 202 userInfos.put("fullname", user.getFullName()); 203 userInfos.put("sortablename", user.getSortableName()); 204 205 if (full) 206 { 207 String udModelId = user.getUserDirectory() != null ? user.getUserDirectory().getUserDirectoryModelId() : ""; 208 209 userInfos.put("populationLabel", _userPopulationDAO.getUserPopulation(populationId).getLabel()); 210 userInfos.put("directory", _userDirectoryFactory.hasExtension(udModelId) ? _userDirectoryFactory.getExtension(udModelId).getLabel() : ""); 211 212 userInfos.put("lastname", user.getLastName()); 213 userInfos.put("firstname", user.getFirstName()); 214 userInfos.put("email", user.getEmail()); 215 } 216 217 return userInfos; 218 } 219 220 /** 221 * Get the user identity from a JSON object 222 * @param json the JSON object representing the user 223 * @return the user identity 224 */ 225 public UserIdentity json2userIdentity(Map<String, ? extends Object> json) 226 { 227 // If the user is empty, return null 228 return Optional.ofNullable(json) 229 .filter(u -> !u.isEmpty() && u.get("login") != null && u.get("populationId") != null) 230 .map(u -> new UserIdentity((String) u.get("login"), (String) u.get("populationId"))) 231 .orElse(null); 232 } 233 234 /** 235 * Get the user from its identity 236 * @param userIdentity The user identity 237 * @return The user or null if not found 238 */ 239 public User getUser (UserIdentity userIdentity) 240 { 241 if (userIdentity == null) 242 { 243 return null; 244 } 245 246 Request request = _getRequest(); 247 248 if (request != null) 249 { 250 // Try to get user from cache if request is not null 251 if (request.getAttribute(__USER_CACHE_REQUEST_ATTR) == null) 252 { 253 request.setAttribute(__USER_CACHE_REQUEST_ATTR, new HashMap<UserIdentity, User>()); 254 } 255 256 @SuppressWarnings("unchecked") 257 Map<UserIdentity, User> userCache = (Map<UserIdentity, User>) request.getAttribute(__USER_CACHE_REQUEST_ATTR); 258 259 User user = userCache.get(userIdentity); 260 if (user != null) 261 { 262 return user; 263 } 264 265 user = _userManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 266 if (user != null) 267 { 268 // Fill cache 269 userCache.put(userIdentity, user); 270 } 271 return user; 272 } 273 else 274 { 275 // Get user ouside of a request (no cache available) 276 return _userManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 277 } 278 } 279 280 private Request _getRequest() 281 { 282 try 283 { 284 return ContextHelper.getRequest(_context); 285 } 286 catch (Exception e) 287 { 288 // There is no request 289 return null; 290 } 291 } 292 293 /** 294 * SAX an user 295 * @param user The user 296 * @param handler The content handler 297 * @throws SAXException If a SAX error occurs 298 */ 299 public void saxUser(User user, ContentHandler handler) throws SAXException 300 { 301 saxUser(user, handler, "user"); 302 } 303 304 /** 305 * SAX an user 306 * @param user The user 307 * @param handler The content handler 308 * @param tagName The XML tag for saxed user 309 * @throws SAXException If a SAX error occurs 310 */ 311 public void saxUser(User user, ContentHandler handler, String tagName) throws SAXException 312 { 313 AttributesImpl attr = new AttributesImpl(); 314 attr.addCDATAAttribute("login", user.getIdentity().getLogin()); 315 attr.addCDATAAttribute("population", user.getIdentity().getPopulationId()); 316 317 XMLUtils.startElement(handler, tagName, attr); 318 319 XMLUtils.createElement(handler, "lastname", user.getLastName()); 320 XMLUtils.createElement(handler, "firstname", user.getFirstName()); 321 XMLUtils.createElement(handler, "email", user.getEmail()); 322 323 XMLUtils.createElement(handler, "fullname", user.getFullName()); 324 XMLUtils.createElement(handler, "sortablename", user.getSortableName()); 325 326 _userPopulationDAO.getUserPopulation(user.getIdentity().getPopulationId()).getLabel().toSAX(handler, "populationLabel"); 327 328 XMLUtils.endElement(handler, tagName); 329 } 330}