0001: /**********************************************************************************
0002: * $URL: https://source.sakaiproject.org/svn/podcasts/tags/sakai_2-4-1/podcasts-app/src/java/org/sakaiproject/tool/podcasts/podHomeBean.java $
0003: * $Id: podHomeBean.java 28734 2007-04-12 01:07:21Z ajpoland@iupui.edu $
0004: ***********************************************************************************
0005: *
0006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
0007: *
0008: * Licensed under the Educational Community License, Version 1.0 (the "License");
0009: * you may not use this file except in compliance with the License.
0010: * You may obtain a copy of the License at
0011: *
0012: * http://www.opensource.org/licenses/ecl1.php
0013: *
0014: * Unless required by applicable law or agreed to in writing, software
0015: * distributed under the License is distributed on an "AS IS" BASIS,
0016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: * See the License for the specific language governing permissions and
0018: * limitations under the License.
0019: *
0020: **********************************************************************************/package org.sakaiproject.tool.podcasts;
0021:
0022: import java.io.BufferedInputStream;
0023: import java.io.IOException;
0024: import java.text.DecimalFormat;
0025: import java.text.ParseException;
0026: import java.text.SimpleDateFormat;
0027: import java.util.ArrayList;
0028: import java.util.Collection;
0029: import java.util.Date;
0030: import java.util.HashMap;
0031: import java.util.Iterator;
0032: import java.util.List;
0033: import java.util.Locale;
0034: import java.util.Map;
0035: import java.util.ResourceBundle;
0036: import java.util.TimeZone;
0037:
0038: import javax.faces.application.FacesMessage;
0039: import javax.faces.component.UIComponent;
0040: import javax.faces.context.ExternalContext;
0041: import javax.faces.context.FacesContext;
0042: import javax.faces.event.AbortProcessingException;
0043: import javax.faces.event.ActionEvent;
0044: import javax.faces.event.PhaseId;
0045: import javax.faces.event.ValueChangeEvent;
0046: import javax.faces.model.SelectItem;
0047:
0048: import org.apache.commons.fileupload.FileItem;
0049: import org.apache.commons.logging.Log;
0050: import org.apache.commons.logging.LogFactory;
0051: import org.sakaiproject.api.app.podcasts.PodcastService;
0052: import org.sakaiproject.authz.api.PermissionsHelper;
0053: import org.sakaiproject.authz.cover.FunctionManager;
0054: import org.sakaiproject.component.cover.ServerConfigurationService;
0055: import org.sakaiproject.content.api.ContentResource;
0056: import org.sakaiproject.entity.api.Entity;
0057: import org.sakaiproject.entity.api.EntityPropertyNotDefinedException;
0058: import org.sakaiproject.entity.api.EntityPropertyTypeException;
0059: import org.sakaiproject.entity.api.ResourceProperties;
0060: import org.sakaiproject.exception.IdInvalidException;
0061: import org.sakaiproject.exception.IdLengthException;
0062: import org.sakaiproject.exception.IdUniquenessException;
0063: import org.sakaiproject.exception.IdUnusedException;
0064: import org.sakaiproject.exception.IdUsedException;
0065: import org.sakaiproject.exception.InUseException;
0066: import org.sakaiproject.exception.InconsistentException;
0067: import org.sakaiproject.exception.OverQuotaException;
0068: import org.sakaiproject.exception.PermissionException;
0069: import org.sakaiproject.exception.ServerOverloadException;
0070: import org.sakaiproject.site.api.Site;
0071: import org.sakaiproject.site.api.SitePage;
0072: import org.sakaiproject.site.cover.SiteService;
0073: import org.sakaiproject.time.api.Time;
0074: import org.sakaiproject.time.cover.TimeService;
0075: import org.sakaiproject.tool.cover.ToolManager;
0076: import org.sakaiproject.util.Validator;
0077:
0078: public class podHomeBean {
0079:
0080: // Message Bundle handles
0081: private static final String QUOTA_ALERT = "quota_alert";
0082: private static final String LENGTH_ALERT = "length_alert";
0083: private static final String PERMISSION_ALERT = "permission_alert";
0084: private static final String INTERNAL_ERROR_ALERT = "internal_error_alert";
0085: private static final String ID_UNUSED_ALERT = "id_unused_alert";
0086: private static final String ID_INVALID_ALERT = "id_invalid_alert";
0087: private static final String IO_ALERT = "io_alert";
0088: private static final String ID_USED_ALERT = "id_used_alert";
0089:
0090: // Patterns for Date and Number formatting
0091: private static final String PUBLISH_DATE_FORMAT = "publish_date_format";
0092: private static final String DATE_PICKER_FORMAT = "date_picker_format";
0093: private static final String DATE_BY_HAND_FORMAT = "date_by_hand_format";
0094: private static final String INTERNAL_DATE_FORMAT = "internal_date_format";
0095:
0096: private static final String LAST_MODIFIED_TIME_FORMAT = "hh:mm a z";
0097: private static final String LAST_MODIFIED_DATE_FORMAT = "MM/dd/yyyy";
0098:
0099: // error handling variables
0100: private boolean displayNoFileErrMsg = false;
0101: private boolean displayNoDateErrMsg = false;
0102: private boolean displayNoTitleErrMsg = false;
0103: private boolean displayInvalidDateErrMsg = false;
0104:
0105: /**
0106: * Bean to store information about a single podcast.
0107: * Used by main page to display and to store which
0108: * podcast is to be Revised or Deleted.
0109: *
0110: * @author josephrodriguez
0111: */
0112: public class DecoratedPodcastBean {
0113:
0114: private String resourceId;
0115: private String filename;
0116: private long fileSize;
0117: private String displayDate;
0118: private String displayDateRevise;
0119: private String title;
0120: private String description;
0121: private String size;
0122: private String type;
0123: private String postedTime;
0124: private String postedDate;
0125: private String author;
0126: private String fileURL;
0127: private String newWindow;
0128: private String fileContentType;
0129:
0130: public DecoratedPodcastBean() {
0131:
0132: }
0133:
0134: public String getDescription() {
0135: return description;
0136: }
0137:
0138: public void setDescription(String decsription) {
0139: this .description = decsription;
0140: }
0141:
0142: public String getDisplayDate() {
0143: return displayDate;
0144: }
0145:
0146: /**
0147: * @param displayDateRevise The displayDateRevise to set.
0148: */
0149: public void setDisplayDateRevise(String displayDateRevise) {
0150: this .displayDateRevise = displayDateRevise;
0151: }
0152:
0153: /** Returns the revised display date for this podcast **/
0154: public String getDisplayDateRevise() {
0155: String dispDate = null;
0156:
0157: if (displayDateRevise == null) {
0158: dispDate = displayDate;
0159: } else {
0160: dispDate = displayDateRevise;
0161: }
0162:
0163: SimpleDateFormat formatter = new SimpleDateFormat(
0164: getErrorMessageString(DATE_BY_HAND_FORMAT));
0165: formatter.setTimeZone(TimeService.getLocalTimeZone());
0166:
0167: try {
0168: Date tempDate = convertDateString(dispDate,
0169: getErrorMessageString(PUBLISH_DATE_FORMAT));
0170:
0171: return formatter.format(tempDate);
0172:
0173: } catch (ParseException e) {
0174: // since revising, only log error if malformed date and not just blank
0175: if (!"".equals(dispDate)) {
0176: LOG
0177: .error("ParseException while rendering Revise Podcast page. ");
0178: }
0179: }
0180:
0181: return dispDate;
0182:
0183: }
0184:
0185: public void setDisplayDate(String displayDate) {
0186: this .displayDate = displayDate;
0187: }
0188:
0189: public String getFilename() {
0190: return filename;
0191: }
0192:
0193: public void setFilename(String filename) {
0194: this .filename = filename;
0195: }
0196:
0197: /** Returns the size (as a formatted String) for this podcast's file **/
0198: public String getSize() {
0199: return size;
0200: }
0201:
0202: /** Sets the size (as a formatted String) for this podcast's file **/
0203: public void setSize(String size) {
0204: this .size = size;
0205: }
0206:
0207: public String getTitle() {
0208: return title;
0209: }
0210:
0211: public void setTitle(String title) {
0212: this .title = title;
0213: }
0214:
0215: /** Returns this podcast's content MIME type ***/
0216: public String getType() {
0217: return type;
0218: }
0219:
0220: /** Sets this podcast's content MIME type ***/
0221: public void setType(String type) {
0222: this .type = type;
0223: }
0224:
0225: public String getPostedTime() {
0226: return postedTime;
0227: }
0228:
0229: public void setPostedTime(String postedTime) {
0230: this .postedTime = postedTime;
0231: }
0232:
0233: public String getPostedDate() {
0234: return postedDate;
0235: }
0236:
0237: public void setPostedDate(String postedDate) {
0238: this .postedDate = postedDate;
0239: }
0240:
0241: public String getAuthor() {
0242: return author;
0243: }
0244:
0245: public void setAuthor(String author) {
0246: this .author = author;
0247: }
0248:
0249: public String getResourceId() {
0250: return resourceId;
0251: }
0252:
0253: public void setResourceId(String resourceId) {
0254: this .resourceId = resourceId;
0255: }
0256:
0257: public long getFileSize() {
0258: return fileSize;
0259: }
0260:
0261: public void setFileSize(long fileSize) {
0262: this .fileSize = fileSize;
0263: }
0264:
0265: /**
0266: * Returns the file URL for the podcast. If errors, return empty
0267: * string.
0268: */
0269: public String getFileURL() {
0270: try {
0271: return podcastService.getPodcastFileURL(resourceId);
0272:
0273: } catch (PermissionException e) {
0274: LOG.info("PermissionException getting file URL for "
0275: + resourceId
0276: + "while displaying podcast file for site "
0277: + podcastService.getSiteId());
0278: setErrorMessage(PERMISSION_ALERT);
0279:
0280: } catch (IdUnusedException e) {
0281: LOG.info("IdUnusedException getting file URL for "
0282: + resourceId
0283: + " while displaying podcast file for site "
0284: + podcastService.getSiteId());
0285: setErrorMessage(ID_UNUSED_ALERT);
0286:
0287: }
0288:
0289: return "";
0290: }
0291:
0292: public void setFileURL(String fileURL) {
0293: this .fileURL = fileURL;
0294: }
0295:
0296: /**
0297: * Returns a value to determine if file should be opened in same
0298: * window or a new one. _self means open in same window, _blank
0299: * means open in a new window. If this resource is not a file,
0300: * it will return an empty string.
0301: *
0302: * @return String
0303: * Returns either '_self' or '_blank' ('' if not a file)
0304: */
0305: public String getNewWindow() {
0306: return Validator.getResourceTarget(fileContentType);
0307: }
0308:
0309: public void setNewWindow(String newWindow) {
0310: this .newWindow = newWindow;
0311: }
0312:
0313: public String getFileContentType() {
0314: return fileContentType;
0315: }
0316:
0317: public void setFileContentType(String fileContentType) {
0318: this .fileContentType = fileContentType;
0319: }
0320:
0321: } // end of DecoratedPodcastBean
0322:
0323: // ====================== End of DecoratedPodcastBean ====================== //
0324:
0325: // podHomeBean constants
0326: private static final String NO_RESOURCES_ERR_MSG = "no_resource_alert";
0327: private static final String NO_RESOURCES_ERR_MSG2 = "no_resource_alert2";
0328: private static final String RESOURCEID = "resourceId";
0329: private static final String FEED_URL_MIDDLE = "podcasts/site/";
0330: private static final String MB = "MB";
0331: private static final String BYTES = "Bytes";
0332:
0333: private static final String MB_NUMBER_FORMAT = "#.#";
0334: private static final String BYTE_NUMBER_FORMAT = "#,###";
0335:
0336: // For date String conversion
0337: private static final Map monStrings;
0338:
0339: static {
0340: monStrings = new HashMap();
0341:
0342: monStrings.put("Jan", "January");
0343: monStrings.put("Feb", "February");
0344: monStrings.put("Mar", "March");
0345: monStrings.put("Apr", "April");
0346: monStrings.put("Jun", "June");
0347: monStrings.put("Jul", "July");
0348: monStrings.put("Aug", "August");
0349: monStrings.put("Sep", "September");
0350: monStrings.put("Oct", "October");
0351: monStrings.put("Nov", "November");
0352: monStrings.put("Dec", "December");
0353: }
0354:
0355: // configurable toolId for Resources tool check
0356: private String RESOURCE_TOOL_ID = ServerConfigurationService
0357: .getString("podcasts.toolid", "sakai.resources");
0358:
0359: /** Used to pull message bundle */
0360: private final String MESSAGE_BUNDLE = "org.sakaiproject.api.podcasts.bundle.Messages";
0361:
0362: // inject the services needed
0363: private PodcastService podcastService;
0364:
0365: private Log LOG = LogFactory.getLog(podHomeBean.class);
0366:
0367: // variables to hold miscellanous information
0368: private List contents;
0369: private String URL;
0370: private DecoratedPodcastBean selectedPodcast;
0371:
0372: // used by podAdd.jsp for adding a podcast
0373: private String filename = "";
0374: private String date = "";
0375: private String title;
0376: private String description;
0377: private String email;
0378: private long fileSize = 0;
0379: private String fileContentType;
0380: private BufferedInputStream fileAsStream;
0381:
0382: // FUTURE: Will be used to implement Email notifications
0383: private SelectItem[] emailItems = {
0384: new SelectItem("none", "None - No notification"),
0385: new SelectItem("low",
0386: "Low - Only participants who have opted in"),
0387: new SelectItem("high", "High - All participants") };
0388:
0389: public podHomeBean() {
0390: }
0391:
0392: /**
0393: * Determines if Resource tool part of the site. Needed to store podcasts.
0394: */
0395: public boolean getResourceToolExists() {
0396: boolean resourceToolExists = false;
0397:
0398: try {
0399: //
0400: // Get a list of tool ids and see if RESOURCE_TOOL_ID is in the returned Collection
0401: LOG
0402: .debug("Checking for presence of Sakai Resources tool using RESOURCE_TOOL_ID = "
0403: + RESOURCE_TOOL_ID);
0404: Site this Site = SiteService.getSite(ToolManager
0405: .getCurrentPlacement().getContext());
0406:
0407: Collection toolsInSite = this Site
0408: .getTools(RESOURCE_TOOL_ID);
0409:
0410: if (!toolsInSite.isEmpty()) {
0411: resourceToolExists = true;
0412: }
0413: } catch (IdUnusedException e) {
0414: LOG
0415: .error("No Site found while trying to check if site has Resources tool.");
0416:
0417: // Only want to display this message if they are instructors or administrators
0418: // so if student say it exists
0419: if (getCanUpdateSite()) {
0420: FacesContext
0421: .getCurrentInstance()
0422: .addMessage(
0423: null,
0424: new FacesMessage(
0425: "Alert: "
0426: + getErrorMessageString(NO_RESOURCES_ERR_MSG)
0427: + ToolManager
0428: .getTool(
0429: RESOURCE_TOOL_ID)
0430: .getTitle()
0431: + " "
0432: + getErrorMessageString(NO_RESOURCES_ERR_MSG2)));
0433: }
0434: }
0435:
0436: // Since multiple checks for this, only want to set the message the first time
0437: if (!resourceToolExists
0438: && (!FacesContext.getCurrentInstance().getMessages()
0439: .hasNext())) {
0440:
0441: if (getCanUpdateSite()) {
0442: FacesContext
0443: .getCurrentInstance()
0444: .addMessage(
0445: null,
0446: new FacesMessage(
0447: "Alert: "
0448: + getErrorMessageString(NO_RESOURCES_ERR_MSG)
0449: + ToolManager
0450: .getTool(
0451: RESOURCE_TOOL_ID)
0452: .getTitle()
0453: + " "
0454: + getErrorMessageString(NO_RESOURCES_ERR_MSG2)));
0455: }
0456: }
0457:
0458: return resourceToolExists;
0459: }
0460:
0461: /**
0462: * Passes an error message to the Spring framework to display on page.
0463: *
0464: * @param alertMsg
0465: * The key to get the message from the message bundle
0466: */
0467: private void setErrorMessage(String alertMsg) {
0468: FacesContext.getCurrentInstance().addMessage(
0469: null,
0470: new FacesMessage("Alert: "
0471: + getErrorMessageString(alertMsg)));
0472: }
0473:
0474: /**
0475: * Determines if the podcast folder exists. If it does not, it will attempt
0476: * to create it.
0477: *
0478: * @return boolean
0479: * TRUE if folder exists, FALSE otherwise.
0480: */
0481: public boolean getPodcastFolderExists() {
0482: boolean podcastFolderExists = false;
0483:
0484: if (getResourceToolExists()) {
0485: // we know resources tool exists, but need to know if podcast folder
0486: // does
0487: try {
0488: podcastFolderExists = podcastService
0489: .checkPodcastFolder();
0490:
0491: } catch (InUseException e) {
0492: LOG
0493: .info("InUseException while attempting to determine if podcast folder exists."
0494: + " for site "
0495: + podcastService.getSiteId());
0496: setErrorMessage(INTERNAL_ERROR_ALERT);
0497:
0498: } catch (PermissionException e) {
0499: LOG
0500: .warn("PermissionException while attempting to determine if podcast folder exists."
0501: + " for site "
0502: + podcastService.getSiteId());
0503: setErrorMessage(PERMISSION_ALERT);
0504:
0505: }
0506: } else if (!getCanUpdateSite()) {
0507: // Resources tool does not exist but for students
0508: // say true to get "There are no podcasts..." message instead of
0509: // error
0510: podcastFolderExists = true;
0511: }
0512:
0513: return podcastFolderExists;
0514: }
0515:
0516: /**
0517: * Returns the URL to point your podcatcher to in order to grab the feed.
0518: *
0519: * @return String
0520: * The feed URL.
0521: */
0522: public String getURL() {
0523: URL = ServerConfigurationService.getServerUrl()
0524: + Entity.SEPARATOR + FEED_URL_MIDDLE
0525: + podcastService.getSiteId();
0526: return URL;
0527: }
0528:
0529: /**
0530: * Used to inject the podcast service into this bean.
0531: *
0532: * @param podcastService
0533: * The podcast service this bean needs
0534: */
0535: public void setPodcastService(PodcastService podcastService) {
0536: this .podcastService = podcastService;
0537: }
0538:
0539: /**
0540: * Gets a particular podcast and packages it as a DecoratedPodcastBean
0541: *
0542: * @param podcastProperties
0543: * Contains the ResourceProperties object of a podcast resource
0544: * @param resourceId
0545: * The resource ID for the podcast
0546: *
0547: * @return DecoratedPodcastBean
0548: * The packaged podcast or null and exception if problems
0549: *
0550: * @throws EntityPropertyNotDefinedException
0551: * The property wanted was not found
0552: * @throws EntityPropertyTypeException
0553: * The property (Date/Time) was not a valid one
0554: */
0555: public DecoratedPodcastBean getAPodcast(
0556: ResourceProperties podcastProperties, String resourceId)
0557: throws EntityPropertyNotDefinedException,
0558: EntityPropertyTypeException {
0559:
0560: DecoratedPodcastBean podcastInfo = new DecoratedPodcastBean();
0561:
0562: // store resourceId
0563: podcastInfo.setResourceId(resourceId);
0564:
0565: // store Title and Description
0566: podcastInfo
0567: .setTitle(podcastProperties
0568: .getPropertyFormatted(ResourceProperties.PROP_DISPLAY_NAME));
0569: podcastInfo
0570: .setDescription(podcastProperties
0571: .getPropertyFormatted(ResourceProperties.PROP_DESCRIPTION));
0572:
0573: Date tempDate = null;
0574: final SimpleDateFormat formatter = new SimpleDateFormat(
0575: getErrorMessageString(PUBLISH_DATE_FORMAT));
0576: formatter.setTimeZone(TimeService.getLocalTimeZone());
0577:
0578: tempDate = podcastService
0579: .getGMTdate(podcastProperties.getTimeProperty(
0580: PodcastService.DISPLAY_DATE).getTime());
0581:
0582: podcastInfo.setDisplayDate(formatter.format(tempDate));
0583:
0584: final String filename = podcastProperties
0585: .getProperty(ResourceProperties.PROP_ORIGINAL_FILENAME);
0586:
0587: // if user puts URL instead of file, this is result
0588: // of retrieving filename
0589: if (filename == null)
0590: return null;
0591:
0592: podcastInfo.setFilename(filename);
0593:
0594: // get content type
0595: podcastInfo.setFileContentType(podcastProperties
0596: .getProperty(ResourceProperties.PROP_CONTENT_TYPE));
0597:
0598: // store actual and formatted file size
0599: // determine whether to display filesize as bytes or MB
0600: long size = Long.parseLong(podcastProperties
0601: .getProperty(ResourceProperties.PROP_CONTENT_LENGTH));
0602: podcastInfo.setFileSize(size);
0603:
0604: double sizeMB = size / (1024.0 * 1024.0);
0605: DecimalFormat df = new DecimalFormat(MB_NUMBER_FORMAT);
0606: String sizeString;
0607: if (sizeMB > 0.3) {
0608: sizeString = df.format(sizeMB) + MB;
0609: } else {
0610: df.applyPattern(BYTE_NUMBER_FORMAT);
0611: sizeString = "" + df.format(size) + " " + BYTES;
0612: }
0613: podcastInfo.setSize(sizeString);
0614:
0615: final String extn = Validator.getFileExtension(filename);
0616: if (extn != "") {
0617: podcastInfo.setType(Validator.getFileExtension(filename)
0618: .toUpperCase());
0619:
0620: } else {
0621: podcastInfo.setType("UNK");
0622:
0623: }
0624:
0625: // get and format last modified time
0626: formatter.applyPattern(LAST_MODIFIED_TIME_FORMAT);
0627:
0628: tempDate = new Date(podcastProperties.getTimeProperty(
0629: ResourceProperties.PROP_MODIFIED_DATE).getTime());
0630:
0631: podcastInfo.setPostedTime(formatter.format(tempDate));
0632:
0633: // get and format last modified date
0634: formatter.applyPattern(LAST_MODIFIED_DATE_FORMAT);
0635:
0636: tempDate = new Date(podcastProperties.getTimeProperty(
0637: ResourceProperties.PROP_MODIFIED_DATE).getTime());
0638:
0639: podcastInfo.setPostedDate(formatter.format(tempDate));
0640:
0641: // get author
0642: podcastInfo.setAuthor(podcastProperties
0643: .getPropertyFormatted(ResourceProperties.PROP_CREATOR));
0644:
0645: return podcastInfo;
0646: }
0647:
0648: /**
0649: * Construct a List of DecoratedPodcastBeans for display on main page
0650: *
0651: * @return List
0652: * List of DecoratedPodcastBeans that are the podcasts
0653: */
0654: public List getContents() {
0655: try {
0656: contents = podcastService.getPodcasts();
0657:
0658: // if cannot update site (ie, student) only display published
0659: // podcasts
0660: if (!podcastService.canUpdateSite(podcastService
0661: .getSiteId())) {
0662: contents = podcastService.filterPodcasts(contents);
0663:
0664: }
0665:
0666: } catch (PermissionException e) {
0667: LOG
0668: .warn("PermissionException getting podcasts for display in site "
0669: + podcastService.getSiteId()
0670: + ". "
0671: + e.getMessage());
0672: setErrorMessage(PERMISSION_ALERT);
0673:
0674: } catch (InUseException e) {
0675: LOG
0676: .warn("InUseException while getting podcasts for display"
0677: + podcastService.getSiteId()
0678: + ". "
0679: + e.getMessage());
0680: setErrorMessage(INTERNAL_ERROR_ALERT);
0681:
0682: } catch (IdInvalidException e) {
0683: LOG
0684: .error("IdInvalidException while getting podcasts for display "
0685: + podcastService.getSiteId()
0686: + ". "
0687: + e.getMessage());
0688: setErrorMessage(ID_INVALID_ALERT);
0689:
0690: } catch (InconsistentException e) {
0691: LOG
0692: .error("InconsistentException while getting podcasts for display "
0693: + podcastService.getSiteId()
0694: + ". "
0695: + e.getMessage());
0696: setErrorMessage(INTERNAL_ERROR_ALERT);
0697:
0698: return null;
0699:
0700: } catch (IdUsedException e) {
0701: LOG
0702: .warn("IdUsedException while gettting podcasts for display "
0703: + podcastService.getSiteId()
0704: + ". "
0705: + e.getMessage());
0706: setErrorMessage(ID_UNUSED_ALERT);
0707:
0708: }
0709:
0710: // create local List of DecoratedBeans
0711: ArrayList decoratedPodcasts = new ArrayList();
0712:
0713: if (contents != null) {
0714: Iterator podcastIter = contents.iterator();
0715:
0716: // for each bean
0717: while (podcastIter.hasNext()) {
0718: try {
0719: // get its properties from ContentHosting
0720: ContentResource podcastResource = (ContentResource) podcastIter
0721: .next();
0722: ResourceProperties podcastProperties = podcastResource
0723: .getProperties();
0724:
0725: // Create a new decorated bean to store the info
0726: DecoratedPodcastBean podcastInfo = getAPodcast(
0727: podcastProperties, podcastResource.getId());
0728:
0729: // add it to the List to send to the page
0730: // if URL, will return null so skip it
0731: if (podcastInfo != null)
0732: decoratedPodcasts.add(podcastInfo);
0733:
0734: // get the next podcast if it exists
0735: } catch (EntityPropertyNotDefinedException e) {
0736: LOG
0737: .error("EntityPropertyNotDefinedException while creating DecoratedPodcastBean "
0738: + " for site "
0739: + podcastService.getSiteId()
0740: + ". SKIPPING..." + e.getMessage());
0741:
0742: } catch (EntityPropertyTypeException e) {
0743: LOG
0744: .error("EntityPropertyTypeException while creating DecoratedPodcastBean "
0745: + " for site "
0746: + podcastService.getSiteId()
0747: + ". SKIPPING..." + e.getMessage());
0748:
0749: }
0750:
0751: }
0752:
0753: }
0754:
0755: return decoratedPodcasts;
0756: }
0757:
0758: /**
0759: * Resources/podcasts exists, but are there any actual podcasts
0760: *
0761: * @return boolean
0762: * TRUE if there are podcasts, FALSE otherwise
0763: */
0764: public boolean getActPodcastsExist() {
0765: boolean actPodcastsExist = false;
0766:
0767: // if student on site that has Podcasts but no Resources, want "There are no..."
0768: if (!getResourceToolExists() && !podcastService.canUpdateSite()) {
0769: return false;
0770: }
0771:
0772: if (!getPodcastFolderExists()) {
0773: // if for some reason there is not a podcast folder
0774: // for example, was renamed in Resources
0775: actPodcastsExist = false;
0776:
0777: } else {
0778: // ask the service if there is anything in the podcast folder
0779: try {
0780: actPodcastsExist = podcastService
0781: .checkForActualPodcasts();
0782:
0783: } catch (PermissionException e) {
0784: LOG
0785: .warn("PermissionException while determining if there are files in the podcast folder "
0786: + " for site "
0787: + podcastService.getSiteId()
0788: + ". "
0789: + e.getMessage());
0790: setErrorMessage(PERMISSION_ALERT);
0791: }
0792: }
0793:
0794: return actPodcastsExist;
0795: }
0796:
0797: /**
0798: * To set the selectedPodcast DecoratedPodcastBean when Revision and
0799: * Deletion links are clicked (possibly Download also)
0800: *
0801: * @param e
0802: * ActionEvent object generated by clicking on a link
0803: */
0804: public void podMainListener(ActionEvent e) {
0805: FacesContext context = FacesContext.getCurrentInstance();
0806: Map requestParams = context.getExternalContext()
0807: .getRequestParameterMap();
0808: final String resourceId = (String) requestParams
0809: .get(RESOURCEID);
0810:
0811: setPodcastSelected(resourceId);
0812: }
0813:
0814: /**
0815: * Does the actual filling up of the selectedPodcast bean
0816: *
0817: * @param resourceId
0818: * Resource ID for the podcast whose link was selected
0819: */
0820: public void setPodcastSelected(String resourceId) {
0821: Iterator podcastIter = contents.iterator();
0822:
0823: // for each bean
0824: while (podcastIter.hasNext()) {
0825: try {
0826:
0827: // get its properties from ContentHosting
0828: ContentResource podcastResource = (ContentResource) podcastIter
0829: .next();
0830:
0831: if (podcastResource.getId().equals(resourceId)) {
0832: selectedPodcast = getAPodcast(podcastResource
0833: .getProperties(), podcastResource.getId());
0834: break; // found and filled, get out of loop
0835: }
0836:
0837: } catch (EntityPropertyNotDefinedException e) {
0838: LOG
0839: .error("EntityPropertyNotDefinedException while attempting to fill selectedPodcast property "
0840: + " for site "
0841: + podcastService.getSiteId()
0842: + ". SKIPPING..." + e.getMessage());
0843: throw new Error(e);
0844:
0845: } catch (EntityPropertyTypeException e) {
0846: LOG
0847: .error("EntityPropertyTypeException while attempting to fill selectedPodcast property "
0848: + " for site "
0849: + podcastService.getSiteId()
0850: + ". SKIPPING..." + e.getMessage());
0851: throw new Error(e);
0852:
0853: }
0854: }
0855: }
0856:
0857: /**
0858: * Returns the current DecoratedPodcastBean set as selectedPodcast.
0859: */
0860: public DecoratedPodcastBean getSelectedPodcast() {
0861: return selectedPodcast;
0862: }
0863:
0864: /**
0865: * Use to set the selectedPodcast object.
0866: */
0867: public void setSelectedPodcast(DecoratedPodcastBean selectedPodcast) {
0868: this .selectedPodcast = selectedPodcast;
0869: }
0870:
0871: public String getFilename() {
0872: return filename;
0873: }
0874:
0875: public void setFilename(String filename) {
0876: this .filename = filename;
0877: }
0878:
0879: public String getDate() {
0880: return date;
0881: }
0882:
0883: public void setDate(String date) {
0884: this .date = date;
0885: }
0886:
0887: public String getTitle() {
0888: return title;
0889: }
0890:
0891: public void setTitle(String title) {
0892: this .title = title;
0893: }
0894:
0895: public String getDescription() {
0896: return description;
0897: }
0898:
0899: public void setDescription(String description) {
0900: this .description = description;
0901: }
0902:
0903: /**
0904: * FUTURE: To display the possible email notification levels
0905: *
0906: * @return SelectItem []
0907: * List of possible email notification levels
0908: */
0909: public SelectItem[] getEmailItems() {
0910: return emailItems;
0911: }
0912:
0913: /**
0914: * FUTURE: Returns the notification level set by the user
0915: *
0916: * @return String
0917: * Returns the current notification level
0918: */
0919: public String getemail() {
0920: return email;
0921: }
0922:
0923: /**
0924: * FUTURE: Sets the notification level
0925: *
0926: * @param email
0927: * String representing the notification level
0928: */
0929: public void setemail(String email) {
0930: this .email = email;
0931: }
0932:
0933: /**
0934: * Returns boolean if user can update podcasts. Used to display modification
0935: * options on main page.
0936: */
0937: public boolean getCanUpdateSite() {
0938: return podcastService.canUpdateSite();
0939: }
0940:
0941: public boolean getHasReadPerm() {
0942: if (podcastService.canUpdateSite()) {
0943: return true;
0944: } else if (!getResourceToolExists()) {
0945: return false;
0946: } else {
0947: boolean b = podcastService
0948: .hasPerm(PodcastService.READ_PERMISSIONS);
0949: return b;
0950: }
0951: }
0952:
0953: public boolean getHasNewPerm() {
0954: if (podcastService.canUpdateSite()) {
0955: return true;
0956: } else if (!getResourceToolExists()) {
0957: return false;
0958: } else {
0959: return podcastService
0960: .hasPerm(PodcastService.NEW_PERMISSIONS);
0961: }
0962: }
0963:
0964: public boolean getHasReviseAnyPerm() {
0965: if (podcastService.canUpdateSite()) {
0966: return true;
0967: } else if (!getResourceToolExists()) {
0968: return false;
0969: } else {
0970: return podcastService
0971: .hasPerm(PodcastService.REVISE_ANY_PERMISSIONS);
0972: }
0973: }
0974:
0975: public boolean getHasReviseOwnPerm() {
0976: if (podcastService.canUpdateSite()) {
0977: return true;
0978: } else {
0979: return podcastService
0980: .hasPerm(PodcastService.REVISE_OWN_PERMISSIONS);
0981: }
0982: }
0983:
0984: public boolean getHasDelAnyPerm() {
0985: if (podcastService.canUpdateSite()) {
0986: return true;
0987: } else {
0988: return podcastService
0989: .hasPerm(PodcastService.DELETE_ANY_PERMISSIONS);
0990: }
0991: }
0992:
0993: public boolean getHasDelOwnPerm() {
0994: if (podcastService.canUpdateSite()) {
0995: return true;
0996: } else {
0997: return podcastService
0998: .hasPerm(PodcastService.DELETE_OWN_PERMISSIONS);
0999: }
1000: }
1001:
1002: public String getUserName() {
1003: return podcastService.getUserName();
1004: }
1005:
1006: /**
1007: * Creates a BufferedInputStream to get ready to upload file selected. Used
1008: * by Add Podcast and Revise Podcast pages.
1009: *
1010: * @param event
1011: * ValueChangeEvent object generated by selecting a file to
1012: * upload.
1013: *
1014: * @throws AbortProcessingException
1015: * Internal processing error attempting to set up BufferedInputStream
1016: */
1017: public void processFileUpload(ValueChangeEvent event)
1018: throws AbortProcessingException {
1019: UIComponent component = event.getComponent();
1020:
1021: Object newValue = event.getNewValue();
1022: Object oldValue = event.getOldValue();
1023: PhaseId phaseId = event.getPhaseId();
1024: Object source = event.getSource();
1025: System.out.println("processFileUpload() event: " + event
1026: + " component: " + component + " newValue: " + newValue
1027: + " oldValue: " + oldValue + " phaseId: " + phaseId
1028: + " source: " + source);
1029:
1030: if (newValue instanceof String)
1031: return;
1032: if (newValue == null)
1033: return;
1034:
1035: FileItem item = (FileItem) event.getNewValue();
1036: String fieldName = item.getFieldName();
1037: filename = Validator.getFileName(item.getName());
1038: fileSize = item.getSize();
1039: fileContentType = item.getContentType();
1040: System.out.println("processFileUpload(): item: " + item
1041: + " fieldname: " + fieldName + " filename: " + filename
1042: + " length: " + fileSize);
1043:
1044: // Read the file as a stream (may be more memory-efficient)
1045: try {
1046: fileAsStream = new BufferedInputStream(item
1047: .getInputStream());
1048:
1049: } catch (IOException e) {
1050: LOG
1051: .warn("IOException while attempting to set BufferedInputStream to upload "
1052: + filename
1053: + " from site "
1054: + podcastService.getSiteId()
1055: + ". "
1056: + e.getMessage());
1057: setErrorMessage(INTERNAL_ERROR_ALERT);
1058:
1059: }
1060:
1061: }
1062:
1063: /**
1064: * Converts the date string input using the FORMAT_STRING given.
1065: *
1066: * @param inputDate
1067: * The string that needs to be converted.
1068: * @param FORMAT_STRING
1069: * The format the data needs to conform to
1070: *
1071: * @return Date
1072: * The Date object containing the date passed in or null if invalid.
1073: *
1074: * @throws ParseException
1075: * If not a valid date compared to FORMAT_STRING given
1076: */
1077: private Date convertDateString(final String inputDate,
1078: final String FORMAT_STRING) throws ParseException {
1079:
1080: Date convertedDate = null;
1081: SimpleDateFormat dateFormat = new SimpleDateFormat(
1082: FORMAT_STRING);
1083: dateFormat.setTimeZone(TimeService.getLocalTimeZone());
1084:
1085: convertedDate = dateFormat.parse(inputDate);
1086:
1087: return convertedDate;
1088: }
1089:
1090: /**
1091: * Performs the actual adding of a podcast. Calls PodcastService to actually
1092: * add the podcast.
1093: *
1094: * @return String Sent to return to main page.
1095: */
1096: public String processAdd() {
1097:
1098: // if OK, need byte array to store contents of file
1099: byte[] fileContents = new byte[(int) fileSize];
1100:
1101: // If problems, stay on this page
1102: String whereToGo = "podcastAdd";
1103:
1104: // validate the input
1105: if (OKtoAdd()) {
1106: try {
1107: fileAsStream.read(fileContents);
1108:
1109: } catch (IOException e) {
1110: LOG
1111: .error("IOException while attempting the actual upload file "
1112: + filename
1113: + " during processAdd "
1114: + " for site "
1115: + podcastService.getSiteId()
1116: + ". "
1117: + e.getMessage());
1118: setErrorMessage(IO_ALERT);
1119:
1120: // stay on Add podcast page
1121: return "podcastAdd";
1122:
1123: }
1124:
1125: try {
1126: Date displayDate = null;
1127:
1128: try {
1129: displayDate = convertDateString(date,
1130: getErrorMessageString(DATE_PICKER_FORMAT));
1131:
1132: } catch (ParseException e) {
1133: // must have entered it in by hand so try again
1134: try {
1135: displayDate = convertDateString(
1136: date,
1137: getErrorMessageString(DATE_BY_HAND_FORMAT));
1138:
1139: } catch (ParseException e1) {
1140: // Now it's invalid, so set error message and stay on page
1141: LOG.warn(
1142: "ParseException attempting to convert "
1143: + date + " both valid ways. "
1144: + e1.getMessage(), e1);
1145:
1146: displayInvalidDateErrMsg = true;
1147: return "podcastAdd";
1148: }
1149:
1150: }
1151:
1152: podcastService.addPodcast(title, displayDate,
1153: description, fileContents, filename,
1154: fileContentType);
1155:
1156: // We're good, no error message need be displayed
1157: displayNoFileErrMsg = false;
1158: displayNoDateErrMsg = false;
1159: displayNoTitleErrMsg = false;
1160: displayInvalidDateErrMsg = false;
1161:
1162: // erase data on page
1163: title = "";
1164: date = null;
1165: description = "";
1166: filename = "";
1167: fileAsStream = null;
1168:
1169: // back to main page
1170: whereToGo = "cancel";
1171:
1172: } catch (OverQuotaException e) {
1173: LOG
1174: .warn("OverQuotaException while attempting to actually add the new podcast "
1175: + " for site "
1176: + podcastService.getSiteId()
1177: + ". "
1178: + e.getMessage());
1179: setErrorMessage(QUOTA_ALERT);
1180:
1181: } catch (ServerOverloadException e) {
1182: LOG
1183: .info("ServerOverloadException while attempting to actually add the new podcast "
1184: + " for site "
1185: + podcastService.getSiteId()
1186: + ". "
1187: + e.getMessage());
1188: setErrorMessage(INTERNAL_ERROR_ALERT);
1189:
1190: } catch (InconsistentException e) {
1191: LOG
1192: .error("InconsistentException while attempting to actually add the new podcast "
1193: + " for site "
1194: + podcastService.getSiteId()
1195: + ". "
1196: + e.getMessage());
1197: throw new Error(e);
1198:
1199: } catch (IdInvalidException e) {
1200: LOG
1201: .error("IdInvalidException while attempting to actually add the new podcast "
1202: + " for site "
1203: + podcastService.getSiteId()
1204: + ". "
1205: + e.getMessage());
1206: setErrorMessage(ID_INVALID_ALERT);
1207:
1208: } catch (IdLengthException e) {
1209: LOG
1210: .warn("IdLengthException while attempting to actually add the new podcast "
1211: + " for site "
1212: + podcastService.getSiteId()
1213: + ". "
1214: + e.getMessage());
1215: setErrorMessage(LENGTH_ALERT);
1216:
1217: } catch (PermissionException e) {
1218: LOG
1219: .warn("PermissionException while attempting to actually add the new podcast "
1220: + " for site "
1221: + podcastService.getSiteId()
1222: + ". "
1223: + e.getMessage());
1224: setErrorMessage(PERMISSION_ALERT);
1225:
1226: } catch (IdUniquenessException e) {
1227: LOG
1228: .error("IdUniquenessException while attempting to actually add the new podcast "
1229: + " for site "
1230: + podcastService.getSiteId()
1231: + ". "
1232: + e.getMessage());
1233: setErrorMessage(ID_USED_ALERT);
1234:
1235: }
1236:
1237: // TODO add email notification code here
1238: /*
1239: * if (email.equalsIgnoreCase("high")) {
1240: * EmailService.send("josrodri@iupui.edu", "josrodri@iupui.edu", "A
1241: * podcast has been added to feed.", "A podcast has been added to
1242: * the list of podcasts. It's publish date will determine when it
1243: * will be available in the feed", null, null, null); } else if
1244: * (email.equalsIgnoreCase("low")){ //TODO: email only those who
1245: * have opted in }
1246: */}
1247:
1248: return whereToGo;
1249: }
1250:
1251: /**
1252: * Erases bean values since no podcast is to be added.
1253: *
1254: * @return String
1255: * Sent to return to main page.
1256: */
1257: public String processCancelAdd() {
1258: date = null;
1259: title = "";
1260: description = "";
1261: fileAsStream = null;
1262: filename = "";
1263: displayNoFileErrMsg = false;
1264: displayNoDateErrMsg = false;
1265: displayNoTitleErrMsg = false;
1266: displayInvalidDateErrMsg = false;
1267:
1268: return "cancel";
1269: }
1270:
1271: /**
1272: * Gathers information and calls PodcastService to make changes to existing
1273: * podcast.
1274: */
1275: public String processRevisePodcast() {
1276: // set error messages to false so can be
1277: // turned on during processing
1278: displayNoTitleErrMsg = false;
1279: displayInvalidDateErrMsg = false;
1280:
1281: String whereToGo = "cancel";
1282: boolean filenameChange = false;
1283: byte[] fileContents = null;
1284:
1285: // if they blank out the title, stay here since
1286: // a title is a requirement
1287: if ("".equals(selectedPodcast.title.trim())) {
1288: displayNoTitleErrMsg = true;
1289: if ("".equals(selectedPodcast.displayDateRevise)) {
1290: displayInvalidDateErrMsg = true;
1291: } else {
1292: displayInvalidDateErrMsg = false;
1293: }
1294:
1295: return "revise";
1296: }
1297:
1298: // If file has changed, change it in the resource
1299: if (filename != null) {
1300: if (!filename.equals("")) {
1301: selectedPodcast.filename = filename;
1302: filenameChange = true;
1303:
1304: if (fileAsStream != null) {
1305: fileContents = new byte[(int) fileSize];
1306:
1307: } else {
1308: fileContents = new byte[(int) selectedPodcast.fileSize];
1309: }
1310:
1311: try {
1312: fileAsStream.read(fileContents);
1313:
1314: } catch (IOException e) {
1315: LOG
1316: .error("IOException while attempting to get file contents when revising podcast for "
1317: + filename
1318: + " in site "
1319: + podcastService.getSiteId()
1320: + ". "
1321: + e.getMessage());
1322: setErrorMessage(IO_ALERT);
1323: return "podcastRevise";
1324:
1325: }
1326: }
1327: }
1328:
1329: Date displayDate = null;
1330: Date displayDateRevise = null;
1331: try {
1332: displayDate = convertDateString(
1333: selectedPodcast.displayDate,
1334: getErrorMessageString(PUBLISH_DATE_FORMAT));
1335:
1336: try {
1337: displayDateRevise = convertDateString(
1338: selectedPodcast.displayDateRevise,
1339: getErrorMessageString(DATE_BY_HAND_FORMAT));
1340:
1341: } catch (ParseException e) {
1342: // must have used date picker, so try again
1343: try {
1344: displayDateRevise = convertDateString(
1345: selectedPodcast.displayDateRevise,
1346: getErrorMessageString(DATE_PICKER_FORMAT));
1347:
1348: } catch (ParseException e1) {
1349: LOG
1350: .error("ParseException attempting to convert date for "
1351: + selectedPodcast.title
1352: + " for site "
1353: + podcastService.getSiteId()
1354: + ". "
1355: + e1.getMessage());
1356: displayInvalidDateErrMsg = true;
1357: return "podcastRevise";
1358:
1359: }
1360: }
1361:
1362: if (filenameChange) {
1363: // filename has changed, so create an entirely new entry - is
1364: // needed since filename part of resource URL
1365: podcastService.addPodcast(selectedPodcast.title,
1366: displayDateRevise, selectedPodcast.description,
1367: fileContents, filename, fileContentType);
1368:
1369: podcastService.removePodcast(selectedPodcast
1370: .getResourceId());
1371: } else {
1372: // only title, description, or date has changed, so can revise
1373: podcastService.revisePodcast(
1374: selectedPodcast.resourceId,
1375: selectedPodcast.title, displayDateRevise,
1376: selectedPodcast.description, fileContents,
1377: selectedPodcast.filename);
1378:
1379: }
1380:
1381: /* FUTURE: Enable notification
1382: if (email.equalsIgnoreCase("high")) {
1383: EmailService.send("josrodri@iupui.edu","josrodri@iupui.edu",
1384: "A podcast has been added to feed.",
1385: "A podcast has been added to the list of podcasts. "
1386: + "It's publish date will determine when it will be available in the feed",
1387: null, null, null);
1388: }
1389: else if (email.equalsIgnoreCase("low")) {
1390: // FUTURE: email only those who have opted in
1391: }
1392: */
1393: } catch (PermissionException e) {
1394: LOG.error("PermissionException while revising podcast "
1395: + selectedPodcast.title + " for site "
1396: + podcastService.getSiteId() + ". "
1397: + e.getMessage());
1398: setErrorMessage(PERMISSION_ALERT);
1399:
1400: } catch (InUseException e) {
1401: LOG.warn("InUseException while revising podcast "
1402: + selectedPodcast.title + " for site "
1403: + podcastService.getSiteId() + ". "
1404: + e.getMessage());
1405: setErrorMessage(INTERNAL_ERROR_ALERT);
1406:
1407: } catch (OverQuotaException e) {
1408: LOG.warn("OverQuotaException while revising podcast "
1409: + selectedPodcast.title + " for site "
1410: + podcastService.getSiteId() + ". "
1411: + e.getMessage());
1412: setErrorMessage(QUOTA_ALERT);
1413:
1414: } catch (ServerOverloadException e) {
1415: LOG.warn("ServerOverloadException while revising podcast "
1416: + selectedPodcast.title + " for site "
1417: + podcastService.getSiteId() + ". "
1418: + e.getMessage());
1419: setErrorMessage(INTERNAL_ERROR_ALERT);
1420:
1421: } catch (IdLengthException e) {
1422: LOG
1423: .warn("IdLengthException while revising podcast with filename changed from "
1424: + selectedPodcast.filename
1425: + " to "
1426: + filename
1427: + " for site "
1428: + podcastService.getSiteId()
1429: + ". "
1430: + e.getMessage());
1431: setErrorMessage(LENGTH_ALERT);
1432: return "podcastRevise";
1433:
1434: } catch (ParseException e) {
1435: LOG.error("ParseException attempting to convert date for "
1436: + selectedPodcast.title + " for site "
1437: + podcastService.getSiteId() + ". "
1438: + e.getMessage());
1439: date = "";
1440: displayInvalidDateErrMsg = true;
1441: return "podcastRevise";
1442:
1443: } catch (Exception e) {
1444: // catches IdUnusedException TypeException
1445: // IdInvalidException InconsistentException
1446: // IdUniquenessException
1447: LOG
1448: .error(
1449: e.getMessage()
1450: + " while revising podcast with filename changed from "
1451: + selectedPodcast.filename + " to "
1452: + filename + " for site "
1453: + podcastService.getSiteId() + ". "
1454: + e.getMessage(), e);
1455: setErrorMessage(INTERNAL_ERROR_ALERT);
1456:
1457: }
1458:
1459: // Reset values to continue processing
1460: date = null;
1461: title = "";
1462: description = "";
1463: fileAsStream = null;
1464: filename = "";
1465: displayNoTitleErrMsg = false;
1466:
1467: return whereToGo;
1468: }
1469:
1470: /**
1471: * Resets selectedPodcast bean since no revision is to be made
1472: */
1473: public String processCancelRevise() {
1474: selectedPodcast = null;
1475: date = null;
1476: title = "";
1477: description = "";
1478: fileAsStream = null;
1479: filename = "";
1480: displayInvalidDateErrMsg = false;
1481: displayNoTitleErrMsg = false;
1482:
1483: return "cancel";
1484: }
1485:
1486: /**
1487: * Used to call podcastService to actually delete selected podcast.
1488: */
1489: public String processDeletePodcast() {
1490: try {
1491: podcastService.removePodcast(selectedPodcast
1492: .getResourceId());
1493:
1494: return "cancel";
1495:
1496: } catch (PermissionException e) {
1497: LOG.error("PermissionException while deleting podcast "
1498: + selectedPodcast.title + " from site "
1499: + podcastService.getSiteId() + ". "
1500: + e.getMessage());
1501: setErrorMessage(PERMISSION_ALERT);
1502:
1503: } catch (InUseException e) {
1504: LOG.warn("InUseException while deleting podcast "
1505: + selectedPodcast.title + " from site "
1506: + podcastService.getSiteId() + ". "
1507: + e.getMessage());
1508: setErrorMessage(INTERNAL_ERROR_ALERT);
1509:
1510: } catch (Exception e) {
1511: // For IdUnusedException and TypeException
1512: LOG.error(e.getMessage() + " while deleting podcast "
1513: + selectedPodcast.title + " from site "
1514: + podcastService.getSiteId() + ". "
1515: + e.getMessage());
1516: setErrorMessage(INTERNAL_ERROR_ALERT);
1517:
1518: }
1519:
1520: // If here these was an error so stay on this page
1521: return "podcastDelete";
1522: }
1523:
1524: /**
1525: * Resets selectedPodcast bean since no deletion is to be made
1526: *
1527: * @return String
1528: * Sent to return to main page.
1529: */
1530: public String processCancelDelete() {
1531: selectedPodcast = null;
1532: return "cancel";
1533:
1534: }
1535:
1536: /**
1537: * Returns whether a no file selected error message is displayed
1538: */
1539: public boolean getDisplayNoFileErrMsg() {
1540: return displayNoFileErrMsg;
1541:
1542: }
1543:
1544: public void setDisplayNoFileErrMsg(boolean displayNoFileErrMsg) {
1545: this .displayNoFileErrMsg = displayNoFileErrMsg;
1546:
1547: }
1548:
1549: /**
1550: * Returns whether a no date error message is displayed
1551: */
1552: public boolean getDisplayNoDateErrMsg() {
1553: return displayNoDateErrMsg;
1554:
1555: }
1556:
1557: public void setDisplayNoDateErrMsg(boolean displayNoDateErrMsg) {
1558: this .displayNoDateErrMsg = displayNoDateErrMsg;
1559:
1560: }
1561:
1562: /**
1563: * Returns whether a no title entered error message is displayed
1564: */
1565: public boolean getDisplayNoTitleErrMsg() {
1566: return displayNoTitleErrMsg;
1567:
1568: }
1569:
1570: public void setDisplayNoTitleErrMsg(boolean displayNoTitleErrMsg) {
1571: this .displayNoTitleErrMsg = displayNoTitleErrMsg;
1572:
1573: }
1574:
1575: /**
1576: * Returns whether an invalid date error message is displayed
1577: */
1578: public boolean getDisplayInvalidDateErrMsg() {
1579: return displayInvalidDateErrMsg;
1580: }
1581:
1582: /**
1583: * @param displayInvalidDateErrMsg
1584: * The displayInvalidDateErrMsg to set.
1585: */
1586: public void setDisplayInvalidDateErrMsg(
1587: boolean displayInvalidDateErrMsg) {
1588: this .displayInvalidDateErrMsg = displayInvalidDateErrMsg;
1589: }
1590:
1591: /**
1592: * Performs validation of input when attempting to add a podcast.
1593: * Checks filename, date, and title fields since those are the
1594: * required ones. If errors, sets boolean flags so proper error
1595: * messages appear on the page.
1596: *
1597: * @return boolean
1598: * TRUE - input validated, FALSE - there were errors
1599: */
1600: private boolean OKtoAdd() {
1601: boolean OKtoAdd = true;
1602:
1603: if (filename == null) {
1604: displayNoFileErrMsg = true;
1605: OKtoAdd = false;
1606:
1607: } else if (filename.trim().equals("")) {
1608: displayNoFileErrMsg = true;
1609: OKtoAdd = false;
1610:
1611: } else {
1612: displayNoFileErrMsg = false;
1613:
1614: }
1615:
1616: if (date == null) {
1617: displayNoDateErrMsg = true;
1618: OKtoAdd = false;
1619:
1620: } else if (date.trim().equals("")) {
1621: displayNoDateErrMsg = true;
1622: OKtoAdd = false;
1623:
1624: } else {
1625: displayNoDateErrMsg = false;
1626:
1627: if (isValidDate(date)) {
1628: displayInvalidDateErrMsg = false;
1629:
1630: } else {
1631: displayInvalidDateErrMsg = true;
1632: OKtoAdd = false;
1633:
1634: }
1635:
1636: }
1637:
1638: if (title == null) {
1639: displayNoTitleErrMsg = true;
1640: OKtoAdd = false;
1641:
1642: } else if (title.trim().equals("")) {
1643: displayNoTitleErrMsg = true;
1644: OKtoAdd = false;
1645:
1646: } else {
1647: displayNoTitleErrMsg = false;
1648:
1649: }
1650:
1651: return OKtoAdd;
1652: }
1653:
1654: /**
1655: * Sets the Faces error message by pulling the message from the
1656: * MessageBundle using the name passed in
1657: *
1658: * @param key
1659: * The name in the MessageBundle for the message wanted
1660: *
1661: * @return String
1662: * The string that is the value of the message
1663: */
1664: private String getErrorMessageString(String key) {
1665: ResourceBundle rb = ResourceBundle.getBundle(MESSAGE_BUNDLE);
1666: return rb.getString(key);
1667:
1668: }
1669:
1670: /**
1671: * Performs date validation checking. Validator object
1672: * does not do bounds checking, so do that and if OK,
1673: * let Validator check for errors like Feb 30, etc.
1674: *
1675: * @param date
1676: * The candidate String date
1677: *
1678: * @return boolean
1679: * TRUE - Conforms to a valid input date format string
1680: * FALSE - Does not conform
1681: */
1682: private boolean isValidDate(String date) {
1683: boolean validDate = true;
1684:
1685: // Should contain date part, time port, AM/PM part
1686: String[] wholeDateSplit = date.split(" ");
1687:
1688: String[] dateSplit = wholeDateSplit[0].split("/");
1689:
1690: if (dateSplit.length != 3) {
1691: return false;
1692:
1693: } else {
1694: int month = Integer.parseInt(dateSplit[0]);
1695: int day = Integer.parseInt(dateSplit[1]);
1696:
1697: if (month < 0 || month > 12) {
1698: return false;
1699: } else if (day < 0 || day > 31) {
1700: return false;
1701: } else if (dateSplit[2].length() != 4) {
1702: return false;
1703: } else {
1704: int year = Integer.parseInt(dateSplit[2]);
1705:
1706: validDate = Validator.checkDate(day, month, year);
1707: }
1708: }
1709:
1710: if (!validDate) {
1711: return false;
1712: } else {
1713: // Date's OK, now to the time
1714: String[] timeSplit = wholeDateSplit[1].split(":");
1715:
1716: // Valid times are hh:mm or hh:mm:ss, so check for either
1717: if (timeSplit.length < 2 || timeSplit.length > 3) {
1718: return false;
1719:
1720: } else if (timeSplit.length == 2) {
1721: int hour = Integer.parseInt(timeSplit[0]);
1722: int min = Integer.parseInt(timeSplit[1]);
1723:
1724: if (hour < 0 || hour > 23) {
1725: return false;
1726:
1727: } else if (min < 0 || min > 60) {
1728: return false;
1729:
1730: }
1731: } else {
1732: int hour = Integer.parseInt(timeSplit[0]);
1733: int min = Integer.parseInt(timeSplit[1]);
1734: int sec = Integer.parseInt(timeSplit[2]);
1735:
1736: if (hour < 0 || hour > 23) {
1737: return false;
1738:
1739: } else if (min < 0 || min > 60) {
1740: return false;
1741:
1742: } else if (sec < 0 || sec > 60) {
1743: return false;
1744:
1745: }
1746: }
1747: }
1748:
1749: // We want a 12 hour clock, so AM/PM needs to be specified
1750: if ("AM".equals(wholeDateSplit[2])
1751: || "PM".equals(wholeDateSplit[2])) {
1752: return true;
1753:
1754: } else {
1755: return false;
1756:
1757: }
1758: }
1759:
1760: private String formatDate(long date) {
1761: String disTimeString = TimeService.newTime(date)
1762: .toStringGmtFull();
1763:
1764: String temp = monStrings.get(disTimeString.substring(0, 3))
1765: + disTimeString.substring(3);
1766:
1767: return temp;
1768:
1769: }
1770: }
|