diff --git a/source/java/org/alfresco/repo/web/scripts/calendar/AbstractCalendarListingWebScript.java b/source/java/org/alfresco/repo/web/scripts/calendar/AbstractCalendarListingWebScript.java index 4b09adac63..c68b710442 100644 --- a/source/java/org/alfresco/repo/web/scripts/calendar/AbstractCalendarListingWebScript.java +++ b/source/java/org/alfresco/repo/web/scripts/calendar/AbstractCalendarListingWebScript.java @@ -24,16 +24,21 @@ import java.util.Calendar; import java.util.Comparator; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import org.alfresco.repo.calendar.CalendarModel; import org.alfresco.service.cmr.calendar.CalendarEntry; import org.alfresco.service.cmr.calendar.CalendarRecurrenceHelper; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; import org.alfresco.util.ISO8601DateFormat; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; /** * This class provides functionality common across the webscripts @@ -136,9 +141,21 @@ public abstract class AbstractCalendarListingWebScript extends AbstractCalendarW // How long is it? long duration = entry.getEnd().getTime() - entry.getStart().getTime(); + // if some instances were deleted from series ignore them + Set childNodeTypeQNames = new HashSet(); + childNodeTypeQNames.add(CalendarModel.TYPE_IGNORE_EVENT); + List ignoreEventList = nodeService.getChildAssocs(entry.getNodeRef(), childNodeTypeQNames); + Set ignoredDates = new HashSet(); + for (ChildAssociationRef ignoreEvent : ignoreEventList) + { + NodeRef nodeRef = ignoreEvent.getChildRef(); + Date ignoredDate = (Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_IGNORE_EVENT_DATE); + ignoredDates.add(ignoredDate); + } + // Get it's recurring instances List dates = CalendarRecurrenceHelper.getRecurrencesOnOrAfter( - entry, from, until, repeatingFirstOnly); + entry, from, until, repeatingFirstOnly, ignoredDates); if (dates == null) { dates = new ArrayList(); @@ -161,27 +178,49 @@ public abstract class AbstractCalendarListingWebScript extends AbstractCalendarW return false; // Remains sorted despite delete } - // Always update the live entry - updateRepeatingStartEnd(dates.get(0), duration, entryResult); + // if some instances were updated + SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd"); + childNodeTypeQNames = new HashSet(); + childNodeTypeQNames.add(CalendarModel.TYPE_UPDATED_EVENT); + List updatedEventList = nodeService.getChildAssocs(entry.getNodeRef(), childNodeTypeQNames); + Map updatedDates = new HashMap(); + for (ChildAssociationRef updatedEvent : updatedEventList) + { + NodeRef nodeRef = updatedEvent.getChildRef(); + Date updatedDate = (Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_EVENT_DATE); + Date newStart = (Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_START); + Date newEnd = (Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_END); + updatedDates.put(fmt.format(updatedDate), new Date[] { newStart, newEnd }); + } + + // first occurrence can be edited as separate event + Date liveEntry = dates.get(0); // If first result only, alter title and finish if (repeatingFirstOnly) { + updateRepeating(entry, updatedDates, entryResult, duration, fmt, liveEntry); + entryResult.put(RESULT_TITLE, entry.getTitle() + " (Repeating)"); return true; // Date has been changed } - - // Otherwise generate one entry per extra date - for (int i=1; i newResult = new HashMap(entryResult); + // Otherwise generate one entry per extra date + for (int i = 1; i < dates.size(); i++) + { + // Clone the properties + Map newResult = new HashMap(entryResult); + + Date extra = dates.get(i); + + updateRepeating(entry, updatedDates, newResult, duration, fmt, extra); + + // Save as a new event + allResults.add(newResult); + } - // Generate start and end based on this date - updateRepeatingStartEnd(dates.get(i), duration, newResult); - - // Save as a new event - allResults.add(newResult); + updateRepeating(entry, updatedDates, entryResult, duration, fmt, liveEntry); } // TODO Skip ignored instances @@ -204,4 +243,26 @@ public abstract class AbstractCalendarListingWebScript extends AbstractCalendarW result.put("legacyDateTo", ldf.format(newEnd)); result.put("legacyTimeTo", ltf.format(newEnd)); } + + private void updateRepeating(CalendarEntry entry, Map updatedDates, Map entryResult, long duration, SimpleDateFormat fmt, Date date) + { + if (updatedDates.keySet().contains(fmt.format(date))) + { + // there is day that was edited + Date[] newValues = updatedDates.get(fmt.format(date)); + long newDuration = newValues[1].getTime() - newValues[0].getTime(); + NodeRef nodeRef = nodeService.getChildAssocsByPropertyValue(entry.getNodeRef(), CalendarModel.PROP_UPDATED_EVENT_DATE, date).get(0).getChildRef(); + if (nodeRef != null) + { + entryResult.put(RESULT_TITLE, (String) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_WHAT)); + entryResult.put("where", (String) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_WHERE)); + } + updateRepeatingStartEnd(newValues[0], newDuration, entryResult); + } + else + { + // Update entry + updateRepeatingStartEnd(date, duration, entryResult); + } + } } diff --git a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryGet.java b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryGet.java index e14ee207a5..9b74796947 100644 --- a/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryGet.java +++ b/source/java/org/alfresco/repo/web/scripts/calendar/CalendarEntryGet.java @@ -23,16 +23,23 @@ import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.ResourceBundle; +import java.util.Set; import java.util.TimeZone; +import org.alfresco.repo.calendar.CalendarModel; import org.alfresco.service.cmr.calendar.CalendarEntry; import org.alfresco.service.cmr.calendar.CalendarEntryDTO; import org.alfresco.service.cmr.calendar.CalendarRecurrenceHelper; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.site.SiteInfo; +import org.alfresco.service.namespace.QName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.simple.JSONObject; @@ -66,7 +73,30 @@ public class CalendarEntryGet extends AbstractCalendarWebScript String message = rb.getString(MSG_EVENT_NOT_FOUND); return buildError(MessageFormat.format(message, eventName)); } - + + Date date = parseDate(req.getParameter("date")); + if (date != null) + { + // if some instances were updated + SimpleDateFormat fdt = new SimpleDateFormat("yyyyMMdd"); + Set childNodeTypeQNames = new HashSet(); + childNodeTypeQNames.add(CalendarModel.TYPE_UPDATED_EVENT); + List updatedEventList = nodeService.getChildAssocs(entry.getNodeRef(), childNodeTypeQNames); + for (ChildAssociationRef updatedEvent : updatedEventList) + { + NodeRef nodeRef = updatedEvent.getChildRef(); + Date updatedDate = (Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_EVENT_DATE); + if (fdt.format(updatedDate).equals(fdt.format(date))) + { + entry.setStart((Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_START)); + entry.setEnd((Date) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_END)); + entry.setTitle((String) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_WHAT)); + entry.setLocation((String) nodeService.getProperty(nodeRef, CalendarModel.PROP_UPDATED_WHERE)); + break; + } + } + } + // Build the object Map result = new HashMap(); result.put("name", entry.getSystemName());