001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/profile/tags/sakai_2-4-1/profile-component-shared/src/java/org/sakaiproject/component/app/profile/ProfileManagerImpl.java $
003: * $Id: ProfileManagerImpl.java 22197 2007-03-05 21:10:05Z gjthomas@iupui.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.component.app.profile;
021:
022: import java.util.ArrayList;
023: import java.util.HashMap;
024: import java.util.HashSet;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028: import java.util.Set;
029: import java.util.Map.Entry;
030:
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033: import org.sakaiproject.api.app.profile.Profile;
034: import org.sakaiproject.api.app.profile.ProfileManager;
035: import org.sakaiproject.api.common.edu.person.SakaiPerson;
036: import org.sakaiproject.api.common.edu.person.SakaiPersonManager;
037: import org.sakaiproject.authz.api.AuthzGroup;
038: import org.sakaiproject.authz.api.GroupNotDefinedException;
039: import org.sakaiproject.authz.cover.AuthzGroupService;
040: import org.sakaiproject.authz.cover.SecurityService;
041: import org.sakaiproject.site.cover.SiteService;
042: import org.sakaiproject.tool.api.Placement;
043: import org.sakaiproject.tool.cover.SessionManager;
044: import org.sakaiproject.tool.cover.ToolManager;
045: import org.sakaiproject.user.api.User;
046: import org.sakaiproject.user.api.UserDirectoryService;
047: import org.sakaiproject.user.api.UserNotDefinedException;
048: import org.sakaiproject.component.cover.ServerConfigurationService;
049:
050: /**
051: * @author rshastri
052: */
053: public class ProfileManagerImpl implements ProfileManager {
054: private static final Log LOG = LogFactory
055: .getLog(ProfileManagerImpl.class);
056:
057: /** Dependency: SakaiPersonManager */
058: private SakaiPersonManager sakaiPersonManager;
059:
060: /** Dependency: userDirectoryService */
061: private UserDirectoryService userDirectoryService;
062:
063: private static final String ANONYMOUS = "Anonymous";
064:
065: public void init() {
066: LOG.debug("init()"); // do nothing (for now)
067: }
068:
069: public void destroy() {
070: LOG.debug("destroy()"); // do nothing (for now)
071: }
072:
073: /**
074: * @see org.sakaiproject.api.app.profile.ProfileManager#getProfile()
075: */
076: public Profile getProfile() {
077: LOG.debug("getProfile()");
078:
079: return getProfileById(getCurrentUserId());
080: }
081:
082: public Map<String, Profile> getProfiles(Set<String> userIds) {
083: LOG.debug("getProfiles()");
084: return findProfiles(userIds);
085: }
086:
087: /**
088: * @see org.sakaiproject.api.app.profile.ProfileManager#findProfiles(java.lang.String) Returns userMutable profiles only
089: */
090: public List findProfiles(String searchString) {
091: if (LOG.isDebugEnabled()) {
092: LOG.debug("findProfiles(" + searchString + ")");
093: }
094: if (searchString == null || searchString.length() < 1)
095: throw new IllegalArgumentException(
096: "Illegal searchString argument passed!");
097:
098: List profiles = sakaiPersonManager
099: .findSakaiPerson(searchString);
100: List searchResults = new ArrayList();
101: Profile profile;
102:
103: if ((profiles != null) && (profiles.size() > 0)) {
104: Iterator profileIterator = profiles.iterator();
105:
106: while (profileIterator.hasNext()) {
107: profile = new ProfileImpl((SakaiPerson) profileIterator
108: .next());
109:
110: // Select the user mutable profile for display on if the public information is viewable.
111: if ((profile != null)
112: && profile.getSakaiPerson().getTypeUuid()
113: .equals(
114: sakaiPersonManager
115: .getUserMutableType()
116: .getUuid())) {
117: if ((getCurrentUserId().equals(profile.getUserId()) || SecurityService
118: .isSuperUser())) {
119: // allow user to search and view own profile and superuser to view all profiles
120: searchResults.add(profile);
121: } else if ((profile.getHidePublicInfo() != null)
122: && (profile.getHidePublicInfo()
123: .booleanValue() != true)) {
124: if (profile.getHidePrivateInfo() != null
125: && profile.getHidePrivateInfo()
126: .booleanValue() != true) {
127: searchResults.add(profile);
128: } else {
129: searchResults
130: .add(getOnlyPublicProfile(profile));
131: }
132:
133: }
134: }
135:
136: }
137: }
138:
139: return searchResults;
140: }
141:
142: /**
143: * @see org.sakaiproject.api.app.profile.ProfileManager#save(org.sakaiproject.api.app.profile.Profile)
144: */
145: public void save(Profile profile) {
146: if (LOG.isDebugEnabled()) {
147: LOG.debug("save(" + profile + ")");
148: }
149: if (profile == null)
150: throw new IllegalArgumentException(
151: "Illegal profile argument passed!");
152:
153: sakaiPersonManager.save(profile.getSakaiPerson());
154: }
155:
156: /**
157: * @param sakaiPersonManager
158: */
159: public void setSakaiPersonManager(
160: SakaiPersonManager sakaiPersonManager) {
161: if (LOG.isDebugEnabled()) {
162: LOG.debug("setSakaiPersonManager(SakaiPersonManager "
163: + sakaiPersonManager + ")");
164: }
165:
166: this .sakaiPersonManager = sakaiPersonManager;
167: }
168:
169: /**
170: * @param userDirectoryService
171: * The userDirectoryService to set.
172: */
173: public void setUserDirectoryService(
174: UserDirectoryService userDirectoryService) {
175: if (LOG.isDebugEnabled()) {
176: LOG.debug("setUserDirectoryService(userDirectoryService "
177: + userDirectoryService + ")");
178: }
179:
180: this .userDirectoryService = userDirectoryService;
181: }
182:
183: /*
184: * (non-Javadoc)
185: *
186: * @see org.sakaiproject.api.app.profile.ProfileManager#getInstitutionalPhotoByUserId(java.lang.String)
187: */
188: public byte[] getInstitutionalPhotoByUserId(String uid) {
189: if (LOG.isDebugEnabled()) {
190: LOG.debug("getInstitutionalPhotoByUserId(String " + uid
191: + ")");
192: }
193: return getInstitutionalPhoto(uid, false);
194:
195: }
196:
197: public byte[] getInstitutionalPhotoByUserId(String uid,
198: boolean siteMaintainer) {
199: if (LOG.isDebugEnabled()) {
200: LOG.debug("getInstitutionalPhotoByUserId(String" + uid
201: + ", boolean " + siteMaintainer + ")");
202: }
203: return getInstitutionalPhoto(uid, true);
204: }
205:
206: /*
207: * (non-Javadoc)
208: *
209: * @see org.sakaiproject.api.app.profile.ProfileManager#getUserProfileById(java.lang.String)
210: */
211: public Profile getUserProfileById(String id) {
212: if (LOG.isDebugEnabled()) {
213: LOG.debug("getUserProfileById(String" + id + ")");
214: }
215: SakaiPerson sakaiPerson = sakaiPersonManager.getSakaiPerson(id,
216: sakaiPersonManager.getUserMutableType());
217: if (sakaiPerson == null) {
218: return null;
219: }
220: return new ProfileImpl(sakaiPerson);
221: }
222:
223: public boolean displayCompleteProfile(Profile profile) {
224: if (LOG.isDebugEnabled()) {
225: LOG.debug("displayCompleteProfile(Profile" + profile + ")");
226: }
227: // complete profile visble to Owner and superUser
228: if (profile == null) {
229: return false;
230: }
231: if ((isCurrentUserProfile(profile) || SecurityService
232: .isSuperUser())) {
233: return true;
234: } else if (profile.getHidePrivateInfo() == null) {
235: return false;
236: }
237: if (profile.getHidePublicInfo() == null) {
238: return false;
239: }
240: if (profile.getHidePrivateInfo().booleanValue() != true
241: && profile.getHidePublicInfo().booleanValue() != true) {
242: return true;
243: } else {
244: return false;
245: }
246: }
247:
248: /*
249: * (non-Javadoc)
250: *
251: * @see org.sakaiproject.api.app.profile.ProfileManager#isCurrentUserProfile(org.sakaiproject.api.app.profile.Profile)
252: */
253: public boolean isCurrentUserProfile(Profile profile) {
254: if (LOG.isDebugEnabled()) {
255: LOG.debug("isCurrentUserProfile(Profile" + profile + ")");
256: }
257: return ((profile != null) && profile.getUserId().equals(
258: getCurrentUserId()));
259: }
260:
261: /*
262: * (non-Javadoc)
263: *
264: * @see org.sakaiproject.api.app.profile.ProfileManager#isDisplayPictureURL(org.sakaiproject.api.app.profile.Profile)
265: */
266: public boolean isDisplayPictureURL(Profile profile) {
267: if (LOG.isDebugEnabled()) {
268: LOG.debug("isDisplayPictureURL(Profile" + profile + ")");
269: }
270: return (profile != null
271: && displayCompleteProfile(profile)
272: && (profile.isInstitutionalPictureIdPreferred() == null || profile
273: .isInstitutionalPictureIdPreferred()
274: .booleanValue() != true)
275: && profile.getPictureUrl() != null && profile
276: .getPictureUrl().trim().length() > 0);
277: }
278:
279: /*
280: * (non-Javadoc)
281: *
282: * @see org.sakaiproject.api.app.profile.ProfileManager#isDisplayUniversityPhoto(org.sakaiproject.api.app.profile.Profile)
283: */
284: public boolean isDisplayUniversityPhoto(Profile profile) {
285: if (LOG.isDebugEnabled()) {
286: LOG.debug("isDisplayUniversityPhoto(Profile" + profile
287: + ")");
288: }
289: return (profile != null
290: && displayCompleteProfile(profile)
291: && profile.isInstitutionalPictureIdPreferred() != null
292: && profile.isInstitutionalPictureIdPreferred()
293: .booleanValue() == true
294: && getInstitutionalPhotoByUserId(profile.getUserId()) != null && getInstitutionalPhotoByUserId(profile
295: .getUserId()).length > 0);
296: }
297:
298: /*
299: * (non-Javadoc)
300: *
301: * @see org.sakaiproject.api.app.profile.ProfileManager#isDisplayUniversityPhotoUnavailable(org.sakaiproject.api.app.profile.Profile)
302: */
303: public boolean isDisplayUniversityPhotoUnavailable(Profile profile) {
304: if (LOG.isDebugEnabled()) {
305: LOG.debug("isDisplayUniversityPhotoUnavailable(Profile"
306: + profile + ")");
307: }
308: return (profile != null
309: && displayCompleteProfile(profile)
310: && profile.isInstitutionalPictureIdPreferred() != null
311: && profile.isInstitutionalPictureIdPreferred()
312: .booleanValue() == true
313: && getInstitutionalPhotoByUserId(profile.getUserId()) == null && (getInstitutionalPhotoByUserId(profile
314: .getUserId()) == null || getInstitutionalPhotoByUserId(profile
315: .getUserId()).length < 1));
316: }
317:
318: /*
319: * (non-Javadoc)
320: *
321: * @see org.sakaiproject.api.app.profile.ProfileManager#isDisplayNoPhoto(org.sakaiproject.api.app.profile.Profile)
322: */
323: public boolean isDisplayNoPhoto(Profile profile) {
324: if (LOG.isDebugEnabled()) {
325: LOG.debug("isDisplayNoPhoto(Profile" + profile + ")");
326: }
327: return (profile == null || !displayCompleteProfile(profile) || (profile
328: .isInstitutionalPictureIdPreferred() == null || (profile
329: .isInstitutionalPictureIdPreferred().booleanValue() != true && (profile
330: .getPictureUrl() == null || profile.getPictureUrl()
331: .trim().length() < 1))));
332: }
333:
334: /*
335: * (non-Javadoc)
336: *
337: * @see org.sakaiproject.api.app.profile.ProfileManager#isShowProfileTool(org.sakaiproject.api.app.profile.Profile)
338: */
339: public boolean isShowTool() {
340: LOG.debug("isShowTool()");
341: Profile profile = getProfile();
342:
343: // implement isAnonymous later on.
344: return (profile.getUserId() != ANONYMOUS && profile.getUserId()
345: .equalsIgnoreCase(getCurrentUserId()));
346: }
347:
348: public boolean isShowSearch() {
349: LOG.debug("isShowSearch()");
350: Profile profile = getProfile();
351: // implement isAnonymous later on.
352: if (!"false"
353: .equalsIgnoreCase(ServerConfigurationService
354: .getString("separateIdEid@org.sakaiproject.user.api.UserDirectoryService"))) {
355: return (profile.getUserId() != ANONYMOUS && isSiteMember(profile
356: .getSakaiPerson().getAgentUuid()));
357: }
358: return (profile.getUserId() != ANONYMOUS && isSiteMember(profile
359: .getUserId()));
360: }
361:
362: private Profile getOnlyPublicProfile(Profile profile) {
363: if (LOG.isDebugEnabled()) {
364: LOG.debug("getOnlyPublicProfile(Profile" + profile + ")");
365: }
366: profile.getSakaiPerson().setJpegPhoto(null);
367: profile.setPictureUrl(null);
368: profile.setEmail(null);
369: profile.setHomepage(null);
370: profile.setHomePhone(null);
371: profile.setOtherInformation(null);
372: return profile;
373: }
374:
375: /**
376: * Get the id photo if the profile member is site member and the requestor is either site maintainter or user or superuser.
377: *
378: * @param userId
379: * @param siteMaintainer
380: * @return
381: */
382: private byte[] getInstitutionalPhoto(String userId,
383: boolean siteMaintainer) {
384: if (LOG.isDebugEnabled()) {
385: LOG.debug("getInstitutionalPhotoByUserId(" + userId + ")");
386: }
387: if (userId == null || userId.length() < 1)
388: throw new IllegalArgumentException(
389: "Illegal userId argument passed!");
390:
391: SakaiPerson sakaiSystemPerson = sakaiPersonManager
392: .getSakaiPerson(userId, sakaiPersonManager
393: .getSystemMutableType());
394: SakaiPerson sakaiPerson = sakaiPersonManager.getSakaiPerson(
395: userId, sakaiPersonManager.getUserMutableType());
396: Profile profile = null;
397:
398: if ((sakaiSystemPerson != null)) {
399: Profile systemProfile = new ProfileImpl(sakaiSystemPerson);
400: // Fetch current users institutional photo for either the user or super user
401: if (getCurrentUserId().equals(userId)
402: || SecurityService.isSuperUser()
403: || (siteMaintainer
404: && doesCurrentUserHaveUpdateAccessToSite() && isSiteMember(userId))) {
405: if (LOG.isDebugEnabled())
406: LOG.debug("Official Photo fetched for userId "
407: + userId);
408: return systemProfile.getInstitutionalPicture();
409: }
410:
411: // if the public information && private information is viewable and user uses to display institutional picture id.
412: if (sakaiPerson != null) {
413: profile = new ProfileImpl(sakaiPerson);
414: if (sakaiPerson != null
415: && (profile.getHidePublicInfo() != null)
416: && (profile.getHidePublicInfo().booleanValue() == false)
417: && profile.getHidePrivateInfo() != null
418: && profile.getHidePrivateInfo().booleanValue() == false
419: && profile.isInstitutionalPictureIdPreferred() != null
420: && profile.isInstitutionalPictureIdPreferred()
421: .booleanValue() == true) {
422: if (LOG.isDebugEnabled())
423: LOG.debug("Official Photo fetched for userId "
424: + userId);
425: return systemProfile.getInstitutionalPicture();
426: }
427:
428: }
429: }
430: return null;
431: }
432:
433: /**
434: * @param uid
435: * @return
436: */
437: private boolean isSiteMember(String uid) {
438: if (LOG.isDebugEnabled()) {
439: LOG.debug("isSiteMember(String" + uid + ")");
440: }
441: try {
442: AuthzGroupService.isAllowed(uid, "site.visit",
443: getCurrentSiteId());
444: } catch (Exception e) {
445: LOG.error("Exception:", e);
446: }
447: return false;
448: }
449:
450: /**
451: * @return
452: */
453: private String getCurrentSiteId() {
454: LOG.debug("getCurrentSiteId()");
455: Placement placement = ToolManager.getCurrentPlacement();
456: return placement.getContext();
457: }
458:
459: /**
460: * @return
461: */
462: private boolean doesCurrentUserHaveUpdateAccessToSite() {
463: LOG.debug("doesCurrentUserHaveUpdateAccessToSite()");
464: try {
465: // If the current site is not my workspace of the user and has update access to the site
466:
467: return (SiteService.allowUpdateSite(getCurrentSiteId()) && !SiteService
468: .isUserSite(getCurrentSiteId()));
469: } catch (Exception e) {
470: LOG.error(e.getMessage(), e);
471: }
472:
473: return false;
474: }
475:
476: /**
477: * @param id
478: * @return
479: */
480: private Profile getProfileById(String id) {
481: Set<String> userIds = new HashSet<String>();
482: userIds.add(id);
483: Map<String, Profile> profiles = findProfiles(userIds);
484: return profiles.get(id);
485: }
486:
487: private Map<String, Profile> findProfiles(Set<String> userIds) {
488: Map<String, Profile> profiles = new HashMap<String, Profile>();
489: Map<String, SakaiPerson> sakaiPeople = sakaiPersonManager
490: .getSakaiPersons(userIds, sakaiPersonManager
491: .getUserMutableType());
492:
493: for (Iterator<String> iter = userIds.iterator(); iter.hasNext();) {
494: String userId = iter.next();
495: if (userId == null || userId.length() < 1) {
496: LOG.info("Illegal uid argument passed: userId="
497: + userId);
498: continue;
499: }
500: SakaiPerson sakaiPerson = sakaiPeople.get(userId);
501:
502: if ((userId != null) && (userId.trim().length() > 0)) {
503: try {
504: User user = userDirectoryService.getUser(userId);
505:
506: if (sakaiPerson == null) {
507: LOG.info("Could not find a sakaiPerson for id="
508: + user.getId() + ", eid="
509: + user.getEid());
510: sakaiPerson = sakaiPersonManager.create(user
511: .getId(), sakaiPersonManager
512: .getUserMutableType());
513: sakaiPeople.put(user.getId(), sakaiPerson);
514: }
515: } catch (UserNotDefinedException e) {
516: // TODO: how to handle this use case with UserDirectoryService? name? email? password? Why even do it? -ggolden
517: // User user = userDirectoryService.addUser(sessionManagerUserId, "", sessionManagerUserId, "", "", "", null);
518:
519: sakaiPerson = sakaiPersonManager.create(userId,
520: sakaiPersonManager.getUserMutableType());
521: }
522: }
523: profiles.put(userId, new ProfileImpl(sakaiPerson));
524: }
525:
526: if (LOG.isDebugEnabled())
527: LOG.debug("Returning profiles for "
528: + profiles.keySet().size() + " users");
529: return profiles;
530: }
531:
532: /**
533: * @return
534: */
535: private String getCurrentUserId() {
536: LOG.debug("getCurrentUser()");
537: return SessionManager.getCurrentSession().getUserId();
538: }
539: }
|