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="nodeService" ref="NodeService" />
<property name="namespaceService" ref="NamespaceService" /> <property name="namespaceService" ref="NamespaceService" />
<property name="searchService" ref="SearchService" /> <property name="searchService" ref="SearchService" />
<property name="versionService" ref="VersionService" />
<property name="publishingEventHelper" ref="publishingEventHelper" /> <property name="publishingEventHelper" ref="publishingEventHelper" />
<property name="retryingTransactionHelper" ref="retryingTransactionHelper" /> <property name="retryingTransactionHelper" ref="retryingTransactionHelper" />
<property name="transferManifestNodeFactory" ref="transferManifestNodeFactory" />
<property name="permissionService" ref="PermissionService" /> <property name="permissionService" ref="PermissionService" />
<property name="publishingStore" value="${spaces.store}" /> <property name="publishingStore" value="${spaces.store}" />
<property name="publishingRootPath" value="${publishing.root}" /> <property name="publishingRootPath" value="${publishing.root}" />
@@ -77,6 +75,8 @@
<property name="serializer" ref="publishingPackageSerializer" /> <property name="serializer" ref="publishingPackageSerializer" />
<property name="workflowService" ref="WorkflowService" /> <property name="workflowService" ref="WorkflowService" />
<property name="permissionService" ref="PermissionService" /> <property name="permissionService" ref="PermissionService" />
<property name="transferManifestNodeFactory" ref="transferManifestNodeFactory" />
<property name="versionService" ref="VersionService" />
<property name="workflowEngineId" value="jbpm" /> <property name="workflowEngineId" value="jbpm" />
</bean> </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.ContentData;
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.repository.NodeService;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
@@ -87,8 +86,6 @@ public class ChannelHelper
public NodeRef createChannelNode(NodeRef parent, ChannelType channelType, String channelName, public NodeRef createChannelNode(NodeRef parent, ChannelType channelType, String channelName,
Map<QName, Serializable> props) Map<QName, Serializable> props)
{ {
Set<AccessPermission> permissions = permissionService.getPermissions(parent);
QName channelQName = getChannelQName(channelName); QName channelQName = getChannelQName(channelName);
QName channelNodeType = channelType.getChannelNodeType(); QName channelNodeType = channelType.getChannelNodeType();
ChildAssociationRef channelAssoc = ChildAssociationRef channelAssoc =
@@ -120,6 +117,18 @@ public class ChannelHelper
* @return * @return
*/ */
public NodeRef mapSourceToEnvironment(NodeRef source, final NodeRef channelNode) 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) if(source == null || channelNode == null)
{ {
@@ -145,6 +154,16 @@ public class ChannelHelper
* @return * @return
*/ */
public NodeRef mapEnvironmentToSource(NodeRef publishedNode) 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); List<AssociationRef> assocs = nodeService.getTargetAssocs(publishedNode, ASSOC_SOURCE);
return NodeUtils.getSingleAssocNode(assocs, true); 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); HashMap<QName, Serializable> actualProps = new HashMap<QName, Serializable>(properties);
actualProps.remove(ContentModel.PROP_NODE_UUID); actualProps.remove(ContentModel.PROP_NODE_UUID);
NodeRef editorialNode = channel.getNodeRef(); NodeRef editorialNode = new NodeRef(channel.getId());
for (Map.Entry<QName, Serializable> entry : actualProps.entrySet()) for (Map.Entry<QName, Serializable> entry : actualProps.entrySet())
{ {
nodeService.setProperty(editorialNode, entry.getKey(), entry.getValue()); 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 * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.alfresco.service.cmr.publishing;
import java.util.Collection; package org.alfresco.repo.publishing;
import org.alfresco.service.cmr.repository.NodeRef;
/** /**
* An extendsion of the {@link PublishingPackage} interface which allows values to be modified.
* @author Brian
* @author Nick Smith * @author Nick Smith
*
* @since 4.0 * @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.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.service.cmr.publishing.NodeSnapshot;
import org.alfresco.service.cmr.publishing.PublishingPackage; import org.alfresco.service.cmr.publishing.PublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry; import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
@@ -33,9 +36,9 @@ import org.alfresco.service.cmr.repository.NodeRef;
* *
* @since 4.0 * @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.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode; import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.service.cmr.publishing.NodeSnapshot; import org.alfresco.service.cmr.publishing.NodeSnapshot;
import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.AssociationRef;
@@ -34,6 +35,8 @@ import org.alfresco.service.namespace.QName;
/** /**
* @author Brian * @author Brian
* @author Nick Smith
* @since 4.0
* *
*/ */
public class NodeSnapshotTransferImpl implements NodeSnapshot public class NodeSnapshotTransferImpl implements NodeSnapshot
@@ -44,16 +47,16 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/** /**
* @param transferNode * @param transferNode
*/ */
public NodeSnapshotTransferImpl(TransferManifestNormalNode transferNode, String version) public NodeSnapshotTransferImpl(TransferManifestNormalNode transferNode)
{ {
this.transferNode = transferNode; this.transferNode = transferNode;
this.version = version; Map<QName, Serializable> props = transferNode.getProperties();
this.version = (String) props.get(ContentModel.PROP_VERSION_LABEL);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getAllParentAssocs() * @see org.alfresco.service.cmr.publishing.NodeSnapshot#getAllParentAssocs()
*/ */
@Override
public List<ChildAssociationRef> getAllParentAssocs() public List<ChildAssociationRef> getAllParentAssocs()
{ {
return transferNode.getParentAssocs(); return transferNode.getParentAssocs();
@@ -62,7 +65,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getAspects() * @see org.alfresco.service.cmr.publishing.NodeSnapshot#getAspects()
*/ */
@Override
public Set<QName> getAspects() public Set<QName> getAspects()
{ {
return transferNode.getAspects(); return transferNode.getAspects();
@@ -71,7 +74,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getNodeRef() * @see org.alfresco.service.cmr.publishing.NodeSnapshot#getNodeRef()
*/ */
@Override
public NodeRef getNodeRef() public NodeRef getNodeRef()
{ {
return transferNode.getNodeRef(); return transferNode.getNodeRef();
@@ -80,7 +83,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getOutboundPeerAssociations() * @see org.alfresco.service.cmr.publishing.NodeSnapshot#getOutboundPeerAssociations()
*/ */
@Override
public List<AssociationRef> getOutboundPeerAssociations() public List<AssociationRef> getOutboundPeerAssociations()
{ {
return transferNode.getTargetAssocs(); return transferNode.getTargetAssocs();
@@ -89,7 +92,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getPrimaryParentAssoc() * @see org.alfresco.service.cmr.publishing.NodeSnapshot#getPrimaryParentAssoc()
*/ */
@Override
public ChildAssociationRef getPrimaryParentAssoc() public ChildAssociationRef getPrimaryParentAssoc()
{ {
return transferNode.getPrimaryParentAssoc(); return transferNode.getPrimaryParentAssoc();
@@ -98,7 +101,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getPrimaryPath() * @see org.alfresco.service.cmr.publishing.NodeSnapshot#getPrimaryPath()
*/ */
@Override
public Path getPrimaryPath() public Path getPrimaryPath()
{ {
return transferNode.getParentPath(); return transferNode.getParentPath();
@@ -107,7 +110,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getProperties() * @see org.alfresco.service.cmr.publishing.NodeSnapshot#getProperties()
*/ */
@Override
public Map<QName, Serializable> getProperties() public Map<QName, Serializable> getProperties()
{ {
return transferNode.getProperties(); return transferNode.getProperties();
@@ -116,7 +119,7 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.publishing.NodeSnapshot#getType() * @see org.alfresco.service.cmr.publishing.NodeSnapshot#getType()
*/ */
@Override
public QName getType() public QName getType()
{ {
return transferNode.getType(); return transferNode.getType();
@@ -125,9 +128,17 @@ public class NodeSnapshotTransferImpl implements NodeSnapshot
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getVersion() public String getVersion()
{ {
return version; 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.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap; 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.PublishingService;
import org.alfresco.service.cmr.publishing.Status; 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.Channel;
import org.alfresco.service.cmr.publishing.channels.ChannelType; import org.alfresco.service.cmr.publishing.channels.ChannelType;
import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.AssociationRef;
@@ -362,13 +361,12 @@ public class PublishEventActionTest extends AbstractPublishingIntegrationTest
// Create Status Update // Create Status Update
String message = "Here is the message "; String message = "Here is the message ";
StatusUpdate status = publishingService.getPublishingQueue().createStatusUpdate(message, source, channel.getId());
String url = "http://test/url"; String url = "http://test/url";
when(channelType.getNodeUrl(any(NodeRef.class))).thenReturn(url); when(channelType.getNodeUrl(any(NodeRef.class))).thenReturn(url);
when(channelType.canPublishStatusUpdates()).thenReturn(true); when(channelType.canPublishStatusUpdates()).thenReturn(true);
publishNode(source, status); publishNode(source, message);
String expMessage = message + " " + url; String expMessage = message + " " + url;
verify(channelType, times(1)).updateStatus(any(Channel.class), eq(expMessage), anyMap()); verify(channelType, times(1)).updateStatus(any(Channel.class), eq(expMessage), anyMap());
@@ -379,23 +377,30 @@ public class PublishEventActionTest extends AbstractPublishingIntegrationTest
return publishNode(source, null); 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) if(publish)
{ {
pckg.addNodesToPublish(source); details.addNodesToPublish(source);
} }
else 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); assertNotNull(eventId);
NodeRef eventNode = new NodeRef(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.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.NodeUtils; import org.alfresco.repo.node.NodeUtils;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException; 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.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.PublishingEvent;
import org.alfresco.service.cmr.publishing.PublishingEventFilter; import org.alfresco.service.cmr.publishing.PublishingEventFilter;
import org.alfresco.service.cmr.publishing.PublishingPackage; 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.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowPath; import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowService;
@@ -93,6 +99,7 @@ import org.apache.commons.logging.LogFactory;
/** /**
* @author Brian * @author Brian
* @author Nick Smith * @author Nick Smith
* @since 4.0
* *
*/ */
public class PublishingEventHelper public class PublishingEventHelper
@@ -102,9 +109,11 @@ public class PublishingEventHelper
private NodeService nodeService; private NodeService nodeService;
private ContentService contentService; private ContentService contentService;
private VersionService versionService;
private WorkflowService workflowService; private WorkflowService workflowService;
private PublishingPackageSerializer serializer; private NodeSnapshotSerializer serializer;
private PermissionService permissionService; private PermissionService permissionService;
private TransferManifestNodeFactory transferManifestNodeFactory;
private String workflowEngineId; private String workflowEngineId;
@@ -126,6 +135,22 @@ public class PublishingEventHelper
this.contentService = contentService; 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 * @param workflowService the workflowService to set
*/ */
@@ -145,7 +170,7 @@ public class PublishingEventHelper
/** /**
* @param serializer the serializer to set * @param serializer the serializer to set
*/ */
public void setSerializer(PublishingPackageSerializer serializer) public void setSerializer(NodeSnapshotSerializer serializer)
{ {
this.serializer = serializer; this.serializer = serializer;
} }
@@ -168,15 +193,15 @@ public class PublishingEventHelper
Map<QName, Serializable> props = nodeService.getProperties(eventNode); Map<QName, Serializable> props = nodeService.getProperties(eventNode);
String statusStr = (String) props.get(PROP_PUBLISHING_EVENT_STATUS); String statusStr = (String) props.get(PROP_PUBLISHING_EVENT_STATUS);
Status status = Status.valueOf(statusStr); 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); Date createdTime = (Date) props.get(ContentModel.PROP_CREATED);
String creator = (String) props.get(ContentModel.PROP_CREATOR); String creator = (String) props.get(ContentModel.PROP_CREATOR);
Date modifiedTime = (Date) props.get(ContentModel.PROP_MODIFIED); Date modifiedTime = (Date) props.get(ContentModel.PROP_MODIFIED);
String modifier = (String) props.get(ContentModel.PROP_MODIFIER); String modifier = (String) props.get(ContentModel.PROP_MODIFIER);
String comment = (String) props.get(PROP_PUBLISHING_EVENT_COMMENT); String comment = (String) props.get(PROP_PUBLISHING_EVENT_COMMENT);
Calendar scheduledTime = getScheduledTime(props); Calendar scheduledTime = getScheduledTime(props);
PublishingPackage publishingPackage = getPublishingPackage(eventNode, channel);
String channel = (String) props.get(PROP_PUBLISHING_EVENT_CHANNEL);
StatusUpdate statusUpdate = buildStatusUpdate(props); StatusUpdate statusUpdate = buildStatusUpdate(props);
return new PublishingEventImpl(eventNode.toString(), return new PublishingEventImpl(eventNode.toString(),
status, channel, status, channel,
@@ -210,28 +235,23 @@ public class PublishingEventHelper
}); });
} }
public NodeRef createNode(NodeRef queueNode, PublishingPackage publishingPackage, String channelId, Calendar schedule, String comment, StatusUpdate statusUpdate) public NodeRef createNode(NodeRef queueNode, PublishingDetails details) throws Exception
throws Exception
{ {
checkChannelAccess(channelId); checkChannelAccess(details.getPublishChannelId());
if(statusUpdate != null && isEmpty(statusUpdate.getChannelIds())==false ) Set<String> statusChannelIds = details.getStatusUpdateChannels();
for (String statusChannelId : statusUpdate.getChannelIds()) if(isEmpty(statusChannelIds)==false )
for (String statusChannelId : statusChannelIds)
{ {
checkChannelAccess(statusChannelId); checkChannelAccess(statusChannelId);
} }
if (schedule == null)
{
schedule = Calendar.getInstance();
}
String name = GUID.generate(); String name = GUID.generate();
Map<QName, Serializable> props = Map<QName, Serializable> props = buildPublishingEventProperties(details, name);
buildPublishingEventProperties(publishingPackage, channelId, schedule, comment, statusUpdate, name);
ChildAssociationRef newAssoc = nodeService.createNode(queueNode, ChildAssociationRef newAssoc = nodeService.createNode(queueNode,
ASSOC_PUBLISHING_EVENT, ASSOC_PUBLISHING_EVENT,
QName.createQName(NAMESPACE, name), QName.createQName(NAMESPACE, name),
TYPE_PUBLISHING_EVENT, props); TYPE_PUBLISHING_EVENT, props);
NodeRef eventNode = newAssoc.getChildRef(); NodeRef eventNode = newAssoc.getChildRef();
setPayload(eventNode, publishingPackage); serializePublishNodes(eventNode, details);
return eventNode; return eventNode;
} }
@@ -245,33 +265,40 @@ public class PublishingEventHelper
} }
} }
private Map<QName, Serializable> buildPublishingEventProperties(PublishingPackage publishingPackage, private Map<QName, Serializable> buildPublishingEventProperties(PublishingDetails details, String name)
String channelId, Calendar schedule, String comment, StatusUpdate statusUpdate, String name)
{ {
Calendar schedule = details.getSchedule();
if (schedule == null)
{
schedule = Calendar.getInstance();
}
Map<QName, Serializable> props = new HashMap<QName, Serializable>(); Map<QName, Serializable> props = new HashMap<QName, Serializable>();
props.put(ContentModel.PROP_NAME, name); props.put(ContentModel.PROP_NAME, name);
props.put(PROP_PUBLISHING_EVENT_STATUS, Status.IN_PROGRESS.name()); props.put(PROP_PUBLISHING_EVENT_STATUS, Status.IN_PROGRESS.name());
props.put(PROP_PUBLISHING_EVENT_TIME, schedule.getTime()); 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_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); props.put(PublishingModel.PROP_PUBLISHING_EVENT_STATUS, PublishingModel.PROPVAL_PUBLISHING_EVENT_STATUS_SCHEDULED);
String comment = details.getComment();
if (comment != null) if (comment != null)
{ {
props.put(PROP_PUBLISHING_EVENT_COMMENT, comment); 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); 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); 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()); props.put(PROP_STATUS_UPDATE_MESSAGE, message);
NodeRef statusNode = statusUpdate.getNodeToLinkTo(); NodeRef statusNode = details.getNodeToLinkTo();
if(statusNode != null) if(statusNode != null)
{ {
props.put(PROP_STATUS_UPDATE_NODE_REF, statusNode.toString()); 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; return props;
} }
@@ -476,15 +503,16 @@ public class PublishingEventHelper
return scheduledTime; return scheduledTime;
} }
private void setPayload(NodeRef eventNode, PublishingPackage publishingPackage) throws Exception private void serializePublishNodes(NodeRef eventNode, PublishingDetails details) throws Exception
{ {
try try
{ {
List<NodeSnapshot> snapshots = createPublishSnapshots(details.getNodesToPublish());
ContentWriter contentWriter = contentService.getWriter(eventNode, ContentWriter contentWriter = contentService.getWriter(eventNode,
PROP_PUBLISHING_EVENT_PAYLOAD, true); PROP_PUBLISHING_EVENT_PAYLOAD, true);
contentWriter.setEncoding("UTF-8"); contentWriter.setEncoding("UTF-8");
OutputStream os = contentWriter.getContentOutputStream(); OutputStream os = contentWriter.getContentOutputStream();
serializer.serialize(publishingPackage, os); serializer.serialize(snapshots, os);
os.flush(); os.flush();
os.close(); 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); ContentReader contentReader = contentService.getReader(eventNode, PROP_PUBLISHING_EVENT_PAYLOAD);
InputStream input = contentReader.getContentInputStream(); InputStream input = contentReader.getContentInputStream();
try try
{ {
Map<NodeRef, PublishingPackageEntry> publishEntires = serializer.deserialize(input); List<NodeSnapshot> snapshots = serializer.deserialize(input);
Map<NodeRef, PublishingPackageEntry> allEntries = getUnpublishPackageEntries(eventNode); Map<NodeRef, PublishingPackageEntry> entries = new HashMap<NodeRef, PublishingPackageEntry>(snapshots.size());
allEntries.putAll(publishEntires); for (NodeSnapshot snapshot : snapshots)
return new PublishingPackageImpl(allEntries); {
NodeRef node = snapshot.getNodeRef();
PublishingPackageEntryImpl entry = new PublishingPackageEntryImpl(true, node, snapshot);
entries.put(node, entry);
}
return entries;
} }
catch (Exception ex) 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") @SuppressWarnings("unchecked")
List<String> entries= (List<String>) nodeService.getProperty(eventNode, PROP_PUBLISHING_EVENT_NODES_TO_UNPUBLISH); 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>(); return new HashMap<NodeRef, PublishingPackageEntry>();
} }
final NodeRef channelNode = new NodeRef(channelId);
List<NodeRef> nodes = NodeUtils.toNodeRefs(entries); List<NodeRef> nodes = NodeUtils.toNodeRefs(entries);
return transformToMap(nodes, new Function<NodeRef, PublishingPackageEntry>() return transformToMap(nodes, new Function<NodeRef, PublishingPackageEntry>()
{ {
@@ -528,13 +612,37 @@ public class PublishingEventHelper
{ {
if(NodeUtils.exists(node, nodeService)) if(NodeUtils.exists(node, nodeService))
{ {
return new PublishingPackageEntryImpl(false, node, null, null); return makeUnpublishEntry(node, channelNode);
} }
return null; 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) public void cancelEvent(String id)
{ {
NodeRef eventNode = getPublishingEventNode(id); NodeRef eventNode = getPublishingEventNode(id);
@@ -577,6 +685,11 @@ public class PublishingEventHelper
return nodeService.createAssociation(publishedNode, eventNode, ASSOC_LAST_PUBLISHING_EVENT); return nodeService.createAssociation(publishedNode, eventNode, ASSOC_LAST_PUBLISHING_EVENT);
} }
public PublishingDetails createPublishingPackageBuilder()
{
return new PublishingDetailsImpl();
}
// public NodePublishStatus checkNodeStatus(NodeRef node, String channelId, NodeRef queue) // public NodePublishStatus checkNodeStatus(NodeRef node, String channelId, NodeRef queue)
// { // {
// PublishingEvent queuedEvent = getQueuedPublishingEvent(node, channelId, queue); // PublishingEvent queuedEvent = getQueuedPublishingEvent(node, channelId, queue);

View File

@@ -42,7 +42,6 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -50,9 +49,8 @@ import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.alfresco.model.ContentModel; 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.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.publishing.Status;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
@@ -128,7 +126,7 @@ public class PublishingEventHelperTest
when(reader.getContentInputStream()).thenReturn(inputStream); when(reader.getContentInputStream()).thenReturn(inputStream);
when(contentService.getReader(any(NodeRef.class), any(QName.class))) when(contentService.getReader(any(NodeRef.class), any(QName.class)))
.thenReturn(reader); .thenReturn(reader);
PublishingPackageSerializer serializer = mock(PublishingPackageSerializer.class); NodeSnapshotSerializer serializer = mock(NodeSnapshotSerializer.class);
helper.setSerializer(serializer); helper.setSerializer(serializer);
PublishingEvent result = helper.getPublishingEvent((NodeRef)null); PublishingEvent result = helper.getPublishingEvent((NodeRef)null);
@@ -181,7 +179,7 @@ public class PublishingEventHelperTest
.thenReturn(writer); .thenReturn(writer);
OutputStream outputStream = mock(OutputStream.class); OutputStream outputStream = mock(OutputStream.class);
when(writer.getContentOutputStream()).thenReturn(outputStream); when(writer.getContentOutputStream()).thenReturn(outputStream);
PublishingPackageSerializer serializer = mock(PublishingPackageSerializer.class); NodeSnapshotSerializer serializer = mock(NodeSnapshotSerializer.class);
helper.setSerializer(serializer); helper.setSerializer(serializer);
NodeRef queue = new NodeRef("foo://bar/queue"); 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())) when(nodeService.createNode(any(NodeRef.class), any(QName.class), any(QName.class), any(QName.class), anyMap()))
.thenReturn(childAssoc); .thenReturn(childAssoc);
Map<NodeRef, PublishingPackageEntry> entires = Collections.emptyMap(); String channelId = "test://channel/id";
PublishingPackage pckg = new PublishingPackageImpl(entires);
String channelName = "test://channel/id";
Calendar schedule = Calendar.getInstance(); Calendar schedule = Calendar.getInstance();
String comment = "The comment"; 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); assertEquals(event, result);
ArgumentCaptor<Map> argument = ArgumentCaptor.forClass(Map.class); ArgumentCaptor<Map> argument = ArgumentCaptor.forClass(Map.class);
@@ -208,7 +209,7 @@ public class PublishingEventHelperTest
Map<QName, Serializable> props = argument.getValue(); Map<QName, Serializable> props = argument.getValue();
assertNotNull(props.get(ContentModel.PROP_NAME)); 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(comment, props.get(PROP_PUBLISHING_EVENT_COMMENT));
assertEquals(schedule.getTime(), props.get(PROP_PUBLISHING_EVENT_TIME)); assertEquals(schedule.getTime(), props.get(PROP_PUBLISHING_EVENT_TIME));
assertEquals(schedule.getTimeZone().getID(), props.get(PROP_PUBLISHING_EVENT_TIME_ZONE)); 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) 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)) if(NodeUtils.exists(publishedNode, nodeService))
{ {
channel.unPublish(publishedNode); 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.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileFolderService; 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.PublishingEvent;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry; import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.publishing.PublishingQueue; import org.alfresco.service.cmr.publishing.PublishingQueue;
@@ -85,16 +85,20 @@ public class PublishingIntegratedTest extends BaseSpringTest
} }
PublishingQueue liveQueue = publishingService.getPublishingQueue(); PublishingQueue liveQueue = publishingService.getPublishingQueue();
MutablePublishingPackage publishingPackage = liveQueue.createPublishingPackageBuilder();
publishingPackage.addNodesToPublish(nodes);
Calendar scheduleTime = Calendar.getInstance(); Calendar schedule = Calendar.getInstance();
scheduleTime.add(Calendar.HOUR, 1); schedule.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); PublishingEvent event = publishingService.getPublishingEvent(eventId);
Assert.assertEquals(scheduleTime, event.getScheduledTime()); Assert.assertEquals(schedule, event.getScheduledTime());
Assert.assertEquals(eventId, event.getId()); Assert.assertEquals(eventId, event.getId());
Collection<PublishingPackageEntry> entries = event.getPackage().getEntries(); Collection<PublishingPackageEntry> entries = event.getPackage().getEntries();
Assert.assertEquals(4, entries.size()); 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()); NamespaceService.CONTENT_MODEL_1_0_URI, Integer.toString(i)), ContentModel.TYPE_CONTENT).getChildRef());
} }
PublishingQueue liveQueue = publishingService.getPublishingQueue(); PublishingQueue liveQueue = publishingService.getPublishingQueue();
MutablePublishingPackage publishingPackage = liveQueue.createPublishingPackageBuilder(); Calendar schedule = Calendar.getInstance();
publishingPackage.addNodesToPublish(nodes); schedule.add(Calendar.HOUR, 1);
Calendar scheduleTime = Calendar.getInstance(); PublishingDetails details = liveQueue.createPublishingDetails()
scheduleTime.add(Calendar.HOUR, 1); .addNodesToPublish(nodes)
String eventId = liveQueue.scheduleNewEvent(publishingPackage, channel.getId(), scheduleTime, null, null); .setPublishChannel(channel.getId())
.setSchedule(schedule);
String eventId = liveQueue.scheduleNewEvent(details);
PublishingEvent event = publishingService.getPublishingEvent(eventId); PublishingEvent event = publishingService.getPublishingEvent(eventId);
Assert.assertNotNull(event); Assert.assertNotNull(event);
publishingService.cancelPublishingEvent(eventId); publishingService.cancelPublishingEvent(eventId);

View File

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

View File

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

View File

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

View File

@@ -34,7 +34,7 @@ import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.security.authentication.AuthenticationUtil; 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.PublishingEvent;
import org.alfresco.service.cmr.publishing.PublishingPackage; import org.alfresco.service.cmr.publishing.PublishingPackage;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry; import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
@@ -69,19 +69,22 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
{ {
NodeRef firstNode = createContent("First"); NodeRef firstNode = createContent("First");
NodeRef secondNode = createContent("second"); 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"); 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(); Calendar schedule = Calendar.getInstance();
schedule.add(Calendar.HOUR, 2); 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. //Check schedule triggered versioning.
Serializable version = nodeService.getProperty(firstNode, PROP_VERSION_LABEL); Serializable version = nodeService.getProperty(firstNode, PROP_VERSION_LABEL);
@@ -120,7 +123,7 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
assertTrue(toUnpublish.contains(thirdNode)); assertTrue(toUnpublish.contains(thirdNode));
// Check the correct version is recorded in the entry. // 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()); assertEquals(version, entry.getSnapshot().getVersion());
NodeRef eventNode = new NodeRef(eventId); NodeRef eventNode = new NodeRef(eventId);
@@ -141,16 +144,17 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
NodeRef firstNode = createContent("First"); NodeRef firstNode = createContent("First");
NodeRef secondNode = createContent("Second"); 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"; 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 // Publish an event with the StatusUpdate
MutablePublishingPackage publishingPackage = publishingService.getPublishingQueue().createPublishingPackageBuilder(); String eventId = testHelper.scheduleEvent1Year(details);
publishingPackage.addNodesToPublish(firstNode, secondNode);
Calendar schedule = Calendar.getInstance();
schedule.add(Calendar.HOUR, 2);
String eventId = testHelper.scheduleEvent1Year(publishingPackage, channelId, comment, update);
PublishingEvent event = publishingService.getPublishingEvent(eventId); PublishingEvent event = publishingService.getPublishingEvent(eventId);
StatusUpdate actualUpdate = event.getStatusUpdate(); StatusUpdate actualUpdate = event.getStatusUpdate();
@@ -158,7 +162,7 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
assertEquals(secondNode, actualUpdate.getNodeToLinkTo()); assertEquals(secondNode, actualUpdate.getNodeToLinkTo());
Set<String> names = actualUpdate.getChannelIds(); Set<String> names = actualUpdate.getChannelIds();
assertEquals(3, names.size()); assertEquals(3, names.size());
assertTrue(names.containsAll(channelNames)); assertTrue(names.containsAll(statusChannels));
} }
@Test @Test
@@ -180,11 +184,12 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
personManager.setUser(user1); personManager.setUser(user1);
// Publish an event // Publish an event
MutablePublishingPackage publishingPackage = publishingService.getPublishingQueue().createPublishingPackageBuilder(); PublishingDetails details = publishingService.getPublishingQueue().createPublishingDetails();
publishingPackage.addNodesToPublish(firstNode, secondNode); details.addNodesToPublish(firstNode, secondNode);
details.setPublishChannel(publishChannel.getId());
try try
{ {
testHelper.scheduleEvent1Year(publishingPackage, publishChannel.getId(), null, null); testHelper.scheduleEvent1Year(details);
fail("shceduleNewEvent should have thrown an AccessDeniedException!"); fail("shceduleNewEvent should have thrown an AccessDeniedException!");
} }
catch(AlfrescoRuntimeException e) catch(AlfrescoRuntimeException e)
@@ -196,14 +201,16 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
testHelper.allowChannelAccess(user1, publishChannel.getId()); testHelper.allowChannelAccess(user1, publishChannel.getId());
// Check publish works now. // Check publish works now.
String eventId = testHelper.scheduleEvent1Year(publishingPackage, publishChannel.getId(), null, null); String eventId = testHelper.scheduleEvent1Year(details);
assertNotNull(eventId); assertNotNull(eventId);
String message = "The message"; String message = "The message";
StatusUpdate update = publishingService.getPublishingQueue().createStatusUpdate(message, secondNode, statusChannel.getId()); details.setStatusMessage(message)
.setStatusNodeToLinkTo(secondNode)
.addStatusUpdateChannels(statusChannel.getId());
try try
{ {
eventId = testHelper.scheduleEvent1Year(publishingPackage, publishChannel.getId(), null, update); eventId = testHelper.scheduleEvent1Year(details);
fail("shceduleNewEvent with status update should have thrown an AccessDeniedException!"); fail("shceduleNewEvent with status update should have thrown an AccessDeniedException!");
} }
catch(AlfrescoRuntimeException e) catch(AlfrescoRuntimeException e)
@@ -215,7 +222,7 @@ public class PublishingQueueImplTest extends AbstractPublishingIntegrationTest
testHelper.allowChannelAccess(user1, statusChannel.getId()); testHelper.allowChannelAccess(user1, statusChannel.getId());
// Check publish works now. // Check publish works now.
eventId = testHelper.scheduleEvent1Year(publishingPackage, publishChannel.getId(), null, update); eventId = testHelper.scheduleEvent1Year(details);
assertNotNull(eventId); 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.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; 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.ChildAssociationRef;
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.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.PermissionService; 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.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
@@ -60,8 +58,6 @@ public class PublishingRootObject
private PublishingEventHelper publishingEventHelper; private PublishingEventHelper publishingEventHelper;
private NamespaceService namespaceService; private NamespaceService namespaceService;
private SearchService searchService; private SearchService searchService;
private VersionService versionService;
private TransferManifestNodeFactory transferManifestNodeFactory;
private RetryingTransactionHelper retryingTransactionHelper; private RetryingTransactionHelper retryingTransactionHelper;
private PermissionService permissionService; private PermissionService permissionService;
@@ -122,7 +118,7 @@ public class PublishingRootObject
private PublishingQueueImpl createPublishingQueue(NodeRef environmentNode) private PublishingQueueImpl createPublishingQueue(NodeRef environmentNode)
{ {
NodeRef queueNode = getPublishingQueueNode(environmentNode); NodeRef queueNode = getPublishingQueueNode(environmentNode);
return new PublishingQueueImpl(queueNode, publishingEventHelper, versionService, transferManifestNodeFactory); return new PublishingQueueImpl(queueNode, publishingEventHelper);
} }
private NodeRef getPublishingQueueNode(NodeRef environmentNode) private NodeRef getPublishingQueueNode(NodeRef environmentNode)
@@ -220,22 +216,6 @@ public class PublishingRootObject
this.searchService = searchService; 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 * @param permissionService the permissionService to set
*/ */

View File

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

View File

@@ -22,62 +22,57 @@ package org.alfresco.repo.publishing;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParserFactory;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode; import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
import org.alfresco.repo.transfer.manifest.TransferManifestHeader; import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode; import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.repo.transfer.manifest.TransferManifestProcessor; import org.alfresco.repo.transfer.manifest.TransferManifestProcessor;
import org.alfresco.repo.transfer.manifest.XMLTransferManifestReader; import org.alfresco.repo.transfer.manifest.XMLTransferManifestReader;
import org.alfresco.repo.transfer.manifest.XMLTransferManifestWriter; import org.alfresco.repo.transfer.manifest.XMLTransferManifestWriter;
import org.alfresco.service.cmr.publishing.PublishingPackage; import org.alfresco.service.cmr.publishing.NodeSnapshot;
import org.alfresco.service.cmr.publishing.PublishingPackageEntry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
/** /**
* @author Brian * @author Brian
* @author Nick Smith * @author Nick Smith
*/ */
public class StandardPublishingPackageSerializer implements PublishingPackageSerializer public class StandardPublishingPackageSerializer implements NodeSnapshotSerializer
{ {
/** /**
* {@inheritDoc} * {@inheritDoc}
* @return
*/ */
public Map<NodeRef, PublishingPackageEntry> deserialize(InputStream input) throws Exception @Override
public List<NodeSnapshot> deserialize(InputStream input) throws Exception
{ {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser parser = saxParserFactory.newSAXParser(); SAXParser parser = saxParserFactory.newSAXParser();
PublishingPackageDeserializer processor = new PublishingPackageDeserializer(); NodeSnapshotDeserializer processor = new NodeSnapshotDeserializer();
XMLTransferManifestReader xmlReader = new XMLTransferManifestReader(processor); XMLTransferManifestReader xmlReader = new XMLTransferManifestReader(processor);
parser.parse(input, xmlReader); parser.parse(input, xmlReader);
return processor.getEntries(); return processor.getSnapshots();
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void serialize(PublishingPackage publishingPackage, OutputStream output) throws Exception public void serialize(Collection<NodeSnapshot> snapshots, OutputStream output) throws Exception
{ {
try try
{ {
Set<NodeRef> nodesToPublish = publishingPackage.getNodesToPublish();
TransferManifestHeader header = new TransferManifestHeader(); TransferManifestHeader header = new TransferManifestHeader();
header.setCreatedDate(new Date()); header.setCreatedDate(new Date());
header.setNodeCount(nodesToPublish.size()); header.setNodeCount(snapshots.size());
header.setReadOnly(false); header.setReadOnly(false);
header.setSync(false); header.setSync(false);
@@ -88,14 +83,12 @@ public class StandardPublishingPackageSerializer implements PublishingPackageSer
transferManifestWriter.writeTransferManifestHeader(header); transferManifestWriter.writeTransferManifestHeader(header);
// Iterate over NodesToPublish and Serialize. // Iterate over NodesToPublish and Serialize.
Map<NodeRef, PublishingPackageEntry> entryMap = publishingPackage.getEntryMap(); for (NodeSnapshot snapshot: snapshots)
for (NodeRef publishNode: nodesToPublish)
{ {
PublishingPackageEntry entry = entryMap.get(publishNode); if (snapshot instanceof NodeSnapshotTransferImpl)
if (entry instanceof PublishingPackageEntryImpl)
{ {
PublishingPackageEntryImpl entryImpl = (PublishingPackageEntryImpl)entry; NodeSnapshotTransferImpl snapshotImpl = (NodeSnapshotTransferImpl)snapshot;
transferManifestWriter.writeTransferManifestNode(entryImpl.getPayload()); transferManifestWriter.writeTransferManifestNode(snapshotImpl.getTransferNode());
} }
} }
transferManifestWriter.endTransferManifest(); transferManifestWriter.endTransferManifest();
@@ -117,16 +110,17 @@ public class StandardPublishingPackageSerializer implements PublishingPackageSer
* @author Nick Smith * @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) public void processTransferManifestNode(TransferManifestNormalNode node)
{ {
Map<QName, Serializable> props = node.getProperties(); NodeSnapshotTransferImpl snapshot = new NodeSnapshotTransferImpl(node);
String version = (String) props.get(ContentModel.PROP_VERSION_LABEL); snapshots.add(snapshot);
entries.put(node.getNodeRef(), new PublishingPackageEntryImpl(true, node.getNodeRef(), node, version));
} }
/** /**
@@ -152,7 +145,7 @@ public class StandardPublishingPackageSerializer implements PublishingPackageSer
*/ */
public void processTransferManifestNode(TransferManifestDeletedNode node) 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; package org.alfresco.service.cmr.publishing;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; 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.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
/** /**
* @author Brian * @author Brian
* @author Nick Smith
* @since 4.0
* *
*/ */
public interface NodeSnapshot public interface NodeSnapshot
@@ -42,37 +40,12 @@ public interface NodeSnapshot
*/ */
NodeRef getNodeRef(); 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. * 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. * @return A map that associates property names to property values for the node.
*/ */
Map<QName, Serializable> getProperties(); 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. * Retrieve the type of the node at the moment the snapshot was taken.
* @return The QName that identifies the type of the node * @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; package org.alfresco.service.cmr.publishing;
import java.util.Calendar;
import java.util.Collection;
import org.alfresco.service.cmr.repository.NodeRef;
public interface PublishingQueue public interface PublishingQueue
{ {
/** /**
* A factory method to create an empty publishing package that can be populated before being passed into * 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. * @return A publishing package that can be populated before being placed on the publishing queue.
*/ */
MutablePublishingPackage createPublishingPackageBuilder(); PublishingDetails createPublishingDetails();
StatusUpdate createStatusUpdate(String message, NodeRef nodeToLinkTo, String... channelIds);
StatusUpdate createStatusUpdate(String message, NodeRef nodeToLinkTo, Collection<String> channelIds);
/** /**
* Adds the supplied publishing package onto the queue. * Adds the supplied publishing package onto the queue.
* @param publishingPackage The publishing package that is to be enqueued * @param publishingDetails 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.
* @return The identifier of the newly scheduled event * @return The identifier of the newly scheduled event
*/ */
String scheduleNewEvent(PublishingPackage publishingPackage, String channelId, Calendar schedule, String comment, StatusUpdate statusUpdate); String scheduleNewEvent(PublishingDetails publishingDetails);
} }