Index: api/src/java/org/sakaiproject/signup/logic/SignupEmailFacade.java =================================================================== --- api/src/java/org/sakaiproject/signup/logic/SignupEmailFacade.java (revision 9469) +++ api/src/java/org/sakaiproject/signup/logic/SignupEmailFacade.java (working copy) @@ -96,4 +96,14 @@ */ void sendEmailToAttendee(SignupEventTrackingInfo signupEventTrackingInfo) throws Exception; + /** + * Send email to attendee or organizers when they update the comment + * + * @param eventTrackingInfo + * an EventTrackingInfo object, which contains all the + * information about user action such as signup and cancel + * @throws Exception + * thrown if something goes bad + */ + void sendUpdateCommentEmail(SignupEventTrackingInfo signupEventTrackingInfo) throws Exception; } Index: api/src/java/org/sakaiproject/signup/logic/SignupMeetingService.java =================================================================== --- api/src/java/org/sakaiproject/signup/logic/SignupMeetingService.java (revision 9469) +++ api/src/java/org/sakaiproject/signup/logic/SignupMeetingService.java (working copy) @@ -333,7 +333,19 @@ * thrown if something goes bad */ void sendCancellationEmail(SignupEventTrackingInfo eventTrackingInfo) throws Exception; - + + /** + * This sends an email notifying the receiver that the comment has been modified + * + * @param eventTrackingInfo + * an EventTrackingInfo object, which contains all the + * information about user action such as signup and cancel as + * well as auto-promotion + * @throws Exception + * thrown if something goes bad + */ + void sendUpdateCommentEmail(SignupEventTrackingInfo eventTrackingInfo) throws Exception; + /** * This will send email to participants by organizer * Index: api/src/java/org/sakaiproject/signup/logic/SignupMessageTypes.java =================================================================== --- api/src/java/org/sakaiproject/signup/logic/SignupMessageTypes.java (revision 9469) +++ api/src/java/org/sakaiproject/signup/logic/SignupMessageTypes.java (working copy) @@ -53,6 +53,10 @@ static final String SIGNUP_MEETING_MODIFIED = "signup.email.meeting.modified"; + static final String ATTENDEE_EDIT_COMMENT_NOTE = "Send email to notify the attendee."; + + static final String ORGANIZER_EDIT_COMMENT_NOTE = "Send email to notify the organizers."; + //The following three are used to determine who should receive email static final String SEND_EMAIL_ALL_PARTICIPANTS = "all"; Index: api/src/java/org/sakaiproject/signup/logic/messages/AttendeeComment.java =================================================================== --- api/src/java/org/sakaiproject/signup/logic/messages/AttendeeComment.java (revision 0) +++ api/src/java/org/sakaiproject/signup/logic/messages/AttendeeComment.java (revision 0) @@ -0,0 +1,53 @@ +package org.sakaiproject.signup.logic.messages; + +public class AttendeeComment { + + private String attendeeComment; + + private String attendeeId; + + private String commentModifierUserId; + + /** + * Constructor + * + * @param attendeeComment + * holds the comment of the attendee in the timeslot + * @param attendeeId + * the attendee's Id + * @param commentModifierUserId + * current user's Id / comment modifier's Id + */ + + public AttendeeComment(String attendeeComment, String attendeeId, String commentModifierUserId){ + this.attendeeComment = attendeeComment; + this.attendeeId = attendeeId; + this.commentModifierUserId = commentModifierUserId; + } + + public String getAttendeeComment() { + return attendeeComment; + } + + public void setAttendeeComment(String attendeeComment) { + this.attendeeComment = attendeeComment; + } + + public String getAttendeeId() { + return attendeeId; + } + + public void setAttendeeId(String attendeeId) { + this.attendeeId = attendeeId; + } + + public String getCommentModifierUserId() { + return commentModifierUserId; + } + + public void setCommentModifierUserId(String commentModifierUserId) { + this.commentModifierUserId = commentModifierUserId; + } + + +} Index: api/src/java/org/sakaiproject/signup/logic/messages/SignupEventTrackingInfo.java =================================================================== --- api/src/java/org/sakaiproject/signup/logic/messages/SignupEventTrackingInfo.java (revision 9469) +++ api/src/java/org/sakaiproject/signup/logic/messages/SignupEventTrackingInfo.java (working copy) @@ -107,4 +107,19 @@ * @return a string value. */ public String getAllAttendeeTransferLogInfo(); + + /** + * set the attendeeComment object + * + * @param attendeeComment + * an AttendeeComment object + */ + public void setAttendeeComment(AttendeeComment attendeeComment); + + /** + * get the AttendeeComment object + * + * @return the AttendeeComment object + */ + public AttendeeComment getAttendeeComment(); } \ No newline at end of file Index: api/src/java/org/sakaiproject/signup/logic/messages/SignupEventTrackingInfoImpl.java =================================================================== --- api/src/java/org/sakaiproject/signup/logic/messages/SignupEventTrackingInfoImpl.java (revision 9469) +++ api/src/java/org/sakaiproject/signup/logic/messages/SignupEventTrackingInfoImpl.java (working copy) @@ -45,6 +45,8 @@ private List attendeeAllocationInfos; private SignupMeeting meeting; + + private AttendeeComment attendeeComment; /** * Constructor @@ -205,4 +207,19 @@ return sb.toString(); } + /** + * {@inheritDoc} + */ + public AttendeeComment getAttendeeComment() { + return attendeeComment; + } + + /** + * {@inheritDoc} + */ + public void setAttendeeComment(AttendeeComment attendeeComment) { + this.attendeeComment = attendeeComment; + } + + } Index: impl/src/bundle/emailMessage.properties =================================================================== --- impl/src/bundle/emailMessage.properties (revision 9592) +++ impl/src/bundle/emailMessage.properties (working copy) @@ -7,6 +7,7 @@ subject.attendee.signup.field={1} has signed up for the meeting on {0} in {2} subject.Cancel.appointment.field=Appointment for meeting on {0} has been canceled by {1} subject.meeting.modification.field={0} has modified the meeting for {1} on {2},{3} +subject.comment.modification.field=Comment in {0} has been modified for meeting {1} on {2}, {3} subject.meeting.cancel.field=Appointment for meeting {0} in {1} has been canceled subject.newMeeting.field=New meeting announced by {0} on {1} subject.organizer.change.appointment.field=Meeting on {0} {1} has been changed @@ -36,6 +37,7 @@ body.timeslot=Time slot: body.ownComment=My Comment: {0} body.commentBy=Comment by {0}: {1} +body.comment=Comment: {0} body.organizer.meeting.timeframe=Meeting Time: {0} - from {1} to {2} ({3}) body.organizer.meeting.crossdays.timeframe=Meeting Time: {0}, {1} to {2}, {3} ({4}) @@ -87,6 +89,7 @@ body.attendee.signup.own=You have signed up for the following meeting in the {0} site on {1}: body.attendee.cancel.own=You have cancelled your appointment for the following meeting in the {0} site on {1}: +body.organizer.comment.update=The comment for the following meeting in the {0} site on {1} has been updated by {2}: ##footer part Index: impl/src/java/org/sakaiproject/signup/logic/SignupEmailFacadeImpl.java =================================================================== --- impl/src/java/org/sakaiproject/signup/logic/SignupEmailFacadeImpl.java (revision 9469) +++ impl/src/java/org/sakaiproject/signup/logic/SignupEmailFacadeImpl.java (working copy) @@ -28,7 +28,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.StringTokenizer; import lombok.Getter; @@ -37,12 +36,9 @@ import net.fortuna.ical4j.model.component.VEvent; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.impl.LogFactoryImpl; import org.apache.commons.validator.EmailValidator; -import org.sakaiproject.authz.api.SecurityAdvisor; -import org.sakaiproject.calendar.api.CalendarEventEdit; import org.sakaiproject.email.api.AddressValidationException; import org.sakaiproject.email.api.Attachment; import org.sakaiproject.email.api.EmailAddress; @@ -52,6 +48,7 @@ import org.sakaiproject.signup.logic.messages.AddAttendeeEmail; import org.sakaiproject.signup.logic.messages.AttendeeCancellationEmail; import org.sakaiproject.signup.logic.messages.AttendeeCancellationOwnEmail; +import org.sakaiproject.signup.logic.messages.AttendeeModifiedCommentEmail; import org.sakaiproject.signup.logic.messages.AttendeeSignupEmail; import org.sakaiproject.signup.logic.messages.AttendeeSignupOwnEmail; import org.sakaiproject.signup.logic.messages.CancelMeetingEmail; @@ -251,7 +248,39 @@ } } - + + /** + * {@inheritDoc} + */ + public void sendUpdateCommentEmail(SignupEventTrackingInfo signupEventTrackingInfo) throws Exception { + try { + User organizer = userDirectoryService.getUser(sakaiFacade.getCurrentUserId()); + boolean isOrganizer = signupEventTrackingInfo.getMeeting().getPermission().isUpdate(); + User attendee = userDirectoryService.getUser(signupEventTrackingInfo.getAttendeeComment().getAttendeeId()); + String emailReturnSiteId = sakaiFacade.getCurrentLocationId(); + AttendeeModifiedCommentEmail email = new AttendeeModifiedCommentEmail(organizer, signupEventTrackingInfo.getMeeting(), + this.sakaiFacade, emailReturnSiteId, signupEventTrackingInfo.getAttendeeComment()); + + if (isOrganizer){ + try{ + sendEmail(attendee, email); + }catch(Exception e){ + //do nothing: avoid one wrong email address for one user to break all things + } + } + else { + try{ + sendEmail(organizer, email); + }catch(Exception e){ + //do nothing: avoid one wrong email address for one user to break all things + } + } + } catch (UserNotDefinedException e) { + throw new Exception("User is not found for userId: " + + signupEventTrackingInfo.getMeeting().getCreatorUserId()); + } + } + /** * {@inheritDoc} */ @@ -700,7 +729,6 @@ return null; } - return message; } Index: impl/src/java/org/sakaiproject/signup/logic/SignupMeetingServiceImpl.java =================================================================== --- impl/src/java/org/sakaiproject/signup/logic/SignupMeetingServiceImpl.java (revision 9526) +++ impl/src/java/org/sakaiproject/signup/logic/SignupMeetingServiceImpl.java (working copy) @@ -292,7 +292,7 @@ } - /* check to see if the user has updte permission at any level */ + /* check to see if the user has update permission at any level */ private boolean isAllowToUpdate(String userId, String siteId, SignupMeeting meeting) { if (sakaiFacade.isUserAdmin(userId)) return true; @@ -1077,6 +1077,13 @@ public void sendCancellationEmail(SignupEventTrackingInfo signupEventTrackingInfo) throws Exception { signupEmailFacade.sendCancellationEmail(signupEventTrackingInfo); } + + /** + * {@inheritDoc} + */ + public void sendUpdateCommentEmail(SignupEventTrackingInfo signupEventTrackingInfo) throws Exception { + signupEmailFacade.sendUpdateCommentEmail(signupEventTrackingInfo); + } /** * {@inheritDoc} Index: impl/src/java/org/sakaiproject/signup/logic/messages/AttendeeModifiedCommentEmail.java =================================================================== --- impl/src/java/org/sakaiproject/signup/logic/messages/AttendeeModifiedCommentEmail.java (revision 0) +++ impl/src/java/org/sakaiproject/signup/logic/messages/AttendeeModifiedCommentEmail.java (revision 0) @@ -0,0 +1,100 @@ +package org.sakaiproject.signup.logic.messages; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.sakaiproject.signup.logic.SakaiFacade; +import org.sakaiproject.signup.model.SignupMeeting; +import org.sakaiproject.user.api.User; + +public class AttendeeModifiedCommentEmail extends SignupEmailBase { + + private final User organizer; + + private final String emailReturnSiteId; + + private AttendeeComment attendeeComment; + + /** + * Constructor + * + * @param organizer + * an User, who organizes the event/meeting + * @param meeting + * a SignupMeeting object + * @param sakaiFacade + * a SakaiFacade object + * @param emailReturnSiteId + * a unique SiteId string + */ + public AttendeeModifiedCommentEmail(User organizer, SignupMeeting meeting, SakaiFacade sakaiFacade, String emailReturnSiteId, AttendeeComment attendeeComment) { + this.organizer = organizer; + this.meeting = meeting; + this.setSakaiFacade(sakaiFacade); + this.emailReturnSiteId = emailReturnSiteId; + this.attendeeComment = attendeeComment; + } + + /** + * {@inheritDoc} + */ + public List getHeader() { + List rv = new ArrayList(); + // Set the content type of the message body to HTML + rv.add("Content-Type: text/html; charset=UTF-8"); + rv.add("Subject: " + getSubject()); + rv.add("From: " + getFromAddress()); + rv.add("To: " + rb.getString("noReply@") + getSakaiFacade().getServerConfigurationService().getServerName()); + + return rv; + } + + /** + * {@inheritDoc} + */ + public String getMessage() { + StringBuilder message = new StringBuilder(); + Object[] params = new Object[] { getSiteTitleWithQuote(emailReturnSiteId), getServiceName(), + makeFirstCapLetter(organizer.getDisplayName()), getSakaiFacade().getUserDisplayLastFirstName(getSakaiFacade().getCurrentUserId()) }; + message.append(newline + MessageFormat.format(rb.getString("body.organizer.comment.update"), params)); + + message.append(newline + newline + + MessageFormat.format(rb.getString("body.meetingTopic.part"), new Object[] { meeting.getTitle() })); + if (!meeting.isMeetingCrossDays()) { + Object[] paramsTimeframe = new Object[] { getTime(meeting.getStartTime()).toStringLocalDate(), + getTime(meeting.getStartTime()).toStringLocalTime(), + getTime(meeting.getEndTime()).toStringLocalTime(), + getSakaiFacade().getTimeService().getLocalTimeZone().getID()}; + message.append(newline + + MessageFormat.format(rb.getString("body.organizer.meeting.timeframe"), paramsTimeframe)); + } else { + Object[] paramsTimeframe1 = new Object[] { getTime(meeting.getStartTime()).toStringLocalTime(), + getTime(meeting.getStartTime()).toStringLocalShortDate(), + getTime(meeting.getEndTime()).toStringLocalTime(), + getTime(meeting.getEndTime()).toStringLocalShortDate(), + getSakaiFacade().getTimeService().getLocalTimeZone().getID()}; + message.append(newline + + MessageFormat.format(rb.getString("body.organizer.meeting.crossdays.timeframe"), paramsTimeframe1)); + } + + message.append(newline + newline + MessageFormat.format(rb.getString("body.comment"), new Object[] { + makeFirstCapLetter(attendeeComment.getAttendeeComment()) })); + + /* footer */ + message.append(newline + getFooter(newline, emailReturnSiteId)); + return message.toString(); + } + + @Override + public String getFromAddress() { + return organizer.getEmail(); + } + + @Override + public String getSubject() { + return MessageFormat.format(rb.getString("subject.comment.modification.field"), new Object[] { + getShortSiteTitleWithQuote(emailReturnSiteId), organizer.getDisplayName(), getTime(meeting.getStartTime()).toStringLocalDate(), + getTime(meeting.getStartTime()).toStringLocalTime() }); + } +} Index: tool/src/bundle/messages.properties =================================================================== --- tool/src/bundle/messages.properties (revision 9591) +++ tool/src/bundle/messages.properties (working copy) @@ -188,6 +188,7 @@ ok_button=OK cancel_button=Cancel save_button=Save +edit_button=Edit delete_attandee_confirmation=Are you sure you want to remove this participant from the time slot? event_add_attendee= Add Participant event_restore_timeslot_label= Restore @@ -212,6 +213,7 @@ organizer_instruction_edit_image= to change or swap participants. organizer_instruction_delete_image= to delete a participant. organizer_instruction_mailto_image= to email a participant. +organizer_instruction_comment_image= to view/edit a attendee's comment. organizer_instruction_max_capacity=- Meeting Organizers can add participants even if time slot is filled to capacity. no_addWaiter_button_due_to_unlimited= --- #tool tips @@ -312,6 +314,8 @@ event_yes_receive_notification= Yes, I want to receive email notification when a participant signs up or cancels an appointment. event_yes_create_email_notification= Yes, send email to notify all the potential participants that this meeting has been published. event_yes_email_notification= Yes, send email to notify the following participants. +event_email_attendee_notification= Send email to notify the attendee. +event_email_organizers_notification= Send email to notify the organizers. event_allow_waitList=Allow Wait List: event_allow_addComment=Allow Adding Comment: event_use_eid_input_mode=User ID Input Mode: @@ -342,8 +346,9 @@ #cancelTimeslot.jsp cancel_timeslot_button=Cancel Timeslot -#vewComment.jsp +#viewComment.jsp event_view_comment_page_title=View Comment +event_edit_comment_page_title=Edit Comment event_attendee_name=Participant Name: event_attendee_eid=Participant UserId: event_attendee_noEmail=No Email @@ -462,6 +467,7 @@ has changed. Some timeslots may now be overbooked. someone.modified.event.content=Someone else has modified the meeting content. Please try again. someone.already.updated.db=Someone else has modified the meeting. Please update the meeting and try again. +someone.already.updated.comment=Someone else has already modified the comment. Please update the comment and try again. warning.some_timeslot_may_locked_canceled=One or more timeslot(s) in the copied meeting is either locked or canceled. someone.already.taken.theTimeslot=The time slot has already been taken and is not available. \ Please join the Wait List to be notified of a cancellation. Index: tool/src/java/org/sakaiproject/signup/tool/jsf/attendee/AttendeeSignupMBean.java =================================================================== --- tool/src/java/org/sakaiproject/signup/tool/jsf/attendee/AttendeeSignupMBean.java (revision 9469) +++ tool/src/java/org/sakaiproject/signup/tool/jsf/attendee/AttendeeSignupMBean.java (working copy) @@ -22,7 +22,9 @@ **********************************************************************************/ package org.sakaiproject.signup.tool.jsf.attendee; +import java.text.MessageFormat; import java.util.Collections; +import java.util.List; import javax.faces.component.UIData; import javax.faces.context.FacesContext; @@ -31,14 +33,15 @@ import lombok.Getter; import lombok.Setter; -import org.apache.commons.lang.StringUtils; -import org.sakaiproject.signup.logic.SignupCalendarHelper; +import org.sakaiproject.signup.logic.SignupUser; import org.sakaiproject.signup.logic.SignupUserActionException; import org.sakaiproject.signup.model.SignupAttendee; import org.sakaiproject.signup.model.SignupMeeting; +import org.sakaiproject.signup.tool.jsf.AttendeeWrapper; import org.sakaiproject.signup.tool.jsf.SignupMeetingWrapper; import org.sakaiproject.signup.tool.jsf.SignupUIBaseBean; import org.sakaiproject.signup.tool.jsf.TimeslotWrapper; +import org.sakaiproject.signup.tool.jsf.attendee.EditCommentSignupMBean; import org.sakaiproject.signup.tool.jsf.organizer.action.AddAttendee; import org.sakaiproject.signup.tool.jsf.organizer.action.AddWaiter; import org.sakaiproject.signup.tool.jsf.organizer.action.CancelAttendee; @@ -61,7 +64,9 @@ private String currentSiteId; private boolean collapsedMeetingInfo; - + + private EditCommentSignupMBean editCommentMBean; + /** * This will initialize all the wrapper objects such as * SignupMeetingWrapper, SignupTimeslotWrapper etc. @@ -93,7 +98,7 @@ return ATTENDEE_ADD_COMMENT_PAGE_URL; else return attendeeSaveSignup();//skip comment page - + } /** @@ -238,7 +243,72 @@ return updateMeetingwrapper(meeting, ATTENDEE_MEETING_PAGE_URL); } + + /** + * This is a JSF action call method by UI to edit the attendee's + * comments of the event/meeting. + * + * @return an action outcome string. + */ + public String editAttendeeComment() { + String attUserId = sakaiFacade.getCurrentUserId(); + String timeslotId = (String) Utilities.getRequestParam("timeslotId"); + if (attUserId == null || timeslotId == null) + return ""; + AttendeeWrapper attWrp = findAttendee(timeslotId, attUserId); + if (attWrp == null) + return ""; + + this.editCommentMBean.init(attWrp, this.getAttendeeRole(attUserId), getMeetingWrapper(), timeslotId); + + return EDIT_COMMENT_PAGE_URL; + } + + /** + * this methods returns the attendee's user role + * @param attendeeUserId + * @return + */ + private String getAttendeeRole(String attendeeUserId) { + SignupUser sUser = getSakaiFacade().getSignupUser(getMeetingWrapper().getMeeting(), attendeeUserId); + if (sUser == null) + return "unknown"; + else + return sUser.getUserRole().getId(); + } + + /** + * find an attendee in a specific time slot + * @param timeslotId + * @param userId + * @return + */ + private AttendeeWrapper findAttendee(String timeslotId, String userId) { + if (getTimeslotWrappers() == null || getTimeslotWrappers().isEmpty()) + return null; + + String timeslotPeriod = null; + for (TimeslotWrapper wrapper : getTimeslotWrappers()) { + if (wrapper.getTimeSlot().getId().toString().equals(timeslotId)) { + timeslotPeriod = getSakaiFacade().getTimeService().newTime( + wrapper.getTimeSlot().getStartTime().getTime()).toStringLocalTime() + + " - " + + getSakaiFacade().getTimeService().newTime(wrapper.getTimeSlot().getEndTime().getTime()) + .toStringLocalTime(); + List attWrp = wrapper.getAttendeeWrappers(); + for (AttendeeWrapper att : attWrp) { + if (att.getSignupAttendee().getAttendeeUserId().equals(userId)) { + att.setTimeslotPeriod(timeslotPeriod); + return att; + } + } + break; + } + } + return null; + } + /** * This is a getter method for UI. * @@ -271,6 +341,24 @@ return currentSiteId; } + + /** + * This is a getter. + * + */ + public EditCommentSignupMBean getEditCommentMBean() { + return editCommentMBean; + } + + /** + * This is a setter. + * + * @param editCommentMBean + * a EditCommentSignupMBean object. + */ + public void setEditCommentMBean(EditCommentSignupMBean editCommentMBean) { + this.editCommentMBean = editCommentMBean; + } /** * It's a getter method for UI. Index: tool/src/java/org/sakaiproject/signup/tool/jsf/attendee/EditCommentSignupMBean.java =================================================================== --- tool/src/java/org/sakaiproject/signup/tool/jsf/attendee/EditCommentSignupMBean.java (revision 0) +++ tool/src/java/org/sakaiproject/signup/tool/jsf/attendee/EditCommentSignupMBean.java (revision 0) @@ -0,0 +1,335 @@ +/********************************************************************************** + * $URL: https://source.sakaiproject.org/contrib/signup/branches/2-6-x/tool/src/java/org/sakaiproject/signup/tool/jsf/attendee/EditCommentSignupMBean.java $ + * $Id: EditCommentSignupMBean.java 56827 2009-01-13 21:52:18Z guangzheng.liu@yale.edu $ +*********************************************************************************** + * + * Copyright (c) 2007, 2008, 2009 Yale University + * + * Licensed under the Educational Community License, Version 1.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/ecl1.php + * + * 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. + * + * See the LICENSE.txt distributed with this file. + * + **********************************************************************************/ +package org.sakaiproject.signup.tool.jsf.attendee; + +import java.util.List; + +import javax.faces.context.FacesContext; + +import org.sakaiproject.exception.PermissionException; +import org.sakaiproject.signup.logic.SignupUser; +import org.sakaiproject.signup.logic.SignupUserActionException; +import org.sakaiproject.signup.logic.messages.AttendeeComment; +import org.sakaiproject.signup.logic.messages.SignupEventTrackingInfo; +import org.sakaiproject.signup.logic.messages.SignupEventTrackingInfoImpl; +import org.sakaiproject.signup.model.SignupMeeting; +import org.sakaiproject.signup.model.SignupTimeslot; +import org.sakaiproject.signup.tool.jsf.AttendeeWrapper; +import org.sakaiproject.signup.tool.jsf.SignupMeetingWrapper; +import org.sakaiproject.signup.tool.jsf.SignupUIBaseBean; +import org.sakaiproject.signup.tool.jsf.TimeslotWrapper; +import org.sakaiproject.signup.tool.jsf.organizer.OrganizerSignupMBean; +import org.sakaiproject.signup.tool.jsf.organizer.action.EditComment; +import org.sakaiproject.signup.tool.util.Utilities; +import org.sakaiproject.user.api.User; + +/** + *

