From 9ef80c899d869996c7fe83eb968b5def37208b3e Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 6 Jul 2011 12:21:34 +0000 Subject: [PATCH] ALF-9156 Update the new Calendar Service to match the pattern agreed yesterday git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28829 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repo/calendar/CalendarEntryImpl.java | 126 +++---------- .../repo/calendar/CalendarServiceImpl.java | 135 ++++++++------ .../calendar/CalendarServiceImplTest.java | 23 ++- .../service/cmr/calendar/CalendarEntry.java | 3 +- .../cmr/calendar/CalendarEntryDTO.java | 176 ++++++++++++++++++ .../service/cmr/calendar/CalendarService.java | 16 +- 6 files changed, 317 insertions(+), 162 deletions(-) create mode 100644 source/java/org/alfresco/service/cmr/calendar/CalendarEntryDTO.java diff --git a/source/java/org/alfresco/repo/calendar/CalendarEntryImpl.java b/source/java/org/alfresco/repo/calendar/CalendarEntryImpl.java index 164110e844..62703994c7 100644 --- a/source/java/org/alfresco/repo/calendar/CalendarEntryImpl.java +++ b/source/java/org/alfresco/repo/calendar/CalendarEntryImpl.java @@ -36,6 +36,7 @@ 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.CalendarEntryDTO; import org.alfresco.service.cmr.calendar.CalendarService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentService; @@ -55,54 +56,26 @@ import org.alfresco.util.registry.NamedObjectRegistry; * @author Nick Burch (based on existing webscript controllers in the REST API) * @since 4.0 */ -public class CalendarEntryImpl implements CalendarEntry +public class CalendarEntryImpl extends CalendarEntryDTO { private NodeRef nodeRef; - private NodeRef parentNodeRef; - private Map properties; - - /** - * Creates an empty Calendar Entry, to be stored in the - * given parent - */ - public CalendarEntryImpl(NodeRef parentNodeRef) - { - this.parentNodeRef = parentNodeRef; - this.properties = new HashMap(); - } + private String systemName; /** * Wraps an existing Calendar Entry node */ - public CalendarEntryImpl(NodeRef nodeRef, NodeRef parentNodeRef, Map properties) + protected CalendarEntryImpl(NodeRef nodeRef, String systemName) { this.nodeRef = nodeRef; - this.parentNodeRef = parentNodeRef; - this.properties = properties; + this.systemName = systemName; } - protected void recordStorageDetails(NodeRef nodeRef) + protected void recordStorageDetails(NodeRef nodeRef, String systemName) { this.nodeRef = nodeRef; + this.systemName = systemName; } - /** - * Returns the NodeRef of the parent where this calendar entry - * lives, or will live - */ - public NodeRef getParentNodeRef() - { - return parentNodeRef; - } - - /** - * Returns the current set of properties - */ - public Map getProperties() - { - return properties; - } - @Override public NodeRef getNodeRef() { @@ -110,72 +83,35 @@ public class CalendarEntryImpl implements CalendarEntry } @Override - public String getSystemName() { - // TODO Auto-generated method stub - return null; + public String getSystemName() + { + return systemName; } - - @Override - public String getTitle() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setTitle(String title) { - // TODO Auto-generated method stub - - } - @Override - public String getDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setDescription(String description) { - // TODO Auto-generated method stub - } - - @Override - public Date getStart() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setStart(Date start) { - // TODO Auto-generated method stub + + /** + * Builds up the node properties for a given Calendar Entry + */ + protected static Map toNodeProperties(CalendarEntry entry) + { + Map properties = new HashMap(); + // TODO + return properties; } - @Override - public Date getEnd() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setEnd(Date end) { - // TODO Auto-generated method stub - + /** + * Populates a Calendar Entry from the given node properties + */ + protected static void populate(CalendarEntry entry, Map properties) + { + // TODO } - @Override - public String getLocation() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setLocation(String location) { - // TODO Auto-generated method stub - - } - - @Override - public List getTags() { - // TODO Auto-generated method stub - return null; + /** + * Populates this entry from the given node properties + */ + protected void populate(Map properties) + { + populate(this, properties); } } diff --git a/source/java/org/alfresco/repo/calendar/CalendarServiceImpl.java b/source/java/org/alfresco/repo/calendar/CalendarServiceImpl.java index a339e68810..68f4f483ed 100644 --- a/source/java/org/alfresco/repo/calendar/CalendarServiceImpl.java +++ b/source/java/org/alfresco/repo/calendar/CalendarServiceImpl.java @@ -19,9 +19,9 @@ package org.alfresco.repo.calendar; import java.io.Serializable; -import java.util.Date; import java.util.Map; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; @@ -97,30 +97,33 @@ public class CalendarServiceImpl implements CalendarService { if(create) { + if(transactionService.isReadOnly()) + { + throw new AlfrescoRuntimeException( + "Unable to create the calendar container from a read only transaction" + ); + } + // Have the site container created if(logger.isDebugEnabled()) { logger.debug("Creating " + CALENDAR_COMPONENT + " container in site " + siteShortName); } - NodeRef container = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() { - public NodeRef doWork() throws Exception + NodeRef container = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() { - return transactionService.getRetryingTransactionHelper().doInTransaction( - new RetryingTransactionCallback() { - public NodeRef execute() throws Throwable { - // Create the site container - NodeRef container = siteService.createContainer( - siteShortName, CALENDAR_COMPONENT, null, null - ); - - // Done - return container; - } - }, false, true - ); - } - }, AuthenticationUtil.getSystemUserName()); + public NodeRef doWork() throws Exception + { + // Create the site container + NodeRef container = siteService.createContainer( + siteShortName, CALENDAR_COMPONENT, null, null + ); + + // Done + return container; + } + }, AuthenticationUtil.getSystemUserName() + ); if(logger.isDebugEnabled()) { @@ -176,7 +179,8 @@ public class CalendarServiceImpl implements CalendarService } @Override - public CalendarEntry getCalendarEntry(String siteShortName, String entryName) { + public CalendarEntry getCalendarEntry(String siteShortName, String entryName) + { NodeRef container = getSiteCalendarContainer(siteShortName, false); if(container == null) { @@ -187,55 +191,78 @@ public class CalendarServiceImpl implements CalendarService NodeRef event = nodeService.getChildByName(container, ContentModel.ASSOC_CONTAINS, entryName); if(event != null) { - return new CalendarEntryImpl(event, container, nodeService.getProperties(event)); + CalendarEntryImpl entry = new CalendarEntryImpl(event, entryName); + entry.populate(nodeService.getProperties(event)); + return entry; } return null; } @Override - public CalendarEntry createCalendarEntry(String siteShortName, - String eventTitle, String eventDescription, Date eventStart, Date eventEnd) { + public CalendarEntry createCalendarEntry(String siteShortName, CalendarEntry entry) + { + if(entry.getNodeRef() != null) + { + throw new IllegalArgumentException("Can't call create for a calendar entry that was previously persisted"); + } + + // Grab the location to store in NodeRef container = getSiteCalendarContainer(siteShortName, true); - CalendarEntry entry = new CalendarEntryImpl(container); - entry.setTitle(eventTitle); - entry.setDescription(eventDescription); - entry.setStart(eventStart); - entry.setEnd(eventEnd); + // Turn the entry into properties + Map properties = CalendarEntryImpl.toNodeProperties(entry); + + // Generate a name + String name = "123.ics"; // TODO + properties.put(ContentModel.PROP_NAME, name); + + // Add the entry + NodeRef nodeRef = nodeService.createNode( + container, + ContentModel.ASSOC_CONTAINS, + QName.createQName(name), + CalendarModel.TYPE_EVENT, + properties + ).getChildRef(); + + // Record it's details + CalendarEntryImpl entryImpl; + if(entry instanceof CalendarEntryImpl) + { + entryImpl = (CalendarEntryImpl)entry; + entryImpl.recordStorageDetails(nodeRef, name); + } + else + { + entryImpl = new CalendarEntryImpl(nodeRef, name); + entryImpl.populate(properties); + } + return entryImpl; + } + + @Override + public CalendarEntry updateCalendarEntry(CalendarEntry entry) { + Map properties = CalendarEntryImpl.toNodeProperties(entry); + + if(entry.getNodeRef() == null) + { + throw new IllegalArgumentException("Can't update a calendar entry that was never persisted, call create instead"); + } + + // Update the existing one + nodeService.setProperties(entry.getNodeRef(), properties); + + // Nothing changed return entry; } @Override - public void saveCalendarEntry(CalendarEntry entry) { - CalendarEntryImpl entryImpl = (CalendarEntryImpl)entry; - Map properties = entryImpl.getProperties(); - + public void deleteCalendarEntry(CalendarEntry entry) { if(entry.getNodeRef() == null) { - // Generate a name - String name = "123.ics"; // TODO - properties.put(ContentModel.PROP_NAME, name); - - // Add the entry - NodeRef nodeRef = nodeService.createNode( - entryImpl.getParentNodeRef(), - ContentModel.ASSOC_CONTAINS, - QName.createQName(name), - CalendarModel.TYPE_EVENT, - properties - ).getChildRef(); - entryImpl.recordStorageDetails(nodeRef); + throw new IllegalArgumentException("Can't delete a calendar entry that was never persisted"); } - else - { - // Update the existing one - nodeService.setProperties(entry.getNodeRef(), properties); - } - } - - @Override - public void deleteCalendarEntry(CalendarEntry entry) { - // TODO Auto-generated method stub + nodeService.deleteNode(entry.getNodeRef()); } } diff --git a/source/java/org/alfresco/repo/calendar/CalendarServiceImplTest.java b/source/java/org/alfresco/repo/calendar/CalendarServiceImplTest.java index c19d68f3f9..454d709c81 100644 --- a/source/java/org/alfresco/repo/calendar/CalendarServiceImplTest.java +++ b/source/java/org/alfresco/repo/calendar/CalendarServiceImplTest.java @@ -21,6 +21,7 @@ package org.alfresco.repo.calendar; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Arrays; @@ -37,6 +38,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.site.SiteModel; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.service.cmr.calendar.CalendarEntry; +import org.alfresco.service.cmr.calendar.CalendarEntryDTO; import org.alfresco.service.cmr.calendar.CalendarService; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; @@ -133,20 +135,31 @@ public class CalendarServiceImplTest // Create one - entry = CALENDAR_SERVICE.createCalendarEntry( - CALENDAR_SITE.getShortName(), "Title", - "Description", new Date(1), new Date(1234) + entry = new CalendarEntryDTO( + "Title", "Description", "Location", new Date(1), new Date(1234) ); // Can't be got until saved assertEquals(null, entry.getSystemName()); assertEquals(null, entry.getNodeRef()); - // But we do know where it'll go - assertNotNull( ((CalendarEntryImpl)entry).getParentNodeRef() ); + + // Can't call update yet + try + { + CALENDAR_SERVICE.updateCalendarEntry(entry); + fail("Shouldn't be able to update a brand new entry"); + } + catch(IllegalArgumentException e) + {} // Have it saved + entry = CALENDAR_SERVICE.createCalendarEntry(CALENDAR_SITE.getShortName(), entry); + + // Ensure it got a noderef, and the correct site + // TODO + testNodesToTidy.add(entry.getNodeRef()); // TODO } diff --git a/source/java/org/alfresco/service/cmr/calendar/CalendarEntry.java b/source/java/org/alfresco/service/cmr/calendar/CalendarEntry.java index 14b7fda7e8..7831d5c2ef 100644 --- a/source/java/org/alfresco/service/cmr/calendar/CalendarEntry.java +++ b/source/java/org/alfresco/service/cmr/calendar/CalendarEntry.java @@ -22,6 +22,7 @@ import java.io.Serializable; import java.util.Date; import java.util.List; +import org.alfresco.repo.security.permissions.PermissionCheckValue; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -30,7 +31,7 @@ import org.alfresco.service.cmr.repository.NodeRef; * @author Nick Burch * @since 4.0 */ -public interface CalendarEntry extends Serializable { +public interface CalendarEntry extends Serializable, PermissionCheckValue { /** * @return the NodeRef of the underlying calendar entry */ diff --git a/source/java/org/alfresco/service/cmr/calendar/CalendarEntryDTO.java b/source/java/org/alfresco/service/cmr/calendar/CalendarEntryDTO.java new file mode 100644 index 0000000000..6a5277776e --- /dev/null +++ b/source/java/org/alfresco/service/cmr/calendar/CalendarEntryDTO.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.service.cmr.calendar; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * This class represents an event in a calendar. + * + * @author Nick Burch + * @since 4.0 + */ +public class CalendarEntryDTO implements CalendarEntry, Serializable { + private NodeRef nodeRef; + private String systemName; + + private String title; + private String description; + private String location; + private Date start; + private Date end; + private List tags; + + /** + * Creates an empty {@link CalendarEntry}, which can be populated + * with set calls. + */ + public CalendarEntryDTO() + {} + + /** + * Creates a {@link CalendarEntry} with common properties. + */ + public CalendarEntryDTO(String title, String description, + String location, Date start, Date end) + { + this.title = title; + this.description = description; + this.location = location; + this.start = start; + this.end = end; + } + + /** + * @return the NodeRef of the underlying calendar entry + */ + public NodeRef getNodeRef() + { + return nodeRef; + } + + /** + * @return the System generated name for the event + */ + public String getSystemName() + { + return systemName; + } + + /** + * @return the Title ("what") of the event + */ + public String getTitle() + { + return title; + } + + /** + * Sets the Title ("what") of the event + */ + public void setTitle(String title) + { + this.title = title; + } + + /** + * @return the Description of the event + */ + public String getDescription() + { + return description; + } + + /** + * Sets the Description of the event + */ + public void setDescription(String description) + { + this.description = description; + } + + /** + * @return the Location of the event + */ + public String getLocation() + { + return location; + } + + /** + * Sets the Location of the event + */ + public void setLocation(String location) + { + this.location = location; + } + + /** + * @return the Start date and time + */ + public Date getStart() + { + return start; + } + + /** + * Sets the event start date and time + */ + public void setStart(Date start) + { + this.start = start; + } + + /** + * @return the End date and time + */ + public Date getEnd() + { + return end; + } + + /** + * Sets the event end date and time + */ + public void setEnd(Date end) + { + this.end = end; + } + + /** + * @return the Tags associated with the event + */ + public List getTags() + { + // TODO Immutable? + return tags; + } + + // TODO All Day events + + // TODO Doc folder + + // TODO Recurrence + + // TODO Is Outlook +} diff --git a/source/java/org/alfresco/service/cmr/calendar/CalendarService.java b/source/java/org/alfresco/service/cmr/calendar/CalendarService.java index 701edaed42..81837b1a4c 100644 --- a/source/java/org/alfresco/service/cmr/calendar/CalendarService.java +++ b/source/java/org/alfresco/service/cmr/calendar/CalendarService.java @@ -33,20 +33,22 @@ import org.alfresco.service.cmr.site.SiteInfo; */ public interface CalendarService { /** - * Creates a new {@link CalendarEntry} for the given site, but - * doesn't save it to the repository. + * Stores a new {@link CalendarEntry} into the given site. + * The concrete class {@link CalendarEntryDTO} can be used + * to create a {@link CalendarEntry} instance for this. * - * @return The newly cre + * @return The newly created CalendarEntry */ @NotAuditable - CalendarEntry createCalendarEntry(String siteShortName, String eventTitle, - String eventDescription, Date from, Date to); + CalendarEntry createCalendarEntry(String siteShortName, CalendarEntry entry); /** - * Saves a {@link CalendarEntry} in the repository. + * Updates an existing {@link CalendarEntry} in the repository. + * + * @return The updated CalendarEntry */ @NotAuditable - void saveCalendarEntry(CalendarEntry entry); + CalendarEntry updateCalendarEntry(CalendarEntry entry); /** * Deletes an existing {@link CalendarEntry} from the repository