diff --git a/config/alfresco/application-context.xml b/config/alfresco/application-context.xml
index dcb36d7bed..eedb8699fa 100644
--- a/config/alfresco/application-context.xml
+++ b/config/alfresco/application-context.xml
@@ -18,6 +18,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/alfresco/web-publishing-context.xml b/config/alfresco/web-publishing-context.xml
index afba82e006..a683dd4079 100644
--- a/config/alfresco/web-publishing-context.xml
+++ b/config/alfresco/web-publishing-context.xml
@@ -39,9 +39,9 @@
-
-
-
+
+
+
@@ -53,21 +53,21 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+
@@ -87,7 +87,7 @@
-
+
diff --git a/config/test/alfresco/test-web-publishing-context.xml b/config/test/alfresco/test-web-publishing-context.xml
index cf84051441..6393f2065e 100644
--- a/config/test/alfresco/test-web-publishing-context.xml
+++ b/config/test/alfresco/test-web-publishing-context.xml
@@ -10,17 +10,22 @@
parent="baseChannelType" />
-
+
+
+
+
+
+
-
+
-
+
@@ -30,7 +35,7 @@
-
+
diff --git a/source/java/org/alfresco/repo/publishing/AbstractChannelType.java b/source/java/org/alfresco/repo/publishing/AbstractChannelType.java
index b43ecc56a5..fa25d33335 100644
--- a/source/java/org/alfresco/repo/publishing/AbstractChannelType.java
+++ b/source/java/org/alfresco/repo/publishing/AbstractChannelType.java
@@ -101,7 +101,7 @@ public abstract class AbstractChannelType implements ChannelType, InitializingBe
@Override
public NodeFilter getNodeFilter()
{
- return null;
+ return nodeFilter;
}
/**
* {@inheritDoc}
@@ -111,5 +111,13 @@ public abstract class AbstractChannelType implements ChannelType, InitializingBe
{
return nodeFinder;
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getMaximumStatusLength()
+ {
+ return -1;
+ }
}
diff --git a/source/java/org/alfresco/repo/publishing/ChannelHelper.java b/source/java/org/alfresco/repo/publishing/ChannelHelper.java
index f88d6d1bd9..51fca08884 100644
--- a/source/java/org/alfresco/repo/publishing/ChannelHelper.java
+++ b/source/java/org/alfresco/repo/publishing/ChannelHelper.java
@@ -20,8 +20,6 @@
package org.alfresco.repo.publishing;
import static org.alfresco.model.ContentModel.ASSOC_CONTAINS;
-import static org.alfresco.model.ContentModel.PROP_CONTENT;
-import static org.alfresco.model.ContentModel.PROP_CONTENT_PROPERTY_NAME;
import static org.alfresco.repo.publishing.PublishingModel.ASPECT_CONTENT_ROOT;
import static org.alfresco.repo.publishing.PublishingModel.ASPECT_PUBLISHED;
import static org.alfresco.repo.publishing.PublishingModel.ASSOC_SOURCE;
@@ -32,6 +30,8 @@ import static org.alfresco.repo.publishing.PublishingModel.PROP_CHANNEL_TYPE_ID;
import static org.alfresco.repo.publishing.PublishingModel.TYPE_DELIVERY_CHANNEL;
import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -40,12 +40,13 @@ import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
+import org.alfresco.service.cmr.model.FileFolderService;
+import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.publishing.channels.Channel;
import org.alfresco.service.cmr.publishing.channels.ChannelService;
import org.alfresco.service.cmr.publishing.channels.ChannelType;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
-import org.alfresco.service.cmr.repository.ContentReader;
-import org.alfresco.service.cmr.repository.ContentService;
+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.namespace.NamespaceService;
@@ -53,6 +54,9 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.GUID;
import org.alfresco.util.Pair;
+import org.alfresco.util.collections.CollectionUtils;
+import org.alfresco.util.collections.Filter;
+import org.alfresco.util.collections.Function;
/**
* @author Nick Smith
@@ -65,8 +69,8 @@ public class ChannelHelper
private NodeService nodeService;
private DictionaryService dictionaryService;
- private ContentService contentService;
-
+ private FileFolderService fileFolderService;
+
public ChannelHelper()
{
super();
@@ -230,47 +234,37 @@ public class ChannelHelper
return assoc;
}
- /**
- * @param nodeToPublish
- * @param channelType
- * @return
- */
public boolean canPublish(NodeRef nodeToPublish, ChannelType type)
{
if(type.canPublish() == false)
{
return false;
}
- boolean isContentTypeSupported = isContentTypeSupported(nodeToPublish, type);
- boolean isMimetypeSupported = isMimetypeSupported(nodeToPublish, type);
+ FileInfo file = fileFolderService.getFileInfo(nodeToPublish);
+ ContentData contentData = file.getContentData();
+ String mimetype = contentData == null ? null : contentData.getMimetype();
+ boolean isContentTypeSupported = isContentTypeSupported(file.getType(), type);
+ boolean isMimetypeSupported = isMimetypeSupported(mimetype, type);
return isContentTypeSupported && isMimetypeSupported;
}
- private boolean isMimetypeSupported(NodeRef nodeToPublish, ChannelType type)
+ private boolean isMimetypeSupported(String mimetype, ChannelType type)
{
Set supportedMimetypes = type.getSupportedMimetypes();
if (supportedMimetypes == null || supportedMimetypes.isEmpty())
{
return true;
}
- QName contentProp = (QName) nodeService.getProperty(nodeToPublish, PROP_CONTENT_PROPERTY_NAME);
- if (contentProp == null)
- {
- String defaultValue = dictionaryService.getProperty(PROP_CONTENT_PROPERTY_NAME).getDefaultValue();
- contentProp = defaultValue == null ? PROP_CONTENT : QName.createQName(defaultValue);
- }
- ContentReader reader = contentService.getReader(nodeToPublish, contentProp);
- return supportedMimetypes.contains(reader.getMimetype());
+ return supportedMimetypes.contains(mimetype);
}
- private boolean isContentTypeSupported(NodeRef nodeToPublish, ChannelType type)
+ private boolean isContentTypeSupported(QName contentType, ChannelType type)
{
Set supportedContentTypes = type.getSupportedContentTypes();
if(supportedContentTypes == null || supportedContentTypes.isEmpty())
{
return true;
}
- QName contentType = nodeService.getType(nodeToPublish);
for (QName supportedType : supportedContentTypes)
{
if(contentType.equals(supportedType)
@@ -306,6 +300,60 @@ public class ChannelHelper
}
return null;
}
+
+ public List getChannels(NodeRef channelContainer, final ChannelService channelService)
+ {
+ List channelAssocs = getChannelAssocs(channelContainer);
+ return CollectionUtils.transform(channelAssocs, getChannelTransformer(channelService));
+ }
+
+ public List getChannelsByType(NodeRef containerNode, String channelTypeId, ChannelService channelService)
+ {
+ List channelAssocs = getChannelAssocsByType(containerNode, channelTypeId);
+ return CollectionUtils.transform(channelAssocs, getChannelTransformer(channelService));
+ }
+
+ public List getReleventChannelTypes(final NodeRef nodeToPublish, Collection channelTypes)
+ {
+ return CollectionUtils.filter(channelTypes, new Filter()
+ {
+ public Boolean apply(ChannelType type)
+ {
+ return canPublish(nodeToPublish, type);
+ }
+ });
+ }
+
+ public List getStatusUpdateChannelTypes(Collection channelTypes)
+ {
+ return CollectionUtils.filter(channelTypes, new Filter()
+ {
+ public Boolean apply(ChannelType type)
+ {
+ return type.canPublishStatusUpdates();
+ }
+ });
+ }
+
+ private List getChannelAssocs(NodeRef channelContainer)
+ {
+ if(channelContainer == null)
+ {
+ return null;
+ }
+ Collection channelNodeTypes = dictionaryService.getSubTypes(TYPE_DELIVERY_CHANNEL, true);
+ HashSet childNodeTypeQNames = new HashSet(channelNodeTypes);
+ return nodeService.getChildAssocs(channelContainer, childNodeTypeQNames);
+ }
+
+ private List getChannelAssocsByType(NodeRef channelContainer, String channelTypeId)
+ {
+ if(channelContainer == null)
+ {
+ return null;
+ }
+ return nodeService.getChildAssocsByPropertyValue(channelContainer, PROP_CHANNEL_TYPE_ID, channelTypeId);
+ }
private Pair getChannelAndType(NodeRef node)
{
@@ -328,10 +376,16 @@ public class ChannelHelper
return null;
}
- public void sendStatusUpdates(NodeRef nodeToPublish, NodeRef channelNode, ChannelType channelType)
+ private Function getChannelTransformer(final ChannelService channelService)
{
- //TODO
-
+ return new Function()
+ {
+ public Channel apply(ChildAssociationRef value)
+ {
+ NodeRef channelNode = value.getChildRef();
+ return buildChannelObject(channelNode, channelService);
+ }
+ };
}
/**
@@ -351,11 +405,11 @@ public class ChannelHelper
}
/**
- * @param contentService the contentService to set
+ * @param fileFolderService the fileFolderService to set
*/
- public void setContentService(ContentService contentService)
+ public void setFileFolderService(FileFolderService fileFolderService)
{
- this.contentService = contentService;
+ this.fileFolderService = fileFolderService;
}
}
diff --git a/source/java/org/alfresco/repo/publishing/ChannelServiceImpl.java b/source/java/org/alfresco/repo/publishing/ChannelServiceImpl.java
index 995434a9d9..a7a3ed7e58 100644
--- a/source/java/org/alfresco/repo/publishing/ChannelServiceImpl.java
+++ b/source/java/org/alfresco/repo/publishing/ChannelServiceImpl.java
@@ -24,7 +24,6 @@ import static org.alfresco.repo.publishing.PublishingModel.TYPE_DELIVERY_CHANNEL
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -40,15 +39,18 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.publishing.channels.Channel;
import org.alfresco.service.cmr.publishing.channels.ChannelService;
import org.alfresco.service.cmr.publishing.channels.ChannelType;
-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.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.transfer.NodeFilter;
import org.alfresco.service.cmr.transfer.NodeFinder;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
+import org.alfresco.util.collections.CollectionUtils;
+import org.alfresco.util.collections.Filter;
+import org.alfresco.util.collections.Function;
/**
* @author Nick Smith
@@ -61,6 +63,8 @@ public class ChannelServiceImpl implements ChannelService
private static final String CHANNEL_CONTAINER_NAME = "channels";
+ public static final String NAME = "channelService";
+
private final Map channelTypes = new TreeMap();
private SiteService siteService;
private NodeService nodeService;
@@ -194,23 +198,8 @@ public class ChannelServiceImpl implements ChannelService
public List getChannels(String siteId)
{
ParameterCheck.mandatory("siteId", siteId);
-
NodeRef channelContainer = getChannelContainer(siteId);
- if(channelContainer == null)
- {
- return Collections.emptyList();
- }
- Collection channelNodeTypes = dictionaryService.getSubTypes(TYPE_DELIVERY_CHANNEL, true);
- HashSet childNodeTypeQNames = new HashSet(channelNodeTypes);
- List channelAssocs = nodeService.getChildAssocs(channelContainer, childNodeTypeQNames);
- List channelList = new ArrayList(channelAssocs.size());
- for (ChildAssociationRef channelAssoc : channelAssocs)
- {
- NodeRef channelNode = channelAssoc.getChildRef();
- Channel channel = channelHelper.buildChannelObject(channelNode, this);
- channelList.add(channel);
- }
- return Collections.unmodifiableList(channelList);
+ return channelHelper.getChannels(channelContainer, this);
}
/**
@@ -239,6 +228,82 @@ public class ChannelServiceImpl implements ChannelService
return null;
}
+ /**
+ * {@inheritDoc}
+ */
+ public List getRelevantPublishingChannels(NodeRef nodeToPublish)
+ {
+ SiteInfo siteInfo = siteService.getSite(nodeToPublish);
+ if(siteInfo != null)
+ {
+ final NodeRef containerNode = getChannelContainer(siteInfo.getShortName());
+ if(containerNode != null)
+ {
+ List types = channelHelper.getReleventChannelTypes(nodeToPublish, channelTypes.values());
+ return getChannelsForTypes(containerNode, types);
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List getPublishingChannels(String siteId)
+ {
+ final NodeRef containerNode = getChannelContainer(siteId);
+ if(containerNode != null)
+ {
+ List types = CollectionUtils.filter(channelTypes.values(), new Filter()
+ {
+ public Boolean apply(ChannelType type)
+ {
+ return type.canPublish();
+ }
+ });
+ return getChannelsForTypes(containerNode, types);
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List getStatusUpdateChannels(String siteId)
+ {
+ final NodeRef containerNode = getChannelContainer(siteId);
+ if (containerNode != null)
+ {
+ List types = channelHelper.getStatusUpdateChannelTypes(channelTypes.values());
+ return getChannelsForTypes(containerNode, types);
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List getStatusUpdateChannels(NodeRef nodeToPublish)
+ {
+ SiteInfo site = siteService.getSite(nodeToPublish);
+ if(site!=null)
+ {
+ return getStatusUpdateChannels(site.getShortName());
+ }
+ return Collections.emptyList();
+ }
+
+ private List getChannelsForTypes(final NodeRef containerNode, List types)
+ {
+ return CollectionUtils.transformFlat(types, new Function>()
+ {
+ public List apply(ChannelType channelType)
+ {
+ return channelHelper.getChannelsByType(containerNode, channelType.getId(), ChannelServiceImpl.this);
+ }
+ });
+ }
+
private NodeRef getChannelContainer(final String siteId)
{
return siteService.getContainer(siteId, CHANNEL_CONTAINER_NAME);
diff --git a/source/java/org/alfresco/repo/publishing/PublishingEventHelperTest.java b/source/java/org/alfresco/repo/publishing/PublishingEventHelperTest.java
index c1e9d631fd..a3ebb8396f 100644
--- a/source/java/org/alfresco/repo/publishing/PublishingEventHelperTest.java
+++ b/source/java/org/alfresco/repo/publishing/PublishingEventHelperTest.java
@@ -78,10 +78,10 @@ public class PublishingEventHelperTest
@Resource(name="publishingEventHelper")
PublishingEventHelper helper;
- @Resource(name="nodeService")
+ @Resource(name="NodeService")
NodeService nodeService;
- @Resource(name="contentService")
+ @Resource(name="ContentService")
ContentService contentService;
@Test
diff --git a/source/java/org/alfresco/repo/publishing/PublishingModel.java b/source/java/org/alfresco/repo/publishing/PublishingModel.java
index 471601cfc9..7b185dfb52 100644
--- a/source/java/org/alfresco/repo/publishing/PublishingModel.java
+++ b/source/java/org/alfresco/repo/publishing/PublishingModel.java
@@ -40,6 +40,7 @@ public interface PublishingModel
public static final QName TYPE_PUBLISHING_QUEUE = QName.createQName(NAMESPACE, "PublishingQueue");
public static final QName TYPE_CHANNEL_CONTAINER = QName.createQName(NAMESPACE, "SiteChannelContainer");
public static final QName TYPE_PUBLISHING_EVENT = QName.createQName(NAMESPACE, "PublishingEvent");
+ public static final QName TYPE_PUBLISHING_CONNECTION = QName.createQName(NAMESPACE, "Connection");
public static final QName ASPECT_CONTENT_ROOT = QName.createQName(NAMESPACE, "ContentRoot");
public static final QName ASPECT_CHANNEL_INFO= QName.createQName(NAMESPACE, "channelInfo");
@@ -60,12 +61,20 @@ public interface PublishingModel
public static final QName PROP_STATUS_UPDATE_CHANNEL_NAMES = QName.createQName(NAMESPACE, "statusUpdateChannelNames");
public static final QName PROP_STATUS_UPDATE_NODE_REF = QName.createQName(NAMESPACE, "statusUpdateNodeRef");
public static final QName PROP_STATUS_UPDATE_MESSAGE = QName.createQName(NAMESPACE, "statusUpdateMessage");
+ // Publishing Connection Properties
+ public static final QName PROP_ACCOUNT_ID= QName.createQName(NAMESPACE, "accountId");
+ public static final QName PROP_PROVIDER_ID= QName.createQName(NAMESPACE, "providerId");
+ public static final QName PROP_PROVIDER_ACCOUNT_ID= QName.createQName(NAMESPACE, "providerAccountId");
+ public static final QName PROP_ACCESS_TOKEN= QName.createQName(NAMESPACE, "accessToken");
+ public static final QName PROP_ACCESS_SECRET= QName.createQName(NAMESPACE, "secret");
+ public static final QName PROP_REFRESH_TOKEN= QName.createQName(NAMESPACE, "refreshToken");
public static final String PROPVAL_PUBLISHING_EVENT_STATUS_SCHEDULED = "SCHEDULED";
public static final String PROPVAL_PUBLISHING_EVENT_STATUS_IN_PROGRESS = "IN_PROGRESS";
public static final String PROPVAL_PUBLISHING_EVENT_STATUS_CANCEL_REQUESTED = "CANCEL_REQUESTED";
public static final String PROPVAL_PUBLISHING_EVENT_STATUS_COMPLETED = "COMPLETED";
public static final String PROPVAL_PUBLISHING_EVENT_STATUS_FAILED = "FAILED";
+
public static final QName ASSOC_PUBLISHING_QUEUE = QName.createQName(NAMESPACE, "publishingQueueAssoc");
public static final QName ASSOC_PUBLISHING_EVENT = QName.createQName(NAMESPACE, "publishingEventAssoc");
diff --git a/source/java/org/alfresco/repo/publishing/PublishingObjectFactory.java b/source/java/org/alfresco/repo/publishing/PublishingObjectFactory.java
index 435f3fbdad..f9f2c70864 100644
--- a/source/java/org/alfresco/repo/publishing/PublishingObjectFactory.java
+++ b/source/java/org/alfresco/repo/publishing/PublishingObjectFactory.java
@@ -34,6 +34,8 @@ import org.alfresco.service.cmr.repository.NodeRef;
*/
public class PublishingObjectFactory implements EnvironmentFactory, PublishingQueueFactory
{
+ public static final String NAME = "publishingObjectFactory";
+
private EnvironmentHelper environmentHelper;
private TransferManifestNodeFactory transferManifestNodeFactory;
private PublishingEventHelper publishingEventHelper;
diff --git a/source/java/org/alfresco/repo/publishing/authorization/NodeBasedConnectionRepository.java b/source/java/org/alfresco/repo/publishing/authorization/NodeBasedConnectionRepository.java
new file mode 100644
index 0000000000..3d20a0eea6
--- /dev/null
+++ b/source/java/org/alfresco/repo/publishing/authorization/NodeBasedConnectionRepository.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.repo.publishing.authorization;
+
+import static org.alfresco.repo.publishing.PublishingModel.PROP_ACCESS_SECRET;
+import static org.alfresco.repo.publishing.PublishingModel.PROP_ACCESS_TOKEN;
+import static org.alfresco.repo.publishing.PublishingModel.PROP_ACCOUNT_ID;
+import static org.alfresco.repo.publishing.PublishingModel.PROP_PROVIDER_ACCOUNT_ID;
+import static org.alfresco.repo.publishing.PublishingModel.PROP_PROVIDER_ID;
+import static org.alfresco.repo.publishing.PublishingModel.PROP_REFRESH_TOKEN;
+import static org.alfresco.repo.publishing.PublishingModel.TYPE_PUBLISHING_CONNECTION;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.model.Repository;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
+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.namespace.QName;
+import org.springframework.social.connect.Connection;
+import org.springframework.social.connect.ConnectionRepository;
+import org.springframework.social.oauth1.OAuthToken;
+import org.springframework.social.twitter.api.TwitterApi;
+import org.springframework.social.twitter.connect.TwitterConnectionFactory;
+
+/**
+ * A node-backed Social Connection Repository, that stores the
+ * credentials and auth tokens in the Data Dictionary.
+ *
+ * @author Nick Burch
+ * @author Nick Smith
+ */
+public class NodeBasedConnectionRepository
+{
+ /**
+ * Serial version UID
+ */
+ private static final long serialVersionUID = 3258131523636186548L;
+
+ /** Reference to the auth store space node */
+ private static final StoreRef SPACES_STORE = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
+ protected static final NodeRef SOCIAL_PUBLISHING_AUTHORISATION_ROOT_NODE_REF =
+ new NodeRef(SPACES_STORE, "social_publishing_authorisation_space");
+
+ private NodeService nodeService;
+ private SearchService searchService;
+ private Repository repositoryHelper;
+
+ // TODO Replace this with doing it properly...
+ private NodeRef authRootNode;
+
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ public void setSearchService(SearchService searchService)
+ {
+ this.searchService = searchService;
+ }
+
+ public void setRepositoryHelper(Repository repositoryHelper)
+ {
+ this.repositoryHelper = repositoryHelper;
+ }
+
+ private void findAuthRootNode() {
+ if(authRootNode != null) return;
+
+ // TODO Replace this with doing it properly...
+ AuthenticationUtil.runAs(new RunAsWork()
+ {
+ @Override
+ public Void doWork() throws Exception
+ {
+ if(! nodeService.exists(SOCIAL_PUBLISHING_AUTHORISATION_ROOT_NODE_REF))
+ {
+ NodeRef dataDictionary = nodeService.getChildByName(
+ repositoryHelper.getCompanyHome(),
+ ContentModel.ASSOC_CONTAINS,
+ "dictionary"
+ );
+ authRootNode = nodeService.getChildByName(
+ dataDictionary,
+ ContentModel.ASSOC_CONTAINS,
+ SOCIAL_PUBLISHING_AUTHORISATION_ROOT_NODE_REF.getId()
+ );
+ if(authRootNode == null)
+ {
+ authRootNode = nodeService.createNode(
+ dataDictionary,
+ ContentModel.ASSOC_CONTAINS,
+ QName.createQName("{}"+SOCIAL_PUBLISHING_AUTHORISATION_ROOT_NODE_REF.getId()),
+ ContentModel.TYPE_FOLDER
+ ).getChildRef();
+ }
+ }
+ else
+ {
+ authRootNode = SOCIAL_PUBLISHING_AUTHORISATION_ROOT_NODE_REF;
+ }
+ return null;
+ }
+ }, AuthenticationUtil.getAdminUserName());
+ }
+
+ private NodeRef findProvider(final String providerId, boolean autoCreate)
+ {
+ NodeRef node = nodeService.getChildByName(
+ authRootNode, ContentModel.ASSOC_CONTAINS, providerId
+ );
+ if(autoCreate && node == null)
+ {
+ node = AuthenticationUtil.runAs(new RunAsWork()
+ {
+ @Override
+ public NodeRef doWork() throws Exception
+ {
+ return nodeService.createNode(
+ authRootNode, ContentModel.ASSOC_CONTAINS,
+ QName.createQName("{}" + providerId),
+ ContentModel.TYPE_FOLDER
+ ).getChildRef();
+ }
+ } , AuthenticationUtil.getAdminUserName()
+ );
+ }
+ return node;
+ }
+
+ private NodeRef findAccount(Serializable accountId, String providerId)
+ {
+ findAuthRootNode();
+ NodeRef folder = findProvider(providerId, false);
+ if(folder == null)
+ {
+ return null;
+ }
+
+ NodeRef account = nodeService.getChildByName(
+ folder, ContentModel.ASSOC_CONTAINS, accountId.toString()
+ );
+ return account;
+ }
+
+ private Connection> buildConnection(NodeRef node)
+ {
+// Map props = nodeService.getProperties(node);
+// return new Connection(
+// (long)-1,
+// (String)props.get(PROP_ACCESS_TOKEN),
+// (String)props.get(PROP_ACCESS_SECRET),
+// (String)props.get(PROP_REFRESH_TOKEN),
+// (String)props.get(PROP_PROVIDER_ACCOUNT_ID)
+// );
+ return null;
+ }
+
+ public boolean isConnected(Serializable accountId, String providerId)
+ {
+ NodeRef account = findAccount(accountId, providerId);
+ return (account != null);
+ }
+
+ public Serializable findAccountIdByConnectionAccessToken(String providerId,
+ String accessToken) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List findAccountIdsForProviderAccountIds(
+ String providerId, List providerAccountIds) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List> findConnections(Serializable accountId,
+ String providerId) {
+ NodeRef account = findAccount(accountId, providerId);
+ if(account == null)
+ {
+ return Collections.emptyList();
+ }
+
+ List> connections = new ArrayList>();
+ connections.add( buildConnection(account) );
+ return connections;
+ }
+
+ public void removeConnection(Serializable accountId, String providerId,
+ Long connectionId)
+ {
+ NodeRef account = findAccount(accountId, providerId);
+ if(account != null)
+ {
+ nodeService.deleteNode(account);
+ }
+ }
+
+ public Connection saveConnection(Serializable accountId, String providerId,
+ Connection connection)
+ {
+// Map args = new HashMap();
+// args.put(ContentModel.PROP_NAME, accountId);
+// args.put(PROP_ACCOUNT_ID, accountId);
+// args.put(PROP_PROVIDER_ID, providerId);
+// args.put(PROP_PROVIDER_ACCOUNT_ID, connection.getProviderAccountId());
+// args.put(PROP_ACCESS_TOKEN, connection.getAccessToken());
+// args.put(PROP_ACCESS_SECRET, connection.getSecret());
+// args.put(PROP_REFRESH_TOKEN, connection.getRefreshToken());
+//
+// findAuthRootNode();
+// NodeRef folder = findProvider(providerId, true);
+// NodeRef node = nodeService.createNode(
+// folder, ContentModel.ASSOC_CONTAINS,
+// QName.createQName("{}" + accountId.toString()),
+// TYPE_PUBLISHING_CONNECTION,
+// args
+// ).getChildRef();
+//
+// return buildConnection(node);
+ return null;
+ }
+}
diff --git a/source/java/org/alfresco/repo/publishing/authorization/NodeBasedConnectionRepository2.java b/source/java/org/alfresco/repo/publishing/authorization/NodeBasedConnectionRepository2.java
new file mode 100644
index 0000000000..70cc47efae
--- /dev/null
+++ b/source/java/org/alfresco/repo/publishing/authorization/NodeBasedConnectionRepository2.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2005-2010 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.repo.publishing.authorization;
+
+import static org.alfresco.model.ContentModel.ASSOC_CONTAINS;
+import static org.alfresco.repo.publishing.PublishingModel.TYPE_PUBLISHING_CONNECTION;
+import java.util.Collections;
+import java.util.List;
+
+import org.alfresco.repo.model.Repository;
+import org.alfresco.service.cmr.model.FileFolderService;
+import org.alfresco.service.cmr.model.FileInfo;
+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.util.collections.CollectionUtils;
+import org.alfresco.util.collections.Function;
+import org.springframework.social.connect.Connection;
+import org.springframework.social.connect.ConnectionKey;
+import org.springframework.social.connect.ConnectionRepository;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+
+/**
+ * @author Nick Smith
+ * @since 4.0
+ *
+ */
+public class NodeBasedConnectionRepository2 implements ConnectionRepository
+{
+ /**
+ * Serial version UID
+ */
+ private static final long serialVersionUID = 3258131523636186548L;
+
+ /** Reference to the auth store space node */
+ private static final StoreRef SPACES_STORE = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
+ protected static final NodeRef SOCIAL_PUBLISHING_AUTHORISATION_ROOT_NODE_REF =
+ new NodeRef(SPACES_STORE, "social_publishing_authorisation_space");
+
+ private NodeService nodeService;
+ private FileFolderService fileFolderService;
+ private SearchService searchService;
+ private Repository repositoryHelper;
+
+ // TODO Replace this with doing it properly...
+ private NodeRef authRootNode;
+
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ /**
+ * @param fileFolderService the fileFolderService to set
+ */
+ public void setFileFolderService(FileFolderService fileFolderService)
+ {
+ this.fileFolderService = fileFolderService;
+ }
+
+ public void setSearchService(SearchService searchService)
+ {
+ this.searchService = searchService;
+ }
+
+ public void setRepositoryHelper(Repository repositoryHelper)
+ {
+ this.repositoryHelper = repositoryHelper;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MultiValueMap> findConnections()
+ {
+ MultiValueMap> results = new LinkedMultiValueMap>();
+ for (String providerId : getAllProviderIds())
+ {
+ List> connections = findConnectionsToProvider(providerId);
+ if(connections!=null && connections.isEmpty() == false)
+ {
+ results.put(providerId, connections);
+ }
+ }
+ return results;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List> findConnectionsToProvider(String providerId)
+ {
+ NodeRef providerNode = getProviderNode(providerId);
+ List connectionNodes = nodeService.getChildAssocs(providerNode, Collections.singleton(TYPE_PUBLISHING_CONNECTION));
+ return convertConnections(connectionNodes);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public MultiValueMap> findConnectionsForUsers(MultiValueMap providerUserIds)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Connection> findConnection(ConnectionKey connectionKey)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Connection findPrimaryConnectionToApi(Class apiType)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Connection findConnectionToApiForUser(Class apiType, String providerUserId)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List> findConnectionsToApi(Class apiType)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addConnection(Connection> connection)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void updateConnection(Connection> connection)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeConnectionsToProvider(String providerId)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeConnection(ConnectionKey connectionKey)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ private List getAllProviderIds()
+ {
+ return CollectionUtils.transform(fileFolderService.listFolders(getAuthentiactionRoot()), new Function()
+ {
+ public String apply(FileInfo value)
+ {
+ return value.getName();
+ }
+ });
+ }
+
+ private NodeRef getProviderNode(String providerId)
+ {
+ return nodeService.getChildByName(getAuthentiactionRoot(), ASSOC_CONTAINS, providerId);
+ }
+
+ private NodeRef getAuthentiactionRoot()
+ {
+ //TODO
+ return null;
+ }
+
+ private List> convertConnections(List connectionNodes)
+ {
+ //TODO
+ return null;
+ }
+
+
+}
diff --git a/source/java/org/alfresco/service/cmr/publishing/channels/ChannelService.java b/source/java/org/alfresco/service/cmr/publishing/channels/ChannelService.java
index 64137262f1..e829a7213b 100644
--- a/source/java/org/alfresco/service/cmr/publishing/channels/ChannelService.java
+++ b/source/java/org/alfresco/service/cmr/publishing/channels/ChannelService.java
@@ -107,4 +107,33 @@ public interface ChannelService
* @return The specified Channel objects or null
if the specified channel does not exist.
*/
Channel getChannel(String id);
+
+ /**
+ * Returns a list of all the channels that are capable of publishing the specified NodeRef.
+ * @param nodeToPublish
+ * @return
+ */
+ List getRelevantPublishingChannels(NodeRef nodeToPublish);
+
+ /**
+ * Returns a list of all the channels that are capable of publishing in the specified Share site.
+ * @param siteId
+ * @return
+ */
+ List getPublishingChannels(String siteId);
+
+ /**
+ * Returns all {@link Channel}s cpaable of performing a status update for the given Share Site.
+ * @param siteId
+ * @return
+ */
+ List getStatusUpdateChannels(String siteId);
+
+ /**
+ * Returns all {@link Channel}s cpaable of performing a status update for the Share Site in which the specified nodeToPublish
exists.
+ * @param siteId
+ * @return
+ */
+ List getStatusUpdateChannels(NodeRef nodeToPublish);
+
}
diff --git a/source/java/org/alfresco/service/cmr/publishing/channels/ChannelType.java b/source/java/org/alfresco/service/cmr/publishing/channels/ChannelType.java
index bc6a74e0f3..7b019ebabb 100644
--- a/source/java/org/alfresco/service/cmr/publishing/channels/ChannelType.java
+++ b/source/java/org/alfresco/service/cmr/publishing/channels/ChannelType.java
@@ -50,4 +50,5 @@ public interface ChannelType
Set getSupportedMimetypes();
Set getSupportedContentTypes();
String getNodeUrl(NodeRef node);
+ int getMaximumStatusLength();
}