/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/podcasts/trunk/podcasts-app/src/java/org/sakaiproject/tool/podcasts/podHomeBean.java $
* $Id: podHomeBean.java 123503 2013-05-01 23:03:51Z azeckoski@unicon.net $
***********************************************************************************
*
* 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.podcasts;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.api.app.podcasts.PodcastPermissionsService;
import org.sakaiproject.api.app.podcasts.PodcastService;
import org.sakaiproject.api.app.podcasts.exception.PodcastException;
import org.sakaiproject.authz.api.PermissionsHelper;
import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.event.api.EventTrackingService;
import org.sakaiproject.content.api.ContentResource;
import org.sakaiproject.entity.api.Entity;
import org.sakaiproject.entity.api.EntityPropertyNotDefinedException;
import org.sakaiproject.entity.api.EntityPropertyTypeException;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.exception.IdInvalidException;
import org.sakaiproject.exception.IdLengthException;
import org.sakaiproject.exception.IdUniquenessException;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.IdUsedException;
import org.sakaiproject.exception.InUseException;
import org.sakaiproject.exception.InconsistentException;
import org.sakaiproject.exception.OverQuotaException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.exception.ServerOverloadException;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.cover.SiteService;
import org.sakaiproject.time.cover.TimeService;
import org.sakaiproject.tool.api.ToolSession;
import org.sakaiproject.tool.cover.SessionManager;
import org.sakaiproject.tool.cover.ToolManager;
import org.sakaiproject.tool.podcasts.util.DateUtil;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.util.Validator;
public class podHomeBean {
// Message Bundle handles
private static final String QUOTA_ALERT = "quota_alert";
private static final String LENGTH_ALERT = "length_alert";
private static final String PERMISSION_ALERT = "permission_alert";
private static final String INTERNAL_ERROR_ALERT = "internal_error_alert";
private static final String ID_UNUSED_ALERT = "id_unused_alert";
private static final String ID_INVALID_ALERT = "id_invalid_alert";
private static final String IO_ALERT = "io_alert";
private static final String ID_USED_ALERT = "id_used_alert";
// Patterns for Date and Number formatting
private static final String PUBLISH_DATE_FORMAT = "publish_date_format";
private static final String DATE_PICKER_FORMAT = "date_picker_format";
private static final String DATE_BY_HAND_FORMAT = "date_by_hand_format";
private static final String INTERNAL_DATE_FORMAT = "internal_date_format";
/** TODO: This is required until date-picker is internationalized. */
private static final String FIXED_DATE_PICKER_FORMAT = "MM/dd/yyyy hh:mm:ss a";
private static final String LAST_MODIFIED_TIME_FORMAT = "hh:mm a z";
private static final String LAST_MODIFIED_DATE_FORMAT = "MM/dd/yyyy";
// error handling variables
private boolean displayNoFileErrMsg = false;
private boolean displayNoDateErrMsg = false;
private boolean displayNoTitleErrMsg = false;
private boolean displayInvalidDateErrMsg = false;
/**
* Bean to store information about a single podcast.
* Used by main page to display and to store which
* podcast is to be Revised or Deleted.
*
* @author josephrodriguez
*/
public class DecoratedPodcastBean {
private String resourceId;
private String filename;
private long fileSize;
private String displayDate;
private String displayDateRevise;
private String title;
private String description;
private String size;
private String type;
private String postedTime;
private String postedDate;
private String author;
private String fileURL;
private String newWindow;
private String fileContentType;
private String styleClass;
private boolean hidden;
public DecoratedPodcastBean() {
styleClass = "";
}
public String getDescription() {
return description;
}
public void setDescription(String decsription) {
this.description = decsription;
}
public String getDisplayDate() {
return displayDate;
}
/**
* @param displayDateRevise The displayDateRevise to set.
*/
public void setDisplayDateRevise(String displayDateRevise) {
this.displayDateRevise = displayDateRevise;
}
/** Returns the revised display date for this podcast **/
public String getDisplayDateRevise() {
String dispDate = null;
if (displayDateRevise == null) {
dispDate = displayDate;
}
else {
dispDate = displayDateRevise;
}
SimpleDateFormat formatter = new SimpleDateFormat(getErrorMessageString(DATE_BY_HAND_FORMAT), rb.getLocale());
formatter.setTimeZone(TimeService.getLocalTimeZone());
try {
Date tempDate = convertDateString(dispDate,
getErrorMessageString(PUBLISH_DATE_FORMAT));
return formatter.format(tempDate);
} catch (ParseException e) {
// since revising, only log error if malformed date and not just blank
if (! "".equals(dispDate)) {
LOG.error("ParseException while rendering Revise Podcast page. ", e);
}
}
return dispDate;
}
public void setDisplayDate(String displayDate) {
this.displayDate = displayDate;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
/** Returns the size (as a formatted String) for this podcast's file **/
public String getSize() {
return size;
}
/** Sets the size (as a formatted String) for this podcast's file **/
public void setSize(String size) {
this.size = size;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
/** Returns this podcast's content MIME type ***/
public String getType() {
return type;
}
/** Sets this podcast's content MIME type ***/
public void setType(String type) {
this.type = type;
}
public String getPostedTime() {
return postedTime;
}
public void setPostedTime(String postedTime) {
this.postedTime = postedTime;
}
public String getPostedDate() {
return postedDate;
}
public void setPostedDate(String postedDate) {
this.postedDate = postedDate;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getResourceId() {
return resourceId;
}
public void setResourceId(String resourceId) {
this.resourceId = resourceId;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
/**
* Returns the file URL for the podcast. If errors, return empty
* string.
*/
public String getFileURL() {
try {
return podcastService.getPodcastFileURL(resourceId);
}
catch (PermissionException e) {
LOG.info("PermissionException getting file URL for "
+ resourceId + "while displaying podcast file for site " + podcastService.getSiteId(), e);
setErrorMessage(PERMISSION_ALERT);
}
catch (IdUnusedException e) {
LOG.info("IdUnusedException getting file URL for " + resourceId
+ " while displaying podcast file for site " + podcastService.getSiteId(), e);
setErrorMessage(ID_UNUSED_ALERT);
}
return "";
}
public void setFileURL(String fileURL) {
this.fileURL = fileURL;
}
/**
* Returns a value to determine if file should be opened in same
* window or a new one. _self means open in same window, _blank
* means open in a new window. If this resource is not a file,
* it will return an empty string.
*
* @return String
* Returns either '_self' or '_blank' ('' if not a file)
*/
public String getNewWindow() {
return Validator.getResourceTarget(fileContentType);
}
public void setNewWindow(String newWindow) {
this.newWindow = newWindow;
}
public String getFileContentType() {
return fileContentType;
}
public void setFileContentType(String fileContentType) {
this.fileContentType = fileContentType;
}
public String getStyleClass() {
return styleClass;
}
public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}
public boolean isHidden() {
return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
} // end of DecoratedPodcastBean
// ====================== End of DecoratedPodcastBean ====================== //
// podHomeBean constants
private static final String RESOURCEID = "resourceId";
private static final String FEED_URL_MIDDLE = "podcasts/site/";
private static final String MB = "MB";
private static final String BYTES = "Bytes";
private static final String MB_NUMBER_FORMAT = "#.#";
private static final String BYTE_NUMBER_FORMAT = "#,###";
// Permissions prefix
private final String CONTENT = "content.";
// For date String conversion
private static final Map monStrings;
static {
monStrings = new HashMap();
monStrings.put("Jan", "January");
monStrings.put("Feb", "February");
monStrings.put("Mar", "March");
monStrings.put("Apr", "April");
monStrings.put("Jun", "June");
monStrings.put("Jul", "July");
monStrings.put("Aug", "August");
monStrings.put("Sep", "September");
monStrings.put("Oct", "October");
monStrings.put("Nov", "November");
monStrings.put("Dec", "December");
}
// configurable toolId for Resources tool check
private String RESOURCE_TOOL_ID = ServerConfigurationService.getString("podcasts.toolid", "sakai.resources");
/** Used to pull message bundle */
// String bundle = FacesContext.getCurrentInstance().getApplication().getMessageBundle();
// toolBundle = new ResourceLoader(bundle);
private ResourceLoader rb;
// inject the services needed
private PodcastService podcastService;
private PodcastPermissionsService podcastPermissionsService;
private Log LOG = LogFactory.getLog(podHomeBean.class);
// variables to hold miscellanous information
private List contents;
private String URL;
private DecoratedPodcastBean selectedPodcast;
// used by podAdd.jsp for adding a podcast
private String filename = "";
private String date = "";
private String title;
private String description;
private String email;
private long fileSize = 0;
private String fileContentType;
private BufferedInputStream fileAsStream;
// FUTURE: Will be used to implement Email notifications
private SelectItem[] emailItems = {
new SelectItem("none", "None - No notification"),
new SelectItem("low", "Low - Only participants who have opted in"),
new SelectItem("high", "High - All participants") };
public podHomeBean() {
}
/**
* Determines if Resource tool part of the site. Needed to store podcasts.
*/
public boolean getResourceToolExists() {
boolean resourceToolExists = false;
String toolId = ToolManager.getTool(RESOURCE_TOOL_ID).getTitle();
try {
//
// Get a list of tool ids and see if RESOURCE_TOOL_ID is in the returned Collection
LOG.debug("Checking for presence of Sakai Resources tool using RESOURCE_TOOL_ID = " + RESOURCE_TOOL_ID);
Site thisSite = SiteService.getSite(ToolManager.getCurrentPlacement().getContext());
Collection toolsInSite = thisSite.getTools(RESOURCE_TOOL_ID);
if (!toolsInSite.isEmpty()) {
resourceToolExists = true;
}
}
catch (IdUnusedException e) {
LOG.error("No Site found while trying to check if site has Resources tool.", e);
// Only want to display this message if they are instructors or administrators
// so if student say it exists
if (getCanUpdateSite()) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Alert: " + getMessageFromBundle("no_resource_alert", new String [] { toolId })));
}
}
// Since multiple checks for this, only want to set the message the first time
if (!resourceToolExists
&& (!FacesContext.getCurrentInstance().getMessages().hasNext())) {
if (getCanUpdateSite()) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Alert: " + getMessageFromBundle("no_resource_alert", new String [] { toolId })));
}
}
return resourceToolExists;
}
/**
* Passes an error message to the Spring framework to display on page.
*
* @param alertMsg
* The key to get the message from the message bundle
*/
private void setErrorMessage(String alertMsg) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Alert: " + getErrorMessageString(alertMsg)));
}
/**
* Determines if the podcast folder exists. If it does not, it will attempt
* to create it.
*
* @return boolean
* TRUE if folder exists, FALSE otherwise.
*/
public boolean getPodcastFolderExists() {
boolean podcastFolderExists = false;
if (getResourceToolExists()) {
// we know resources tool exists, but need to know if podcast folder
// does
try {
podcastFolderExists = podcastService.checkPodcastFolder();
}
catch (InUseException e) {
LOG.info("InUseException while attempting to determine if podcast folder exists."
+ " for site " + podcastService.getSiteId(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
}
catch (PermissionException e) {
LOG.warn("PermissionException while attempting to determine if podcast folder exists."
+ " for site " + podcastService.getSiteId(), e);
setErrorMessage(PERMISSION_ALERT);
}
}
else if (!getCanUpdateSite()) {
// Resources tool does not exist but for students
// say true to get "There are no podcasts..." message instead of
// error
podcastFolderExists = true;
}
return podcastFolderExists;
}
/**
* Returns the URL to point your podcatcher to in order to grab the feed.
*
* @return String
* The feed URL.
*/
public String getURL() {
URL = ServerConfigurationService.getServerUrl() + Entity.SEPARATOR
+ FEED_URL_MIDDLE + podcastService.getSiteId();
return URL;
}
/**
* Returns String to be passed to permissions page.
*/
private String getPermissionsMessage() {
String podcastsSiteId = Validator.escapeUrl(SiteService.getSiteDisplay(podcastService.getSiteId()));
String permissionMsg = getMessageFromBundle("permission_directions", new String [] { podcastsSiteId });
return permissionMsg;
}
/**
* Constructs call to permissions helper and redirects to it to display
* Podcasts folder permissions page.
*/
public String processPermissions() {
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
ToolSession toolSession = SessionManager.getCurrentToolSession();
try {
String url = "sakai.permissions.helper.helper/tool?session." +
PermissionsHelper.DESCRIPTION + "=" + getPermissionsMessage() +
"&session." + PermissionsHelper.TARGET_REF + "=" +
podcastService.getPodcastsFolderRef() +
"&session." + PermissionsHelper.PREFIX + "=" + CONTENT +
"&session." + PermissionsHelper.ROLES_REF + "=" +
"/site/" + podcastService.getSiteId();
// Set permission descriptions
if (toolSession != null) {
ResourceLoader pRb = new ResourceLoader("org.sakaiproject.api.podcasts.bundle.permissions");
HashMap<String, String> pRbValues = new HashMap<String, String>();
for (Iterator<Entry<String, String>> mapIter = pRb.entrySet().iterator();mapIter.hasNext();)
{
Entry<String, String> entry = mapIter.next();
pRbValues.put(entry.getKey(), entry.getValue());
}
toolSession.setAttribute("permissionDescriptions", pRbValues);
}
context.redirect(url);
}
catch (IOException e) {
throw new RuntimeException("Failed to redirect to helper", e);
}
return null;
}
/**
* Used to inject the podcast service into this bean.
*
* @param podcastService
* The podcast service this bean needs
*/
public void setPodcastService(PodcastService podcastService) {
this.podcastService = podcastService;
}
public void setPodcastPermissionsService(PodcastPermissionsService podcastPermissionsService) {
this.podcastPermissionsService = podcastPermissionsService;
}
/**
* Returns whether podcast should be 'hidden' in UI. Conditions:
* Hidden property set
* Release date is in future
* Retract date is in past
*
* @param podcastResource
* The actual podcast to check
* @param tempDate
* Release date (if exists) or display date (older version)
*/
private boolean hiddenInUI(ContentResource podcastResource, Date tempDate) {
return podcastPermissionsService.isResourceHidden(podcastResource, tempDate);
}
/**
* Returns whether the Podcasts folder should be considered HIDDEN in UI
*/
public boolean isPodcastFolderHidden() {
boolean hidden;
try {
return podcastService.isPodcastFolderHidden(podcastService.getSiteId());
}
catch (Exception e) {
// if problems accessing, then should be hidden, so return false
return true;
}
}
/**
* Receives a particular podcast and packages it as a DecoratedPodcastBean
*
* @param podcastProperties
* Contains the ResourceProperties object of a podcast resource
* @param resourceId
* The resource ID for the podcast
*
* @return DecoratedPodcastBean
* The packaged podcast or null and exception if problems
*
* @throws EntityPropertyNotDefinedException
* The property wanted was not found
* @throws EntityPropertyTypeException
* The property (Date/Time) was not a valid one
*/
public DecoratedPodcastBean getAPodcast(ContentResource podcastResource, boolean folderHidden)
throws EntityPropertyNotDefinedException,
EntityPropertyTypeException {
ResourceProperties podcastProperties = podcastResource.getProperties();
DecoratedPodcastBean podcastInfo = null;
// first check if hidden.
// if instructor or has hidden property, set hidden property of decorated bean
// if not, return null since user cannot see
Date tempDate = null;
final SimpleDateFormat formatter = new SimpleDateFormat(getErrorMessageString(PUBLISH_DATE_FORMAT), rb.getLocale());
formatter.setTimeZone(TimeService.getLocalTimeZone());
// get release/publish date - else part needed for podcasts created before release/retract dates
// feature implemented
if (podcastResource.getReleaseDate() == null) {
tempDate = podcastService.getGMTdate(podcastProperties
.getTimeProperty(PodcastService.DISPLAY_DATE).getTime());
}
else {
tempDate = new Date(podcastResource.getReleaseDate().getTime());
}
// store result of hidden property OR after retract date OR before release date
final boolean uiHidden = folderHidden || hiddenInUI(podcastResource, tempDate);
if (! uiHidden || getHasHidden()) {
podcastInfo = new DecoratedPodcastBean();
podcastInfo.setDisplayDate(formatter.format(tempDate));
// store resourceId
podcastInfo.setResourceId(podcastResource.getId());
// store Title and Description
podcastInfo.setTitle(podcastProperties
.getPropertyFormatted(ResourceProperties.PROP_DISPLAY_NAME));
podcastInfo.setDescription(podcastProperties
.getPropertyFormatted(ResourceProperties.PROP_DESCRIPTION));
podcastInfo.setHidden(uiHidden);
// if podcast should be hidden, set style class to 'inactive'
if (uiHidden) {
podcastInfo.setStyleClass("inactive");
}
String filename = null;
try {
String url = podcastService.getPodcastFileURL(podcastResource.getId());
filename = url.substring(url.lastIndexOf("/")+1);
}
catch (PermissionException e) {
LOG.warn("PermissionException getting podcast with id " + podcastResource.getId() + " while constructing DecoratedPodcastBean for site "
+ podcastService.getSiteId() + ". " + e.getMessage(), e);
}
catch (IdUnusedException e) {
LOG.warn("IdUnusedException getting podcast with id " + podcastResource.getId() + " while constructing DecoratedPodcastBean for site "
+ podcastService.getSiteId() + ". " + e.getMessage(), e);
}
// if user puts URL instead of file, this is result of retrieving filename
if (filename == null)
return null;
podcastInfo.setFilename(filename);
// get content type
podcastInfo.setFileContentType(podcastProperties.getProperty(ResourceProperties.PROP_CONTENT_TYPE));
// store actual and formatted file size
// determine whether to display filesize as bytes or MB
final long size = Long.parseLong(podcastProperties.getProperty(ResourceProperties.PROP_CONTENT_LENGTH));
podcastInfo.setFileSize(size);
final double sizeMB = size / (1024.0 * 1024.0);
final DecimalFormat df = new DecimalFormat(MB_NUMBER_FORMAT);
String sizeString;
if (sizeMB > 0.3) {
sizeString = df.format(sizeMB) + MB;
}
else {
df.applyPattern(BYTE_NUMBER_FORMAT);
sizeString = "" + df.format(size) + " " + BYTES;
}
podcastInfo.setSize(sizeString);
final String extn = Validator.getFileExtension(filename);
if (! "".equals(extn)) {
podcastInfo.setType(Validator.getFileExtension(filename).toUpperCase());
}
else {
podcastInfo.setType("UNK");
}
// get and format last modified time
formatter.applyPattern(LAST_MODIFIED_TIME_FORMAT);
tempDate = new Date(podcastProperties.getTimeProperty(ResourceProperties.PROP_MODIFIED_DATE).getTime());
podcastInfo.setPostedTime(formatter.format(tempDate));
// get and format last modified date
formatter.applyPattern(LAST_MODIFIED_DATE_FORMAT);
tempDate = new Date(podcastProperties.getTimeProperty(ResourceProperties.PROP_MODIFIED_DATE).getTime());
podcastInfo.setPostedDate(formatter.format(tempDate));
// get author
podcastInfo.setAuthor(podcastProperties.getPropertyFormatted(ResourceProperties.PROP_CREATOR));
}
return podcastInfo;
}
/**
* Construct a List of DecoratedPodcastBeans for display on main page
*
* @return List
* List of DecoratedPodcastBeans that are the podcasts
*/
public List getContents() {
boolean folderHidden = false;
try {
// if entire folder set to HIDDEN and don't have site.upd or hidden perm
// return empty list since cannot access
// if have proper perms, set switch so all podcasts greyed out in UI
if (podcastService.isPodcastFolderHidden(podcastService.getSiteId())) {
if (! podcastPermissionsService.hasPerm(PodcastPermissionsService.HIDDEN_PERMISSIONS,
podcastService.retrievePodcastFolderId(
podcastService.getSiteId()))) {
return new ArrayList();
}
else {
folderHidden = true;
}
}
contents = podcastService.getPodcasts();
// if cannot update site (ie, student) only display published podcasts
if (! podcastPermissionsService.canUpdateSite(podcastService.getSiteId())) {
contents = podcastService.filterPodcasts(contents);
}
// SAK-23566 indicate the student viewed their grades
EventTrackingService ets = (EventTrackingService) ComponentManager.get(EventTrackingService.class);
String podcastFolderId = podcastService.retrievePodcastFolderId(podcastService.getSiteId());
if (ets != null && podcastFolderId != null) {
ets.post(ets.newEvent("podcast.read", podcastFolderId, false));
}
}
catch (PermissionException e) {
LOG.warn("PermissionException getting podcasts for display in site "
+ podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(PERMISSION_ALERT);
}
catch (InUseException e) {
LOG.warn("InUseException while getting podcasts for display"
+ podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
}
catch (IdInvalidException e) {
LOG.error("IdInvalidException while getting podcasts for display "
+ podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(ID_INVALID_ALERT);
}
catch (InconsistentException e) {
LOG.error("InconsistentException while getting podcasts for display "
+ podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
return null;
}
catch (IdUsedException e) {
LOG.warn("IdUsedException while gettting podcasts for display "
+ podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(ID_UNUSED_ALERT);
}
catch (IdUnusedException e) {
LOG.warn("IdUnusedException while determining if Podcasts folder has HIDDEN permission set"
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
}
// create local List of DecoratedBeans
ArrayList decoratedPodcasts = new ArrayList();
if (contents != null) {
Iterator podcastIter = contents.iterator();
// for each bean
while (podcastIter.hasNext()) {
try {
// get its properties from ContentHosting
final ContentResource podcastResource = (ContentResource) podcastIter.next();
ResourceProperties podcastProperties = podcastResource.getProperties();
// Create a new decorated bean to store the info
DecoratedPodcastBean podcastInfo = getAPodcast(podcastResource, folderHidden);
// add it to the List to send to the page. if URL, will return null so skip it
if (podcastInfo != null)
decoratedPodcasts.add(podcastInfo);
}
catch (EntityPropertyNotDefinedException e) {
LOG.error("EntityPropertyNotDefinedException while creating DecoratedPodcastBean "
+ " for site "+ podcastService.getSiteId() + ". SKIPPING..." + e.getMessage(), e);
}
catch (EntityPropertyTypeException e) {
LOG.error("EntityPropertyTypeException while creating DecoratedPodcastBean "
+ " for site "+ podcastService.getSiteId() + ". SKIPPING..." + e.getMessage(), e);
}
}
}
return decoratedPodcasts;
}
/**
* Resources/podcasts exists, but are there any actual podcasts
*
* @return boolean
* TRUE if there are podcasts, FALSE otherwise
*/
public boolean getActPodcastsExist() {
boolean actPodcastsExist = false;
// if student on site that has Podcasts but no Resources, want "There are no..."
if (!getResourceToolExists() && ! podcastPermissionsService.canUpdateSite()) {
return false;
}
if (!getPodcastFolderExists()) {
// if for some reason there is not a podcast folder
// for example, was renamed in Resources
actPodcastsExist = false;
}
else {
// ask the service if there is anything in the podcast folder
try {
actPodcastsExist = podcastService.checkForActualPodcasts();
}
catch (PermissionException e) {
LOG.warn("PermissionException while determining if there are files in the podcast folder "
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(PERMISSION_ALERT);
}
}
return actPodcastsExist;
}
/**
* To set the selectedPodcast DecoratedPodcastBean when Revision and
* Deletion links are clicked (possibly Download also)
*
* @param e
* ActionEvent object generated by clicking on a link
*/
public void podMainListener(ActionEvent e) {
FacesContext context = FacesContext.getCurrentInstance();
Map requestParams = context.getExternalContext()
.getRequestParameterMap();
final String resourceId = (String) requestParams.get(RESOURCEID);
setPodcastSelected(resourceId);
}
/**
* Does the actual filling up of the selectedPodcast bean
*
* @param resourceId
* Resource ID for the podcast whose link was selected
*/
public void setPodcastSelected(String resourceId) {
Iterator podcastIter = contents.iterator();
// for each bean
while (podcastIter.hasNext()) {
try {
// get its properties from ContentHosting
ContentResource podcastResource = (ContentResource) podcastIter.next();
if (podcastResource.getId().equals(resourceId)) {
selectedPodcast = getAPodcast(podcastResource,
podcastService.isPodcastFolderHidden(podcastService.getSiteId()));
break; // found and filled, get out of loop
}
}
catch (EntityPropertyNotDefinedException e) {
LOG.error("EntityPropertyNotDefinedException while attempting to fill selectedPodcast property "
+ " for site " + podcastService.getSiteId() + ". SKIPPING..." + e.getMessage(), e);
throw new PodcastException(e);
}
catch (EntityPropertyTypeException e) {
LOG.error("EntityPropertyTypeException while attempting to fill selectedPodcast property "
+ " for site " + podcastService.getSiteId() + ". SKIPPING..." + e.getMessage(), e);
throw new PodcastException(e);
}
catch (IdUnusedException e) {
LOG.error("IdUnusedException while attempting to determine if Podcasts folder is hidden for site "
+ podcastService.getSiteId() + ". SKIPPING..." + e.getMessage(), e);
}
catch (PermissionException e) {
LOG.error("PermissionException while attempting to determine if Podcasts folder is hidden for site "
+ podcastService.getSiteId() + ". SKIPPING..." + e.getMessage(),e );
}
}
}
/**
* Returns the current DecoratedPodcastBean set as selectedPodcast.
*/
public DecoratedPodcastBean getSelectedPodcast() {
return selectedPodcast;
}
/**
* Use to set the selectedPodcast object.
*/
public void setSelectedPodcast(DecoratedPodcastBean selectedPodcast) {
this.selectedPodcast = selectedPodcast;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/**
* FUTURE: To display the possible email notification levels
*
* @return SelectItem []
* List of possible email notification levels
*/
public SelectItem[] getEmailItems() {
return emailItems;
}
/**
* FUTURE: Returns the notification level set by the user
*
* @return String
* Returns the current notification level
*/
public String getemail() {
return email;
}
/**
* FUTURE: Sets the notification level
*
* @param email
* String representing the notification level
*/
public void setemail(String email) {
this.email = email;
}
/**
* Returns boolean if user can update podcasts. Used to display modification
* options on main page.
*/
public boolean getCanUpdateSite() {
return podcastPermissionsService.canUpdateSite();
}
public boolean getHasReadPerm() {
if (! getResourceToolExists()){
return false;
}
else {
try {
return podcastPermissionsService.hasPerm(PodcastPermissionsService.READ_PERMISSIONS,
podcastService.retrievePodcastFolderId(
podcastService.getSiteId()));
}
catch (PermissionException e) {
// problem getting podcast folder id, so return false
}
return false;
}
}
public boolean getHasNewPerm() {
if (! getResourceToolExists()){
return false;
}
else {
try {
return podcastPermissionsService.hasPerm(PodcastPermissionsService.NEW_PERMISSIONS,
podcastService.retrievePodcastFolderId(
podcastService.getSiteId()));
}
catch (PermissionException e) {
// problem getting podcast folder id, so return false
}
return false;
}
}
public boolean getHasReviseAnyPerm() {
if (! getResourceToolExists()){
return false;
}
else {
try {
return podcastPermissionsService.hasPerm(PodcastPermissionsService.REVISE_ANY_PERMISSIONS,
podcastService.retrievePodcastFolderId(
podcastService.getSiteId()));
}
catch (PermissionException e) {
// problem getting podcast folder id, so return false
}
return false;
}
}
public boolean getHasReviseOwnPerm() {
try {
return podcastPermissionsService.hasPerm(PodcastPermissionsService.REVISE_OWN_PERMISSIONS,
podcastService.retrievePodcastFolderId(
podcastService.getSiteId()));
}
catch (PermissionException e) {
// problem getting podcast folder id, so return false
}
return false;
}
public boolean getHasDelAnyPerm() {
try {
return podcastPermissionsService.hasPerm(PodcastPermissionsService.DELETE_ANY_PERMISSIONS,
podcastService.retrievePodcastFolderId(
podcastService.getSiteId()));
}
catch (PermissionException e) {
// problem getting podcast folder id, so return false
}
return false;
}
public boolean getHasDelOwnPerm() {
try {
return podcastPermissionsService.hasPerm(PodcastPermissionsService.DELETE_OWN_PERMISSIONS,
podcastService.retrievePodcastFolderId(
podcastService.getSiteId()));
}
catch (PermissionException e) {
// problem getting podcast folder id, so return false
}
return false;
}
/**
* Returns TRUE if user has ALLGROUPS permission (or site.upd which supercedes),
* FALSE if not
*/
public boolean getHasAllGroups() {
try {
return podcastPermissionsService.hasPerm(PodcastPermissionsService.ALL_GROUPS_PERMISSIONS,
podcastService.retrievePodcastFolderId(
podcastService.getSiteId()));
}
catch (PermissionException e) {
// problem getting podcast folder id, so return false
}
return false;
}
public boolean getHasHidden() {
try {
return podcastPermissionsService.hasPerm(PodcastPermissionsService.HIDDEN_PERMISSIONS,
podcastService.retrievePodcastFolderId(
podcastService.getSiteId()));
}
catch (PermissionException e) {
// problem getting podcast folder id, so return false
}
return false;
}
public String getUserName() {
return podcastService.getUserName();
}
public boolean isCanAccessFolder() {
return getCanUpdateSite()
|| ! isPodcastFolderHidden()
|| (isPodcastFolderHidden() && getHasHidden());
// || (isPodcastFolderGroupRestricted() && userInGroupRestrictedTo());
}
/**
* Creates a BufferedInputStream to get ready to upload file selected. Used
* by Add Podcast and Revise Podcast pages.
*
* @param event
* ValueChangeEvent object generated by selecting a file to
* upload.
*
* @throws AbortProcessingException
* Internal processing error attempting to set up BufferedInputStream
*/
public void processFileUpload(ValueChangeEvent event)
throws AbortProcessingException {
UIComponent component = event.getComponent();
Object newValue = event.getNewValue();
Object oldValue = event.getOldValue();
PhaseId phaseId = event.getPhaseId();
Object source = event.getSource();
// System.out.println("processFileUpload() event: " + event
// + " component: " + component + " newValue: " + newValue
// + " oldValue: " + oldValue + " phaseId: " + phaseId
// + " source: " + source);
if (newValue instanceof String)
return;
if (newValue == null)
return;
FileItem item = (FileItem) event.getNewValue();
String fieldName = item.getFieldName();
filename = Validator.getFileName(item.getName());
fileSize = item.getSize();
fileContentType = item.getContentType();
// System.out.println("processFileUpload(): item: " + item
// + " fieldname: " + fieldName + " filename: " + filename
// + " length: " + fileSize);
// Read the file as a stream (may be more memory-efficient)
try {
fileAsStream = new BufferedInputStream(item.getInputStream());
}
catch (IOException e) {
LOG.warn("IOException while attempting to set BufferedInputStream to upload "
+ filename + " from site " + podcastService.getSiteId() + ". "
+ e.getMessage(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
}
}
/**
* Converts the date string input using the FORMAT_STRING given.
*
* @param inputDate
* The string that needs to be converted.
* @param FORMAT_STRING
* The format the data needs to conform to
*
* @return Date
* The Date object containing the date passed in or null if invalid.
*
* @throws ParseException
* If not a valid date compared to FORMAT_STRING given
*/
private Date convertDateString(final String inputDate,
final String FORMAT_STRING) throws ParseException {
Date convertedDate = null;
SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT_STRING, rb.getLocale());
dateFormat.setTimeZone(TimeService.getLocalTimeZone());
try {
convertedDate = dateFormat.parse(inputDate);
} catch (ParseException e) {
// TODO: This is required until date-picker is internationalized.
dateFormat = new SimpleDateFormat(FORMAT_STRING, Locale.ENGLISH);
dateFormat.setTimeZone(TimeService.getLocalTimeZone());
convertedDate = dateFormat.parse(inputDate);
}
return convertedDate;
}
/**
* Performs the actual adding of a podcast. Calls PodcastService to actually
* add the podcast.
*
* @return String Sent to return to main page.
*/
public String processAdd() {
// if OK, need byte array to store contents of file
byte[] fileContents = new byte[(int) fileSize];
// If problems, stay on this page
String whereToGo = "podcastAdd";
// validate the input
if (OKtoAdd()) {
try {
fileAsStream.read(fileContents);
}
catch (IOException e) {
LOG.error("IOException while attempting the actual upload file " + filename + " during processAdd "
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(IO_ALERT);
// stay on Add podcast page
return "podcastAdd";
}
finally {
try {
if (fileAsStream != null)
fileAsStream.close();
} catch (IOException ioe) {
LOG.warn("IOException error while closing the stream:" + ioe);
}
}
try {
Date displayDate = null;
try {
displayDate = convertDateString(date,
FIXED_DATE_PICKER_FORMAT);
}
catch (ParseException e) {
// must have entered it in by hand so try again
try {
displayDate = convertDateString(date,
getErrorMessageString(DATE_BY_HAND_FORMAT));
}
catch (ParseException e1) {
// Now it's invalid, so set error message and stay on page
LOG.warn("ParseException attempting to convert " + date
+ " both valid ways. " + e1.getMessage(), e1);
displayInvalidDateErrMsg = true;
return "podcastAdd";
}
}
podcastService.addPodcast(title, displayDate, description,
fileContents, filename, fileContentType);
// We're good, no error message need be displayed
displayNoFileErrMsg = false;
displayNoDateErrMsg = false;
displayNoTitleErrMsg = false;
displayInvalidDateErrMsg = false;
// erase data on page
title = "";
date = null;
description = "";
filename = "";
try {
fileAsStream = null;
} catch (Exception e){
LOG.warn("Exception error while setting the stream to null: " + e);
}
finally {
try {
if (fileAsStream != null)
fileAsStream.close();
} catch (IOException ioe) {
LOG.warn("IOException error while closing the stream:" + ioe);
}
}
// back to main page
whereToGo = "cancel";
}
catch (OverQuotaException e) {
LOG.warn("OverQuotaException while attempting to actually add the new podcast "
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(QUOTA_ALERT);
}
catch (ServerOverloadException e) {
LOG.info("ServerOverloadException while attempting to actually add the new podcast "
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
}
catch (InconsistentException e) {
LOG.error("InconsistentException while attempting to actually add the new podcast "
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
throw new PodcastException(e);
}
catch (IdInvalidException e) {
LOG.error("IdInvalidException while attempting to actually add the new podcast "
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(ID_INVALID_ALERT);
}
catch (IdLengthException e) {
LOG.warn("IdLengthException while attempting to actually add the new podcast "
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(LENGTH_ALERT);
}
catch (PermissionException e) {
LOG.warn("PermissionException while attempting to actually add the new podcast "
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(PERMISSION_ALERT);
}
catch (IdUniquenessException e) {
LOG.error("IdUniquenessException while attempting to actually add the new podcast "
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(ID_USED_ALERT);
}
// TODO add email notification code here
/*
* if (email.equalsIgnoreCase("high")) {
* EmailService.send("josrodri@iupui.edu", "josrodri@iupui.edu", "A
* podcast has been added to feed.", "A podcast has been added to
* the list of podcasts. It's publish date will determine when it
* will be available in the feed", null, null, null); } else if
* (email.equalsIgnoreCase("low")){ //TODO: email only those who
* have opted in }
*/}
return whereToGo;
}
/**
* Erases bean values since no podcast is to be added.
*
* @return String
* Sent to return to main page.
*/
public String processCancelAdd() {
date = null;
title = "";
description = "";
try {
fileAsStream = null;
} catch (Exception e){
LOG.warn("Exception error while setting the stream to null: " + e);
}
finally {
try {
if (fileAsStream != null)
fileAsStream.close();
} catch (IOException ioe) {
LOG.warn("IOException error while closing the stream:" + ioe);
}
}
filename = "";
displayNoFileErrMsg = false;
displayNoDateErrMsg = false;
displayNoTitleErrMsg = false;
displayInvalidDateErrMsg = false;
return "cancel";
}
/**
* Gathers information and calls PodcastService to make changes to existing
* podcast.
*/
public String processRevisePodcast() {
// set error messages to false so can be
// turned on during processing
displayNoTitleErrMsg = false;
displayInvalidDateErrMsg = false;
String whereToGo = "cancel";
boolean filenameChange = false;
byte[] fileContents = null;
// if they blank out the title, stay here since
// a title is a requirement
if ("".equals(selectedPodcast.title.trim())) {
displayNoTitleErrMsg = true;
if ("".equals(selectedPodcast.displayDateRevise)) {
displayInvalidDateErrMsg = true;
}
else {
displayInvalidDateErrMsg = false;
}
return "revise";
}
// If file has changed, change it in the resource
if (filename != null) {
if (!filename.equals("")) {
selectedPodcast.filename = filename;
filenameChange = true;
if (fileAsStream != null) {
fileContents = new byte[(int) fileSize];
}
else {
fileContents = new byte[(int) selectedPodcast.fileSize];
}
try {
if (fileAsStream != null) {
fileAsStream.read(fileContents);
}
}
catch (IOException e) {
LOG.error("IOException while attempting to get file contents when revising podcast for "
+ filename + " in site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(IO_ALERT);
return "podcastRevise";
}
finally {
try {
if (fileAsStream != null)
fileAsStream.close();
} catch (IOException ioe) {
LOG.warn("IOException error while closing the stream:" + ioe);
}
}
}
}
Date displayDate = null;
Date displayDateRevise = null;
try {
try {
// SAK-13493: SimpleDateFormat.parse() did not enforce format specified, so
// had to call custom method to check if String was valid
if (DateUtil.isValidDate(selectedPodcast.displayDateRevise, getErrorMessageString(DATE_BY_HAND_FORMAT), rb.getLocale())) {
displayDateRevise = convertDateString(selectedPodcast.displayDateRevise,
getErrorMessageString(DATE_BY_HAND_FORMAT));
}
else {
throw new ParseException("Invalid displayDate stored in selectedPodcast", 0);
}
}
catch (ParseException e) {
// must have used date picker, so try again
if (isValidDate(selectedPodcast.displayDateRevise)) {
displayDateRevise = convertDateString(selectedPodcast.displayDateRevise,
FIXED_DATE_PICKER_FORMAT);
}
else {
throw new ParseException("Invalid displayDate entered while revising podcast " + selectedPodcast.filename, 0);
}
}
if (filenameChange) {
// filename has changed, so create an entirely new entry - is
// needed since filename part of resource URL
podcastService.addPodcast(selectedPodcast.title, displayDateRevise,
selectedPodcast.description, fileContents, filename,
fileContentType);
podcastService.removePodcast(selectedPodcast.getResourceId());
}
else {
// only title, description, or date has changed, so can revise
podcastService.revisePodcast(selectedPodcast.resourceId,
selectedPodcast.title, displayDateRevise,
selectedPodcast.description, fileContents,
selectedPodcast.filename);
}
/* FUTURE: Enable notification
if (email.equalsIgnoreCase("high")) {
EmailService.send("josrodri@iupui.edu","josrodri@iupui.edu",
"A podcast has been added to feed.",
"A podcast has been added to the list of podcasts. "
+ "It's publish date will determine when it will be available in the feed",
null, null, null);
}
else if (email.equalsIgnoreCase("low")) {
// FUTURE: email only those who have opted in
}
*/
}
catch (ParseException e1) {
LOG.error("ParseException attempting to convert date for " + selectedPodcast.title
+ " for site " + podcastService.getSiteId() + ". " + e1.getMessage(), e1);
date = "";
displayInvalidDateErrMsg = true;
return "podcastRevise";
}
catch (PermissionException e) {
LOG.error("PermissionException while revising podcast "
+ selectedPodcast.title + " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(PERMISSION_ALERT);
}
catch (InUseException e) {
LOG.warn("InUseException while revising podcast "
+ selectedPodcast.title + " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
}
catch (OverQuotaException e) {
LOG.warn("OverQuotaException while revising podcast "
+ selectedPodcast.title + " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(QUOTA_ALERT);
}
catch (ServerOverloadException e) {
LOG.warn("ServerOverloadException while revising podcast "
+ selectedPodcast.title + " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
}
catch (IdLengthException e) {
LOG.warn("IdLengthException while revising podcast with filename changed from "
+ selectedPodcast.filename + " to " + filename
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(LENGTH_ALERT);
return "podcastRevise";
}
catch (Exception e) {
// catches IdUnusedException TypeException
// IdInvalidException InconsistentException
// IdUniquenessException
LOG.error(e.getMessage() + " while revising podcast with filename changed from "
+ selectedPodcast.filename + " to " + filename
+ " for site " + podcastService.getSiteId() + ". " + e.getMessage(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
}
// Reset values to continue processing
date = null;
title = "";
description = "";
try {
fileAsStream = null;
} catch (Exception e){
LOG.warn("Exception error while setting the stream to null: " + e);
}
finally {
try {
if (fileAsStream != null)
fileAsStream.close();
} catch (IOException ioe) {
LOG.warn("IOException error while closing the stream:" + ioe);
}
}
filename = "";
displayNoTitleErrMsg = false;
return whereToGo;
}
/**
* Resets selectedPodcast bean since no revision is to be made
*/
public String processCancelRevise() {
selectedPodcast = null;
date = null;
title = "";
description = "";
try {
fileAsStream = null;
} catch (Exception e){
LOG.warn("Exception error while setting the stream to null: " + e);
}
finally {
try {
if (fileAsStream != null)
fileAsStream.close();
} catch (IOException ioe) {
LOG.warn("IOException error while closing the stream:" + ioe);
}
}
filename = "";
displayInvalidDateErrMsg = false;
displayNoTitleErrMsg = false;
return "cancel";
}
/**
* Used to call podcastService to actually delete selected podcast.
*/
public String processDeletePodcast() {
try {
podcastService.removePodcast(selectedPodcast.getResourceId());
return "cancel";
}
catch (PermissionException e) {
LOG.error("PermissionException while deleting podcast "
+ selectedPodcast.title + " from site " + podcastService.getSiteId()
+ ". " + e.getMessage(), e);
setErrorMessage(PERMISSION_ALERT);
}
catch (InUseException e) {
LOG.warn("InUseException while deleting podcast "
+ selectedPodcast.title + " from site " + podcastService.getSiteId()
+ ". " + e.getMessage(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
}
catch (Exception e) {
// For IdUnusedException and TypeException
LOG.error(e.getMessage() + " while deleting podcast "
+ selectedPodcast.title + " from site " + podcastService.getSiteId()
+ ". " + e.getMessage(), e);
setErrorMessage(INTERNAL_ERROR_ALERT);
}
// If here these was an error so stay on this page
return "podcastDelete";
}
/**
* Resets selectedPodcast bean since no deletion is to be made
*
* @return String
* Sent to return to main page.
*/
public String processCancelDelete() {
selectedPodcast = null;
return "cancel";
}
/**
* Returns whether a no file selected error message is displayed
*/
public boolean getDisplayNoFileErrMsg() {
return displayNoFileErrMsg;
}
public void setDisplayNoFileErrMsg(boolean displayNoFileErrMsg) {
this.displayNoFileErrMsg = displayNoFileErrMsg;
}
/**
* Returns whether a no date error message is displayed
*/
public boolean getDisplayNoDateErrMsg() {
return displayNoDateErrMsg;
}
public void setDisplayNoDateErrMsg(boolean displayNoDateErrMsg) {
this.displayNoDateErrMsg = displayNoDateErrMsg;
}
/**
* Returns whether a no title entered error message is displayed
*/
public boolean getDisplayNoTitleErrMsg() {
return displayNoTitleErrMsg;
}
public void setDisplayNoTitleErrMsg(boolean displayNoTitleErrMsg) {
this.displayNoTitleErrMsg = displayNoTitleErrMsg;
}
public boolean getErrorOnPage() {
return displayNoFileErrMsg || displayNoDateErrMsg || displayNoTitleErrMsg || displayInvalidDateErrMsg;
}
/**
* Returns whether an invalid date error message is displayed
*/
public boolean getDisplayInvalidDateErrMsg() {
return displayInvalidDateErrMsg;
}
/**
* @param displayInvalidDateErrMsg
* The displayInvalidDateErrMsg to set.
*/
public void setDisplayInvalidDateErrMsg(boolean displayInvalidDateErrMsg) {
this.displayInvalidDateErrMsg = displayInvalidDateErrMsg;
}
/**
* Performs validation of input when attempting to add a podcast.
* Checks filename, date, and title fields since those are the
* required ones. If errors, sets boolean flags so proper error
* messages appear on the page.
*
* @return boolean
* TRUE - input validated, FALSE - there were errors
*/
private boolean OKtoAdd() {
boolean OKtoAdd = true;
if (filename == null) {
displayNoFileErrMsg = true;
OKtoAdd = false;
}
else if (filename.trim().equals("")) {
displayNoFileErrMsg = true;
OKtoAdd = false;
}
else {
displayNoFileErrMsg = false;
}
if (date == null) {
displayNoDateErrMsg = true;
OKtoAdd = false;
}
else if (date.trim().equals("")) {
displayNoDateErrMsg = true;
OKtoAdd = false;
}
else {
displayNoDateErrMsg = false;
if (DateUtil.isValidDate(date, getErrorMessageString(DATE_BY_HAND_FORMAT), rb.getLocale())
|| isValidDate(date)) {
displayInvalidDateErrMsg = false;
}
else {
displayInvalidDateErrMsg = true;
OKtoAdd = false;
}
}
if (title == null) {
displayNoTitleErrMsg = true;
OKtoAdd = false;
}
else if (title.trim().equals("")) {
displayNoTitleErrMsg = true;
OKtoAdd = false;
}
else {
displayNoTitleErrMsg = false;
}
return OKtoAdd;
}
/**
* Sets the Faces error message by pulling the message from the
* MessageBundle using the name passed in
*
* @param key
* The name in the MessageBundle for the message wanted
*
* @return String
* The string that is the value of the message
*/
private String getErrorMessageString(String key) {
return getMessageFromBundle(key);
}
/**
* Performs date validation checking. Validator object
* does not do bounds checking, so do that and if OK,
* let Validator check for errors like Feb 30, etc.
*
* TODO: Try and find an actual validator to replace this
* method
*
* @param date
* The candidate String date
*
* @return boolean
* TRUE - Conforms to a valid input date format string
* FALSE - Does not conform
*/
private boolean isValidDate(String date) {
boolean validDate = true;
// Should contain date part, time port, AM/PM part
String[] wholeDateSplit = date.split(" ");
// if not in 2 parts, input error
if (wholeDateSplit.length != 3) {
return false;
}
// since date entered first, check it first
String[] dateSplit = wholeDateSplit[0].split("/");
if (dateSplit.length != 3) {
return false;
}
else {
if(!dateSplit[0].equals("") && !dateSplit[1].equals("") && !dateSplit[2].equals("")) {
int month = Integer.parseInt(dateSplit[0]);
int day = Integer.parseInt(dateSplit[1]);
if (month < 0 || month > 12) {
return false;
}
else if (day < 0 || day > 31) {
return false;
}
else if (dateSplit[2].length() != 4) {
return false;
}
else {
int year = Integer.parseInt(dateSplit[2]);
validDate = Validator.checkDate(day, month, year);
}
} else {
return false;
}
}
if (! validDate) {
return false;
}
else {
// Date's OK, now to the time
String[] timeSplit = wholeDateSplit[1].split(":");
// Valid times are hh:mm or hh:mm:ss, so check for either
if (timeSplit.length < 2 || timeSplit.length > 3) {
return false;
}
else if (timeSplit.length == 2) {
if(!timeSplit[0].equals("") && !timeSplit[1].equals("")) {
int hour = Integer.parseInt(timeSplit[0]);
int min = Integer.parseInt(timeSplit[1]);
if (hour < 1 || hour > 12) {
return false;
}
else if (min < 0 || min > 59) {
return false;
}
}
else {
return false;
}
}
else {
if(!timeSplit[0].equals("") && !timeSplit[1].equals("") && !timeSplit[2].equals("")) {
int hour = Integer.parseInt(timeSplit[0]);
int min = Integer.parseInt(timeSplit[1]);
int sec = Integer.parseInt(timeSplit[2]);
if (hour < 1 || hour > 12) {
return false;
}
else if (min < 0 || min > 59) {
return false;
}
else if (sec < 0 || sec > 59) {
return false;
}
}
else {
return false;
}
}
}
// We want a 12 hour clock, so AM/PM needs to be specified
if ("AM".equalsIgnoreCase(wholeDateSplit[2]) || "PM".equalsIgnoreCase(wholeDateSplit[2])) {
return true;
}
else {
return false;
}
}
private String formatDate(long date) {
String disTimeString = TimeService.newTime(date).toStringGmtFull();
String temp = monStrings.get(disTimeString.substring(0, 3)) + disTimeString.substring(3);
return temp;
}
/**
* Returns whether a file too large tried to be uploaded. (SAK-9822)
*/
public boolean getUploadStatus() {
LOG.debug("getUploadStatus()");
FacesContext context = FacesContext.getCurrentInstance();
String status = (String) ((HttpServletRequest) context.getExternalContext().getRequest()).getAttribute("upload.status");
return "size_limit_exceeded".equals(status);
}
/**
* Returns the message that a file too large tried to be uploaded. (SAK-9822)
*/
public String getMaxSizeExceededAlert() {
// TODO: pull this from the ServerConfigurationService? RequestFilter?
FacesContext context = FacesContext.getCurrentInstance();
String uploadMaxSize = ServerConfigurationService.getString("content.upload.max");
Long override = (Long) ((HttpServletRequest) context.getExternalContext().getRequest()).getAttribute("upload.limit");
if (override != null && override > 0) {
uploadMaxSize = override.toString();
}
return getMessageFromBundle("max_size_exceeded_alert", new String [] { uploadMaxSize });
}
public String getMessageFromBundle(String key, Object[] args) {
return MessageFormat.format(getMessageFromBundle(key), args);
}
public String getMessageFromBundle(String key) {
if (rb == null) {
String bundle = FacesContext.getCurrentInstance().getApplication().getMessageBundle();
rb = new ResourceLoader(bundle);
}
return rb.getString(key);
}
}