+ * This JSF UIBean class will handle information exchanges between Attendees's + * edit comment page:editComment.jsp and backbone system. + *

+ */ +public class EditCommentSignupMBean extends SignupUIBaseBean { + + private AttendeeWrapper attendeeWrapper; + + private String AttendeeRole; + + private boolean validationError; + + private String relatedTimeslotId; + + private String comment; + + /** + * To initialize this UIBean, which lives in a session scope. + * + * @param attwrp + * an AttendeeWrapper object. + * @param role + * a String value + * @param meetingwrp + * a SignupMeetingWrapper object. + * @para timeslotId + * a String value + */ + public void init(AttendeeWrapper attwrp, String role, SignupMeetingWrapper meetingwrp, String timeslotId) { + this.attendeeWrapper = attwrp; + this.AttendeeRole = role; + this.meetingWrapper = meetingwrp; + this.relatedTimeslotId = timeslotId; + this.comment = meetingwrp.getMeeting().getTimeslot(findTimeslotId()).getAttendee(attendeeWrapper.getSignupAttendee().getAttendeeUserId()).getComments(); + } + + /* + * Method that directs users to the edit comment page when clicked + */ + public String editAttendeeComment(){ + String attUserId = attendeeWrapper.getSignupAttendee().getAttendeeUserId(); + String timeslotId = relatedTimeslotId; + if (attUserId == null || timeslotId == null) + return ""; + + this.init(attendeeWrapper, this.getAttendeeRole(attUserId), getMeetingWrapper(), timeslotId); + + return EDIT_COMMENT_PAGE_URL; + } + + /** + * Method that returns the attendee's role for permission purposes + * @param attendeeUserId + * @return + */ + private String getAttendeeRole(String attendeeUserId) { + SignupUser sUser = getSakaiFacade().getSignupUser(getMeetingWrapper().getMeeting(), attendeeUserId); + if (sUser == null) + return "unknown"; + else + return sUser.getUserRole().getId(); + } + + + /*private AttendeeWrapper findAttendee(String timeslotId, String userId) { + if (getTimeslotWrappers() == null || getTimeslotWrappers().isEmpty()) + return null; + + String timeslotPeriod = null; + for (TimeslotWrapper wrapper : getTimeslotWrappers()) { + if (wrapper.getTimeSlot().getId().toString().equals(timeslotId)) { + timeslotPeriod = getSakaiFacade().getTimeService().newTime( + wrapper.getTimeSlot().getStartTime().getTime()).toStringLocalTime() + + " - " + + getSakaiFacade().getTimeService().newTime(wrapper.getTimeSlot().getEndTime().getTime()) + .toStringLocalTime(); + List attWrp = wrapper.getAttendeeWrappers(); + for (AttendeeWrapper att : attWrp) { + if (att.getSignupAttendee().getAttendeeUserId().equals(userId)) { + att.setTimeslotPeriod(timeslotPeriod); + return att; + } + } + break; + } + } + return null; + }*/ + + /* + * Method to find a timeslot's ID + */ + public Long findTimeslotId(){ + List timeslotList = meetingWrapper.getMeeting().getSignupTimeSlots(); + Long timeslotId = null; + String attendeeId = attendeeWrapper.getSignupAttendee().getAttendeeUserId(); + + for(int i = 0; i < timeslotList.size(); i++){ + for(int j = 0; j < timeslotList.get(i).getAttendees().size(); j++) { + if(timeslotList.get(i).getAttendees().get(j).getAttendeeUserId().equals(attendeeId)){ + timeslotId = timeslotList.get(i).getId(); + } + } + } + + return timeslotId; + } + + /* + * when the save button is clicked, this method saves the comment to the database if conditions are met + */ + public String attendeeSaveComment(){ + + if (validationError) { + validationError = false; + return ""; + } + + SignupMeeting meeting = meetingWrapper.getMeeting(); //old meeting + Long timeslotId = findTimeslotId(); + boolean isOrganizer = meeting.getPermission().isUpdate(); + String attendeeId = attendeeWrapper.getSignupAttendee().getAttendeeUserId(); + + try { + if(!isOrganizer && !sakaiFacade.getCurrentUserId().equals(attendeeId)){ + Utilities.addErrorMessage(Utilities.rb.getString("no.permissoin.do_it")); + return ""; + } + else{ + EditComment editComment = new EditComment(signupMeetingService, attendeeId, + sakaiFacade.getCurrentLocationId(), false, meeting, timeslotId, getSakaiFacade()); + meeting = editComment.updateComment(comment); + } + + if (sendEmail) { + try { + SignupEventTrackingInfo trackingInfo = new SignupEventTrackingInfoImpl(); + trackingInfo.setMeeting(meeting); + trackingInfo.setAttendeeComment(new AttendeeComment(comment, attendeeId, sakaiFacade.getCurrentUserId())); + signupMeetingService.sendUpdateCommentEmail(trackingInfo); + } catch (Exception e) { + logger.error(Utilities.rb.getString("email.exception") + " - " + e.getMessage(), e); + Utilities.addErrorMessage(Utilities.rb.getString("email.exception")); + } + } + + } catch (PermissionException pe) { + Utilities.addErrorMessage(Utilities.rb.getString("no.permissoin.do_it")); + } catch (SignupUserActionException ue) { + /* TODO need to keep in the same page with new data if db changes */ + Utilities.addErrorMessage(ue.getMessage()); + } catch (Exception e) { + Utilities.addErrorMessage(Utilities.rb.getString("db.error_or_event.notExisted")); + logger.error(Utilities.rb.getString("db.error_or_event.notExisted") + " - " + e.getClass() + ":" + e.getMessage()); + Utilities.resetMeetingList(); + return MAIN_EVENTS_LIST_PAGE_URL; + } + if(isOrganizer){ + reloadMeetingWrapperInOrganizerPage(); + } + + /* + * refresh meeting list to catch the changes when go back the main + * meeting list page + */ + if (Utilities.getSignupMeetingsBean().isShowMyAppointmentTime()) + Utilities.resetMeetingList(); + + return updateMeetingwrapper(meeting, checkReturnUrl()); + + } + + /* + * Method used to reload the meeting wrapper for the organizer to get the newest updated meeting list + */ + private void reloadMeetingWrapperInOrganizerPage() { + OrganizerSignupMBean bean = (OrganizerSignupMBean) FacesContext.getCurrentInstance().getExternalContext() + .getSessionMap().get("OrganizerSignupMBean"); + SignupMeeting meeting = reloadMeeting(meetingWrapper.getMeeting()); + this.meetingWrapper.setMeeting(meeting); + //update latest creator for UI + this.meetingWrapper.setCreator(sakaiFacade.getUserDisplayName(meeting.getCreatorUserId())); + bean.reset(meetingWrapper); + } + + /** + * + * @param meeting + * @return + */ + private SignupMeeting reloadMeeting(SignupMeeting meeting) { + return signupMeetingService.loadSignupMeeting(meeting.getId(), sakaiFacade.getCurrentUserId(), sakaiFacade + .getCurrentLocationId()); + } + + /* + * This method returns the meeting page url depending on the user's role + */ + public String checkReturnUrl(){ + boolean isOrganizer = meetingWrapper.getMeeting().getPermission().isUpdate(); + + if(isOrganizer) + return ORGANIZER_MEETING_PAGE_URL; + else + return ATTENDEE_MEETING_PAGE_URL; + } + + /* + * Checks if the user is an organizer and returns the comment note + */ + public String getUserType(){ + boolean isOrganizer = meetingWrapper.getMeeting().getPermission().isUpdate(); + + if(isOrganizer) + return ATTENDEE_EDIT_COMMENT_NOTE; + else + return ORGANIZER_EDIT_COMMENT_NOTE; + } + + /** + * This is a getter method for UI. + * + * @return an AttendeeWrapper object. + */ + public AttendeeWrapper getAttendeeWrapper() { + return attendeeWrapper; + } + + /** + * This is a setter. + * + * @param attendeeWrapper + * an AttendeeWrapper object. + */ + public void setAttendeeWrapper(AttendeeWrapper attendeeWrapper) { + this.attendeeWrapper = attendeeWrapper; + } + + /** + * This is a getter method for UI. + * + * @return a string value. + */ + public String getAttendeeRole() { + return AttendeeRole; + } + + /** + * This is a setter. + * + * @param attendeeRole + * a string value. + */ + public void setAttendeeRole(String attendeeRole) { + AttendeeRole = attendeeRole; + } + + /** + * Overwrite the default one. + * + * @return a SignupMeetingWrapper object. + */ + public SignupMeetingWrapper getMeetingWrapper() { + return meetingWrapper; + } + + /** + * show the attendee's Eid (user Id) + * @return eid String + */ + public String getAttendeeEid(){ + String eid = attendeeWrapper.getSignupAttendee().getAttendeeUserId(); + User user = sakaiFacade.getUser(attendeeWrapper.getSignupAttendee().getAttendeeUserId()); + if(user !=null){ + eid = user.getEid(); + } + + return eid; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } +} Index: tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/CopyMeetingSignupMBean.java =================================================================== --- tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/CopyMeetingSignupMBean.java (revision 9635) +++ tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/CopyMeetingSignupMBean.java (working copy) @@ -110,7 +110,7 @@ private List allowedUserList; - private boolean missingSitGroupWarning; + private boolean missingSiteGroupWarning; private List missingSites; @@ -164,7 +164,7 @@ repeatType = ONCE_ONLY; repeatTypeUnknown=true; showAttendeeName = false; - missingSitGroupWarning = false; + missingSiteGroupWarning = false; /*cleanup previously unused attachments in CHS*/ if(this.signupMeeting !=null) @@ -218,7 +218,7 @@ markerTimeslots(this.customTimeSlotWrpList); } - getUserDefineTimeslotBean().init(this.signupMeeting, COPTY_MEETING_PAGE_URL, this.customTimeSlotWrpList, UserDefineTimeslotBean.COPY_MEETING); + getUserDefineTimeslotBean().init(this.signupMeeting, COPY_MEETING_PAGE_URL, this.customTimeSlotWrpList, UserDefineTimeslotBean.COPY_MEETING); } @@ -489,14 +489,14 @@ /*Mark the time slot sequence for recurring events changes issues*/ markerTimeslots(this.customTimeSlotWrpList); - getUserDefineTimeslotBean().init(this.signupMeeting, COPTY_MEETING_PAGE_URL,this.customTimeSlotWrpList, UserDefineTimeslotBean.COPY_MEETING); + getUserDefineTimeslotBean().init(this.signupMeeting, COPY_MEETING_PAGE_URL,this.customTimeSlotWrpList, UserDefineTimeslotBean.COPY_MEETING); }else{ if(!Utilities.isDataIntegritySafe(isUserDefinedTS(),UserDefineTimeslotBean.COPY_MEETING,getUserDefineTimeslotBean())){ return ORGANIZER_MEETING_PAGE_URL; } this.customTimeSlotWrpList = getUserDefineTimeslotBean().getDestTSwrpList(); - getUserDefineTimeslotBean().init(this.signupMeeting, COPTY_MEETING_PAGE_URL,this.customTimeSlotWrpList, UserDefineTimeslotBean.COPY_MEETING); + getUserDefineTimeslotBean().init(this.signupMeeting, COPY_MEETING_PAGE_URL,this.customTimeSlotWrpList, UserDefineTimeslotBean.COPY_MEETING); } return CUSTOM_DEFINED_TIMESLOT_PAGE_URL; @@ -941,7 +941,7 @@ createSiteGroups.processSiteGroupSelectionMarks(); setCurrentSite(createSiteGroups.getCurrentSite()); setOtherSites(createSiteGroups.getOtherSites()); - setMissingSitGroupWarning(createSiteGroups.isSiteOrGroupTruncated()); + setMissingSiteGroupWarning(createSiteGroups.isSiteOrGroupTruncated()); setMissingSites(createSiteGroups.getMissingSites()); setMissingGroups(createSiteGroups.getMissingGroups()); } @@ -1008,12 +1008,12 @@ * * @return a boolean value */ - public boolean isMissingSitGroupWarning() { - return missingSitGroupWarning; + public boolean isMissingSiteGroupWarning() { + return missingSiteGroupWarning; } - private void setMissingSitGroupWarning(boolean missingSitGroupWarning) { - this.missingSitGroupWarning = missingSitGroupWarning; + private void setMissingSiteGroupWarning(boolean missingSiteGroupWarning) { + this.missingSiteGroupWarning = missingSiteGroupWarning; } public List getMissingSites() { Index: tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/OrganizerSignupMBean.java =================================================================== --- tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/OrganizerSignupMBean.java (revision 9469) +++ tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/OrganizerSignupMBean.java (working copy) @@ -45,6 +45,7 @@ import org.sakaiproject.signup.tool.jsf.SignupMeetingWrapper; import org.sakaiproject.signup.tool.jsf.SignupUIBaseBean; import org.sakaiproject.signup.tool.jsf.TimeslotWrapper; +import org.sakaiproject.signup.tool.jsf.attendee.EditCommentSignupMBean; import org.sakaiproject.signup.tool.jsf.organizer.action.AddAttendee; import org.sakaiproject.signup.tool.jsf.organizer.action.AddWaiter; import org.sakaiproject.signup.tool.jsf.organizer.action.CancelAttendee; @@ -117,7 +118,7 @@ private EditMeetingSignupMBean editMeetingMBean; - private ViewCommentSignupMBean viewCommentMBean; + private EditCommentSignupMBean editCommentMBean; private CancelRestoreTimeslot cancelRestoreTimeslot; @@ -138,7 +139,7 @@ reset(meetingWrapper); loadAllAttendees(meetingWrapper.getMeeting()); } - + /** * This will basically update the Timeslot wrappers after event/meeting is * updated @@ -185,7 +186,7 @@ public String copyMeeting() { copyMeetingMBean.setMeetingWrapper(getMeetingWrapper()); copyMeetingMBean.reset(); - return COPTY_MEETING_PAGE_URL; + return COPY_MEETING_PAGE_URL; } /** @@ -261,25 +262,30 @@ AttendeeWrapper attWrp = findAttendee(timeslotId, attUserId); if (attWrp == null) return ""; - - this.viewCommentMBean.init(attWrp, this.getAttendeeRole(attUserId), getMeetingWrapper()); + + this.editCommentMBean.init(attWrp, this.getAttendeeRole(attUserId), getMeetingWrapper(), timeslotId); return VIEW_COMMENT_PAGE_URL; } - /* find an attendee in a specific time slot */ + /** + * find an attendee in a specific time slot + * @param timeslotId + * @param userId + * @return + */ private AttendeeWrapper findAttendee(String timeslotId, String userId) { if (getTimeslotWrappers() == null || getTimeslotWrappers().isEmpty()) return null; String timeslotPeriod = null; - for (TimeslotWrapper wraper : getTimeslotWrappers()) { - if (wraper.getTimeSlot().getId().toString().equals(timeslotId)) { + for (TimeslotWrapper wrapper : getTimeslotWrappers()) { + if (wrapper.getTimeSlot().getId().toString().equals(timeslotId)) { timeslotPeriod = getSakaiFacade().getTimeService().newTime( - wraper.getTimeSlot().getStartTime().getTime()).toStringLocalTime() + wrapper.getTimeSlot().getStartTime().getTime()).toStringLocalTime() + " - " - + getSakaiFacade().getTimeService().newTime(wraper.getTimeSlot().getEndTime().getTime()) + + getSakaiFacade().getTimeService().newTime(wrapper.getTimeSlot().getEndTime().getTime()) .toStringLocalTime(); - List attWrp = wraper.getAttendeeWrappers(); + List attWrp = wrapper.getAttendeeWrappers(); for (AttendeeWrapper att : attWrp) { if (att.getSignupAttendee().getAttendeeUserId().equals(userId)) { att.setTimeslotPeriod(timeslotPeriod); @@ -292,6 +298,11 @@ return null; } + /** + * + * @param attendeeUserId + * @return + */ private String getAttendeeRole(String attendeeUserId) { SignupUser sUser = getSakaiFacade().getSignupUser(getMeetingWrapper().getMeeting(), attendeeUserId); if (sUser == null) @@ -394,6 +405,11 @@ return swapAttendee.getSignupEventTrackingInfo(); } + /** + * + * @return + * @throws Exception + */ private SignupEventTrackingInfo replaceAttendee() throws Exception { String userEidOrEmail = null; if (isEidInputMode()) { @@ -450,7 +466,6 @@ setEidInputMode(true); return; } - try { Site site = getSakaiFacade().getSiteService().getSite(getSakaiFacade().getCurrentLocationId()); @@ -1166,20 +1181,20 @@ /** * This is a getter method. * - * @return a ViewCommentSignupMBean object. + * @return a EditCommentSignupMBean object. */ - public ViewCommentSignupMBean getViewCommentMBean() { - return viewCommentMBean; + public EditCommentSignupMBean getEditCommentMBean() { + return editCommentMBean; } /** * This is a setter. * - * @param viewCommentMBean - * a ViewCommentSignupMBean object. + * @param editCommentMBean + * a EditCommentSignupMBean object. */ - public void setViewCommentMBean(ViewCommentSignupMBean viewCommentMBean) { - this.viewCommentMBean = viewCommentMBean; + public void setEditCommentMBean(EditCommentSignupMBean editCommentMBean) { + this.editCommentMBean = editCommentMBean; } /** Index: tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/ViewCommentSignupMBean.java =================================================================== --- tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/ViewCommentSignupMBean.java (revision 9469) +++ tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/ViewCommentSignupMBean.java (working copy) @@ -1,119 +0,0 @@ -/********************************************************************************** - * $URL: https://source.sakaiproject.org/contrib/signup/branches/2-6-x/tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/ViewCommentSignupMBean.java $ - * $Id: ViewCommentSignupMBean.java 56827 2009-01-13 21:52:18Z guangzheng.liu@yale.edu $ -*********************************************************************************** - * - * Copyright (c) 2007, 2008, 2009 Yale University - * - * Licensed under the Educational Community License, Version 1.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/ecl1.php - * - * 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. - * - * See the LICENSE.txt distributed with this file. - * - **********************************************************************************/ -package org.sakaiproject.signup.tool.jsf.organizer; - -import org.sakaiproject.signup.tool.jsf.AttendeeWrapper; -import org.sakaiproject.signup.tool.jsf.SignupMeetingWrapper; -import org.sakaiproject.signup.tool.jsf.SignupUIBaseBean; -import org.sakaiproject.user.api.User; - -/** - *

- * This JSF UIBean class will handle information exchanges between Organizer's - * view comment page:viewComment.jsp and backbone system. - *

- */ -public class ViewCommentSignupMBean extends SignupUIBaseBean { - - private AttendeeWrapper attendeeWraper; - - private String AttendeeRole; - - /** - * To initialize this UIBean, which lives in a session scope. - * - * @param attwrp - * an AttendeeWrapper object. - * @param role - * a stirng value - * @param meetingwrp - * a SignupMeetingWrapper object. - */ - public void init(AttendeeWrapper attwrp, String role, SignupMeetingWrapper meetingwrp) { - this.attendeeWraper = attwrp; - this.AttendeeRole = role; - this.meetingWrapper = meetingwrp; - } - - /** - * This is a getter method for UI. - * - * @return an AttendeeWrapper object. - */ - public AttendeeWrapper getAttendeeWraper() { - return attendeeWraper; - } - - /** - * This is a setter. - * - * @param attendeeWraper - * an AttendeeWrapper object. - */ - public void setAttendeeWraper(AttendeeWrapper attendeeWraper) { - this.attendeeWraper = attendeeWraper; - } - - /** - * This is a getter method for UI. - * - * @return a string value. - */ - public String getAttendeeRole() { - return AttendeeRole; - } - - /** - * This is a setter. - * - * @param attendeeRole - * a string value. - */ - public void setAttendeeRole(String attendeeRole) { - AttendeeRole = attendeeRole; - } - - /** - * Overwrite the default one. - * - * @return a SignupMeetingWrapper object. - */ - public SignupMeetingWrapper getMeetingWrapper() { - return meetingWrapper; - } - - /** - * show the attendee's Eid (user Id) - * @return eid String - */ - public String getAttendeeEid(){ - String eid =attendeeWraper.getSignupAttendee().getAttendeeUserId(); - User user = sakaiFacade.getUser(attendeeWraper.getSignupAttendee().getAttendeeUserId()); - if(user !=null){ - eid = user.getEid(); - } - - return eid; - } - -} Index: tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/action/EditComment.java =================================================================== --- tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/action/EditComment.java (revision 0) +++ tool/src/java/org/sakaiproject/signup/tool/jsf/organizer/action/EditComment.java (revision 0) @@ -0,0 +1,110 @@ +package org.sakaiproject.signup.tool.jsf.organizer.action; + +import org.sakaiproject.signup.logic.SakaiFacade; +import org.sakaiproject.signup.logic.SignupMeetingService; +import org.sakaiproject.signup.logic.SignupUserActionException; +import org.sakaiproject.signup.model.SignupMeeting; +import org.sakaiproject.signup.tool.util.Utilities; +import org.springframework.dao.OptimisticLockingFailureException; + +public class EditComment extends SignupAction { + + private SignupMeeting originalMeeting; + + private Long relatedTimeslotId; + + private String modifiedComment; + + private SakaiFacade sakaiFacade; + + /** + * + * @param signupMeetingService + * @param currentUserId + * @param currentSiteId + * @param isOrganizer + * @param meeting + * @param timeslotId + * @param sakaiFacade + */ + public EditComment(SignupMeetingService signupMeetingService, String currentUserId, String currentSiteId, + boolean isOrganizer, SignupMeeting meeting, Long timeslotId, SakaiFacade sakaiFacade) { + super(currentUserId, currentSiteId, signupMeetingService, isOrganizer); + + this.originalMeeting = meeting; + this.relatedTimeslotId = timeslotId; + this.sakaiFacade = sakaiFacade; + } + + /** + * This method checks all the preconditions before saving the data into the database + * + * @param upToDateMeeting + * takes in the most up to date signup meeting + * @param timeslotId + * takes in a timeslotId + * @throws Exception + */ + private void checkPrecondition(SignupMeeting upToDateMeeting, Long timeslotId) throws Exception { + // TODO Auto-generated method stub + String originalComment = findUserComment(originalMeeting, timeslotId); + String upToDateComment = findUserComment(upToDateMeeting, timeslotId); + + if(!originalComment.equals(upToDateComment)){ + throw new SignupUserActionException(Utilities.rb.getString("someone.already.updated.comment")); + } + if(upToDateMeeting.getTimeslot(timeslotId) != null && upToDateMeeting.getTimeslot(timeslotId).getAttendee(userId) != null){ + upToDateMeeting.getTimeslot(timeslotId).getAttendee(userId).setComments(this.modifiedComment); + } + else + throw new SignupUserActionException(Utilities.rb.getString("someone.already.updated.comment")); + } + + /** + * This method is used to find the user's comment + * + * @param meeting + * takes in a signup meeting + * @param timeslotId + * takes in a timeslotId + * @return + * @throws Exception + */ + private String findUserComment(SignupMeeting meeting, Long timeslotId) throws Exception { + if(meeting.getTimeslot(timeslotId) != null && meeting.getTimeslot(timeslotId).getAttendee(userId) != null){ + return meeting.getTimeslot(timeslotId).getAttendee(userId).getComments(); + } + else + throw new SignupUserActionException(Utilities.rb.getString("someone.already.updated.comment")); + } + + /** + * + * @param newComment + * takes in a string new comment + * @return + * @throws Exception + */ + public SignupMeeting updateComment(String newComment) throws Exception { + this.modifiedComment = newComment; + boolean isOrganizer = originalMeeting.getPermission().isUpdate(); + String currentUserId = sakaiFacade.getCurrentUserId(); + + for (int i = 0; i < MAX_NUMBER_OF_RETRY; i++) { + try { + SignupMeeting upToDateMeeting = signupMeetingService.loadSignupMeeting(originalMeeting.getId(), currentUserId, siteId); + checkPrecondition(upToDateMeeting, relatedTimeslotId); + if(isOrganizer) + upToDateMeeting.setPermission(originalMeeting.getPermission()); + signupMeetingService.updateSignupMeeting(upToDateMeeting, isOrganizer); + upToDateMeeting = signupMeetingService.loadSignupMeeting(originalMeeting.getId(), currentUserId, siteId); + + return upToDateMeeting; + + } catch (OptimisticLockingFailureException oe) { + // don't do any thing + } + } + throw new SignupUserActionException(Utilities.rb.getString("someone.already.updated.db")); + } +} Index: tool/src/java/org/sakaiproject/signup/tool/util/SignupBeanConstants.java =================================================================== --- tool/src/java/org/sakaiproject/signup/tool/util/SignupBeanConstants.java (revision 9469) +++ tool/src/java/org/sakaiproject/signup/tool/util/SignupBeanConstants.java (working copy) @@ -90,8 +90,10 @@ public static final String ORGANIZER_MEETING_PAGE_URL = "organizerMeeting"; public static final String VIEW_COMMENT_PAGE_URL = "viewComment"; + + public static final String EDIT_COMMENT_PAGE_URL = "editComment"; - public static final String COPTY_MEETING_PAGE_URL = "copyMeeting"; + public static final String COPY_MEETING_PAGE_URL = "copyMeeting"; public static final String MODIFY_MEETING_PAGE_URL = "modifyMeeting"; Index: tool/src/webapp/WEB-INF/faces-config.xml =================================================================== --- tool/src/webapp/WEB-INF/faces-config.xml (revision 9469) +++ tool/src/webapp/WEB-INF/faces-config.xml (working copy) @@ -96,6 +96,10 @@ /signup/organizer/viewComment.jsp + editComment + /signup/attendee/editComment.jsp + + cancelTimeslot /signup/organizer/cancelTimeslot.jsp @@ -161,14 +165,14 @@ #{EditMeetingSignupMBean} - viewCommentMBean - #{ViewCommentSignupMBean} + editCommentMBean + #{EditCommentSignupMBean} - ViewCommentSignupMBean - org.sakaiproject.signup.tool.jsf.organizer.ViewCommentSignupMBean + EditCommentSignupMBean + org.sakaiproject.signup.tool.jsf.attendee.EditCommentSignupMBean session signupMeetingService @@ -243,6 +247,10 @@ attachmentHandler #{AttachmentHandler} + + editCommentMBean + #{EditCommentSignupMBean} + @@ -329,6 +337,16 @@ + UserTimeZone + org.sakaiproject.signup.tool.jsf.UserTimeZone + application + + sakaiFacade + #{org_sakaiproject_signup_logic_SakaiFacade} + + + + AttachmentHandler org.sakaiproject.signup.tool.jsf.attachment.AttachmentHandler session Index: tool/src/webapp/signup/attendee/editComment.jsp =================================================================== --- tool/src/webapp/signup/attendee/editComment.jsp (revision 0) +++ tool/src/webapp/signup/attendee/editComment.jsp (revision 0) @@ -0,0 +1,67 @@ +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://sakaiproject.org/jsf/sakai" prefix="sakai" %> +<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tool/src/webapp/signup/attendee/signupMeeting.jsp =================================================================== --- tool/src/webapp/signup/attendee/signupMeeting.jsp (revision 9591) +++ tool/src/webapp/signup/attendee/signupMeeting.jsp (working copy) @@ -191,8 +191,8 @@ - - + + @@ -201,7 +201,7 @@ <%-- control expand-collapse --%> - + @@ -250,7 +250,7 @@ - + @@ -285,7 +285,7 @@ - + @@ -293,7 +293,7 @@ - + @@ -304,7 +304,6 @@ - @@ -316,6 +315,13 @@ + + + + + + + - + @@ -309,7 +309,7 @@ - + Index: tool/src/webapp/signup/organizer/modifyMeeting.jsp =================================================================== --- tool/src/webapp/signup/organizer/modifyMeeting.jsp (revision 9591) +++ tool/src/webapp/signup/organizer/modifyMeeting.jsp (working copy) @@ -241,7 +241,7 @@ - + @@ -257,7 +257,7 @@ - + Index: tool/src/webapp/signup/organizer/orgSignupMeeting.jsp =================================================================== --- tool/src/webapp/signup/organizer/orgSignupMeeting.jsp (revision 9591) +++ tool/src/webapp/signup/organizer/orgSignupMeeting.jsp (working copy) @@ -393,7 +393,7 @@ - + @@ -627,6 +627,13 @@ + + + + + + + Index: tool/src/webapp/signup/organizer/viewComment.jsp =================================================================== --- tool/src/webapp/signup/organizer/viewComment.jsp (revision 9620) +++ tool/src/webapp/signup/organizer/viewComment.jsp (working copy) @@ -33,25 +33,25 @@ - + - + - + - + - + - + - + @@ -59,12 +59,13 @@ - - + + - - + + +