mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-21 18:09:20 +00:00
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:
@@ -24,16 +24,21 @@ import java.util.Calendar;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.CalendarEntry;
|
||||||
import org.alfresco.service.cmr.calendar.CalendarRecurrenceHelper;
|
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.alfresco.util.ISO8601DateFormat;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
import org.joda.time.format.ISODateTimeFormat;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides functionality common across the webscripts
|
* This class provides functionality common across the webscripts
|
||||||
@@ -136,9 +141,21 @@ public abstract class AbstractCalendarListingWebScript extends AbstractCalendarW
|
|||||||
// How long is it?
|
// How long is it?
|
||||||
long duration = entry.getEnd().getTime() - entry.getStart().getTime();
|
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
|
// Get it's recurring instances
|
||||||
List<Date> dates = CalendarRecurrenceHelper.getRecurrencesOnOrAfter(
|
List<Date> dates = CalendarRecurrenceHelper.getRecurrencesOnOrAfter(
|
||||||
entry, from, until, repeatingFirstOnly);
|
entry, from, until, repeatingFirstOnly, ignoredDates);
|
||||||
if (dates == null)
|
if (dates == null)
|
||||||
{
|
{
|
||||||
dates = new ArrayList<Date>();
|
dates = new ArrayList<Date>();
|
||||||
@@ -161,29 +178,51 @@ public abstract class AbstractCalendarListingWebScript extends AbstractCalendarW
|
|||||||
return false; // Remains sorted despite delete
|
return false; // Remains sorted despite delete
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always update the live entry
|
// if some instances were updated
|
||||||
updateRepeatingStartEnd(dates.get(0), duration, entryResult);
|
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 first result only, alter title and finish
|
||||||
if (repeatingFirstOnly)
|
if (repeatingFirstOnly)
|
||||||
{
|
{
|
||||||
|
updateRepeating(entry, updatedDates, entryResult, duration, fmt, liveEntry);
|
||||||
|
|
||||||
entryResult.put(RESULT_TITLE, entry.getTitle() + " (Repeating)");
|
entryResult.put(RESULT_TITLE, entry.getTitle() + " (Repeating)");
|
||||||
return true; // Date has been changed
|
return true; // Date has been changed
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Otherwise generate one entry per extra date
|
// Otherwise generate one entry per extra date
|
||||||
for (int i=1; i<dates.size(); i++)
|
for (int i = 1; i < dates.size(); i++)
|
||||||
{
|
{
|
||||||
// Clone the properties
|
// Clone the properties
|
||||||
Map<String, Object> newResult = new HashMap<String, Object>(entryResult);
|
Map<String, Object> newResult = new HashMap<String, Object>(entryResult);
|
||||||
|
|
||||||
// Generate start and end based on this date
|
Date extra = dates.get(i);
|
||||||
updateRepeatingStartEnd(dates.get(i), duration, newResult);
|
|
||||||
|
updateRepeating(entry, updatedDates, newResult, duration, fmt, extra);
|
||||||
|
|
||||||
// Save as a new event
|
// Save as a new event
|
||||||
allResults.add(newResult);
|
allResults.add(newResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRepeating(entry, updatedDates, entryResult, duration, fmt, liveEntry);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Skip ignored instances
|
// TODO Skip ignored instances
|
||||||
|
|
||||||
// New dates have been added
|
// New dates have been added
|
||||||
@@ -204,4 +243,26 @@ public abstract class AbstractCalendarListingWebScript extends AbstractCalendarW
|
|||||||
result.put("legacyDateTo", ldf.format(newEnd));
|
result.put("legacyDateTo", ldf.format(newEnd));
|
||||||
result.put("legacyTimeTo", ltf.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,16 +23,23 @@ import java.text.MessageFormat;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.alfresco.repo.calendar.CalendarModel;
|
||||||
import org.alfresco.service.cmr.calendar.CalendarEntry;
|
import org.alfresco.service.cmr.calendar.CalendarEntry;
|
||||||
import org.alfresco.service.cmr.calendar.CalendarEntryDTO;
|
import org.alfresco.service.cmr.calendar.CalendarEntryDTO;
|
||||||
import org.alfresco.service.cmr.calendar.CalendarRecurrenceHelper;
|
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.AccessStatus;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.cmr.site.SiteInfo;
|
import org.alfresco.service.cmr.site.SiteInfo;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
@@ -67,6 +74,29 @@ public class CalendarEntryGet extends AbstractCalendarWebScript
|
|||||||
return buildError(MessageFormat.format(message, eventName));
|
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
|
// Build the object
|
||||||
Map<String, Object> result = new HashMap<String, Object>();
|
Map<String, Object> result = new HashMap<String, Object>();
|
||||||
result.put("name", entry.getSystemName());
|
result.put("name", entry.getSystemName());
|
||||||
|
Reference in New Issue
Block a user