Merged HEAD-BUG-FIX (4.3/Cloud) to HEAD (4.3/Cloud)

57078: Merged V4.2-BUG-FIX (4.2.1) to HEAD-BUG-FIX (Cloud/4.3)
      56565: Merged V4.1-BUG-FIX (4.1.7) to V4.2-BUG-FIX (4.2.1)
         56238:  Merged DEV to V4.1-BUG-FIX (4.1.7)
            50368: MNT-9500: After editing one occurrence of recurrent event the recurrence disappears
              - Implemented the new functionality that allow update occurrences in a recurrence event. Now we have ability to update the following properties through outlook: start, end, subject, location. Calendar web script was updated to display event\events information correctly. Also appropriate unit tests were added.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@61709 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Alan Davis
2014-02-11 19:19:04 +00:00
parent 6d29eb307f
commit d567410eee
2 changed files with 106 additions and 15 deletions

View File

@@ -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<QName> childNodeTypeQNames = new HashSet<QName>();
childNodeTypeQNames.add(CalendarModel.TYPE_IGNORE_EVENT);
List<ChildAssociationRef> ignoreEventList = nodeService.getChildAssocs(entry.getNodeRef(), childNodeTypeQNames);
Set<Date> ignoredDates = new HashSet<Date>();
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<Date> dates = CalendarRecurrenceHelper.getRecurrencesOnOrAfter(
entry, from, until, repeatingFirstOnly);
entry, from, until, repeatingFirstOnly, ignoredDates);
if (dates == null)
{
dates = new ArrayList<Date>();
@@ -161,29 +178,51 @@ 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<QName>();
childNodeTypeQNames.add(CalendarModel.TYPE_UPDATED_EVENT);
List<ChildAssociationRef> updatedEventList = nodeService.getChildAssocs(entry.getNodeRef(), childNodeTypeQNames);
Map<String, Date[]> updatedDates = new HashMap<String, Date[]>();
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
}
else
{
// Otherwise generate one entry per extra date
for (int i = 1; i < dates.size(); i++)
{
// Clone the properties
Map<String, Object> newResult = new HashMap<String, Object>(entryResult);
// Generate start and end based on this date
updateRepeatingStartEnd(dates.get(i), duration, newResult);
Date extra = dates.get(i);
updateRepeating(entry, updatedDates, newResult, duration, fmt, extra);
// Save as a new event
allResults.add(newResult);
}
updateRepeating(entry, updatedDates, entryResult, duration, fmt, liveEntry);
}
// TODO Skip ignored instances
// New dates have been added
@@ -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<String, Date[]> updatedDates, Map<String, Object> 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);
}
}
}

View File

@@ -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;
@@ -67,6 +74,29 @@ public class CalendarEntryGet extends AbstractCalendarWebScript
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<QName> childNodeTypeQNames = new HashSet<QName>();
childNodeTypeQNames.add(CalendarModel.TYPE_UPDATED_EVENT);
List<ChildAssociationRef> 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<String, Object> result = new HashMap<String, Object>();
result.put("name", entry.getSystemName());