/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/profile/trunk/profile-app/src/java/org/sakaiproject/tool/profile/ProfileTool.java $
* $Id: ProfileTool.java 105078 2012-02-24 23:00:38Z ottenhoff@longsight.com $
***********************************************************************************
*
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 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.opensource.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.tool.profile;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.api.app.profile.Profile;
import org.sakaiproject.api.app.profile.ProfileManager;
import org.sakaiproject.site.cover.SiteService;
import org.sakaiproject.tool.cover.ToolManager;
import org.sakaiproject.util.FormattedText;
import org.sakaiproject.util.ResourceLoader;
//to allow user edits
import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.user.cover.UserDirectoryService;
import org.sakaiproject.user.api.UserEdit;
import org.sakaiproject.user.api.User;
import org.sakaiproject.entity.api.Entity;
/**
* @author rshastri
*/
public class ProfileTool
{
private static final Log LOG = LogFactory.getLog(ProfileTool.class);
/** Resource bundle using current language locale */
private static ResourceLoader rb = new ResourceLoader("org.sakaiproject.tool.profile.bundle.Messages");
/** Configuration bundle using current language locale */
private static ResourceLoader cb = new ResourceLoader("org.sakaiproject.tool.profile.config.Config");
private static final String NONE = "none";
private static final String UNIVERSITY_PHOTO = "universityId";
private static final String PICTURE_URL = "pictureUrl";
private static final String NO_PICTURE = "photoUnavialable";
private static final String NO_UNIVERSITY_PHOTO_AVAILABLE = "officalPhotoUnavailable";
private ProfileManager profileService;
private Profile profile;
private boolean loadingFirstTime = true;
private String pictureIdPreference = NONE;
private boolean displayPicture = false;
private boolean displayNoProfileMsg = false;
private boolean displayEvilTagMsg = false;
private boolean displayEmptyFirstNameMsg = false;
private boolean displayEmptyLastNameMsg = false;
private boolean displayMalformedPictureUrlError = false;
private boolean displayMalformedHomepageUrlError = false;
private boolean displayInvalidEmailError = false;
private String malformedUrlError = null;
private String evilTagMsg = null;
/**
* Process data for save action on edit page.
*
* @return navigation outcome: return to main page or if no user is present throw permission exception
*/
public String processActionEditSave()
{
LOG.debug("processActionEditSave()");
displayEvilTagMsg = false;
displayEmptyFirstNameMsg = false;
displayEmptyLastNameMsg = false;
displayMalformedPictureUrlError = false;
displayMalformedHomepageUrlError = false;
displayInvalidEmailError = false;
if ((profile != null) && (profile.getUserId() == null))
{
LOG.error("processActionEditSave :" + "No User Found");
return "permissionException";
}
if (profile.getFirstName() == null || profile.getFirstName().trim().length() < 1)
{
displayEmptyFirstNameMsg = true;
return "edit";
}
if (profile.getLastName() == null || profile.getLastName().trim().length() < 1)
{
displayEmptyLastNameMsg = true;
return "edit";
}
if (profile.getEmail() == null || !isValidEmail(profile.getEmail())) {
displayInvalidEmailError = true;
return "edit";
}
if (profile.getOtherInformation() != null)
{
StringBuilder alertMsg = new StringBuilder();
String errorMsg = null;
try
{
errorMsg = FormattedText.processFormattedText(profile.getOtherInformation(), alertMsg);
if (alertMsg.length() > 0)
{
evilTagMsg = alertMsg.toString();
displayEvilTagMsg = true;
return "edit";
}
}
catch (Exception e)
{
LOG.error(" " + errorMsg, e);
}
}
if ((getPictureIdPreference() != null) && getPictureIdPreference().equals(UNIVERSITY_PHOTO))
{
profile.setInstitutionalPictureIdPreferred(new Boolean(true));
profile.setPictureUrl(null);
displayPicture = true;
this.pictureIdPreference = UNIVERSITY_PHOTO;
}
else if ((getPictureIdPreference() != null) && (getPictureIdPreference().equals(PICTURE_URL)))
{
profile.setInstitutionalPictureIdPreferred(new Boolean(false));
displayPicture = true;
this.pictureIdPreference = PICTURE_URL;
if (profile.getPictureUrl() != null && profile.getPictureUrl().trim().length() > 0)
{
try
{
String pictureUrl = validateURL(profile.getPictureUrl());
profile.setPictureUrl(pictureUrl);
}
catch (MalformedURLException e)
{
this.displayMalformedPictureUrlError = true;
this.malformedUrlError = rb.getString("validurl") + " \"" + profile.getPictureUrl() + "\" " + rb.getString("invalid");
return "edit";
}
}
}
else
{
// returns null or none
profile.setInstitutionalPictureIdPreferred(new Boolean(false));
profile.setPictureUrl(null);
displayPicture = false;
this.pictureIdPreference = NONE;
}
// Catch a bad url passed in homepage.
if(profile.getHomepage() != null && profile.getHomepage().trim().length()>0)
{
try
{
String homepageUrl = validateURL(profile.getHomepage().trim());
profile.setHomepage(homepageUrl);
}
catch (MalformedURLException e)
{
this.displayMalformedHomepageUrlError = true;
this.malformedUrlError = rb.getString("validurl") + " \"" + profile.getHomepage() + "\" " + rb.getString("invalid");
return "edit";
}
}
try
{
profileService.save(profile);
}
catch (Exception e)
{
LOG.error(e.getMessage(), e);
}
return "main";
}
/**
* Setup before navigating to edit page
*
* @return navigation outcome: return to edit page or if no user is present throw permission exception
*/
public String processActionEdit()
{
LOG.debug("processActionEdit()");
try
{
if ((profile != null) && (profile.getUserId() == null))
{
LOG.error("processActionEdit : " + "No User Found");
return "PermissionException";
}
setPictureIdPreference(profile);
return "edit";
}
catch (Exception e)
{
LOG.error(e.getMessage(), e);
return null;
}
}
/**
* @return
*/
public String processCancel()
{
LOG.debug("processCancel()");
profile = profileService.getProfile();
return "main";
}
/**
* Setup to fetch a profile
*
* @return Profile for user logged in or empty profile
*/
public Profile getProfile()
{
LOG.debug("getProfile()");
if (loadingFirstTime)
{
profile = profileService.getProfile();
setPictureIdPreference(profile);
loadingFirstTime = false;
}
else
{
if (profile == null)
{
displayNoProfileMsg = true;
}
else
{
if ((profile.getFirstName() == null) || (profile.getLastName() == null))
{
displayNoProfileMsg = true;
}
else
{
if (profile.getFirstName().equalsIgnoreCase("") || profile.getLastName().equalsIgnoreCase(""))
displayNoProfileMsg = true;
else
displayNoProfileMsg = false;
}
}
}
return profile;
}
/**
* Getter for ProfileManager service
*
* @return instance of ProfileManager
*/
public ProfileManager getProfileService()
{
LOG.debug("getProfileService()");
return profileService;
}
/**
* Setter for ProfileManager service
*
* @param profileService
*/
public void setProfileService(ProfileManager profileService)
{
if (LOG.isDebugEnabled())
{
LOG.debug("setProfileService(ProfileManager" + profileService + ")()");
}
this.profileService = profileService;
}
/**
* @return
*/
public boolean isDisplayNoProfileMsg()
{
LOG.debug("isDisplayNoProfileMsg()");
return displayNoProfileMsg;
}
/**
* Getter for property if the tool bean is loaded for first time
*
* @return boolean value
*/
public boolean isLoadingFirstTime()
{
LOG.debug("isLoadingFirstTime()");
return loadingFirstTime;
}
/**
* Returns display picture preference
*
* @return String
*/
public String getPictureIdPreference()
{
LOG.debug("getPictureIdPreference()");
return pictureIdPreference;
}
/**
* Set display picture preference
*
* @param pictureIDPreference
*/
public void setPictureIdPreference(String pictureIdPreference)
{
if (LOG.isDebugEnabled())
{
LOG.debug("setPictureIDPreference(String" + pictureIdPreference + ")");
}
this.pictureIdPreference = pictureIdPreference;
}
public boolean isShowTool()
{
LOG.debug("isShowTool()");
return profileService.isShowTool();
}
public boolean isShowSearch()
{
LOG.debug("isShowSearch()");
return profileService.isShowSearch();
}
/**
* @return
*/
public String getTitle()
{
LOG.debug("getTitle()");
return SiteService.findTool(ToolManager.getCurrentPlacement().getId()).getTitle();
}
/**
* @return
*/
public String getEvilTagMsg()
{
LOG.debug("getEvilTagMsg()");
return evilTagMsg;
}
/**
* @return
*/
public boolean isDisplayEvilTagMsg()
{
LOG.debug("isDisplayEvilTagMsg()");
return displayEvilTagMsg;
}
public boolean isDisplayInvalidEmailMsg() {
return displayInvalidEmailError;
}
/**
* @return
*/
public boolean isDisplayEmptyFirstNameMsg()
{
LOG.debug("isDisplayEmptyFirstNameMsg()");
return displayEmptyFirstNameMsg;
}
/**
* @return
*/
public boolean isDisplayEmptyLastNameMsg()
{
LOG.debug("isDisplayEmptyLastNameMsg()");
return displayEmptyLastNameMsg;
}
/**
* @return
*/
public boolean isDisplayNoPicture()
{
LOG.debug("isDisplayPicture()");
return profileService.isDisplayNoPhoto(profile);
}
/**
* @param profile
*/
public void setProfile(Profile profile)
{
if (LOG.isDebugEnabled())
{
LOG.debug("setProfile(Profile" + profile + ")");
}
this.profile = profile;
}
/**
* @return
*/
public boolean isDisplayPictureURL()
{
LOG.debug("isDisplayPictureURL()");
return profileService.isDisplayPictureURL(profile);
}
/**
* @return
*/
public boolean isDisplayUniversityPhoto()
{
LOG.debug("isDisplayUniversityPhoto()");
return profileService.isDisplayUniversityPhoto(profile);
}
/**
* @return
*/
public boolean isDisplayUniversityPhotoUnavailable()
{
LOG.debug("isDisplayUniversityPhotoUnavailable()");
return profileService.isDisplayUniversityPhotoUnavailable(profile);
}
/**
* @param profile
*/
private void setPictureIdPreference(Profile profile)
{
if (LOG.isDebugEnabled())
{
LOG.debug("setPictureIdPreference(Profile" + profile + ")");
}
if (profile.isInstitutionalPictureIdPreferred() != null
&& profile.isInstitutionalPictureIdPreferred().booleanValue() == true)
{
this.pictureIdPreference = UNIVERSITY_PHOTO;
this.displayPicture = true;
}
else if (profile.getPictureUrl() != null && profile.getPictureUrl().length() > 0)
{
this.pictureIdPreference = PICTURE_URL;
this.displayPicture = true;
}
else
{
this.pictureIdPreference = NONE;
this.displayPicture = false;
}
}
/**
* @return
*/
public boolean isDisplayMalformedPictureUrlError()
{
LOG.debug("isDisplayMalformedPictureUrlError()");
return displayMalformedPictureUrlError;
}
/**
* @return
*/
public boolean isDisplayMalformedHomepageUrlError()
{
LOG.debug("isDisplayMalformedHomepageUrlError()");
return displayMalformedHomepageUrlError;
}
/**
* @return
*/
public String getMalformedUrlError()
{
LOG.debug("getMalformedUrlError()");
return malformedUrlError;
}
/**
*
* @param url
* @return
* @throws MalformedURLException
*/
private String validateURL(String url) throws MalformedURLException
{
if (url == null || url.equals (""))
{
// ignore the empty url field
}
else if (url.indexOf ("://") == -1)
{
// if it's missing the transport, add http://
url = "http://" + url;
}
if(url != null && !url.equals(""))
{
// valid protocol?
try
{
// test to see if the input validates as a URL.
// Checks string for format only.
URL u = new URL(url);
}
catch (MalformedURLException e1)
{
try
{
Pattern pattern = Pattern.compile("\\s*([a-zA-Z0-9]+)://([^\\n]+)");
Matcher matcher = pattern.matcher(url);
if(matcher.matches())
{
// if URL has "unknown" protocol, check remaider with
// "http" protocol and accept input it that validates.
URL test = new URL("http://" + matcher.group(2));
}
else
{
throw e1;
}
}
catch (MalformedURLException e2)
{
throw e1;
}
}
}
return url;
}
/**
* Is this a valid email the service will recognize
* @param email
* @return
*/
private boolean isValidEmail(String email) {
// TODO: Use a generic Sakai utility class (when a suitable one exists)
if (email == null || email.equals(""))
return false;
email = email.trim();
//must contain @
if (email.indexOf("@") == -1)
return false;
//an email can't contain spaces
if (email.indexOf(" ") > 0)
return false;
//"^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*$"
if (email.matches("^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*$"))
return true;
return false;
}
/**
* Returns String for image. Uses the config bundle
* to return paths to not available images.
*/
public String getImageUrlToDisplay() {
String imageUrl = "";
if (isDisplayUniversityPhoto()) {
imageUrl = "ProfileImageServlet.prf?photo=" + profile.getUserId();
}
else if (isDisplayPictureURL()) {
imageUrl = profile.getPictureUrl();
}
else if (isDisplayNoPicture()) {
imageUrl = cb.getString(NO_PICTURE);
}
else { //if (isDisplayUniversityPhotoUnavailable()){
imageUrl = cb.getString(NO_UNIVERSITY_PHOTO_AVAILABLE);
}
return imageUrl;
}
}