Finished implementing Unpublishing.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29625 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
N Smith
2011-08-09 11:01:23 +00:00
parent d004bc3e90
commit 0dc8ed5929
23 changed files with 666 additions and 477 deletions

View File

@@ -62,10 +62,8 @@
<property name="nodeService" ref="NodeService" />
<property name="namespaceService" ref="NamespaceService" />
<property name="searchService" ref="SearchService" />
<property name="versionService" ref="VersionService" />
<property name="publishingEventHelper" ref="publishingEventHelper" />
<property name="retryingTransactionHelper" ref="retryingTransactionHelper" />
<property name="transferManifestNodeFactory" ref="transferManifestNodeFactory" />
<property name="permissionService" ref="PermissionService" />
<property name="publishingStore" value="${spaces.store}" />
<property name="publishingRootPath" value="${publishing.root}" />
@@ -77,6 +75,8 @@
<property name="serializer" ref="publishingPackageSerializer" />
<property name="workflowService" ref="WorkflowService" />
<property name="permissionService" ref="PermissionService" />
<property name="transferManifestNodeFactory" ref="transferManifestNodeFactory" />
<property name="versionService" ref="VersionService" />
<property name="workflowEngineId" value="jbpm" />
</bean>

View File

@@ -49,7 +49,6 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService;
@@ -87,8 +86,6 @@ public class ChannelHelper
public NodeRef createChannelNode(NodeRef parent, ChannelType channelType, String channelName,
Map<QName, Serializable> props)
{
Set<AccessPermission> permissions = permissionService.getPermissions(parent);
QName channelQName = getChannelQName(channelName);
QName channelNodeType = channelType.getChannelNodeType();
ChildAssociationRef channelAssoc =
@@ -120,6 +117,18 @@ public class ChannelHelper
* @return
*/
public NodeRef mapSourceToEnvironment(NodeRef source, final NodeRef channelNode)
{
return mapSourceToEnvironment(source, channelNode, nodeService);
}
/**
* Given a noderef from the editorial space (e.g. the doclib), this returns the corresponding noderef published to the specified channel.
* @param source
* @param channelNode
* @param nodeService
* @return
*/
public static NodeRef mapSourceToEnvironment(NodeRef source, final NodeRef channelNode, final NodeService nodeService)
{
if(source == null || channelNode == null)
{
@@ -145,6 +154,16 @@ public class ChannelHelper
* @return
*/
public NodeRef mapEnvironmentToSource(NodeRef publishedNode)
{
return mapEnvironmentToSource(publishedNode, nodeService);
}
/**
* Given a published noderef, this returns the corresponding source noderef in the editorial space (doclib).
* @param publishedNode
* @return
*/
public static NodeRef mapEnvironmentToSource(NodeRef publishedNode, NodeService nodeService)
{
List<AssociationRef> assocs = nodeService.getTargetAssocs(publishedNode, ASSOC_SOURCE);
return NodeUtils.getSingleAssocNode(assocs, true);

View File

@@ -296,7 +296,7 @@ public class ChannelServiceImpl implements ChannelService
{
HashMap<QName, Serializable> actualProps = new HashMap<QName, Serializable>(properties);
actualProps.remove(ContentModel.PROP_NODE_UUID);
NodeRef editorialNode = channel.getNodeRef();
NodeRef editorialNode = new NodeRef(channel.getId());
for (Map.Entry<QName, Serializable> entry : actualProps.entrySet())
{
nodeService.setProperty(editorialNode, entry.getKey(), entry.getValue());

View File

@@ -1,168 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.publishing;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transfer.manifest.TransferManifestNodeFactory;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.service.cmr.publishing.PublishingPackage;
import org.alfresco.service.cmr.publishing.MutablePublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionService;
/**
* @author Brian
* @author Nick Smith
*
* @since 4.0
*/
public class MutablePublishingPackageImpl implements MutablePublishingPackage
{
private final VersionService versionService;
private final TransferManifestNodeFactory transferManifestNodeFactory;
private final Map<NodeRef, PublishingPackageEntry> entryMap = new HashMap<NodeRef, PublishingPackageEntry>();
private final Set<NodeRef> nodesToPublish = new HashSet<NodeRef>();
private final Set<NodeRef> nodesToUnpublish= new HashSet<NodeRef>();
/**
* @param transferManifestNodeFactory
*/
public MutablePublishingPackageImpl(TransferManifestNodeFactory transferManifestNodeFactory,
VersionService versionService)
{
this.transferManifestNodeFactory = transferManifestNodeFactory;
this.versionService = versionService;
}
/**
* {@inheritDoc}
*/
public MutablePublishingPackage addNodesToPublish(NodeRef... nodesToAdd)
{
return addNodesToPublish(Arrays.asList(nodesToAdd));
}
/**
* {@inheritDoc}
*/
public MutablePublishingPackage addNodesToPublish(final Collection<NodeRef> nodesToAdd)
{
AuthenticationUtil.runAs(new RunAsWork<Void>()
{
public Void doWork() throws Exception
{
versionNodes(nodesToAdd);
return null;
}
}, AuthenticationUtil.getSystemUserName());
nodesToPublish.addAll(nodesToAdd);
return this;
}
private void versionNodes(Collection<NodeRef> nodesToAdd)
{
for (NodeRef nodeRef : nodesToAdd)
{
Version version = versionService.createVersion(nodeRef, null);
String versionLabel = null;
if(version != null)
{
versionLabel = version.getVersionLabel();
}
TransferManifestNormalNode payload = (TransferManifestNormalNode) transferManifestNodeFactory.createTransferManifestNode(nodeRef, null);
if (TransferManifestNormalNode.class.isAssignableFrom(payload.getClass()))
{
PublishingPackageEntryImpl publishingPackage = new PublishingPackageEntryImpl(true, nodeRef, payload, versionLabel);
entryMap.put(nodeRef, publishingPackage);
}
}
}
/**
* {@inheritDoc}
*/
public MutablePublishingPackage addNodesToUnpublish(NodeRef... nodesToRemove)
{
return addNodesToUnpublish(Arrays.asList(nodesToRemove));
}
/**
* {@inheritDoc}
*/
public MutablePublishingPackage addNodesToUnpublish(Collection<NodeRef> nodesToRemove)
{
for (NodeRef nodeRef : nodesToRemove)
{
entryMap.put(nodeRef, new PublishingPackageEntryImpl(false, nodeRef, null, null));
}
nodesToUnpublish.addAll(nodesToRemove);
return this;
}
/**
* {@inheritDoc}
*/
public Collection<PublishingPackageEntry> getEntries()
{
return entryMap.values();
}
/**
* {@inheritDoc}
*/
public Set<NodeRef> getNodesToPublish()
{
return nodesToPublish;
}
/**
* {@inheritDoc}
*/
public Set<NodeRef> getNodesToUnpublish()
{
return nodesToUnpublish;
}
/**
* {@inheritDoc}
*/
public Map<NodeRef, PublishingPackageEntry> getEntryMap()
{
return entryMap;
}
/**
* {@inheritDoc}
*/
public PublishingPackage build()
{
return new PublishingPackageImpl(entryMap);
}
}

View File

@@ -16,28 +16,15 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.service.cmr.publishing;
import java.util.Collection;
import org.alfresco.service.cmr.repository.NodeRef;
package org.alfresco.repo.publishing;
/**
* An extendsion of the {@link PublishingPackage} interface which allows values to be modified.
* @author Brian
* @author Nick Smith
*
* @since 4.0
*
*/
public interface MutablePublishingPackage extends PublishingPackage
public class NodeSnapshotFactory
{
MutablePublishingPackage addNodesToUnpublish(NodeRef... nodesToRemove);
MutablePublishingPackage addNodesToUnpublish(Collection<NodeRef> nodesToRemove);
MutablePublishingPackage addNodesToPublish(NodeRef... nodesToPublish);
MutablePublishingPackage addNodesToPublish(Collection<NodeRef> nodesToPublish);
PublishingPackage build();
}

View File

@@ -21,8 +21,11 @@ package org.alfresco.repo.publishing;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.alfresco.service.cmr.publishing.NodeSnapshot;
import org.alfresco.service.cmr.publishing.PublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -33,9 +36,9 @@ import org.alfresco.service.cmr.repository.NodeRef;
*
* @since 4.0
*/
public interface PublishingPackageSerializer
public interface NodeSnapshotSerializer
{
void serialize(PublishingPackage publishingPackage, OutputStream output) throws Exception;
void serialize(Collection<NodeSnapshot> snapshots, OutputStream output) throws Exception;
Map<NodeRef, PublishingPackageEntry> deserialize(InputStream input) throws Exception;
List<NodeSnapshot> deserialize(InputStream input) throws Exception;
}

View File

@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.service.cmr.publishing.NodeSnapshot;
import org.alfresco.service.cmr.repository.AssociationRef;
@@ -34,6 +35,8 @@ import org.alfresco.service.namespace.QName;
/**
* @author Brian
* @author Nick Smith
* @since 4.0
*
*/
public class NodeSnapshotTransferImpl implements NodeSnapshot
@@ -44,16 +47,16 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/**
* @param transferNode
*/
public NodeSnapshotTransferImpl(TransferManifestNormalNode transferNode, String version)
public NodeSnapshotTransferImpl(TransferManifestNormalNode transferNode)
{
this.transferNode = transferNode;
this.version = version;
Map<QName, Serializable> props = transferNode.getProperties();
this.version = (String) props.get(ContentModel.PROP_VERSION_LABEL);
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getAllParentAssocs()
*/
@Override
public List<ChildAssociationRef> getAllParentAssocs()
{
return transferNode.getParentAssocs();
@@ -62,7 +65,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getAspects()
*/
@Override
public Set<QName> getAspects()
{
return transferNode.getAspects();
@@ -71,7 +74,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getNodeRef()
*/
@Override
public NodeRef getNodeRef()
{
return transferNode.getNodeRef();
@@ -80,7 +83,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getOutboundPeerAssociations()
*/
@Override
public List<AssociationRef> getOutboundPeerAssociations()
{
return transferNode.getTargetAssocs();
@@ -89,7 +92,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getPrimaryParentAssoc()
*/
@Override
public ChildAssociationRef getPrimaryParentAssoc()
{
return transferNode.getPrimaryParentAssoc();
@@ -98,7 +101,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getPrimaryPath()
*/
@Override
public Path getPrimaryPath()
{
return transferNode.getParentPath();
@@ -107,7 +110,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getProperties()
*/
@Override
public Map<QName, Serializable> getProperties()
{
return transferNode.getProperties();
@@ -116,7 +119,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getType()
*/
@Override
public QName getType()
{
return transferNode.getType();
@@ -125,9 +128,17 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/**
* {@inheritDoc}
*/
@Override
public String getVersion()
{
return version;
}
/**
* @return the transferNode
*/
public TransferManifestNormalNode getTransferNode()
{
return transferNode;
}
}

View File

@@ -46,10 +46,9 @@ import javax.annotation.Resource;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.publishing.MutablePublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingDetails;
import org.alfresco.service.cmr.publishing.PublishingService;
import org.alfresco.service.cmr.publishing.Status;
import org.alfresco.service.cmr.publishing.StatusUpdate;
import org.alfresco.service.cmr.publishing.channels.Channel;
import org.alfresco.service.cmr.publishing.channels.ChannelType;
import org.alfresco.service.cmr.repository.AssociationRef;
@@ -362,13 +361,12 @@ public class PublishEventActionTest extends AbstractPublishingIntegrationTest
// Create Status Update
String message = "Here is the message ";
StatusUpdate status = publishingService.getPublishingQueue().createStatusUpdate(message, source, channel.getId());
String url = "http://test/url";
when(channelType.getNodeUrl(any(NodeRef.class))).thenReturn(url);
when(channelType.canPublishStatusUpdates()).thenReturn(true);
publishNode(source, status);
publishNode(source, message);
String expMessage = message + " " + url;
verify(channelType, times(1)).updateStatus(any(Channel.class), eq(expMessage), anyMap());
@@ -379,23 +377,30 @@ public class PublishEventActionTest extends AbstractPublishingIntegrationTest
return publishNode(source, null);
}
private NodeRef publishNode(NodeRef source, StatusUpdate statusUpdate)
private NodeRef publishNode(NodeRef source, String message)
{
return publishNode(source, statusUpdate, true);
return publishNode(source, message, true);
}
private NodeRef publishNode(NodeRef source, StatusUpdate statusUpdate, boolean publish)
private NodeRef publishNode(NodeRef source, String message, boolean publish)
{
MutablePublishingPackage pckg = publishingService.getPublishingQueue().createPublishingPackageBuilder();
PublishingDetails details = publishingService.getPublishingQueue().createPublishingDetails();
details.setPublishChannel(channel.getId());
if(publish)
{
pckg.addNodesToPublish(source);
details.addNodesToPublish(source);
}
else
{
pckg.addNodesToUnpublish(source);
details.addNodesToUnpublish(source);
}
String eventId = testHelper.scheduleEvent1Year(pckg, channel.getId(), null, statusUpdate);
if(message!=null)
{
details.setStatusMessage(message)
.setStatusNodeToLinkTo(source)
.addStatusUpdateChannels(channel.getId());
}
String eventId = testHelper.scheduleEvent1Year(details);
assertNotNull(eventId);
NodeRef eventNode = new NodeRef(eventId);

View File

@@ -0,0 +1,216 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.publishing;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.alfresco.service.cmr.publishing.PublishingDetails;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* @author Brian
* @author Nick Smith
*
* @since 4.0
*/
public class PublishingDetailsImpl implements PublishingDetails
{
private final Set<NodeRef> nodesToPublish = new HashSet<NodeRef>();
private final Set<NodeRef> nodesToUnpublish= new HashSet<NodeRef>();
private final Set<String> statusChannels = new HashSet<String>();
private NodeRef nodeToLinkTo = null;
private String message = null;
private Calendar schedule = null;
private String comment = null;
private String publishChannelId = null;
/**
* {@inheritDoc}
*/
public PublishingDetails addNodesToPublish(NodeRef... nodesToAdd)
{
return addNodesToPublish(Arrays.asList(nodesToAdd));
}
/**
* {@inheritDoc}
*/
public PublishingDetails addNodesToUnpublish(NodeRef... nodesToRemove)
{
return addNodesToUnpublish(Arrays.asList(nodesToRemove));
}
/**
* {@inheritDoc}
*/
@Override
public PublishingDetails addNodesToUnpublish(Collection<NodeRef> nodesToRemove)
{
this.nodesToUnpublish.addAll(nodesToRemove);
return this;
}
/**
* {@inheritDoc}
*/
public PublishingDetails addNodesToPublish(Collection<NodeRef> nodesToAdd)
{
this.nodesToPublish.addAll(nodesToAdd);
return this;
}
/**
* {@inheritDoc}
*/
public PublishingDetails setPublishChannel(String publishChannelId)
{
this.publishChannelId = publishChannelId;
return this;
}
/**
* {@inheritDoc}
*/
public PublishingDetails setComment(String comment)
{
this.comment = comment;
return this;
}
/**
* {@inheritDoc}
*/
public PublishingDetails setSchedule(Calendar schedule)
{
this.schedule = schedule;
return this;
}
/**
* {@inheritDoc}
*/
public PublishingDetails setStatusMessage(String message)
{
this.message = message;
return this;
}
/**
* {@inheritDoc}
*/
public PublishingDetails setStatusNodeToLinkTo(NodeRef nodeToLinkTo)
{
this.nodeToLinkTo = nodeToLinkTo;
return this;
}
/**
* {@inheritDoc}
*/
public PublishingDetails addStatusUpdateChannels(Collection<String> channelIds)
{
statusChannels.addAll(channelIds);
return this;
}
/**
* {@inheritDoc}
*/
public PublishingDetails addStatusUpdateChannels(String... channelIds)
{
return addStatusUpdateChannels(Arrays.asList(channelIds));
}
/**
* {@inheritDoc}
*/
public Set<NodeRef> getNodesToPublish()
{
return nodesToPublish;
}
/**
* {@inheritDoc}
*/
public Set<NodeRef> getNodesToUnpublish()
{
return nodesToUnpublish;
}
/**
* @return the statusChannels
*/
public Set<String> getStatusChannels()
{
return statusChannels;
}
/**
* @return the comment
*/
public String getComment()
{
return comment;
}
/**
* @return the message
*/
public String getStatusMessage()
{
return message;
}
/**
* @return the nodeToLinkTo
*/
public NodeRef getNodeToLinkTo()
{
return nodeToLinkTo;
}
/**
* @return the publishChannelId
*/
public String getPublishChannelId()
{
return publishChannelId;
}
/**
* @return the schedule
*/
public Calendar getSchedule()
{
return schedule;
}
public Set<String> getStatusUpdateChannels()
{
return statusChannels;
}
}

View File

@@ -60,8 +60,13 @@ import java.util.TimeZone;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.NodeUtils;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.transfer.manifest.TransferManifestNodeFactory;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.publishing.NodeSnapshot;
import org.alfresco.service.cmr.publishing.PublishingDetails;
import org.alfresco.service.cmr.publishing.PublishingEvent;
import org.alfresco.service.cmr.publishing.PublishingEventFilter;
import org.alfresco.service.cmr.publishing.PublishingPackage;
@@ -77,6 +82,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService;
@@ -93,6 +99,7 @@ import org.apache.commons.logging.LogFactory;
/**
* @author Brian
* @author Nick Smith
* @since 4.0
*
*/
public class PublishingEventHelper
@@ -102,9 +109,11 @@ public class PublishingEventHelper
private NodeService nodeService;
private ContentService contentService;
private VersionService versionService;
private WorkflowService workflowService;
private PublishingPackageSerializer serializer;
private NodeSnapshotSerializer serializer;
private PermissionService permissionService;
private TransferManifestNodeFactory transferManifestNodeFactory;
private String workflowEngineId;
@@ -126,6 +135,22 @@ public class PublishingEventHelper
this.contentService = contentService;
}
/**
* @param transferManifestNodeFactory the transferManifestNodeFactory to set
*/
public void setTransferManifestNodeFactory(TransferManifestNodeFactory transferManifestNodeFactory)
{
this.transferManifestNodeFactory = transferManifestNodeFactory;
}
/**
* @param versionService the versionService to set
*/
public void setVersionService(VersionService versionService)
{
this.versionService = versionService;
}
/**
* @param workflowService the workflowService to set
*/
@@ -145,7 +170,7 @@ public class PublishingEventHelper
/**
* @param serializer the serializer to set
*/
public void setSerializer(PublishingPackageSerializer serializer)
public void setSerializer(NodeSnapshotSerializer serializer)
{
this.serializer = serializer;
}
@@ -168,15 +193,15 @@ public class PublishingEventHelper
Map<QName, Serializable> props = nodeService.getProperties(eventNode);
String statusStr = (String) props.get(PROP_PUBLISHING_EVENT_STATUS);
Status status = Status.valueOf(statusStr);
PublishingPackage publishingPackage = getPayLoad(eventNode);
String channel = (String) props.get(PROP_PUBLISHING_EVENT_CHANNEL);
Date createdTime = (Date) props.get(ContentModel.PROP_CREATED);
String creator = (String) props.get(ContentModel.PROP_CREATOR);
Date modifiedTime = (Date) props.get(ContentModel.PROP_MODIFIED);
String modifier = (String) props.get(ContentModel.PROP_MODIFIER);
String comment = (String) props.get(PROP_PUBLISHING_EVENT_COMMENT);
Calendar scheduledTime = getScheduledTime(props);
PublishingPackage publishingPackage = getPublishingPackage(eventNode, channel);
String channel = (String) props.get(PROP_PUBLISHING_EVENT_CHANNEL);
StatusUpdate statusUpdate = buildStatusUpdate(props);
return new PublishingEventImpl(eventNode.toString(),
status, channel,
@@ -210,28 +235,23 @@ public class PublishingEventHelper
});
}
public NodeRef createNode(NodeRef queueNode, PublishingPackage publishingPackage, String channelId, Calendar schedule, String comment, StatusUpdate statusUpdate)
throws Exception
public NodeRef createNode(NodeRef queueNode, PublishingDetails details) throws Exception
{
checkChannelAccess(channelId);
if(statusUpdate != null && isEmpty(statusUpdate.getChannelIds())==false )
for (String statusChannelId : statusUpdate.getChannelIds())
checkChannelAccess(details.getPublishChannelId());
Set<String> statusChannelIds = details.getStatusUpdateChannels();
if(isEmpty(statusChannelIds)==false )
for (String statusChannelId : statusChannelIds)
{
checkChannelAccess(statusChannelId);
}
if (schedule == null)
{
schedule = Calendar.getInstance();
}
String name = GUID.generate();
Map<QName, Serializable> props =
buildPublishingEventProperties(publishingPackage, channelId, schedule, comment, statusUpdate, name);
Map<QName, Serializable> props = buildPublishingEventProperties(details, name);
ChildAssociationRef newAssoc = nodeService.createNode(queueNode,
ASSOC_PUBLISHING_EVENT,
QName.createQName(NAMESPACE, name),
TYPE_PUBLISHING_EVENT, props);
NodeRef eventNode = newAssoc.getChildRef();
setPayload(eventNode, publishingPackage);
serializePublishNodes(eventNode, details);
return eventNode;
}
@@ -245,33 +265,40 @@ public class PublishingEventHelper
}
}
private Map<QName, Serializable> buildPublishingEventProperties(PublishingPackage publishingPackage,
String channelId, Calendar schedule, String comment, StatusUpdate statusUpdate, String name)
private Map<QName, Serializable> buildPublishingEventProperties(PublishingDetails details, String name)
{
Calendar schedule = details.getSchedule();
if (schedule == null)
{
schedule = Calendar.getInstance();
}
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
props.put(ContentModel.PROP_NAME, name);
props.put(PROP_PUBLISHING_EVENT_STATUS, Status.IN_PROGRESS.name());
props.put(PROP_PUBLISHING_EVENT_TIME, schedule.getTime());
props.put(PublishingModel.PROP_PUBLISHING_EVENT_TIME_ZONE, schedule.getTimeZone().getID());
props.put(PublishingModel.PROP_PUBLISHING_EVENT_CHANNEL, channelId);
props.put(PublishingModel.PROP_PUBLISHING_EVENT_CHANNEL, details.getPublishChannelId());
props.put(PublishingModel.PROP_PUBLISHING_EVENT_STATUS, PublishingModel.PROPVAL_PUBLISHING_EVENT_STATUS_SCHEDULED);
String comment = details.getComment();
if (comment != null)
{
props.put(PROP_PUBLISHING_EVENT_COMMENT, comment);
}
Collection<String> publshStrings = mapNodesToStrings(publishingPackage.getNodesToPublish());
Collection<String> publshStrings = mapNodesToStrings(details.getNodesToPublish());
props.put(PROP_PUBLISHING_EVENT_NODES_TO_PUBLISH, (Serializable) publshStrings);
Collection<String> unpublshStrings = mapNodesToStrings(publishingPackage.getNodesToUnpublish());
Collection<String> unpublshStrings = mapNodesToStrings(details.getNodesToUnpublish());
props.put(PROP_PUBLISHING_EVENT_NODES_TO_UNPUBLISH, (Serializable) unpublshStrings);
if(statusUpdate != null)
String message = details.getStatusMessage();
Set<String> statusChannels = details.getStatusUpdateChannels();
if(message != null && isEmpty(statusChannels)==false)
{
props.put(PROP_STATUS_UPDATE_MESSAGE, statusUpdate.getMessage());
NodeRef statusNode = statusUpdate.getNodeToLinkTo();
props.put(PROP_STATUS_UPDATE_MESSAGE, message);
NodeRef statusNode = details.getNodeToLinkTo();
if(statusNode != null)
{
props.put(PROP_STATUS_UPDATE_NODE_REF, statusNode.toString());
}
props.put(PROP_STATUS_UPDATE_CHANNEL_NAMES, (Serializable) statusUpdate.getChannelIds());
props.put(PROP_STATUS_UPDATE_CHANNEL_NAMES, (Serializable) statusChannels);
}
return props;
}
@@ -476,15 +503,16 @@ public class PublishingEventHelper
return scheduledTime;
}
private void setPayload(NodeRef eventNode, PublishingPackage publishingPackage) throws Exception
private void serializePublishNodes(NodeRef eventNode, PublishingDetails details) throws Exception
{
try
{
List<NodeSnapshot> snapshots = createPublishSnapshots(details.getNodesToPublish());
ContentWriter contentWriter = contentService.getWriter(eventNode,
PROP_PUBLISHING_EVENT_PAYLOAD, true);
contentWriter.setEncoding("UTF-8");
OutputStream os = contentWriter.getContentOutputStream();
serializer.serialize(publishingPackage, os);
serializer.serialize(snapshots, os);
os.flush();
os.close();
}
@@ -495,16 +523,71 @@ public class PublishingEventHelper
}
}
private PublishingPackage getPayLoad(NodeRef eventNode) throws AlfrescoRuntimeException
private PublishingPackage getPublishingPackage(NodeRef eventNode, String channelId) throws AlfrescoRuntimeException
{
Map<NodeRef, PublishingPackageEntry> publishEntires = getPublishEntries(eventNode);
Map<NodeRef, PublishingPackageEntry> allEntries = getUnpublishEntries(eventNode, channelId);
allEntries.putAll(publishEntires);
return new PublishingPackageImpl(allEntries);
}
public Map<NodeRef, PublishingPackageEntry> createPublishEntries(Collection<NodeRef> nodesToAdd)
{
return transformToMap(nodesToAdd, new Function<NodeRef, PublishingPackageEntry>()
{
public PublishingPackageEntry apply(NodeRef node)
{
return createPublishEntry(node);
}
});
}
private PublishingPackageEntry createPublishEntry(NodeRef node)
{
NodeSnapshotTransferImpl snapshot = createPublishSnapshot(node);
return new PublishingPackageEntryImpl(true, node, snapshot);
}
private List<NodeSnapshot> createPublishSnapshots(final Collection<NodeRef> nodes)
{
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<List<NodeSnapshot>>()
{
public List<NodeSnapshot> doWork() throws Exception
{
return transform(nodes, new Function<NodeRef, NodeSnapshot>()
{
public NodeSnapshot apply(NodeRef node)
{
return createPublishSnapshot(node);
}
});
}
}, AuthenticationUtil.getSystemUserName());
}
private NodeSnapshotTransferImpl createPublishSnapshot(NodeRef node)
{
versionService.createVersion(node, null);
TransferManifestNormalNode payload = (TransferManifestNormalNode) transferManifestNodeFactory.createTransferManifestNode(node, null);
NodeSnapshotTransferImpl snapshot = new NodeSnapshotTransferImpl(payload);
return snapshot;
}
private Map<NodeRef, PublishingPackageEntry> getPublishEntries(NodeRef eventNode)
{
ContentReader contentReader = contentService.getReader(eventNode, PROP_PUBLISHING_EVENT_PAYLOAD);
InputStream input = contentReader.getContentInputStream();
try
{
Map<NodeRef, PublishingPackageEntry> publishEntires = serializer.deserialize(input);
Map<NodeRef, PublishingPackageEntry> allEntries = getUnpublishPackageEntries(eventNode);
allEntries.putAll(publishEntires);
return new PublishingPackageImpl(allEntries);
List<NodeSnapshot> snapshots = serializer.deserialize(input);
Map<NodeRef, PublishingPackageEntry> entries = new HashMap<NodeRef, PublishingPackageEntry>(snapshots.size());
for (NodeSnapshot snapshot : snapshots)
{
NodeRef node = snapshot.getNodeRef();
PublishingPackageEntryImpl entry = new PublishingPackageEntryImpl(true, node, snapshot);
entries.put(node, entry);
}
return entries;
}
catch (Exception ex)
{
@@ -513,7 +596,7 @@ public class PublishingEventHelper
}
}
private Map<NodeRef, PublishingPackageEntry> getUnpublishPackageEntries(NodeRef eventNode)
public Map<NodeRef, PublishingPackageEntry> getUnpublishEntries(NodeRef eventNode, String channelId)
{
@SuppressWarnings("unchecked")
List<String> entries= (List<String>) nodeService.getProperty(eventNode, PROP_PUBLISHING_EVENT_NODES_TO_UNPUBLISH);
@@ -521,6 +604,7 @@ public class PublishingEventHelper
{
return new HashMap<NodeRef, PublishingPackageEntry>();
}
final NodeRef channelNode = new NodeRef(channelId);
List<NodeRef> nodes = NodeUtils.toNodeRefs(entries);
return transformToMap(nodes, new Function<NodeRef, PublishingPackageEntry>()
{
@@ -528,13 +612,37 @@ public class PublishingEventHelper
{
if(NodeUtils.exists(node, nodeService))
{
return new PublishingPackageEntryImpl(false, node, null, null);
return makeUnpublishEntry(node, channelNode);
}
return null;
}
});
}
private PublishingPackageEntry makeUnpublishEntry(NodeRef source, NodeRef channelNode)
{
NodeRef lastEvent = getLastPublishEvent(source, channelNode);
NodeSnapshot snapshot = null;
if(lastEvent!=null)
{
Map<NodeRef, PublishingPackageEntry> entries = getPublishEntries(lastEvent);
PublishingPackageEntry entry = entries.get(source);
snapshot = entry.getSnapshot();
}
return new PublishingPackageEntryImpl(false, source, snapshot);
}
public NodeRef getLastPublishEvent(NodeRef source, NodeRef channelNode)
{
NodeRef publishedNode = ChannelHelper.mapSourceToEnvironment(source, channelNode, nodeService);
if(publishedNode == null)
{
return null;
}
List<AssociationRef> assocs = nodeService.getTargetAssocs(publishedNode, ASSOC_LAST_PUBLISHING_EVENT);
return NodeUtils.getSingleAssocNode(assocs, true);
}
public void cancelEvent(String id)
{
NodeRef eventNode = getPublishingEventNode(id);
@@ -577,6 +685,11 @@ public class PublishingEventHelper
return nodeService.createAssociation(publishedNode, eventNode, ASSOC_LAST_PUBLISHING_EVENT);
}
public PublishingDetails createPublishingPackageBuilder()
{
return new PublishingDetailsImpl();
}
// public NodePublishStatus checkNodeStatus(NodeRef node, String channelId, NodeRef queue)
// {
// PublishingEvent queuedEvent = getQueuedPublishingEvent(node, channelId, queue);

View File

@@ -42,7 +42,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -50,9 +49,8 @@ import java.util.Map;
import javax.annotation.Resource;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.publishing.PublishingDetails;
import org.alfresco.service.cmr.publishing.PublishingEvent;
import org.alfresco.service.cmr.publishing.PublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.publishing.Status;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -128,7 +126,7 @@ public class PublishingEventHelperTest
when(reader.getContentInputStream()).thenReturn(inputStream);
when(contentService.getReader(any(NodeRef.class), any(QName.class)))
.thenReturn(reader);
PublishingPackageSerializer serializer = mock(PublishingPackageSerializer.class);
NodeSnapshotSerializer serializer = mock(NodeSnapshotSerializer.class);
helper.setSerializer(serializer);
PublishingEvent result = helper.getPublishingEvent((NodeRef)null);
@@ -181,7 +179,7 @@ public class PublishingEventHelperTest
.thenReturn(writer);
OutputStream outputStream = mock(OutputStream.class);
when(writer.getContentOutputStream()).thenReturn(outputStream);
PublishingPackageSerializer serializer = mock(PublishingPackageSerializer.class);
NodeSnapshotSerializer serializer = mock(NodeSnapshotSerializer.class);
helper.setSerializer(serializer);
NodeRef queue = new NodeRef("foo://bar/queue");
@@ -191,13 +189,16 @@ public class PublishingEventHelperTest
when(nodeService.createNode(any(NodeRef.class), any(QName.class), any(QName.class), any(QName.class), anyMap()))
.thenReturn(childAssoc);
Map<NodeRef, PublishingPackageEntry> entires = Collections.emptyMap();
PublishingPackage pckg = new PublishingPackageImpl(entires);
String channelName = "test://channel/id";
String channelId = "test://channel/id";
Calendar schedule = Calendar.getInstance();
String comment = "The comment";
NodeRef result = helper.createNode(queue, pckg, channelName, schedule, comment, null);
PublishingDetails details = new PublishingDetailsImpl()
.setSchedule(schedule)
.setPublishChannel(channelId)
.setComment(comment);
NodeRef result = helper.createNode(queue, details);
assertEquals(event, result);
ArgumentCaptor<Map> argument = ArgumentCaptor.forClass(Map.class);
@@ -208,7 +209,7 @@ public class PublishingEventHelperTest
Map<QName, Serializable> props = argument.getValue();
assertNotNull(props.get(ContentModel.PROP_NAME));
assertEquals(channelName, props.get(PROP_PUBLISHING_EVENT_CHANNEL));
assertEquals(channelId, props.get(PROP_PUBLISHING_EVENT_CHANNEL));
assertEquals(comment, props.get(PROP_PUBLISHING_EVENT_COMMENT));
assertEquals(schedule.getTime(), props.get(PROP_PUBLISHING_EVENT_TIME));
assertEquals(schedule.getTimeZone().getID(), props.get(PROP_PUBLISHING_EVENT_TIME_ZONE));

View File

@@ -150,7 +150,8 @@ public class PublishingEventProcessor
public void unpublishEntry(Channel channel, PublishingPackageEntry entry)
{
NodeRef publishedNode = channelHelper.mapSourceToEnvironment(entry.getNodeRef(), channel.getNodeRef());
NodeRef channelNode = new NodeRef(channel.getId());
NodeRef publishedNode = channelHelper.mapSourceToEnvironment(entry.getNodeRef(), channelNode);
if(NodeUtils.exists(publishedNode, nodeService))
{
channel.unPublish(publishedNode);

View File

@@ -34,7 +34,7 @@ import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.publishing.MutablePublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingDetails;
import org.alfresco.service.cmr.publishing.PublishingEvent;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.publishing.PublishingQueue;
@@ -85,16 +85,20 @@ public class PublishingIntegratedTest extends BaseSpringTest
}
PublishingQueue liveQueue = publishingService.getPublishingQueue();
MutablePublishingPackage publishingPackage = liveQueue.createPublishingPackageBuilder();
publishingPackage.addNodesToPublish(nodes);
Calendar scheduleTime = Calendar.getInstance();
scheduleTime.add(Calendar.HOUR, 1);
String eventId = liveQueue.scheduleNewEvent(publishingPackage, channel.getId(), scheduleTime, null, null);
Calendar schedule = Calendar.getInstance();
schedule.add(Calendar.HOUR, 1);
PublishingDetails details = liveQueue.createPublishingDetails()
.addNodesToPublish(nodes)
.setPublishChannel(channel.getId())
.setSchedule(schedule);
String eventId = liveQueue.scheduleNewEvent(details);
PublishingEvent event = publishingService.getPublishingEvent(eventId);
Assert.assertEquals(scheduleTime, event.getScheduledTime());
Assert.assertEquals(schedule, event.getScheduledTime());
Assert.assertEquals(eventId, event.getId());
Collection<PublishingPackageEntry> entries = event.getPackage().getEntries();
Assert.assertEquals(4, entries.size());
@@ -118,12 +122,14 @@ public class PublishingIntegratedTest extends BaseSpringTest
NamespaceService.CONTENT_MODEL_1_0_URI, Integer.toString(i)), ContentModel.TYPE_CONTENT).getChildRef());
}
PublishingQueue liveQueue = publishingService.getPublishingQueue();
MutablePublishingPackage publishingPackage = liveQueue.createPublishingPackageBuilder();
publishingPackage.addNodesToPublish(nodes);
Calendar schedule = Calendar.getInstance();
schedule.add(Calendar.HOUR, 1);
Calendar scheduleTime = Calendar.getInstance();
scheduleTime.add(Calendar.HOUR, 1);
String eventId = liveQueue.scheduleNewEvent(publishingPackage, channel.getId(), scheduleTime, null, null);
PublishingDetails details = liveQueue.createPublishingDetails()
.addNodesToPublish(nodes)
.setPublishChannel(channel.getId())
.setSchedule(schedule);
String eventId = liveQueue.scheduleNewEvent(details);
PublishingEvent event = publishingService.getPublishingEvent(eventId);
Assert.assertNotNull(event);
publishingService.cancelPublishingEvent(eventId);

View File

@@ -19,8 +19,6 @@
package org.alfresco.repo.publishing;
import org.alfresco.repo.transfer.manifest.TransferManifestNode;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.service.cmr.publishing.NodeSnapshot;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -36,17 +34,13 @@ class PublishingPackageEntryImpl implements PublishingPackageEntry
{
private final boolean publish;
private final NodeRef nodeRef;
private final TransferManifestNormalNode payload;
private final String version;
private final NodeSnapshot snapshot;
public PublishingPackageEntryImpl(boolean publish,
NodeRef nodeRef, TransferManifestNormalNode payload,
String version)
public PublishingPackageEntryImpl(boolean publish, NodeRef nodeRef, NodeSnapshot snapshot)
{
this.publish = publish;
this.nodeRef = nodeRef;
this.payload = payload;
this.version = version;
this.snapshot= snapshot;
}
/**
@@ -65,20 +59,11 @@ class PublishingPackageEntryImpl implements PublishingPackageEntry
return publish;
}
/**
* @return the payload
*/
public TransferManifestNode getPayload()
{
return payload;
}
/**
* {@inheritDoc}
*/
public NodeSnapshot getSnapshot()
{
//TODO Add versioning information.
return new NodeSnapshotTransferImpl(payload, version);
return snapshot;
}
}

View File

@@ -19,14 +19,11 @@
package org.alfresco.repo.publishing;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -36,33 +33,27 @@ import java.util.Set;
import javax.annotation.Resource;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transfer.manifest.TransferManifestNodeFactory;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.publishing.NodeSnapshot;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.transfer.TransferDefinition;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author Brian
* @author Nick Smith
* @since 4.0
*
*/
public class PublishingPackageSerializerTest extends AbstractPublishingIntegrationTest
{
@Autowired
protected RetryingTransactionHelper retryingTransactionHelper;
@Resource(name="publishingPackageSerializer")
private StandardPublishingPackageSerializer serializer;
@@ -126,28 +117,20 @@ public class PublishingPackageSerializerTest extends AbstractPublishingIntegrati
@Test
public void testSerializer() throws Exception
{
TransferManifestNodeFactory mockTMNFactory = mock(TransferManifestNodeFactory.class);
VersionService mockVersionService = mock(VersionService.class);
MutablePublishingPackageImpl packageImpl = new MutablePublishingPackageImpl(mockTMNFactory, mockVersionService);
when(mockTMNFactory.createTransferManifestNode(any(NodeRef.class), any(TransferDefinition.class)))
.thenReturn(normalNode1);
packageImpl.addNodesToPublish(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,"Hello"));
NodeSnapshotTransferImpl transferSnapshot = new NodeSnapshotTransferImpl(normalNode1);
ByteArrayOutputStream os = new ByteArrayOutputStream();
serializer.serialize(packageImpl, os);
serializer.serialize(Collections.<NodeSnapshot>singleton(transferSnapshot), os);
os.close();
byte[] output = os.toByteArray();
ByteArrayInputStream is = new ByteArrayInputStream(output);
Map<NodeRef, PublishingPackageEntry> entryMap = serializer.deserialize(is);
assertEquals(1, entryMap.size());
assertTrue(entryMap.containsKey(normalNode1.getNodeRef()));
PublishingPackageEntryImpl entry = (PublishingPackageEntryImpl) entryMap.get(normalNode1.getNodeRef());
assertEquals(TransferManifestNormalNode.class, entry.getPayload().getClass());
TransferManifestNormalNode deserializedNode = (TransferManifestNormalNode) entry.getPayload();
assertEquals(normalNode1.getType(), deserializedNode.getType());
List<NodeSnapshot> snapshots = serializer.deserialize(is);
assertEquals(1, snapshots.size());
NodeSnapshot snapshot = snapshots.get(0);
assertEquals(normalNode1.getNodeRef(), snapshot.getNodeRef());
assertEquals(normalNode1.getType(), snapshot.getType());
assertEquals(normalNode1.getAspects(), snapshot.getAspects());
assertEquals(normalNode1.getProperties(), snapshot.getProperties());
}
}

View File

@@ -20,20 +20,16 @@
package org.alfresco.repo.publishing;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.transfer.manifest.TransferManifestNodeFactory;
import org.alfresco.service.cmr.publishing.MutablePublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingDetails;
import org.alfresco.service.cmr.publishing.PublishingEvent;
import org.alfresco.service.cmr.publishing.PublishingEventFilter;
import org.alfresco.service.cmr.publishing.PublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingQueue;
import org.alfresco.service.cmr.publishing.StatusUpdate;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.version.VersionService;
/**
* @author Brian
@@ -44,25 +40,20 @@ public class PublishingQueueImpl implements PublishingQueue
{
private final static String MSG_FAILED_TO_CREATE_PUBLISHING_EVENT = "publishing-create-event-failed";
private final NodeRef nodeRef;
private final TransferManifestNodeFactory transferManifestNodeFactory;
private final VersionService versionService;
private final PublishingEventHelper publishingEventHelper;
public PublishingQueueImpl(NodeRef nodeRef, PublishingEventHelper publishingEventHelper,
VersionService versionService, TransferManifestNodeFactory transferManifestNodeFactory)
public PublishingQueueImpl(NodeRef nodeRef, PublishingEventHelper publishingEventHelper)
{
this.nodeRef = nodeRef;
this.publishingEventHelper = publishingEventHelper;
this.versionService = versionService;
this.transferManifestNodeFactory = transferManifestNodeFactory;
}
/**
* {@inheritDoc}
*/
public MutablePublishingPackage createPublishingPackageBuilder()
public PublishingDetails createPublishingDetails()
{
return new MutablePublishingPackageImpl(transferManifestNodeFactory, versionService);
return publishingEventHelper.createPublishingPackageBuilder();
}
/**
@@ -100,12 +91,12 @@ public class PublishingQueueImpl implements PublishingQueue
/**
* {@inheritDoc}
*/
public String scheduleNewEvent(PublishingPackage publishingPackage, String channelId, Calendar schedule, String comment, StatusUpdate statusUpdate)
public String scheduleNewEvent(PublishingDetails publishingDetails)
{
try
{
NodeRef eventNode = publishingEventHelper.createNode(nodeRef, publishingPackage, channelId, schedule, comment, statusUpdate);
publishingEventHelper.startPublishingWorkflow(eventNode, schedule);
NodeRef eventNode = publishingEventHelper.createNode(nodeRef, publishingDetails);
publishingEventHelper.startPublishingWorkflow(eventNode, publishingDetails.getSchedule());
return eventNode.toString();
}
catch (Exception ex)

View File

@@ -34,7 +34,7 @@ import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.publishing.MutablePublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingDetails;
import org.alfresco.service.cmr.publishing.PublishingEvent;
import org.alfresco.service.cmr.publishing.PublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
@@ -69,19 +69,22 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
{
NodeRef firstNode = createContent("First");
NodeRef secondNode = createContent("second");
assertNull(nodeService.getProperty(firstNode, PROP_VERSION_LABEL));
assertNull(nodeService.getProperty(firstNode, PROP_VERSION_LABEL));
MutablePublishingPackage publishingPackage = publishingService.getPublishingQueue().createPublishingPackageBuilder();
publishingPackage.addNodesToPublish(firstNode, secondNode);
NodeRef thirdNode = createContent("third");
publishingPackage.addNodesToUnpublish(thirdNode);
assertNull(nodeService.getProperty(firstNode, PROP_VERSION_LABEL));
assertNull(nodeService.getProperty(firstNode, PROP_VERSION_LABEL));
Calendar schedule = Calendar.getInstance();
schedule.add(Calendar.HOUR, 2);
String eventId = publishingService.getPublishingQueue().scheduleNewEvent(publishingPackage, channelId, schedule, comment, null);
PublishingDetails details = publishingService.getPublishingQueue().createPublishingDetails()
.addNodesToPublish(firstNode, secondNode)
.addNodesToUnpublish(thirdNode)
.setPublishChannel(channelId)
.setSchedule(schedule)
.setComment(comment);
String eventId = testHelper.scheduleEvent(details);
//Check schedule triggered versioning.
Serializable version = nodeService.getProperty(firstNode, PROP_VERSION_LABEL);
@@ -120,7 +123,7 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
assertTrue(toUnpublish.contains(thirdNode));
// Check the correct version is recorded in the entry.
PublishingPackageEntry entry = publishingPackage.getEntryMap().get(firstNode);
PublishingPackageEntry entry = pckg.getEntryMap().get(firstNode);
assertEquals(version, entry.getSnapshot().getVersion());
NodeRef eventNode = new NodeRef(eventId);
@@ -141,16 +144,17 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
NodeRef firstNode = createContent("First");
NodeRef secondNode = createContent("Second");
List<String> channelNames = Arrays.asList("test://channel/Channel1", "test://channel/Channel2", "test://channel/Channel3" );
List<String> statusChannels = Arrays.asList("test://channel/Channel1", "test://channel/Channel2", "test://channel/Channel3" );
String message = "The message";
StatusUpdate update = publishingService.getPublishingQueue().createStatusUpdate(message, secondNode, channelNames);
PublishingDetails details = publishingService.getPublishingQueue().createPublishingDetails()
.setPublishChannel(channelId)
.addNodesToPublish(firstNode, secondNode)
.setStatusMessage(message)
.setStatusNodeToLinkTo(secondNode)
.addStatusUpdateChannels(statusChannels);
// Publish an event with the StatusUpdate
MutablePublishingPackage publishingPackage = publishingService.getPublishingQueue().createPublishingPackageBuilder();
publishingPackage.addNodesToPublish(firstNode, secondNode);
Calendar schedule = Calendar.getInstance();
schedule.add(Calendar.HOUR, 2);
String eventId = testHelper.scheduleEvent1Year(publishingPackage, channelId, comment, update);
String eventId = testHelper.scheduleEvent1Year(details);
PublishingEvent event = publishingService.getPublishingEvent(eventId);
StatusUpdate actualUpdate = event.getStatusUpdate();
@@ -158,7 +162,7 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
assertEquals(secondNode, actualUpdate.getNodeToLinkTo());
Set<String> names = actualUpdate.getChannelIds();
assertEquals(3, names.size());
assertTrue(names.containsAll(channelNames));
assertTrue(names.containsAll(statusChannels));
}
@Test
@@ -180,11 +184,12 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
personManager.setUser(user1);
// Publish an event
MutablePublishingPackage publishingPackage = publishingService.getPublishingQueue().createPublishingPackageBuilder();
publishingPackage.addNodesToPublish(firstNode, secondNode);
PublishingDetails details = publishingService.getPublishingQueue().createPublishingDetails();
details.addNodesToPublish(firstNode, secondNode);
details.setPublishChannel(publishChannel.getId());
try
{
testHelper.scheduleEvent1Year(publishingPackage, publishChannel.getId(), null, null);
testHelper.scheduleEvent1Year(details);
fail("shceduleNewEvent should have thrown an AccessDeniedException!");
}
catch(AlfrescoRuntimeException e)
@@ -196,14 +201,16 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
testHelper.allowChannelAccess(user1, publishChannel.getId());
// Check publish works now.
String eventId = testHelper.scheduleEvent1Year(publishingPackage, publishChannel.getId(), null, null);
String eventId = testHelper.scheduleEvent1Year(details);
assertNotNull(eventId);
String message = "The message";
StatusUpdate update = publishingService.getPublishingQueue().createStatusUpdate(message, secondNode, statusChannel.getId());
details.setStatusMessage(message)
.setStatusNodeToLinkTo(secondNode)
.addStatusUpdateChannels(statusChannel.getId());
try
{
eventId = testHelper.scheduleEvent1Year(publishingPackage, publishChannel.getId(), null, update);
eventId = testHelper.scheduleEvent1Year(details);
fail("shceduleNewEvent with status update should have thrown an AccessDeniedException!");
}
catch(AlfrescoRuntimeException e)
@@ -215,7 +222,7 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
testHelper.allowChannelAccess(user1, statusChannel.getId());
// Check publish works now.
eventId = testHelper.scheduleEvent1Year(publishingPackage, publishChannel.getId(), null, update);
eventId = testHelper.scheduleEvent1Year(details);
assertNotNull(eventId);
}

View File

@@ -32,14 +32,12 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.transfer.manifest.TransferManifestNodeFactory;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
@@ -60,8 +58,6 @@ public class PublishingRootObject
private PublishingEventHelper publishingEventHelper;
private NamespaceService namespaceService;
private SearchService searchService;
private VersionService versionService;
private TransferManifestNodeFactory transferManifestNodeFactory;
private RetryingTransactionHelper retryingTransactionHelper;
private PermissionService permissionService;
@@ -122,7 +118,7 @@ public class PublishingRootObject
private PublishingQueueImpl createPublishingQueue(NodeRef environmentNode)
{
NodeRef queueNode = getPublishingQueueNode(environmentNode);
return new PublishingQueueImpl(queueNode, publishingEventHelper, versionService, transferManifestNodeFactory);
return new PublishingQueueImpl(queueNode, publishingEventHelper);
}
private NodeRef getPublishingQueueNode(NodeRef environmentNode)
@@ -220,22 +216,6 @@ public class PublishingRootObject
this.searchService = searchService;
}
/**
* @param transferManifestNodeFactory the transferManifestNodeFactory to set
*/
public void setTransferManifestNodeFactory(TransferManifestNodeFactory transferManifestNodeFactory)
{
this.transferManifestNodeFactory = transferManifestNodeFactory;
}
/**
* @param versionService the versionService to set
*/
public void setVersionService(VersionService versionService)
{
this.versionService = versionService;
}
/**
* @param permissionService the permissionService to set
*/

View File

@@ -20,8 +20,8 @@
package org.alfresco.repo.publishing;
import static org.alfresco.model.ContentModel.TYPE_CONTENT;
import static org.alfresco.repo.publishing.PublishingModel.TYPE_DELIVERY_CHANNEL;
import static org.alfresco.repo.publishing.PublishingModel.PROP_AUTHORISATION_COMPLETE;
import static org.alfresco.repo.publishing.PublishingModel.TYPE_DELIVERY_CHANNEL;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
@@ -39,10 +39,9 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.publishing.PublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingDetails;
import org.alfresco.service.cmr.publishing.PublishingQueue;
import org.alfresco.service.cmr.publishing.PublishingService;
import org.alfresco.service.cmr.publishing.StatusUpdate;
import org.alfresco.service.cmr.publishing.channels.Channel;
import org.alfresco.service.cmr.publishing.channels.ChannelService;
import org.alfresco.service.cmr.publishing.channels.ChannelType;
@@ -53,7 +52,6 @@ import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.alfresco.util.collections.CollectionUtils;
/**
* @author Nick Smith
@@ -213,17 +211,18 @@ public class PublishingTestHelper
}, AuthenticationUtil.getSystemUserName());
}
public String scheduleEvent1Year(PublishingPackage pckg, String channelId, String comment, StatusUpdate statusUpdate)
public String scheduleEvent1Year(PublishingDetails details)
{
Calendar schedule = Calendar.getInstance();
schedule.add(Calendar.YEAR, 1);
return scheduleEvent(pckg, channelId, schedule, comment, statusUpdate);
details.setSchedule(schedule);
return scheduleEvent(details);
}
public String scheduleEvent(PublishingPackage pckg, String channelId, Calendar schedule, String comment, StatusUpdate statusUpdate)
public String scheduleEvent(PublishingDetails details)
{
PublishingQueue queue = publishingService.getPublishingQueue();
String eventId = queue.scheduleNewEvent(pckg, channelId, schedule, comment, statusUpdate);
String eventId = queue.scheduleNewEvent(details);
events.add(eventId);
return eventId;
}

View File

@@ -22,62 +22,57 @@ package org.alfresco.repo.publishing;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.repo.transfer.manifest.TransferManifestProcessor;
import org.alfresco.repo.transfer.manifest.XMLTransferManifestReader;
import org.alfresco.repo.transfer.manifest.XMLTransferManifestWriter;
import org.alfresco.service.cmr.publishing.PublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.cmr.publishing.NodeSnapshot;
import org.xml.sax.SAXException;
/**
* @author Brian
* @author Nick Smith
*/
public class StandardPublishingPackageSerializer implements PublishingPackageSerializer
public class StandardPublishingPackageSerializer implements NodeSnapshotSerializer
{
/**
* {@inheritDoc}
* @return
*/
public Map<NodeRef, PublishingPackageEntry> deserialize(InputStream input) throws Exception
@Override
public List<NodeSnapshot> deserialize(InputStream input) throws Exception
{
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser parser = saxParserFactory.newSAXParser();
PublishingPackageDeserializer processor = new PublishingPackageDeserializer();
NodeSnapshotDeserializer processor = new NodeSnapshotDeserializer();
XMLTransferManifestReader xmlReader = new XMLTransferManifestReader(processor);
parser.parse(input, xmlReader);
return processor.getEntries();
return processor.getSnapshots();
}
/**
* {@inheritDoc}
*/
public void serialize(PublishingPackage publishingPackage, OutputStream output) throws Exception
public void serialize(Collection<NodeSnapshot> snapshots, OutputStream output) throws Exception
{
try
{
Set<NodeRef> nodesToPublish = publishingPackage.getNodesToPublish();
TransferManifestHeader header = new TransferManifestHeader();
header.setCreatedDate(new Date());
header.setNodeCount(nodesToPublish.size());
header.setNodeCount(snapshots.size());
header.setReadOnly(false);
header.setSync(false);
@@ -88,14 +83,12 @@ public class StandardPublishingPackageSerializer implements PublishingPackageSer
transferManifestWriter.writeTransferManifestHeader(header);
// Iterate over NodesToPublish and Serialize.
Map<NodeRef, PublishingPackageEntry> entryMap = publishingPackage.getEntryMap();
for (NodeRef publishNode: nodesToPublish)
for (NodeSnapshot snapshot: snapshots)
{
PublishingPackageEntry entry = entryMap.get(publishNode);
if (entry instanceof PublishingPackageEntryImpl)
if (snapshot instanceof NodeSnapshotTransferImpl)
{
PublishingPackageEntryImpl entryImpl = (PublishingPackageEntryImpl)entry;
transferManifestWriter.writeTransferManifestNode(entryImpl.getPayload());
NodeSnapshotTransferImpl snapshotImpl = (NodeSnapshotTransferImpl)snapshot;
transferManifestWriter.writeTransferManifestNode(snapshotImpl.getTransferNode());
}
}
transferManifestWriter.endTransferManifest();
@@ -117,16 +110,17 @@ public class StandardPublishingPackageSerializer implements PublishingPackageSer
* @author Nick Smith
*
*/
public static class PublishingPackageDeserializer implements TransferManifestProcessor
public static class NodeSnapshotDeserializer implements TransferManifestProcessor
{
Map<NodeRef,PublishingPackageEntry> entries = new HashMap<NodeRef,PublishingPackageEntry>();
private List<NodeSnapshot> snapshots = new ArrayList<NodeSnapshot>();
/**
* @return the entries
* @return the snapshots
*/
public Map<NodeRef,PublishingPackageEntry> getEntries()
public List<NodeSnapshot> getSnapshots()
{
return entries;
return snapshots;
}
/**
@@ -142,9 +136,8 @@ public class StandardPublishingPackageSerializer implements PublishingPackageSer
*/
public void processTransferManifestNode(TransferManifestNormalNode node)
{
Map<QName, Serializable> props = node.getProperties();
String version = (String) props.get(ContentModel.PROP_VERSION_LABEL);
entries.put(node.getNodeRef(), new PublishingPackageEntryImpl(true, node.getNodeRef(), node, version));
NodeSnapshotTransferImpl snapshot = new NodeSnapshotTransferImpl(node);
snapshots.add(snapshot);
}
/**
@@ -152,7 +145,7 @@ public class StandardPublishingPackageSerializer implements PublishingPackageSer
*/
public void processTransferManifestNode(TransferManifestDeletedNode node)
{
entries.put(node.getNodeRef(), new PublishingPackageEntryImpl(false, node.getNodeRef(), null, null));
//NOOP
}
/**

View File

@@ -20,18 +20,16 @@
package org.alfresco.service.cmr.publishing;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName;
/**
* @author Brian
* @author Nick Smith
* @since 4.0
*
*/
public interface NodeSnapshot
@@ -42,37 +40,12 @@ public interface NodeSnapshot
*/
NodeRef getNodeRef();
/**
* Retrieve the primary parent association of the node at the moment this snapshot was taken
* @return The ChildAssociationRef object that describes the primary parent association of the node
*/
ChildAssociationRef getPrimaryParentAssoc();
/**
* Retrieve the primary path to the node at the moment this snapshot was taken. Note that the elements in this path describe
* the associations between the nodes in the hierarchy - not the "display path"
* @return A Path object that describes the primary path to the node
*/
Path getPrimaryPath();
/**
* The property values assigned to the node at the moment the snapshot was taken.
* @return A map that associates property names to property values for the node.
*/
Map<QName, Serializable> getProperties();
/**
* Retrieve all the parent associations of the node at the moment the snapshot was taken
* @return A list of ChildAssociationRef objects, each describing one parent association of the node.
*/
List<ChildAssociationRef> getAllParentAssocs();
/**
* Retrieve all the peer associations for which this node was the source at the moment the snapshot was taken
* @return A list of AssociationRef objects, each describing a peer association for which this node is the source
*/
List<AssociationRef> getOutboundPeerAssociations();
/**
* Retrieve the type of the node at the moment the snapshot was taken.
* @return The QName that identifies the type of the node

View File

@@ -0,0 +1,95 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.service.cmr.publishing;
import java.util.Calendar;
import java.util.Collection;
import java.util.Set;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* A simple DTO used to gather parameters for scheduling a Publishing Event.
*
* @author Brian
* @author Nick Smith
*
* @since 4.0
*/
public interface PublishingDetails
{
PublishingDetails addNodesToUnpublish(NodeRef... nodesToRemove);
PublishingDetails addNodesToUnpublish(Collection<NodeRef> nodesToRemove);
PublishingDetails addNodesToPublish(NodeRef... nodesToPublish);
PublishingDetails addNodesToPublish(Collection<NodeRef> nodesToPublish);
PublishingDetails setPublishChannel(String channelId);
PublishingDetails setComment(String comment);
PublishingDetails setSchedule(Calendar schedule);
PublishingDetails setStatusMessage(String message);
PublishingDetails setStatusNodeToLinkTo(NodeRef nodeToLinkTo);
PublishingDetails addStatusUpdateChannels(Collection<String> channelIds);
PublishingDetails addStatusUpdateChannels(String... channelIds);
/**
* @return the comment
*/
String getComment();
/**
* @return the message
*/
String getStatusMessage();
/**
* @return the nodeToLinkTo
*/
NodeRef getNodeToLinkTo();
/**
* @return the publishChannelId
*/
String getPublishChannelId();
/**
* @return the schedule
*/
Calendar getSchedule();
Set<String> getStatusUpdateChannels();
/**
* @return a {@link Set} of all the {@link NodeRef}s to be published.
*/
Set<NodeRef> getNodesToPublish();
/**
* @return a {@link Set} of all the {@link NodeRef}s to be unpublished.
*/
Set<NodeRef> getNodesToUnpublish();
}

View File

@@ -19,31 +19,20 @@
package org.alfresco.service.cmr.publishing;
import java.util.Calendar;
import java.util.Collection;
import org.alfresco.service.cmr.repository.NodeRef;
public interface PublishingQueue
{
/**
* A factory method to create an empty publishing package that can be populated before being passed into
* a call to the {@link PublishingQueue#scheduleNewEvent(PublishingPackage, String, Calendar, String, StatusUpdate)} operation.
* a call to the {@link PublishingQueue#scheduleNewEvent(PublishingDetails)} operation.
* @return A publishing package that can be populated before being placed on the publishing queue.
*/
MutablePublishingPackage createPublishingPackageBuilder();
StatusUpdate createStatusUpdate(String message, NodeRef nodeToLinkTo, String... channelIds);
StatusUpdate createStatusUpdate(String message, NodeRef nodeToLinkTo, Collection<String> channelIds);
PublishingDetails createPublishingDetails();
/**
* Adds the supplied publishing package onto the queue.
* @param publishingPackage The publishing package that is to be enqueued
* @param channelId The name of the channel that the package is to be published to
* @param schedule The time at which the new publishing event should be scheduled (optional - <code>null</code> indicates "as soon as possible")
* @param comment A comment to be stored with this new event (optional - may be <code>null</code>)
* @param statusUpdate defines the status update (if any). If <code>null</code> then no status update is sent.
* @param publishingDetails The publishing package that is to be enqueued
* @return The identifier of the newly scheduled event
*/
String scheduleNewEvent(PublishingPackage publishingPackage, String channelId, Calendar schedule, String comment, StatusUpdate statusUpdate);
String scheduleNewEvent(PublishingDetails publishingDetails);
}