ALF-9156 Flesh out more of the Calendar API, and start on using it for the rest API

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28839 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2011-07-06 15:55:15 +00:00
parent 5b22f82860
commit d1c6383f6e
5 changed files with 332 additions and 46 deletions

View File

@@ -21,36 +21,12 @@ package org.alfresco.repo.calendar;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.query.CannedQueryFactory;
import org.alfresco.query.CannedQueryResults;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.blog.cannedqueries.DraftsAndPublishedBlogPostsCannedQuery;
import org.alfresco.repo.blog.cannedqueries.DraftsAndPublishedBlogPostsCannedQueryFactory;
import org.alfresco.repo.blog.cannedqueries.GetBlogPostsCannedQuery;
import org.alfresco.repo.blog.cannedqueries.GetBlogPostsCannedQueryFactory;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
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.CalendarService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.tagging.TaggingService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
import org.alfresco.util.registry.NamedObjectRegistry;
/** /**
* @author Nick Burch (based on existing webscript controllers in the REST API) * @author Nick Burch (based on existing webscript controllers in the REST API)
@@ -94,7 +70,19 @@ public class CalendarEntryImpl extends CalendarEntryDTO
protected static Map<QName,Serializable> toNodeProperties(CalendarEntry entry) protected static Map<QName,Serializable> toNodeProperties(CalendarEntry entry)
{ {
Map<QName,Serializable> properties = new HashMap<QName, Serializable>(); Map<QName,Serializable> properties = new HashMap<QName, Serializable>();
// TODO properties.put(CalendarModel.PROP_WHAT, entry.getTitle());
properties.put(CalendarModel.PROP_DESCRIPTION, entry.getDescription());
properties.put(CalendarModel.PROP_WHERE, entry.getLocation());
properties.put(CalendarModel.PROP_FROM_DATE, entry.getStart());
properties.put(CalendarModel.PROP_TO_DATE, entry.getEnd());
properties.put(CalendarModel.PROP_RECURRENCE_RULE, entry.getRecurrenceRule());
properties.put(CalendarModel.PROP_RECURRENCE_LAST_MEETING, entry.getLastRecurrence());
properties.put(CalendarModel.PROP_IS_OUTLOOK, entry.isOutlook());
properties.put(CalendarModel.PROP_OUTLOOK_UID, entry.getOutlookUID());
// properties.put(CalendarModel.PROP_COLOR, entry.getColor();
// TODO Tags, doc folders
return properties; return properties;
} }
@@ -104,7 +92,19 @@ public class CalendarEntryImpl extends CalendarEntryDTO
*/ */
protected static void populate(CalendarEntry entry, Map<QName,Serializable> properties) protected static void populate(CalendarEntry entry, Map<QName,Serializable> properties)
{ {
// TODO entry.setTitle((String)properties.get(CalendarModel.PROP_WHAT));
entry.setLocation((String)properties.get(CalendarModel.PROP_WHERE));
entry.setDescription((String)properties.get(CalendarModel.PROP_DESCRIPTION));
entry.setStart((Date)properties.get(CalendarModel.PROP_FROM_DATE));
entry.setEnd((Date)properties.get(CalendarModel.PROP_TO_DATE));
entry.setRecurrenceRule((String)properties.get(CalendarModel.PROP_RECURRENCE_RULE));
entry.setLastRecurrence((Date)properties.get(CalendarModel.PROP_RECURRENCE_LAST_MEETING));
entry.setOutlook((Boolean)properties.get(CalendarModel.PROP_IS_OUTLOOK));
entry.setOutlookUID((String)properties.get(CalendarModel.PROP_OUTLOOK_UID));
//entry.setColor(properties.get(CalendarModel.PROP_COLOR));
// TODO Tags, doc folders
} }
/** /**

View File

@@ -43,7 +43,7 @@ import org.apache.commons.logging.LogFactory;
*/ */
public class CalendarServiceImpl implements CalendarService public class CalendarServiceImpl implements CalendarService
{ {
private static final String CALENDAR_COMPONENT = "calendar"; protected static final String CALENDAR_COMPONENT = "calendar";
/** /**
* For backwards compatibility with pre-Swift, we are asking the query to give us an accurate total count of how many * For backwards compatibility with pre-Swift, we are asking the query to give us an accurate total count of how many

View File

@@ -19,6 +19,7 @@
package org.alfresco.repo.calendar; package org.alfresco.repo.calendar;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@@ -72,6 +73,7 @@ import org.springframework.context.ApplicationContext;
*/ */
public class CalendarServiceImplTest public class CalendarServiceImplTest
{ {
private static final String TEST_SITE_PREFIX = "CalendarSiteTest";
private static final ApplicationContext testContext = ApplicationContextHelper.getApplicationContext(); private static final ApplicationContext testContext = ApplicationContextHelper.getApplicationContext();
@@ -138,6 +140,8 @@ public class CalendarServiceImplTest
entry = new CalendarEntryDTO( entry = new CalendarEntryDTO(
"Title", "Description", "Location", new Date(1), new Date(1234) "Title", "Description", "Location", new Date(1), new Date(1234)
); );
entry.setOutlook(true);
entry.setOutlookUID("12345LookOut!");
// Can't be got until saved // Can't be got until saved
assertEquals(null, entry.getSystemName()); assertEquals(null, entry.getSystemName());
@@ -158,24 +162,163 @@ public class CalendarServiceImplTest
entry = CALENDAR_SERVICE.createCalendarEntry(CALENDAR_SITE.getShortName(), entry); entry = CALENDAR_SERVICE.createCalendarEntry(CALENDAR_SITE.getShortName(), entry);
// Ensure it got a noderef, and the correct site // Ensure it got a noderef, and the correct site
// TODO assertNotNull(entry.getNodeRef());
testNodesToTidy.add(entry.getNodeRef()); assertNotNull(entry.getSystemName());
// TODO NodeRef container = NODE_SERVICE.getPrimaryParent(entry.getNodeRef()).getParentRef();
NodeRef site = NODE_SERVICE.getPrimaryParent(container).getParentRef();
assertEquals(CALENDAR_SITE.getNodeRef(), site);
// Check the details on the object
assertEquals("Title", entry.getTitle());
assertEquals("Description", entry.getDescription());
assertEquals("Location", entry.getLocation());
assertEquals(1, entry.getStart().getTime());
assertEquals(1234, entry.getEnd().getTime());
assertEquals(null, entry.getRecurrenceRule());
assertEquals(null, entry.getLastRecurrence());
assertEquals(true, entry.isOutlook());
assertEquals("12345LookOut!", entry.getOutlookUID());
// Fetch it, and check the details
entry = CALENDAR_SERVICE.getCalendarEntry(CALENDAR_SITE.getShortName(), entry.getSystemName());
assertEquals("Title", entry.getTitle());
assertEquals("Description", entry.getDescription());
assertEquals("Location", entry.getLocation());
assertEquals(1, entry.getStart().getTime());
assertEquals(1234, entry.getEnd().getTime());
assertEquals(null, entry.getRecurrenceRule());
assertEquals(null, entry.getLastRecurrence());
assertEquals(true, entry.isOutlook());
assertEquals("12345LookOut!", entry.getOutlookUID());
// Mark it as done with
testNodesToTidy.add(entry.getNodeRef());
} }
@Test public void createUpdateDeleteEntry() throws Exception @Test public void createUpdateDeleteEntry() throws Exception
{ {
// TODO CalendarEntry entry;
// Create an entry
entry = new CalendarEntryDTO(
"Title", "Description", "Location", new Date(1), new Date(1234)
);
entry.setOutlook(true);
entry.setOutlookUID("12345LookOut!");
entry = CALENDAR_SERVICE.createCalendarEntry(CALENDAR_SITE.getShortName(), entry);
// Check it
assertEquals("Title", entry.getTitle());
assertEquals("Description", entry.getDescription());
assertEquals("Location", entry.getLocation());
assertEquals(1, entry.getStart().getTime());
assertEquals(1234, entry.getEnd().getTime());
assertEquals(null, entry.getRecurrenceRule());
assertEquals(null, entry.getLastRecurrence());
assertEquals(true, entry.isOutlook());
assertEquals("12345LookOut!", entry.getOutlookUID());
// Change it
entry.setTitle("New Title");
entry.setStart(new Date(1234567));
entry.setEnd(new Date(1294567));
entry.setRecurrenceRule("1w");
entry.setLastRecurrence(new Date(1234567));
entry.setOutlook(false);
entry.setOutlookUID(null);
CALENDAR_SERVICE.updateCalendarEntry(entry);
// Fetch, and check
entry = CALENDAR_SERVICE.getCalendarEntry(CALENDAR_SITE.getShortName(), entry.getSystemName());
assertEquals("New Title", entry.getTitle());
assertEquals("Description", entry.getDescription());
assertEquals("Location", entry.getLocation());
assertEquals(1234567, entry.getStart().getTime());
assertEquals(1294567, entry.getEnd().getTime());
assertEquals("1w", entry.getRecurrenceRule());
assertEquals(1234567, entry.getLastRecurrence().getTime());
assertEquals(false, entry.isOutlook());
assertEquals(null, entry.getOutlookUID());
// Delete it
CALENDAR_SERVICE.deleteCalendarEntry(entry);
// Check it went
assertEquals(null, CALENDAR_SERVICE.getCalendarEntry(CALENDAR_SITE.getShortName(), entry.getSystemName()));
// Finally, check the all day flag detection
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
// Neither start nor end are at midnight to start
assertEquals(false, CalendarEntryDTO.isAllDay(entry));
// Set the start to midnight
entry.setStart(c.getTime());
assertEquals(false, CalendarEntryDTO.isAllDay(entry));
// And end, will then count as all day
entry.setEnd(c.getTime());
assertEquals(true, CalendarEntryDTO.isAllDay(entry));
} }
/** /**
* Ensures that when we try to write an entry to the * Ensures that when we try to write an entry to the
* container of a new site, it is correctly setup for us * container of a new site, it is correctly setup for us.
* This test does it's own transactions
*/ */
@Test public void newContainerSetup() throws Exception @Test public void newContainerSetup() throws Exception
{ {
// TODO final String TEST_SITE_NAME = "CalendarTestNewTestSite";
TRANSACTION_HELPER.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
{
@Override
public Void execute() throws Throwable
{
if(SITE_SERVICE.getSite(TEST_SITE_NAME) != null)
{
SITE_SERVICE.deleteSite(TEST_SITE_NAME);
}
SITE_SERVICE.createSite(
TEST_SITE_PREFIX, TEST_SITE_NAME, "Test", "Test", SiteVisibility.PUBLIC
);
// Won't have the container to start with
assertFalse(SITE_SERVICE.hasContainer(TEST_SITE_NAME, CalendarServiceImpl.CALENDAR_COMPONENT));
// Create a calendar entry
CalendarEntry entry = new CalendarEntryDTO(
"Title", "Description", "Location", new Date(1), new Date(1234)
);
CALENDAR_SERVICE.createCalendarEntry(TEST_SITE_NAME, entry);
// It will now exist
assertTrue(SITE_SERVICE.hasContainer(TEST_SITE_NAME, CalendarServiceImpl.CALENDAR_COMPONENT));
// It'll be a tag scope too
NodeRef container = SITE_SERVICE.getContainer(TEST_SITE_NAME, CalendarServiceImpl.CALENDAR_COMPONENT);
assertTrue(TAGGING_SERVICE.isTagScope(container));
// Tidy up
SITE_SERVICE.deleteSite(TEST_SITE_NAME);
return null;
}
});
} }
@Test public void calendarListing() throws Exception @Test public void calendarListing() throws Exception
@@ -190,7 +333,7 @@ public class CalendarServiceImplTest
@Override @Override
public SiteInfo execute() throws Throwable public SiteInfo execute() throws Throwable
{ {
SiteInfo site = SITE_SERVICE.createSite("CalendarSiteTest", CalendarServiceImplTest.class.getSimpleName() + "_testSite" + System.currentTimeMillis(), SiteInfo site = SITE_SERVICE.createSite(TEST_SITE_PREFIX, CalendarServiceImplTest.class.getSimpleName() + "_testSite" + System.currentTimeMillis(),
"test site title", "test site description", SiteVisibility.PUBLIC); "test site title", "test site description", SiteVisibility.PUBLIC);
CLASS_TEST_NODES_TO_TIDY.add(site.getNodeRef()); CLASS_TEST_NODES_TO_TIDY.add(site.getNodeRef());
return site; return site;

View File

@@ -93,15 +93,53 @@ public interface CalendarEntry extends Serializable, PermissionCheckValue {
void setEnd(Date end); void setEnd(Date end);
/** /**
* @return the Tags associated with the event * Gets the event recurrence rule.
* TODO Define these
*/ */
List<String> getTags(); String getRecurrenceRule();
// TODO All Day events /**
* Sets the event recurrence rule
* TODO Define these
*/
void setRecurrenceRule(String recurrenceRule);
/**
* Gets the date of the last instance of this recurring event
*/
Date getLastRecurrence();
/**
* Sets the date of the last instance of this recurring event
*/
void setLastRecurrence(Date lastRecurrence);
/**
* Is this an outlook based event?
*/
boolean isOutlook();
/**
* Sets if this is an outlook based event or not
*/
void setOutlook(boolean outlook);
/**
* Gets the UID used by Outlook for this event.
* See {@link CalendarEntry#isOutlook()}
*/
String getOutlookUID();
/**
* Sets the UID used by Outlook for this event.
* When a UID is set, normally the isOutlook flag is set too.
*/
void setOutlookUID(String outlookUID);
// TODO Doc folder // TODO Doc folder
// TODO Recurrence /**
* @return the Tags associated with the event
// TODO Is Outlook */
List<String> getTags();
} }

View File

@@ -19,6 +19,7 @@
package org.alfresco.service.cmr.calendar; package org.alfresco.service.cmr.calendar;
import java.io.Serializable; import java.io.Serializable;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@@ -39,6 +40,10 @@ public class CalendarEntryDTO implements CalendarEntry, Serializable {
private String location; private String location;
private Date start; private Date start;
private Date end; private Date end;
private String recurrenceRule;
private Date lastRecurrence;
private boolean isOutlook = false;
private String outlookUID;
private List<String> tags; private List<String> tags;
/** /**
@@ -157,6 +162,72 @@ public class CalendarEntryDTO implements CalendarEntry, Serializable {
this.end = end; this.end = end;
} }
/**
* Gets the event recurrence rule.
*/
public String getRecurrenceRule()
{
return recurrenceRule;
}
/**
* Sets the event recurrence rule
*/
public void setRecurrenceRule(String recurrenceRule)
{
this.recurrenceRule = recurrenceRule;
}
/**
* Gets the date of the last instance of this recurring event
*/
public Date getLastRecurrence()
{
return lastRecurrence;
}
/**
* Sets the date of the last instance of this recurring event
*/
public void setLastRecurrence(Date lastRecurrence)
{
this.lastRecurrence = lastRecurrence;
}
/**
* Is this an outlook based event?
*/
public boolean isOutlook()
{
return isOutlook;
}
/**
* Sets if this is an outlook based event or not
*/
public void setOutlook(boolean outlook)
{
this.isOutlook = outlook;
}
/**
* Gets the UID used by Outlook for this event.
* See {@link CalendarEntry#isOutlook()}
*/
public String getOutlookUID()
{
return outlookUID;
}
/**
* Sets the UID used by Outlook for this event.
* When a UID is set, normally the isOutlook flag is set too.
*/
public void setOutlookUID(String outlookUID)
{
this.outlookUID = outlookUID;
}
/** /**
* @return the Tags associated with the event * @return the Tags associated with the event
*/ */
@@ -166,11 +237,45 @@ public class CalendarEntryDTO implements CalendarEntry, Serializable {
return tags; return tags;
} }
// TODO All Day events
// TODO Doc folder // TODO Doc folder
// TODO Recurrence /**
* Does the given {@link CalendarEntry} define an all-day
// TODO Is Outlook * event?
* An All Day Event is defined as one starting at midnight
* on a day, and ending at midnight.
*
* For a single day event, the start and end dates should be
* the same, and the times for both are midnight.
* For a multi day event, the start and end times are midnight,
* for the first and last days respectively.
* TODO Timezones!
*/
public static boolean isAllDay(CalendarEntry entry)
{
if(entry.getStart() == null || entry.getEnd() == null)
{
// One or both dates is missing
return false;
}
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
start.setTime(entry.getStart());
end.setTime(entry.getEnd());
if(start.get(Calendar.HOUR_OF_DAY) == 0 &&
start.get(Calendar.MINUTE) == 0 &&
start.get(Calendar.SECOND) == 0 &&
end.get(Calendar.HOUR_OF_DAY) == 0 &&
end.get(Calendar.MINUTE) == 0 &&
end.get(Calendar.SECOND) == 0)
{
// Both midnight, counts as all day
return true;
}
// In any other case, it isn't an all-day
return false;
}
} }