/** * Copyright (c) 2008-2010 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sakaiproject.profile2.logic; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import lombok.Setter; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.sakaiproject.api.common.edu.person.SakaiPerson; import org.sakaiproject.profile2.conversion.ProfileConverter; import org.sakaiproject.profile2.dao.ProfileDao; import org.sakaiproject.profile2.exception.ProfileNotDefinedException; import org.sakaiproject.profile2.hbm.model.ProfileImageExternal; import org.sakaiproject.profile2.hbm.model.ProfileImageUploaded; import org.sakaiproject.profile2.model.BasicPerson; import org.sakaiproject.profile2.model.CompanyProfile; import org.sakaiproject.profile2.model.Person; import org.sakaiproject.profile2.model.ProfilePrivacy; import org.sakaiproject.profile2.model.SocialNetworkingInfo; import org.sakaiproject.profile2.model.UserProfile; import org.sakaiproject.profile2.util.ProfileConstants; import org.sakaiproject.profile2.util.ProfileUtils; import org.sakaiproject.user.api.User; /** * Implementation of ProfileLogic for Profile2. * * @author Steve Swinsburg (s.swinsburg@lancaster.ac.uk) * */ public class ProfileLogicImpl implements ProfileLogic { private static final Logger log = Logger.getLogger(ProfileLogicImpl.class); /** * {@inheritDoc} */ public UserProfile getUserProfile(final String userUuid) { //check auth and get currentUserUuid String currentUserUuid = sakaiProxy.getCurrentUserId(); if(currentUserUuid == null) { throw new SecurityException("Must be logged in to get a UserProfile."); } //get User User u = sakaiProxy.getUserById(userUuid); if(u == null) { log.error("User " + userUuid + " does not exist."); return null; } //setup obj UserProfile p = new UserProfile(); p.setUserUuid(userUuid); p.setDisplayName(u.getDisplayName()); p.setImageUrl(imageLogic.getProfileImageEntityUrl(userUuid, ProfileConstants.PROFILE_IMAGE_MAIN)); p.setImageThumbUrl(imageLogic.getProfileImageEntityUrl(userUuid, ProfileConstants.PROFILE_IMAGE_THUMBNAIL)); //get SakaiPerson SakaiPerson sakaiPerson = sakaiProxy.getSakaiPerson(userUuid); if(sakaiPerson == null) { //no profile, return basic info only. return p; } //transform p = transformSakaiPersonToUserProfile(p, sakaiPerson); //if person requested own profile or superuser, no need for privacy checks //add the additional information and return if(userUuid.equals(currentUserUuid) || sakaiProxy.isSuperUser()) { p.setEmail(u.getEmail()); p.setStatus(statusLogic.getUserStatus(userUuid)); p.setSocialInfo(getSocialNetworkingInfo(userUuid)); p.setCompanyProfiles(getCompanyProfiles(userUuid)); return p; } //get privacy record ProfilePrivacy privacy = privacyLogic.getPrivacyRecordForUser(userUuid); //check friend status boolean friend = connectionsLogic.isUserXFriendOfUserY(userUuid, currentUserUuid); //REMOVE basic info if not allowed if(!privacyLogic.isUserXBasicInfoVisibleByUserY(userUuid, privacy, currentUserUuid, friend)) { p.setNickname(null); p.setDateOfBirth(null); p.setPersonalSummary(null); } //ADD email if allowed, REMOVE contact info if not if(privacyLogic.isUserXContactInfoVisibleByUserY(userUuid, privacy, currentUserUuid, friend)) { p.setEmail(u.getEmail()); } else { p.setEmail(null); p.setHomepage(null); p.setHomephone(null); p.setWorkphone(null); p.setMobilephone(null); p.setFacsimile(null); } //REMOVE staff info if not allowed if(!privacyLogic.isUserXStaffInfoVisibleByUserY(userUuid, privacy, currentUserUuid, friend)) { p.setDepartment(null); p.setPosition(null); p.setSchool(null); p.setRoom(null); p.setStaffProfile(null); p.setAcademicProfileUrl(null); p.setUniversityProfileUrl(null); p.setPublications(null); } //REMOVE student info if not allowed if(!privacyLogic.isUserXStudentInfoVisibleByUserY(userUuid, privacy, currentUserUuid, friend)) { p.setCourse(null); p.setSubjects(null); } //REMOVE personal info if not allowed if(!privacyLogic.isUserXPersonalInfoVisibleByUserY(userUuid, privacy, currentUserUuid, friend)) { p.setFavouriteBooks(null); p.setFavouriteTvShows(null); p.setFavouriteMovies(null); p.setFavouriteQuotes(null); } //ADD social networking info if allowed if(privacyLogic.isUserXSocialNetworkingInfoVisibleByUserY(userUuid, privacy, currentUserUuid, friend)) { p.setSocialInfo(getSocialNetworkingInfo(userUuid)); } //ADD company info if activated and allowed, REMOVE business bio if not if(sakaiProxy.isBusinessProfileEnabled()) { if(privacyLogic.isUserXBusinessInfoVisibleByUserY(userUuid, privacy, currentUserUuid, friend)) { p.setCompanyProfiles(getCompanyProfiles(userUuid)); } else { p.setBusinessBiography(null); } } else { p.setBusinessBiography(null); } //ADD profile status if allowed if(privacyLogic.isUserXStatusVisibleByUserY(userUuid, privacy, currentUserUuid, friend)) { p.setStatus(statusLogic.getUserStatus(userUuid)); } return p; } /** * {@inheritDoc} */ public boolean saveUserProfile(UserProfile p) { //TODO return false; } /** * {@inheritDoc} */ public boolean addNewCompanyProfile(final CompanyProfile companyProfile) { if(dao.addNewCompanyProfile(companyProfile)){ log.info("Added new company profile for user: " + companyProfile.getUserUuid()); return true; } return false; } /** * {@inheritDoc} */ public boolean updateCompanyProfile(final CompanyProfile companyProfile) { if(dao.updateCompanyProfile(companyProfile)){ log.info("Saved company profile for user: "+ companyProfile.getUserUuid()); return true; } return false; } /** * {@inheritDoc} */ public List<CompanyProfile> getCompanyProfiles(final String userId) { return dao.getCompanyProfiles(userId); } /** * {@inheritDoc} */ public boolean removeCompanyProfile(String userId, long companyProfileId) { if (userId == null || new Long(companyProfileId) == null) { throw new IllegalArgumentException("Null argument in ProfileLogicImpl.removeCompanyProfile()"); } CompanyProfile companyProfile = dao.getCompanyProfile(userId, companyProfileId); if (companyProfile == null) { log.error("CompanyProfile record does not exist for userId: "+ userId + ", companyProfileId: " + companyProfileId); return false; } if(dao.removeCompanyProfile(companyProfile)){ log.info("User: " + userId + " removed company profile: "+ companyProfileId); return true; } return false; } /** * {@inheritDoc} */ public SocialNetworkingInfo getSocialNetworkingInfo(final String userId) { if(userId == null){ throw new IllegalArgumentException("Null argument in ProfileLogic.getSocialNetworkingInfo"); } SocialNetworkingInfo socialNetworkingInfo = dao.getSocialNetworkingInfo(userId); if (null == socialNetworkingInfo) { socialNetworkingInfo = new SocialNetworkingInfo(userId); } return socialNetworkingInfo; } /** * {@inheritDoc} */ public boolean saveSocialNetworkingInfo(SocialNetworkingInfo socialNetworkingInfo) { if(dao.saveSocialNetworkingInfo(socialNetworkingInfo)) { log.info("Updated social networking info for user: " + socialNetworkingInfo.getUserUuid()); return true; } return false; } /** * {@inheritDoc} */ public List<Person> findUsersByNameOrEmail(String search) { List<User> users = new ArrayList<User>(); List<String> sakaiPersonUuids = new ArrayList<String>(); //add users from SakaiPerson (clean list) sakaiPersonUuids = dao.findSakaiPersonsByNameOrEmail(search); users.addAll(sakaiProxy.getUsers(sakaiPersonUuids)); //add local users from UserDirectoryService users.addAll(sakaiProxy.searchUsers(search)); //add external users from UserDirectoryService users.addAll(sakaiProxy.searchExternalUsers(search)); //remove duplicates ProfileUtils.removeDuplicates(users); log.debug("Found " + users.size() + " results for search: " + search); //restrict to only return the max number. UI will print message int maxResults = sakaiProxy.getMaxSearchResults(); if(users.size() >= maxResults) { users = users.subList(0, maxResults); } //remove invisible users = removeInvisibleUsers(users); return getPersons(users); } /** * {@inheritDoc} */ public List<Person> findUsersByInterest(String search) { List<User> users = new ArrayList<User>(); List<String> sakaiPersonUuids = new ArrayList<String>(); //add users from SakaiPerson sakaiPersonUuids = dao.findSakaiPersonsByInterest(search); users.addAll(sakaiProxy.getUsers(sakaiPersonUuids)); //restrict to only return the max number. UI will print message int maxResults = sakaiProxy.getMaxSearchResults(); if(users.size() >= maxResults) { users = users.subList(0, maxResults); } //remove invisible users = removeInvisibleUsers(users); return getPersons(users); } /** * {@inheritDoc} */ public BasicPerson getBasicPerson(String userUuid) { return getBasicPerson(sakaiProxy.getUserById(userUuid)); } /** * {@inheritDoc} */ public BasicPerson getBasicPerson(User user) { BasicPerson p = new BasicPerson(); p.setUuid(user.getId()); p.setDisplayName(user.getDisplayName()); p.setType(user.getType()); return p; } /** * {@inheritDoc} */ public List<BasicPerson> getBasicPersons(List<User> users) { List<BasicPerson> list = new ArrayList<BasicPerson>(); for(User u:users){ list.add(getBasicPerson(u)); } return list; } /** * {@inheritDoc} */ public Person getPerson(String userUuid) { return getPerson(sakaiProxy.getUserById(userUuid)); } /** * {@inheritDoc} */ public Person getPerson(User user) { //catch for non existent user if(user == null){ return null; } Person p = new Person(); String userUuid = user.getId(); p.setUuid(userUuid); p.setDisplayName(user.getDisplayName()); p.setType(user.getType()); p.setPreferences(preferencesLogic.getPreferencesRecordForUser(userUuid)); p.setPrivacy(privacyLogic.getPrivacyRecordForUser(userUuid)); p.setProfile(getUserProfile(userUuid)); return p; } /** * {@inheritDoc} */ public List<Person> getPersons(List<User> users) { List<Person> list = new ArrayList<Person>(); for(User u:users){ list.add(getPerson(u)); } return list; } /** * {@inheritDoc} */ public List<String> getAllSakaiPersonIds() { return dao.getAllSakaiPersonIds(); } /** * {@inheritDoc} */ public int getAllSakaiPersonIdsCount() { return dao.getAllSakaiPersonIdsCount(); } //service init public void init() { log.info("Profile2: init()"); //do we need to run the image conversion utility? if(sakaiProxy.isProfileConversionEnabled()) { //run the profile image converter converter.convertProfileImages(); } //do we need to import profiles? if(sakaiProxy.isProfileImportEnabled()) { String csv = sakaiProxy.getProfileImportCsvPath(); //run the profile importer converter.importProfiles(csv); } } /** * Remove invisible users from the list * @param users * @return cleaned list */ private List<User> removeInvisibleUsers(List<User> users){ //if superuser return list unchanged. if(sakaiProxy.isSuperUser()){ return users; } //get list of invisible users as Users List<User> invisibleUsers = sakaiProxy.getUsers(sakaiProxy.getInvisibleUsers()); if(invisibleUsers.isEmpty()) { return users; } //remove users.removeAll(invisibleUsers); return users; } /** * Convenience method to map a SakaiPerson object onto a UserProfile object * * @param sp input SakaiPerson * @return returns a UserProfile representation of the SakaiPerson object */ private UserProfile transformSakaiPersonToUserProfile(UserProfile p, SakaiPerson sp) { //map fields from SakaiPerson to UserProfile //basic info p.setNickname(sp.getNickname()); p.setDateOfBirth(sp.getDateOfBirth()); p.setPersonalSummary(sp.getNotes()); //contact info p.setHomepage(sp.getLabeledURI()); p.setWorkphone(sp.getTelephoneNumber()); p.setHomephone(sp.getHomePhone()); p.setMobilephone(sp.getMobile()); p.setFacsimile(sp.getFacsimileTelephoneNumber()); //staff info p.setDepartment(sp.getOrganizationalUnit()); p.setPosition(sp.getTitle()); p.setSchool(sp.getCampus()); p.setRoom(sp.getRoomNumber()); p.setStaffProfile(sp.getStaffProfile()); p.setAcademicProfileUrl(sp.getAcademicProfileUrl()); p.setUniversityProfileUrl(sp.getUniversityProfileUrl()); p.setPublications(sp.getPublications()); //student info p.setCourse(sp.getEducationCourse()); p.setSubjects(sp.getEducationSubjects()); //personal info p.setFavouriteBooks(sp.getFavouriteBooks()); p.setFavouriteTvShows(sp.getFavouriteTvShows()); p.setFavouriteMovies(sp.getFavouriteMovies()); p.setFavouriteQuotes(sp.getFavouriteQuotes()); //business info p.setBusinessBiography(sp.getBusinessBiography()); return p; } private SakaiProxy sakaiProxy; public void setSakaiProxy(SakaiProxy sakaiProxy) { this.sakaiProxy = sakaiProxy; } private ProfileDao dao; public void setDao(ProfileDao dao) { this.dao = dao; } private ProfilePreferencesLogic preferencesLogic; public void setPreferencesLogic(ProfilePreferencesLogic preferencesLogic) { this.preferencesLogic = preferencesLogic; } private ProfileStatusLogic statusLogic; public void setStatusLogic(ProfileStatusLogic statusLogic) { this.statusLogic = statusLogic; } private ProfilePrivacyLogic privacyLogic; public void setPrivacyLogic(ProfilePrivacyLogic privacyLogic) { this.privacyLogic = privacyLogic; } private ProfileConnectionsLogic connectionsLogic; public void setConnectionsLogic(ProfileConnectionsLogic connectionsLogic) { this.connectionsLogic = connectionsLogic; } private ProfileImageLogic imageLogic; public void setImageLogic(ProfileImageLogic imageLogic) { this.imageLogic = imageLogic; } @Setter private ProfileConverter converter; }