Java tutorial
/** * Copyright (c) 2008-2012 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.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.Collections; import java.util.List; import lombok.Setter; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.sakaiproject.profile2.dao.ProfileDao; import org.sakaiproject.profile2.hbm.model.ProfileImageExternal; import org.sakaiproject.profile2.hbm.model.ProfileImageOfficial; import org.sakaiproject.profile2.hbm.model.ProfileImageUploaded; import org.sakaiproject.profile2.model.GalleryImage; import org.sakaiproject.profile2.model.MimeTypeByteArray; import org.sakaiproject.profile2.model.Person; import org.sakaiproject.profile2.model.ProfileImage; import org.sakaiproject.profile2.model.ProfilePreferences; import org.sakaiproject.profile2.model.ProfilePrivacy; import org.sakaiproject.profile2.types.PrivacyType; import org.sakaiproject.profile2.util.Messages; import org.sakaiproject.profile2.util.ProfileConstants; import org.sakaiproject.profile2.util.ProfileUtils; import org.sakaiproject.user.api.User; import org.sakaiproject.user.api.UserNotDefinedException; /** * Implementation of ProfileImageLogic API * * @author Steve Swinsburg (steve.swinsburg@gmail.com) * */ public class ProfileImageLogicImpl implements ProfileImageLogic { private static final Logger log = Logger.getLogger(ProfileImageLogicImpl.class); /** * {@inheritDoc} */ public ProfileImage getBlankProfileImage() { ProfileImage profileImage = new ProfileImage(); profileImage.setExternalImageUrl(getUnavailableImageURL()); profileImage.setDefault(true); return profileImage; } /** * {@inheritDoc} */ public ProfileImage getProfileImage(String userUuid, ProfilePreferences prefs, ProfilePrivacy privacy, int size) { return getProfileImage(userUuid, prefs, privacy, size, null); } /** * {@inheritDoc} */ public ProfileImage getOfficialProfileImage(String userUuid, String siteId) { ProfileImage profileImage = new ProfileImage(); profileImage.setDefault(false); //will be overridden if required String currentUserId = sakaiProxy.getCurrentUserId(); String defaultImageUrl = getUnavailableImageURL(); //check permissions. if not allowed, set default and return if (!sakaiProxy.isUserMyWorkspace(siteId)) { log.debug("checking if user: " + currentUserId + " has permissions in site: " + siteId); if (!sakaiProxy.isUserAllowedInSite(currentUserId, ProfileConstants.ROSTER_VIEW_PHOTO, siteId)) { profileImage.setExternalImageUrl(defaultImageUrl); profileImage.setDefault(true); return profileImage; } } //otherwise get official image return getOfficialImage(userUuid, profileImage, defaultImageUrl, StringUtils.equals(userUuid, currentUserId)); } /** * {@inheritDoc} */ public ProfileImage getProfileImage(String userUuid, ProfilePreferences prefs, ProfilePrivacy privacy, int size, String siteId) { ProfileImage image = new ProfileImage(); boolean allowed = false; boolean isSameUser = false; image.setDefault(false); //will be overridden if it is actually a default image String defaultImageUrl; if (ProfileConstants.PROFILE_IMAGE_THUMBNAIL == size) { defaultImageUrl = getUnavailableImageThumbnailURL(); } else { defaultImageUrl = getUnavailableImageURL(); } //get current user String currentUserUuid = sakaiProxy.getCurrentUserId(); if (StringUtils.equals(userUuid, currentUserUuid)) { isSameUser = true; } //if no current user we are not logged in (could be from entity provider) if (StringUtils.isBlank(currentUserUuid)) { // this is where the logic for handling public profile images will go //right now we throw a security exception. throw new SecurityException("Must be logged in to request a profile image."); } //check prefs supplied was valid, if given if (prefs != null && !StringUtils.equals(userUuid, prefs.getUserUuid())) { log.error("ProfilePreferences data supplied was not for user: " + userUuid); image.setExternalImageUrl(defaultImageUrl); image.setAltText(getAltText(userUuid, isSameUser, false)); image.setDefault(true); return image; } //check privacy supplied was valid, if given if (privacy != null && !StringUtils.equals(userUuid, privacy.getUserUuid())) { log.error("ProfilePrivacy data supplied was not for user: " + userUuid); image.setExternalImageUrl(defaultImageUrl); image.setAltText(getAltText(userUuid, isSameUser, false)); image.setDefault(true); return image; } //check if same user if (isSameUser) { allowed = true; } //if we have a siteId and it's not a my workspace site, check if the current user has permissions to view the image if (StringUtils.isNotBlank(siteId)) { if (!sakaiProxy.isUserMyWorkspace(siteId)) { log.debug("checking if user: " + currentUserUuid + " has permissions in site: " + siteId); allowed = sakaiProxy.isUserAllowedInSite(currentUserUuid, ProfileConstants.ROSTER_VIEW_PHOTO, siteId); } } //if not allowed yet, check we have a privacy record, if not, get one if (!allowed && privacy == null) { privacy = privacyLogic.getPrivacyRecordForUser(userUuid); //if still null, default image if (privacy == null) { log.error("Couldn't retrieve ProfilePrivacy data for user: " + userUuid + ". Using default image."); image.setExternalImageUrl(defaultImageUrl); image.setAltText(getAltText(userUuid, isSameUser, false)); image.setDefault(true); return image; } } //if not allowed, check privacy record if (!allowed) { allowed = privacyLogic.isActionAllowed(userUuid, currentUserUuid, PrivacyType.PRIVACY_OPTION_PROFILEIMAGE); } //default if still not allowed if (!allowed) { image.setExternalImageUrl(defaultImageUrl); image.setAltText(getAltText(userUuid, isSameUser, false)); image.setDefault(true); return image; } //check if we have an image for this user type (if enabled) //if we have one, return it. otherwise continue to the rest of the checks. String userTypeImageUrl = getUserTypeImageUrl(userUuid); if (StringUtils.isNotBlank(userTypeImageUrl)) { image.setExternalImageUrl(userTypeImageUrl); image.setAltText(getAltText(userUuid, isSameUser, true)); return image; } //lookup global image setting, this will be used if no preferences were supplied. int imageType = sakaiProxy.getProfilePictureType(); //if we have no prefs, try to get one, it won't be considered if it is still null. if (prefs == null) { prefs = preferencesLogic.getPreferencesRecordForUser(userUuid); } //if we have prefs and the conditions are set for a user to be able to make a choice, get the pref. if (prefs != null && sakaiProxy.isUsingOfficialImageButAlternateSelectionEnabled()) { if (prefs.isUseOfficialImage()) { imageType = ProfileConstants.PICTURE_SETTING_OFFICIAL; } } //prefs for gravatar, only if enabled if (prefs != null && sakaiProxy.isGravatarImageEnabledGlobally()) { if (prefs.isUseGravatar()) { imageType = ProfileConstants.PICTURE_SETTING_GRAVATAR; } } if (log.isDebugEnabled()) { log.debug("image type: " + imageType); log.debug("size requested: " + size); } //get the image based on the global type/preference switch (imageType) { case ProfileConstants.PICTURE_SETTING_UPLOAD: MimeTypeByteArray mtba = getUploadedProfileImage(userUuid, size); //if no uploaded image, use the default image url if (mtba == null || mtba.getBytes() == null) { image.setExternalImageUrl(defaultImageUrl); image.setDefault(true); } else { image.setUploadedImage(mtba.getBytes()); image.setMimeType(mtba.getMimeType()); } image.setAltText(getAltText(userUuid, isSameUser, true)); break; case ProfileConstants.PICTURE_SETTING_URL: image.setExternalImageUrl(getExternalProfileImageUrl(userUuid, size)); if (StringUtils.equals(image.getExternalImageUrl(), defaultImageUrl)) { image.setDefault(true); } image.setAltText(getAltText(userUuid, isSameUser, true)); break; case ProfileConstants.PICTURE_SETTING_OFFICIAL: image = getOfficialImage(userUuid, image, defaultImageUrl, isSameUser); break; case ProfileConstants.PICTURE_SETTING_GRAVATAR: String gravatarUrl = getGravatarUrl(userUuid); if (StringUtils.isBlank(gravatarUrl)) { image.setExternalImageUrl(defaultImageUrl); image.setAltText(getAltText(userUuid, isSameUser, false)); image.setDefault(true); } else { image.setExternalImageUrl(gravatarUrl); image.setAltText(getAltText(userUuid, isSameUser, true)); } break; default: image.setExternalImageUrl(defaultImageUrl); image.setAltText(getAltText(userUuid, isSameUser, false)); image.setDefault(true); break; } return image; } /** * Gets the official image from url, ldap or filesystem, depending on what is specified in props. Filesystem photos * are looked up by appending the first letter of a user's eid, then a slash, then the second letter of the eid * followed by a slash and finally the eid suffixed by '.jpg'. * * Like this: * /official-photos/a/d/adrian.jpg */ private ProfileImage getOfficialImage(String userUuid, ProfileImage image, String defaultImageUrl, boolean isSameUser) { String officialImageSource = sakaiProxy.getOfficialImageSource(); log.debug( "Fetching official image. userUuid: " + userUuid + ", officialImageSource: " + officialImageSource); //check source and get appropriate value if (StringUtils.equals(officialImageSource, ProfileConstants.OFFICIAL_IMAGE_SETTING_URL)) { image.setOfficialImageUrl(getOfficialImageUrl(userUuid)); //PRFL-790 if URL security is required, get and set bytes and remove url boolean urlSecurityEnabled = Boolean.valueOf( sakaiProxy.getServerConfigurationParameter("profile2.official.image.url.secure", "false")); if (urlSecurityEnabled && StringUtils.isNotBlank(image.getOfficialImageUrl())) { log.debug("URL Security is active"); byte[] imageUrlBytes = this.getUrlAsBytes(image.getOfficialImageUrl()); image.setUploadedImage(imageUrlBytes); image.setOfficialImageUrl(null); } } else if (StringUtils.equals(officialImageSource, ProfileConstants.OFFICIAL_IMAGE_SETTING_PROVIDER)) { String data = getOfficialImageEncoded(userUuid); if (StringUtils.isBlank(data)) { image.setExternalImageUrl(defaultImageUrl); image.setDefault(true); } else { image.setOfficialImageEncoded(data); } } else if (StringUtils.equals(officialImageSource, ProfileConstants.OFFICIAL_IMAGE_SETTING_FILESYSTEM)) { //get the path based on the config from sakai.properties, basedir, pattern etc String filename = getOfficialImageFileSystemPath(userUuid); File file = new File(filename); try { byte[] data = getBytesFromFile(file); if (data != null) { image.setUploadedImage(data); } else { image.setExternalImageUrl(defaultImageUrl); image.setDefault(true); } } catch (IOException e) { log.error("Could not find/read official profile image file: " + filename + ". The default profile image will be used instead."); image.setExternalImageUrl(defaultImageUrl); image.setDefault(true); } } image.setAltText(getAltText(userUuid, isSameUser, true)); return image; } /** * {@inheritDoc} */ public ProfileImage getProfileImage(Person person, int size) { return getProfileImage(person.getUuid(), person.getPreferences(), person.getPrivacy(), size, null); } /** * {@inheritDoc} */ public ProfileImage getProfileImage(Person person, int size, String siteId) { return getProfileImage(person.getUuid(), person.getPreferences(), person.getPrivacy(), size, siteId); } /** * {@inheritDoc} */ public boolean setUploadedProfileImage(String userUuid, byte[] imageBytes, String mimeType, String fileName) { //check auth and get currentUserUuid String currentUserUuid = sakaiProxy.getCurrentUserId(); if (currentUserUuid == null) { throw new SecurityException("You must be logged in to update a user's profile image."); } //check admin, or the currentUser and given uuid match if (!sakaiProxy.isSuperUser() && !StringUtils.equals(currentUserUuid, userUuid)) { throw new SecurityException("Not allowed to save."); } //check image is actually allowed to be changed if (!sakaiProxy.isProfilePictureChangeEnabled()) { log.warn( "Profile image changes are not permitted as per sakai.properties setting 'profile2.picture.change.enabled'."); return false; } /* * MAIN PROFILE IMAGE */ //scale image byte[] mainImageBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_IMAGE_XY, mimeType); //create resource ID String mainResourceId = sakaiProxy.getProfileImageResourcePath(userUuid, ProfileConstants.PROFILE_IMAGE_MAIN); //save, if error, log and return. if (!sakaiProxy.saveFile(mainResourceId, userUuid, fileName, mimeType, mainImageBytes)) { log.error("Couldn't add main image to CHS. Aborting."); return false; } /* * THUMBNAIL PROFILE IMAGE */ //scale image byte[] thumbnailImageBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_THUMBNAIL_IMAGE_XY, mimeType); //create resource ID String thumbnailResourceId = sakaiProxy.getProfileImageResourcePath(userUuid, ProfileConstants.PROFILE_IMAGE_THUMBNAIL); log.debug("Profile.ChangeProfilePicture.onSubmit thumbnailResourceId: " + thumbnailResourceId); //save, if error, warn, erase thumbnail reference, and continue (we really only need the main image) if (!sakaiProxy.saveFile(thumbnailResourceId, userUuid, fileName, mimeType, thumbnailImageBytes)) { log.warn("Couldn't add thumbnail image to CHS. Main image will be used instead."); thumbnailResourceId = null; } /* * AVATAR PROFILE IMAGE */ //scale image byte[] avatarImageBytes = ProfileUtils.createAvatar(imageBytes, mimeType); //create resource ID String avatarResourceId = sakaiProxy.getProfileImageResourcePath(userUuid, ProfileConstants.PROFILE_IMAGE_AVATAR); log.debug("Profile.ChangeProfilePicture.onSubmit avatarResourceId: " + avatarResourceId); //save, if error, warn, erase avatar reference, and continue (we really only need the main image) if (!sakaiProxy.saveFile(avatarResourceId, userUuid, fileName, mimeType, avatarImageBytes)) { log.warn("Couldn't add avatar image to CHS. Main image will be used instead."); avatarResourceId = null; } /* * SAVE IMAGE RESOURCE IDS */ //save ProfileImageUploaded profileImage = new ProfileImageUploaded(userUuid, mainResourceId, thumbnailResourceId, avatarResourceId, true); if (dao.addNewProfileImage(profileImage)) { log.info("Added a new profile image for user: " + userUuid); return true; } return false; } /** * {@inheritDoc} */ public boolean setExternalProfileImage(String userUuid, String fullSizeUrl, String thumbnailUrl, String avatar) { //check auth and get currentUserUuid String currentUserUuid = sakaiProxy.getCurrentUserId(); if (currentUserUuid == null) { throw new SecurityException("You must be logged in to update a user's profile image."); } //check admin, or the currentUser and given uuid match if (!sakaiProxy.isSuperUser() && !StringUtils.equals(currentUserUuid, userUuid)) { throw new SecurityException("Not allowed to save."); } //check image is actually allowed to be changed if (!sakaiProxy.isProfilePictureChangeEnabled()) { log.warn( "Profile image changes are not permitted as per sakai.properties setting 'profile2.picture.change.enabled'."); return false; } //save ProfileImageExternal externalImage = new ProfileImageExternal(userUuid, fullSizeUrl, thumbnailUrl, avatar); if (dao.saveExternalImage(externalImage)) { log.info("Updated external image record for user: " + userUuid); return true; } return false; } /** * {@inheritDoc} */ public boolean saveOfficialImageUrl(final String userUuid, final String url) { ProfileImageOfficial officialImage = new ProfileImageOfficial(userUuid, url); if (dao.saveOfficialImageUrl(officialImage)) { log.info("Updated official image record for user: " + userUuid); return true; } return false; } /** * {@inheritDoc} */ public boolean addGalleryImage(String userUuid, byte[] imageBytes, String mimeType, String fileName) { // check auth and get currentUserUuid String currentUserUuid = sakaiProxy.getCurrentUserId(); if (currentUserUuid == null) { throw new SecurityException("You must be logged in to add a gallery image."); } // check admin, or the currentUser and given uuid match if (!sakaiProxy.isSuperUser() && !StringUtils.equals(currentUserUuid, userUuid)) { throw new SecurityException("You are not allowed to add a gallery image."); } String imageId = sakaiProxy.createUuid(); // create resource ID String mainResourcePath = sakaiProxy.getProfileGalleryImagePath(userUuid, imageId); byte[] scaledImageBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_GALLERY_IMAGE_XY, mimeType); // save image if (!sakaiProxy.saveFile(mainResourcePath, userUuid, fileName, mimeType, scaledImageBytes)) { log.error("Couldn't add gallery image to CHS. Aborting."); return false; } // create thumbnail byte[] thumbnailBytes = ProfileUtils.scaleImage(imageBytes, ProfileConstants.MAX_GALLERY_THUMBNAIL_IMAGE_XY, mimeType); String thumbnailResourcePath = sakaiProxy.getProfileGalleryThumbnailPath(userUuid, imageId); sakaiProxy.saveFile(thumbnailResourcePath, userUuid, fileName, mimeType, thumbnailBytes); //save GalleryImage galleryImage = new GalleryImage(userUuid, mainResourcePath, thumbnailResourcePath, fileName); if (dao.addNewGalleryImage(galleryImage)) { log.info("Added new gallery image for user: " + galleryImage.getUserUuid()); return true; } return false; } /** * {@inheritDoc} */ public List<GalleryImage> getGalleryImages(String userUuid) { // check auth and get currentUserUuid String currentUserUuid = sakaiProxy.getCurrentUserId(); if (currentUserUuid == null) { throw new SecurityException("You must be logged in to make a request for a user's gallery images."); } return dao.getGalleryImages(userUuid); } /** * {@inheritDoc} */ public List<GalleryImage> getGalleryImagesRandomized(String userUuid) { List<GalleryImage> images = getGalleryImages(userUuid); Collections.shuffle(images); return images; } /** * {@inheritDoc} */ public boolean removeGalleryImage(String userId, long imageId) { if (userId == null || Long.valueOf(imageId) == null) { throw new IllegalArgumentException("Null argument in ProfileLogicImpl.removeGalleryImage()"); } // check auth and get currentUserUuid String currentUserUuid = sakaiProxy.getCurrentUserId(); if (currentUserUuid == null) { throw new SecurityException("You must be logged in to remove a gallery image."); } // check admin, or the currentUser and given uuid match if (!sakaiProxy.isSuperUser() && !StringUtils.equals(currentUserUuid, userId)) { throw new SecurityException("You are not allowed to remove this gallery image."); } GalleryImage galleryImage = dao.getGalleryImageRecord(userId, imageId); if (galleryImage == null) { log.error("GalleryImage record does not exist for userId: " + userId + ", imageId: " + imageId); return false; } //delete main image if (!sakaiProxy.removeResource(galleryImage.getMainResource())) { log.error("Gallery image not removed: " + galleryImage.getMainResource()); } //delete thumbnail if (!sakaiProxy.removeResource(galleryImage.getThumbnailResource())) { log.error("Gallery thumbnail not removed: " + galleryImage.getThumbnailResource()); } if (dao.removeGalleryImage(galleryImage)) { log.info("User: " + userId + " removed gallery image: " + imageId); return true; } return false; } /** * {@inheritDoc} */ public String getGravatarUrl(final String userUuid) { String email = sakaiProxy.getUserEmail(userUuid); if (StringUtils.isBlank(email)) { return null; } return ProfileConstants.GRAVATAR_BASE_URL + ProfileUtils.calculateMD5(email) + "?s=200"; } /** * {@inheritDoc} */ public boolean resetProfileImage(final String userUuid) { if (dao.invalidateCurrentProfileImage(userUuid)) { log.info("Invalidated profile image for user: " + userUuid); return true; } return false; } /** * {@inheritDoc} */ public boolean profileImageIsDefault(final String userUuid) { ProfileImage image = getProfileImage(userUuid, null, null, ProfileConstants.PROFILE_IMAGE_MAIN); return image.isDefault(); } /** * Generate the full URL to the default image (either full or thumbnail) * @param imagePath * @return */ private String getUnavailableImageURL(String imagePath) { StringBuilder path = new StringBuilder(); path.append(sakaiProxy.getServerUrl()); path.append(imagePath); return path.toString(); } /** * {@inheritDoc} */ public String getUnavailableImageURL() { return getUnavailableImageURL(ProfileConstants.UNAVAILABLE_IMAGE_FULL); } /** * {@inheritDoc} */ public String getUnavailableImageThumbnailURL() { return getUnavailableImageURL(ProfileConstants.UNAVAILABLE_IMAGE_THUMBNAIL); } /** * {@inheritDoc} */ public String getProfileImageEntityUrl(String userUuid, int size) { StringBuilder sb = new StringBuilder(); sb.append(sakaiProxy.getServerUrl()); sb.append("/direct/profile/"); sb.append(userUuid); sb.append("/image/"); if (size == ProfileConstants.PROFILE_IMAGE_THUMBNAIL) { sb.append("thumb/"); } return sb.toString(); } /** * {@inheritDoc} */ public int getGalleryImagesCount(final String userUuid) { return dao.getGalleryImagesCount(userUuid); } /** * Get the profile image for the given user, allowing fallback if no thumbnail exists. * * @param userUuid the uuid of the user we are querying * @param size comes from ProfileConstants, main or thumbnail, also maps to a directory in ContentHosting * @return MimeTypeByteArray or null * * <p>Note: if thumbnail is requested and none exists, the main image will be returned instead. It can be scaled in the markup.</p> * */ private MimeTypeByteArray getUploadedProfileImage(String userUuid, int size) { MimeTypeByteArray mtba = new MimeTypeByteArray(); //get record from db ProfileImageUploaded profileImage = dao.getCurrentProfileImageRecord(userUuid); if (profileImage == null) { log.debug("ProfileLogic.getUploadedProfileImage() null for userUuid: " + userUuid); return null; } //get main image if (size == ProfileConstants.PROFILE_IMAGE_MAIN) { mtba = sakaiProxy.getResource(profileImage.getMainResource()); } //or get thumbnail if (size == ProfileConstants.PROFILE_IMAGE_THUMBNAIL) { mtba = sakaiProxy.getResource(profileImage.getThumbnailResource()); //PRFL-706, if the file is deleted, catch any possible NPE if (mtba == null || mtba.getBytes() == null) { mtba = sakaiProxy.getResource(profileImage.getMainResource()); } } if (size == ProfileConstants.PROFILE_IMAGE_AVATAR) { mtba = sakaiProxy.getResource(profileImage.getAvatarResource()); //PRFL-706, if the file is deleted, catch any possible NPE if (mtba == null || mtba.getBytes() == null) { mtba = sakaiProxy.getResource(profileImage.getMainResource()); } } return mtba; } /** * Get the URL to an image that a user has specified as their profile image * @param userId uuid of user * @param size comes from ProfileConstants. main or thumbnail. * * <p>Note: if thumbnail is requested and none exists, the main image will be returned instead. It can be scaled in the markup.</p> * * @return url to the image, or a default image if none. */ private String getExternalProfileImageUrl(final String userUuid, final int size) { //get external image record for this user ProfileImageExternal externalImage = dao.getExternalImageRecordForUser(userUuid); //setup default String defaultImageUrl = getUnavailableImageURL(); //if none, return null if (externalImage == null) { return defaultImageUrl; } //otherwise get the url for the type they requested String url = null; if (size == ProfileConstants.PROFILE_IMAGE_MAIN) { if (log.isDebugEnabled()) { log.debug("Returning main image url for userId: " + userUuid); } url = externalImage.getMainUrl(); } if (size == ProfileConstants.PROFILE_IMAGE_THUMBNAIL) { if (log.isDebugEnabled()) { log.debug("Returning thumb image url for userId: " + userUuid); } url = externalImage.getThumbnailUrl(); } if (size == ProfileConstants.PROFILE_IMAGE_AVATAR) { if (log.isDebugEnabled()) { log.debug("Returning avatar image url for userId: " + userUuid); } url = externalImage.getAvatarUrl(); } //if we have a url, return it, if (StringUtils.isNotBlank(url)) { return url; } else { //otherwise fallback url = externalImage.getMainUrl(); if (StringUtils.isBlank(url)) { url = defaultImageUrl; } } //no url log.info("ProfileLogic.getExternalProfileImageUrl. No URL for userId: " + userUuid + ", imageType: " + size + ". Returning default."); return defaultImageUrl; } /** * Get the URL to a user's official profile image * @param userUuid uuid of user * * @return url or a default image if none */ private String getOfficialImageUrl(final String userUuid) { //get external image record for this user ProfileImageOfficial official = dao.getOfficialImageRecordForUser(userUuid); //setup default String defaultImageUrl = getUnavailableImageURL(); //if none, return null if (official == null) { return defaultImageUrl; } if (StringUtils.isBlank(official.getUrl())) { log.info("ProfileLogic.getOfficialImageUrl. No URL for userUuid: " + userUuid + ". Returning default."); return defaultImageUrl; } return official.getUrl(); } /** * Get the official image data from the user properties, encoded in BASE64 * @param userUuid uuid of user * @return base64 encoded data, or null. */ private String getOfficialImageEncoded(final String userUuid) { User u = sakaiProxy.getUserById(userUuid); return u.getProperties().getProperty(sakaiProxy.getOfficialImageAttribute()); } /** * Helper to get the altText to be used for the image * @param userUuid * @param isOwner * @param hasImage * @return */ private String getAltText(String userUuid, boolean isOwner, boolean hasImage) { //owner and has an image if (isOwner && hasImage) { return Messages.getString("profile.image.my.alt"); } //owner and doesnt have an image if (isOwner && !hasImage) { return Messages.getString("profile.image.my.none.alt"); } //not owner so get name if (!isOwner) { String displayName = sakaiProxy.getUserDisplayName(userUuid); return Messages.getString("profile.image.other.alt", new Object[] { displayName }); } return null; } /** * Gets the url to the user type image (PRFL-691) * *<p>This first checks if the option is enabled (profile2.user.type.image.enabled=true). *<p>If so, it attempts to get the value for profile.user.type.image.<usertype> which should be an absolute URL. *<p>If there is one, it is returned, if not, return null. Also returns null if userType is undefined. * @param userUuid uuid of the user to get the image for * @return url or null. */ private String getUserTypeImageUrl(String userUuid) { boolean enabled = Boolean .valueOf(sakaiProxy.getServerConfigurationParameter("profile2.user.type.image.enabled", "false")); String imageUrl = null; if (enabled) { String userType = sakaiProxy.getUserType(userUuid); if (StringUtils.isNotBlank(userType)) { imageUrl = sakaiProxy.getServerConfigurationParameter("profile.user.type.image." + userType, null); } } return imageUrl; } /** * Read a file to a byte array. * * @param file * @return byte[] if file ok, or null if its too big * @throws IOException */ private byte[] getBytesFromFile(File file) throws IOException { // Get the size of the file long length = file.length(); if (length > (ProfileConstants.MAX_IMAGE_UPLOAD_SIZE * FileUtils.ONE_MB)) { log.error("File too large: " + file.getCanonicalPath()); return null; } // return file contents return FileUtils.readFileToByteArray(file); } /** * Helper to get the path to the official image on the filesystem. This could be in one of several patterns. * @param userUuid * @return */ private String getOfficialImageFileSystemPath(String userUuid) { //get basepath, common to all String basepath = sakaiProxy.getOfficialImagesDirectory(); //get the pattern String pattern = sakaiProxy.getOfficialImagesFileSystemPattern(); //get user, common for all User user = sakaiProxy.getUserById(userUuid); String userEid = user.getEid(); String filename = null; //create the path based on the basedir and pattern if (StringUtils.equals(pattern, "ALL_IN_ONE")) { filename = basepath + File.separator + userEid + ".jpg"; } else if (StringUtils.equals(pattern, "ONE_DEEP")) { String firstLetter = userEid.substring(0, 1); filename = basepath + File.separator + firstLetter + File.separator + userEid + ".jpg"; } //insert more patterns here as required. Dont forget to update SakaiProxy and confluence with details. else { //TWO_DEEP is default String firstLetter = userEid.substring(0, 1); String secondLetter = userEid.substring(1, 2); filename = basepath + File.separator + firstLetter + File.separator + secondLetter + File.separator + userEid + ".jpg"; } if (log.isDebugEnabled()) { log.debug("Path to official image on filesystem is: " + filename); } return filename; } /** * Get a URL resource as a byte[] * @param url URL to fetch * @return */ private byte[] getUrlAsBytes(String url) { byte[] data = null; try { URL u = new URL(url); URLConnection uc = u.openConnection(); uc.setReadTimeout(5000); //5 sec timeout InputStream inputStream = uc.getInputStream(); data = IOUtils.toByteArray(inputStream); } catch (Exception e) { log.error("Failed to retrieve url bytes: " + e.getClass() + ": " + e.getMessage()); } return data; } @Setter private SakaiProxy sakaiProxy; @Setter private ProfilePrivacyLogic privacyLogic; @Setter private ProfileConnectionsLogic connectionsLogic; @Setter private ProfilePreferencesLogic preferencesLogic; @Setter private ProfileDao dao; }