Blog Integration module moved into core

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8333 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mike Hatfield 2008-02-20 09:36:44 +00:00
parent 2237d2f748
commit a0834aed8e
13 changed files with 1781 additions and 28 deletions

View File

@ -7,7 +7,7 @@
<bean id="BlogIntegrationService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.module.blogIntegration.BlogIntegrationService</value>
<value>org.alfresco.repo.blogIntegration.BlogIntegrationService</value>
</property>
<property name="target">
<ref bean="blogIntegrationService"/>
@ -35,7 +35,7 @@
<bean id="BlogIntegrationService_security" class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
<bean id="blogIntegrationService" class="org.alfresco.module.blogIntegration.BlogIntegrationServiceImpl">
<bean id="blogIntegrationService" class="org.alfresco.repo.blogIntegration.BlogIntegrationServiceImpl">
<property name="nodeService" ref="NodeService"/>
<property name="contentService" ref="ContentService"/>
</bean>
@ -46,42 +46,19 @@
<property name="blogIntegrationService" ref="blogIntegrationService"/>
</bean>
<bean id="wordPressBlogIntegration" parent="baseBlogIntegrationImplmentation" class="org.alfresco.module.blogIntegration.wordpress.WordPressIntegration">
<bean id="wordPressBlogIntegration" parent="baseBlogIntegrationImplmentation" class="org.alfresco.repo.blogIntegration.wordpress.WordPressIntegration">
<property name="name" value="wordpress"/>
<property name="displayName" value="WordPress"/>
</bean>
<bean id="typePadBlogIntegration" parent="baseBlogIntegrationImplmentation" class="org.alfresco.module.blogIntegration.typepad.TypepadIntegration">
<bean id="typePadBlogIntegration" parent="baseBlogIntegrationImplmentation" class="org.alfresco.repo.blogIntegration.typepad.TypepadIntegration">
<property name="name" value="typepad"/>
<property name="displayName" value="Typepad"/>
</bean>
<!-- UI Configuration Bootstrap -->
<bean id="org_alfresco_module_blogIntegration_ConfigBootstrap" class="org.alfresco.web.config.WebClientConfigBootstrap" init-method="init">
<property name="configs">
<list>
<value>classpath:alfresco/module/org.alfresco.module.blogIntegration/ui/web-client-custom.xml</value>
</list>
</property>
</bean>
<!-- UI Action Listeners -->
<bean id="org_alfresco_module_blogIntegration_BlogDetailsActionListener" class="org.alfresco.module.blogIntegration.ui.BlogDetailsActionListener">
<property name="serviceRegistry">
<ref bean="ServiceRegistry"/>
</property>
</bean>
<bean id="org_alfresco_module_blogIntegration_BlogActionListener" class="org.alfresco.module.blogIntegration.ui.BlogActionListener">
<property name="serviceRegistry" ref="ServiceRegistry"/>
<property name="blogIntegrationService" ref="BlogIntegrationService"/>
</bean>
<!-- Blog Repository Actions -->
<bean id="blog-post" class="org.alfresco.module.blogIntegration.BlogAction" parent="action-executer">
<bean id="blog-post" class="org.alfresco.repo.action.executer.BlogAction" parent="action-executer">
<property name="nodeService">
<ref bean="nodeService" />
</property>

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.model;
import org.alfresco.service.namespace.QName;
/**
* @author Roy Wetherall
*/
public interface BlogIntegrationModel
{
static final String MODEL_URL = "http://www.alfresco.org/model/blogintegration/1.0";
static final String MODEL_PREFIX = "blg";
static final QName ASPECT_BLOG_DETAILS = QName.createQName(MODEL_URL, "blogDetails");
static final QName PROP_BLOG_IMPLEMENTATION = QName.createQName(MODEL_URL, "blogImplementation");
static final QName PROP_ID = QName.createQName(MODEL_URL, "id");
static final QName PROP_NAME = QName.createQName(MODEL_URL, "name");
static final QName PROP_DESCRIPTION = QName.createQName(MODEL_URL, "description");
static final QName PROP_URL = QName.createQName(MODEL_URL, "url");
static final QName PROP_USER_NAME = QName.createQName(MODEL_URL, "userName");
static final QName PROP_PASSWORD = QName.createQName(MODEL_URL, "password");
static final QName ASPECT_BLOG_POST = QName.createQName(MODEL_URL, "blogPost");
static final QName PROP_POST_ID = QName.createQName(MODEL_URL, "postId");
static final QName PROP_PUBLISHED = QName.createQName(MODEL_URL, "published");
static final QName PROP_LINK = QName.createQName(MODEL_URL, "link");
static final QName PROP_POSTED = QName.createQName(MODEL_URL, "posted");
static final QName PROP_LAST_UPDATE = QName.createQName(MODEL_URL, "lastUpdate");
static final QName ASSOC_BLOG_DETAILS = QName.createQName(MODEL_URL, "blogDetails");
}

View File

@ -0,0 +1,171 @@
/**
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.action.executer;
import java.util.List;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.blogIntegration.BlogDetails;
import org.alfresco.repo.blogIntegration.BlogIntegrationRuntimeException;
import org.alfresco.repo.blogIntegration.BlogIntegrationService;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.alfresco.model.BlogIntegrationModel;
import org.alfresco.model.ContentModel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Post blog repository action
*
* @author mikeh
*/
public class BlogAction extends ActionExecuterAbstractBase implements BlogIntegrationModel
{
public static final String NAME = "blog-post";
public static final String PARAM_BLOG_ACTION = "action";
private static Log logger = LogFactory.getLog(BlogAction.class);
private DictionaryService dictionaryService;
private NodeService nodeService;
private BlogIntegrationService blogIntegrationService;
/**
* Set the node service
*
* @param nodeService the node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Set the dictionary service
*
* @param dictionaryService the dictionary service
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* Set the blog integration service
*
* @param blogIntegrationService the blog integration service
*/
public void setBlogIntegrationService(BlogIntegrationService blogIntegrationService)
{
this.blogIntegrationService = blogIntegrationService;
}
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
{
String blogAction = (String)action.getParameterValue(PARAM_BLOG_ACTION);
try
{
if ("post".equals(blogAction) == true)
{
QName type = this.nodeService.getType(actionedUponNodeRef);
if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) == true)
{
List<BlogDetails> list = this.blogIntegrationService.getBlogDetails(actionedUponNodeRef);
if (list.size() != 0)
{
// Take the 'nearest' blog details
BlogDetails blogDetails = list.get(0);
this.blogIntegrationService.newPost(blogDetails, actionedUponNodeRef, ContentModel.PROP_CONTENT, true);
}
}
}
else if ("update".equals(blogAction) == true)
{
QName type = this.nodeService.getType(actionedUponNodeRef);
if (this.nodeService.hasAspect(actionedUponNodeRef, ASPECT_BLOG_POST) == true &&
this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) == true)
{
this.blogIntegrationService.updatePost(actionedUponNodeRef, ContentModel.PROP_CONTENT, true);
}
}
else if ("remove".equals(blogAction) == true)
{
QName type = this.nodeService.getType(actionedUponNodeRef);
if (this.nodeService.hasAspect(actionedUponNodeRef, ASPECT_BLOG_POST) == true &&
this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) == true)
{
this.blogIntegrationService.deletePost(actionedUponNodeRef);
}
}
else
{
throw new BlogIntegrationRuntimeException("Invalid action has been specified '" + blogAction + "'");
}
action.setParameterValue(PARAM_RESULT, "");
}
catch (BlogIntegrationRuntimeException ex)
{
action.setParameterValue(PARAM_RESULT, ex.getMessage());
}
catch (Exception ex)
{
action.setParameterValue(PARAM_RESULT, "Action failed. Please check blog configuration parameters.");
}
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
// Add definitions for action parameters
paramList.add(
new ParameterDefinitionImpl(PARAM_BLOG_ACTION,
DataTypeDefinition.TEXT,
true,
getParamDisplayLabel(PARAM_BLOG_ACTION)));
paramList.add(
new ParameterDefinitionImpl(PARAM_RESULT,
DataTypeDefinition.TEXT,
false,
getParamDisplayLabel(PARAM_RESULT)));
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration;
/**
* Base blog implementation class. Extend this when writting a blog integration implementation.
*
* @author Roy Wetherall
*/
public abstract class BaseBlogIntegrationImplementation implements BlogIntegrationImplementation
{
/** Blog integration service */
private BlogIntegrationService blogIntegrationService;
/** Integration name */
private String name;
/** Display name */
private String displayName;
/**
* Sets the blog integration service
*
* @param blogIntegrationService the blog integration service
*/
public void setBlogIntegrationService(BlogIntegrationService blogIntegrationService)
{
this.blogIntegrationService = blogIntegrationService;
}
/**
* Registers the blog implementation with the blog integration service.
*/
public void register()
{
this.blogIntegrationService.register(this);
}
/**
* Sets the name of the blog integration service
*
* @param name the name
*/
public void setName(String name)
{
this.name = name;
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationImplementation#getName()
*/
public String getName()
{
return this.name;
}
/**
* Sets the display name
*
* @param displayName the display name
*/
public void setDisplayName(String displayName)
{
this.displayName = displayName;
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationImplementation#getDisplayName()
*/
public String getDisplayName()
{
return this.displayName;
}
}

View File

@ -0,0 +1,213 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.model.BlogIntegrationModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Blog details. Contains the detail of a blog.
*
* @author Roy Wetherall
*/
public class BlogDetails implements BlogIntegrationModel
{
/** Node that has the blog details aspect applied */
private NodeRef nodeRef;
/** The blog implementation name (eg: wordpress, typepad, etc) */
private String implementationName;
/** The blog id */
private String blogId;
/** The blog URL */
private String url;
/** The user name */
private String userName;
/** The password */
private String password;
/** The display name of the blog */
private String name;
/** The description of the blog */
private String description;
/**
* Create a BlogDetails object from a node that has the blogDetails aspect applied.
*
* @param nodeService the node service
* @param nodeRef the node reference
* @return BlogDetails the blog details
*/
public static BlogDetails createBlogDetails(NodeService nodeService, NodeRef nodeRef)
{
// Check for the blog details aspect
if (nodeService.hasAspect(nodeRef, ASPECT_BLOG_DETAILS) == false)
{
throw new BlogIntegrationRuntimeException("Can not create blog details object since node does not have blogDetails aspect.");
}
// Get the blog details
Map<QName, Serializable> props = nodeService.getProperties(nodeRef);
return new BlogDetails(
(String)props.get(PROP_BLOG_IMPLEMENTATION),
(String)props.get(PROP_ID),
(String)props.get(PROP_URL),
(String)props.get(PROP_USER_NAME),
(String)props.get(PROP_PASSWORD),
(String)props.get(PROP_NAME),
(String)props.get(PROP_DESCRIPTION),
nodeRef);
}
/**
* Constructor
*
* @param implementationName the implementation name
* @param blogId the blog id
* @param url the blog URL
* @param userName the user name
* @param password the password
* @param name the name
* @param description the description
*/
public BlogDetails(String implementationName, String blogId, String url, String userName, String password, String name, String description)
{
this(implementationName, blogId, url, userName, password, name, description, null);
}
/**
* Constructor
*
* @param implementationName the implementation name
* @param blogId the blog id
* @param url the blog URL
* @param userName the user name
* @param password the password
* @param name the name
* @param description the description
* @param nodeRef the node reference
*/
public BlogDetails(String implementationName, String blogId, String url, String userName, String password, String name, String description, NodeRef nodeRef)
{
this.implementationName = implementationName;
this.blogId = blogId;
this.url = url;
this.userName = userName;
this.password = password;
this.name = name;
this.description = description;
this.nodeRef = nodeRef;
}
/**
* Gets the node reference
*
* @return NodeRef the node reference
*/
public NodeRef getNodeRef()
{
return nodeRef;
}
/**
* Get the implementation name
*
* @return String the implementation name
*/
public String getImplementationName()
{
return this.implementationName;
}
/**
* Get the blog id
*
* @return String the blog id
*/
public String getBlogId()
{
return this.blogId;
}
/**
* Get the blog URL
*
* @return String the blog URL
*/
public String getUrl()
{
return this.url;
}
/**
* Get the user name
*
* @return String the user name
*/
public String getUserName()
{
return this.userName;
}
/**
* Get the password
*
* @return String the password
*/
public String getPassword()
{
return this.password;
}
/**
* Get the name
*
* @return String the name
*/
public String getName()
{
return name;
}
/**
* Get the description
*
* @return String the description
*/
public String getDescription()
{
return description;
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration;
import java.util.Map;
/**
* Blog integration implementation interface
*
* @author Roy Wetherall
*/
public interface BlogIntegrationImplementation
{
/**
* Gets the name of the blog integration
*
* @return String the name of the blog integration
*/
String getName();
/**
* Gets the display name of the blog integration
*
* @return String the display name of the blog integration
*/
String getDisplayName();
/**
* Create a new post on the blog.
*
* @param blogDetails the blog details
* @param title the title of the post
* @param body the body of the post
* @param publish indicates whether the post is published or not
* @return String the newly created post id
*/
String newPost(BlogDetails blogDetails, String title, String body, boolean publish);
/**
* Update an exisiting blog post
*
* @param blogDetails
* @param postId
* @param title
* @param body
* @param publish
* @return
*/
boolean updatePost(BlogDetails blogDetails, String postId, String title, String body, boolean publish);
/**
* Get the details of an existing blog post
*
* @param blogDetails
* @param postId
* @return
*/
Map<String, Object> getPost(BlogDetails blogDetails, String postId);
/**
* Delete an existing blog post
*
* @param blogDetails
* @param postId
* @return
*/
boolean deletePost(BlogDetails blogDetails, String postId);
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* Blog integration runtime exception
*
* @author Roy Wetherall
*/
public class BlogIntegrationRuntimeException extends AlfrescoRuntimeException
{
private static final long serialVersionUID = -159901552962025003L;
/**
* Constructor
*
* @param msgId
*/
public BlogIntegrationRuntimeException(String msgId)
{
super(msgId);
}
/**
* Constructor
*
* @param msgId
* @param msgParams
*/
public BlogIntegrationRuntimeException(String msgId, Object[] msgParams)
{
super(msgId, msgParams);
}
/**
* Constructor
*
* @param msgId
* @param cause
*/
public BlogIntegrationRuntimeException(String msgId, Throwable cause)
{
super(msgId, cause);
}
/**
* Constructor
*
* @param msgId
* @param msgParams
* @param cause
*/
public BlogIntegrationRuntimeException(String msgId, Object[] msgParams, Throwable cause)
{
super(msgId, msgParams, cause);
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration;
import java.util.List;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* Blog integration service.
*
* @author Roy Wetherall
*
*/
public interface BlogIntegrationService
{
/**
* Register a new blog integration implementation with the service
*
* @param implementation the implementation
*/
void register(BlogIntegrationImplementation implementation);
/**
* Get the named blog integration implementation, null if name not recognised
*
* @param implementationName the implementation name
* @return BlogIntegrationImplementation the blog integration implementation
*/
BlogIntegrationImplementation getBlogIntegrationImplementation(String implementationName);
/**
* Get a list of the registered integration implementations.
*
* @return List<BlogIntegrationImplementaion> list of registered blog integration implementations
*/
List<BlogIntegrationImplementation> getBlogIntegrationImplementations();
/**
* Given a node reference, gets a list of 'in scope' BlogDetails.
*
* The node itself and then the primary parent hierarchy is searched and any blog details found returned in
* a list, with the 'nearest' first.
*
* @param nodeRef the node reference
* @return List<BlogDetails> list of the blog details found 'in scope' for the node, empty if none found
*/
List<BlogDetails> getBlogDetails(NodeRef nodeRef);
/**
* Posts the content of a node to the blog specified
*
* @param blogDetails
* @param nodeRef
* @param contentProperty
* @param publish
*/
void newPost(BlogDetails blogDetails, NodeRef nodeRef, QName contentProperty, boolean publish);
/**
*
* @param postId
* @param nodeRef
* @param contentProperty
* @param publish
*/
void updatePost(NodeRef nodeRef, QName contentProperty, boolean publish);
/**
*
* @param postId
* @param nodeRef
*/
void deletePost(NodeRef nodeRef);
}

View File

@ -0,0 +1,375 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.BlogIntegrationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.AssociationRef;
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.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Blog integration service implementation
*
* @author Roy Wetherall
*/
public class BlogIntegrationServiceImpl implements BlogIntegrationService, BlogIntegrationModel
{
/** Node service */
private NodeService nodeService;
/** Content service */
private ContentService contentService;
/** Registered blog integration implemenatations */
private Map<String, BlogIntegrationImplementation> implementations = new HashMap<String, BlogIntegrationImplementation>(5);
/** Supported mimetypes */
public static List<String> supportedMimetypes = new ArrayList<String>(5);
/** Static initialisation of supported mimetypes */
static
{
supportedMimetypes.add(MimetypeMap.MIMETYPE_TEXT_PLAIN);
supportedMimetypes.add(MimetypeMap.MIMETYPE_HTML);
}
/**
* Set the node service
*
* @param nodeService the node service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Set the content service
*
* @param contentService the content service
*/
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationService#register(org.alfresco.module.blogIntegration.BlogIntegrationImplementation)
*/
public void register(BlogIntegrationImplementation implementation)
{
if (this.implementations.containsKey(implementation.getName()) == true)
{
throw new BlogIntegrationRuntimeException("A blog implementation with name '" + implementation.getName() + "' has already been registered.");
}
this.implementations.put(implementation.getName(), implementation);
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationService#getBlogIntegrationImplementation(java.lang.String)
*/
public BlogIntegrationImplementation getBlogIntegrationImplementation(String implementationName)
{
return this.implementations.get(implementationName);
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationService#getBlogIntegrationImplementations()
*/
public List<BlogIntegrationImplementation> getBlogIntegrationImplementations()
{
return new ArrayList<BlogIntegrationImplementation>(this.implementations.values());
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationService#getBlogDetails(org.alfresco.service.cmr.repository.NodeRef)
*/
public List<BlogDetails> getBlogDetails(NodeRef nodeRef)
{
List<BlogDetails> result = new ArrayList<BlogDetails>(5);
// First check the node itself
if (this.nodeService.hasAspect(nodeRef, ASPECT_BLOG_DETAILS) == true)
{
result.add(BlogDetails.createBlogDetails(this.nodeService, nodeRef));
}
// Now walk up the parent hiearchy adding details as they are found
getBlogDetailsImpl(nodeRef, result);
return result;
}
/**
* Helper method that recurses up the primary parent hierarchy checking for
* blog details
*
* @param nodeRef the node reference
* @param blogDetails list of blog details
*/
private void getBlogDetailsImpl(NodeRef nodeRef, List<BlogDetails> blogDetails)
{
// Check the parent assoc
ChildAssociationRef parentAssoc = this.nodeService.getPrimaryParent(nodeRef);
if (parentAssoc != null)
{
// Check for the blog details
NodeRef parent = parentAssoc.getParentRef();
if (parent != null)
{
if (this.nodeService.hasAspect(parent, ASPECT_BLOG_DETAILS) == true)
{
blogDetails.add(BlogDetails.createBlogDetails(this.nodeService, parent));
}
// Recurse
getBlogDetailsImpl(parent, blogDetails);
}
}
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationService#newPost(org.alfresco.module.blogIntegration.BlogDetails, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, boolean)
*/
public void newPost(BlogDetails blogDetails, NodeRef nodeRef, QName contentProperty, boolean publish)
{
// Get the blog implementation
BlogIntegrationImplementation implementation = getImplementation(blogDetails.getImplementationName());
// Check that this node has not already been posted to a blog
if (this.nodeService.hasAspect(nodeRef, ASPECT_BLOG_POST) == true)
{
throw new BlogIntegrationRuntimeException("Can not create new blog post since this conten has already been posted to a blog.");
}
// Get the posts body
ContentReader contentReader = this.contentService.getReader(nodeRef, contentProperty);
if (contentReader == null)
{
throw new BlogIntegrationRuntimeException("No content found for new blog entry.");
}
// Check the mimetype
String body = null;
if (supportedMimetypes.contains(contentReader.getMimetype()) == true)
{
// Get the content
body = contentReader.getContentString();
}
else
{
throw new BlogIntegrationRuntimeException("The content mimetype '" + contentReader.getMimetype() + "' is not supported.");
}
// Get the posts title
String title = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE);
if (title == null || title.length() == 0)
{
if (body.length() > 23)
{
// Get the title from the first 22 character plus ' ...'
title = body.substring(0, 23) + " ...";
}
else
{
title = body;
}
}
// Post the new blog entry
String postId = implementation.newPost(blogDetails, title, body, true);
// Get the blog details node if the is one
NodeRef blogDetailsNodeRef = blogDetails.getNodeRef();
if (blogDetailsNodeRef != null)
{
// Now get the details of the newly created post
Map<String, Object> details = implementation.getPost(blogDetails, postId);
String link = (String)details.get("link");
// Add the details of the new post to the node
Map<QName, Serializable> props = new HashMap<QName, Serializable>(5);
props.put(PROP_POST_ID, postId);
if (link != null)
{
props.put(PROP_LINK, link);
}
Date now = new Date();
props.put(PROP_POSTED, now);
props.put(PROP_LAST_UPDATE, now);
props.put(PROP_PUBLISHED, Boolean.valueOf(publish));
this.nodeService.addAspect(nodeRef, ASPECT_BLOG_POST, props);
// Associate to the blog details
this.nodeService.createAssociation(nodeRef, blogDetailsNodeRef, ASSOC_BLOG_DETAILS);
}
}
/**
* Gets the blog implementation based on its name
*
* @param implementationName the implementation name
* @return BlogIntegrationImplementation the blog integration
*/
private BlogIntegrationImplementation getImplementation(String implementationName)
{
if (this.implementations.containsKey(implementationName) == false)
{
throw new BlogIntegrationRuntimeException("There is no blog implementation present for '" + implementationName + "'");
}
return this.implementations.get(implementationName);
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationService#updatePost(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, boolean)
*/
public void updatePost(NodeRef nodeRef, QName contentProperty, boolean publish)
{
// Get the blog details and post id
BlogDetails blogDetails = null;
String postId = null;
if (this.nodeService.hasAspect(nodeRef, ASPECT_BLOG_POST) == true)
{
List<AssociationRef> assocs = this.nodeService.getTargetAssocs(nodeRef, ASSOC_BLOG_DETAILS);
if (assocs.size() == 0)
{
throw new BlogIntegrationRuntimeException("Can not resolve blog details for update because blogDetails association is not populated.");
}
else
{
blogDetails = BlogDetails.createBlogDetails(this.nodeService, assocs.get(0).getTargetRef());
postId = (String)this.nodeService.getProperty(nodeRef, PROP_POST_ID);
}
}
else
{
throw new BlogIntegrationRuntimeException("Can not update blog post as this node has not been previously posted to a blog.");
}
// Get the blog implementation
BlogIntegrationImplementation implementation = getImplementation(blogDetails.getImplementationName());
// Get the posts title
String title = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE);
if (title == null || title.length() == 0)
{
throw new BlogIntegrationRuntimeException("No title available for update blog post. Set the title property and re-try.");
}
// Get the posts body
ContentReader contentReader = this.contentService.getReader(nodeRef, contentProperty);
if (contentReader == null)
{
throw new BlogIntegrationRuntimeException("No content found for update blog entry.");
}
// Check the mimetype
String body = null;
if (supportedMimetypes.contains(contentReader.getMimetype()) == true)
{
// Get the content
body = contentReader.getContentString();
}
else
{
throw new BlogIntegrationRuntimeException("The content mimetype '" + contentReader.getMimetype() + "' is not supported.");
}
// Update the blog post
boolean result = implementation.updatePost(blogDetails, postId, title, body, publish);
// Check the return result
if (result == false)
{
throw new BlogIntegrationRuntimeException("The update of the post unexpectedly failed. Check your blog for more information.");
}
// Now get the details of the newly created post
Map<String, Object> details = implementation.getPost(blogDetails, postId);
String link = (String)details.get("link");
// Update the post details accordingly
Map<QName, Serializable> props = this.nodeService.getProperties(nodeRef);
Date now = new Date();
props.put(PROP_LAST_UPDATE, now);
props.put(PROP_PUBLISHED, Boolean.valueOf(publish));
props.put(PROP_LINK, link);
this.nodeService.setProperties(nodeRef, props);
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationService#deletePost(org.alfresco.service.cmr.repository.NodeRef)
*/
public void deletePost(NodeRef nodeRef)
{
// Get the blog details and post id
BlogDetails blogDetails = null;
String postId = null;
if (this.nodeService.hasAspect(nodeRef, ASPECT_BLOG_POST) == true)
{
List<AssociationRef> assocs = this.nodeService.getTargetAssocs(nodeRef, ASSOC_BLOG_DETAILS);
if (assocs.size() == 0)
{
throw new BlogIntegrationRuntimeException("Can not resolve blog details for delete because blogDetails association is not populated.");
}
else
{
blogDetails = BlogDetails.createBlogDetails(this.nodeService, assocs.get(0).getTargetRef());
postId = (String)this.nodeService.getProperty(nodeRef, PROP_POST_ID);
}
}
else
{
throw new BlogIntegrationRuntimeException("Can not delete blog post as this node has not been previously posted to a blog.");
}
// Get the blog implementation
BlogIntegrationImplementation implementation = getImplementation(blogDetails.getImplementationName());
// Delete the post
boolean result = implementation.deletePost(blogDetails, postId);
// Check the return result
if (result == false)
{
throw new BlogIntegrationRuntimeException("Deleting the post unexpectedly failed. Check your blog for more information.");
}
// Remove the postDetails aspect from the node
this.nodeService.removeAspect(nodeRef, ASPECT_BLOG_POST);
}
}

View File

@ -0,0 +1,259 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.BlogIntegrationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseAlfrescoSpringTest;
/**
* @author Roy Wetherall
*/
public class BlogIntegrationServiceSystemTest extends BaseAlfrescoSpringTest implements BlogIntegrationModel
{
/**
* Wordpress details
*
* http://paulhh.wordpress.com/xmlrpc.php
* paulhh
* 114eb1
*/
/**
* Typepad details
*
* http://www.typepad.com/t/api
* http://rwetherall.typepad.com/my_test_blog
* 1340792
* rwetherall
*
*/
/** Blog Details **/
private static final String BLOG = "wordpress";
private static final String BLOG_URL = "http://paulhh.wordpress.com";
private static final String BLOG_USER = "paulhh";
private static final String BLOG_PWD = "114eb1";
private static final String BLOG_ID = "0";
private static final String BLOG_NAME = "Test blog details";
private static final String BLOG_DESCRIPTION = "These are the details used to test the blog integration service";
/** Blog entry */
private static final String TITLE = "My Test Post @ " + new Date().toString();
//private static final String TITLE = "";
private static final String MODIFIED_TITLE = "My Test Post Modified @ " + new Date().toString();
private static final String DESCRIPTION = "This is a description of my test post.";
private static final String POST_CONTENT = "Hello and welcome to my test post. This has been posted from the blog integration system test @ " + new Date().toString();
private static final String MODIFIED_POST_CONTENT = "Hello and welcome to my MODIFIED test post. This has been posted and MODIFIED from the blog integration system test @ " + new Date().toString();
private static final boolean PUBLISH = true;
private NodeService nodeService;
private ContentService contentService;
private SearchService searchService;
private BlogIntegrationService blogService;
private NodeRef nodeRef;
private NodeRef blogDetailsNodeRef;
@Override
protected void onSetUpInTransaction()
throws Exception
{
super.onSetUpInTransaction();
// Get references to the relevant services
this.nodeService = (NodeService)this.applicationContext.getBean("nodeService");
this.contentService = (ContentService)this.applicationContext.getBean("contentService");
this.searchService = (SearchService)this.applicationContext.getBean("searchService");
this.blogService = (BlogIntegrationService)this.applicationContext.getBean("blogIntegrationService");
// Get a reference to the company home node
ResultSet results1 = this.searchService.query(
new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"),
SearchService.LANGUAGE_XPATH,
"app:company_home");
NodeRef companyHome = results1.getNodeRefs().get(0);
// Create the blog details node
this.blogDetailsNodeRef = this.nodeService.createNode(
companyHome,
ContentModel.ASSOC_CHILDREN,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testFolder"),
ContentModel.TYPE_FOLDER).getChildRef();
this.nodeService.setProperty(this.blogDetailsNodeRef, ContentModel.PROP_NAME, "testFolder");
Map<QName, Serializable> props2 = new HashMap<QName, Serializable>(5);
props2.put(PROP_BLOG_IMPLEMENTATION, BLOG);
props2.put(PROP_ID, BLOG_ID);
props2.put(PROP_NAME, BLOG_NAME);
props2.put(PROP_DESCRIPTION, BLOG_DESCRIPTION);
props2.put(PROP_URL, BLOG_URL);
props2.put(PROP_USER_NAME, BLOG_USER);
props2.put(PROP_PASSWORD, BLOG_PWD);
this.nodeService.addAspect(this.blogDetailsNodeRef, ASPECT_BLOG_DETAILS, props2);
// Create the content node
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_NAME, "myBlogEntry.txt");
this.nodeRef = this.nodeService.createNode(
this.blogDetailsNodeRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myBlogEntry.txt"),
ContentModel.TYPE_CONTENT,
props).getChildRef();
// Add the titled aspect
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(2);
titledProps.put(ContentModel.PROP_TITLE, TITLE);
titledProps.put(ContentModel.PROP_DESCRIPTION, DESCRIPTION);
this.nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_TITLED, titledProps);
// Add some content
ContentWriter contentWriter = this.contentService.getWriter(this.nodeRef, ContentModel.PROP_CONTENT, true);
contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
contentWriter.setEncoding("UTF-8");
contentWriter.putContent(POST_CONTENT);
}
public void testGetBlogIntegrationImplementations()
{
List<BlogIntegrationImplementation> list = this.blogService.getBlogIntegrationImplementations();
assertNotNull(list);
assertEquals(2, list.size());
BlogIntegrationImplementation blog = this.blogService.getBlogIntegrationImplementation(BLOG);
assertNotNull(blog);
assertEquals(BLOG, blog.getName());
}
public void testGetBlogDetails()
{
List<BlogDetails> details = this.blogService.getBlogDetails(this.nodeRef);
assertNotNull(details);
assertEquals(1, details.size());
assertEquals(BLOG_URL, details.get(0).getUrl());
List<BlogDetails> details2 = this.blogService.getBlogDetails(this.blogDetailsNodeRef);
assertNotNull(details2);
assertEquals(1, details2.size());
assertEquals(BLOG_URL, details2.get(0).getUrl());
}
public void testNewPost()
{
// Create the blog details
BlogDetails blogDetails = BlogDetails.createBlogDetails(this.nodeService, this.blogDetailsNodeRef);
// Do a quick check on the blog details
assertEquals(this.blogDetailsNodeRef, blogDetails.getNodeRef());
assertEquals(BLOG, blogDetails.getImplementationName());
assertEquals(BLOG_ID, blogDetails.getBlogId());
assertEquals(BLOG_NAME, blogDetails.getName());
assertEquals(BLOG_DESCRIPTION, blogDetails.getDescription());
assertEquals(BLOG_URL, blogDetails.getUrl());
assertEquals(BLOG_USER, blogDetails.getUserName());
assertEquals(BLOG_PWD, blogDetails.getPassword());
// Post and publish the content contained on the node
this.blogService.newPost(blogDetails, this.nodeRef, ContentModel.PROP_CONTENT, PUBLISH);
// Check the details of the node after the post
assertTrue(this.nodeService.hasAspect(this.nodeRef, ASPECT_BLOG_POST));
assertNotNull(this.nodeService.getProperty(this.nodeRef, PROP_POST_ID));
System.out.println("The newly create post has id " + this.nodeService.getProperty(this.nodeRef, PROP_POST_ID));
List<AssociationRef> assocs = this.nodeService.getTargetAssocs(this.nodeRef, ASSOC_BLOG_DETAILS);
assertEquals(1, assocs.size());
NodeRef testRef = assocs.get(0).getTargetRef();
assertEquals(blogDetailsNodeRef, testRef);
// TODO check the other stuff
// Check that im not allowed to create another new post with the same node
try
{
this.blogService.newPost(blogDetails, this.nodeRef, ContentModel.PROP_CONTENT, PUBLISH);
}
catch (BlogIntegrationRuntimeException e)
{
// Expected
}
// Edit the title and content
this.nodeService.setProperty(this.nodeRef, ContentModel.PROP_TITLE, MODIFIED_TITLE);
}
public void testUpdatePost()
{
// Create the blog details
BlogDetails blogDetails = BlogDetails.createBlogDetails(this.nodeService, this.blogDetailsNodeRef);
// Post and publish the content contained on the node
this.blogService.newPost(blogDetails, this.nodeRef, ContentModel.PROP_CONTENT, PUBLISH);
// Edit the title and content of the node
this.nodeService.setProperty(this.nodeRef, ContentModel.PROP_TITLE, MODIFIED_TITLE);
ContentWriter contentWriter = this.contentService.getWriter(this.nodeRef, ContentModel.PROP_CONTENT, true);
contentWriter.putContent(MODIFIED_POST_CONTENT);
// Update the post
this.blogService.updatePost(this.nodeRef, ContentModel.PROP_CONTENT, PUBLISH);
// Check the updated meta-data .... TODO
}
public void testDeletePost()
{
// Create the blog details
BlogDetails blogDetails = BlogDetails.createBlogDetails(this.nodeService, this.blogDetailsNodeRef);
// Post and publish the content contained on the node
this.blogService.newPost(blogDetails, this.nodeRef, ContentModel.PROP_CONTENT, PUBLISH);
// Delete the post
this.blogService.deletePost(this.nodeRef);
// Check the aspect has bee removed from the node
assertFalse(this.nodeService.hasAspect(this.nodeRef, ASPECT_BLOG_POST));
}
}

View File

@ -0,0 +1,232 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import marquee.xmlrpc.XmlRpcClient;
import marquee.xmlrpc.XmlRpcException;
import marquee.xmlrpc.XmlRpcParser;
import marquee.xmlrpc.XmlRpcSerializer;
import marquee.xmlrpc.serializers.HashtableSerializer;
/**
* Default blog integration implementation. Uses various standard XML PRC blogging API to satisfy the
* blog integration implementation interface.
*
* Based on origional contribution by Sudhakar Selvaraj.
*
* @author Roy Wetherall
*/
public abstract class DefaultBlogIntegrationImplementation extends BaseBlogIntegrationImplementation
{
/** Blog actions */
protected static final String ACTION_NEW_POST = "metaWeblog.newPost";
protected static final String ACTION_EDIT_POST = "metaWeblog.editPost";
protected static final String ACTION_GET_POST = "metaWeblog.getPost";
protected static final String ACTION_DELETE_POST = "blogger.deletePost";
/**
* Gets the XML RPC end point URL for the given blog details.
*
* @param blogDetails blog details
* @return String the end point URL
*/
protected abstract String getEndpointURL(BlogDetails blogDetails);
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationImplementation#newPost(org.alfresco.module.blogIntegration.BlogDetails, java.lang.String, java.lang.String, boolean)
*/
public String newPost(BlogDetails blogDetails, String title, String body, boolean publish)
{
// Create the hash table containing details of the post's content
Hashtable<String, Object> content = new Hashtable<String, Object>();
content.put("title", title);
content.put("description", body);
// Create a list of parameters
List<Object> params = new ArrayList<Object>(5);
params.add(blogDetails.getBlogId());
params.add(blogDetails.getUserName());
params.add(blogDetails.getPassword());
params.add(content);
params.add(publish);
// Create the new post
return (String)execute(getEndpointURL(blogDetails), ACTION_NEW_POST, params);
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationImplementation#updatePost(org.alfresco.module.blogIntegration.BlogDetails, java.lang.String, java.lang.String, java.lang.String, boolean)
*/
public boolean updatePost(BlogDetails blogDetails, String postId, String title, String body, boolean publish)
{
// Create the hash table containing details of the post's content
Hashtable<String, Object> content = new Hashtable<String, Object>();
content.put("title", title);
content.put("description", body);
// Create a list of parameters
List<Object> params = new ArrayList<Object>(5);
params.add(postId);
params.add(blogDetails.getUserName());
params.add(blogDetails.getPassword());
params.add(content);
params.add(publish);
// Create the new post
Object result = execute(getEndpointURL(blogDetails), ACTION_EDIT_POST, params);
if (result.getClass().equals(Boolean.class))
{
return ((Boolean)result).booleanValue();
}
return false;
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationImplementation#getPost(org.alfresco.module.blogIntegration.BlogDetails, java.lang.String)
*/
@SuppressWarnings("unchecked")
public Map<String, Object> getPost(BlogDetails blogDetails, String postId)
{
// Create a list of parameters
List<Object> params = new ArrayList<Object>(3);
params.add(postId);
params.add(blogDetails.getUserName());
params.add(blogDetails.getPassword());
// Get the post details
return (Map<String, Object>)execute(getEndpointURL(blogDetails), ACTION_GET_POST, params);
}
/**
* @see org.alfresco.module.blogIntegration.BlogIntegrationImplementation#deletePost(org.alfresco.module.blogIntegration.BlogDetails, java.lang.String)
*/
public boolean deletePost(BlogDetails blogDetails, String postId)
{
// Create a list of parameters
List<Object> params = new ArrayList<Object>(5);
// Use the blog id for the app key
params.add(blogDetails.getBlogId());
params.add(postId);
params.add(blogDetails.getUserName());
params.add(blogDetails.getPassword());
params.add(true);
// Delete post
Object result = execute(getEndpointURL(blogDetails), ACTION_DELETE_POST, params);
if (result.getClass().equals(Boolean.class))
{
return ((Boolean)result).booleanValue();
}
return false;
}
/**
* Helper method to get the XML RPC client
*
* @param url
* @return
*/
private XmlRpcClient getClient(String url)
{
XmlRpcClient client = null;
try
{
XmlRpcSerializer.registerCustomSerializer(new HashtableSerializer());
XmlRpcParser.setDriver("org.apache.xerces.parsers.SAXParser");
client = new XmlRpcClient(new URL(url));
}
catch (MalformedURLException exception)
{
throw new BlogIntegrationRuntimeException("Blog url '" + url + "' is invalid.", exception);
}
return client;
}
/**
* Executes an XML RPC method
*
* @param url
* @param method
* @param params
* @return
*/
protected Object execute(String url, String method, List<Object> params)
{
Object result = null;
try
{
XmlRpcClient client = getClient(url);
result = client.invoke(method, params);
}
catch (XmlRpcException exception)
{
throw new BlogIntegrationRuntimeException("Failed to execute blog action '" + method + "' @ url '" + url + "'", exception);
}
return result;
}
/**
* Checks a url for a protocol and adds http if none present
*
* @param url the url
* @return String the checked url
*/
protected String checkForProtocol(String url)
{
if (url.indexOf("://") == -1)
{
url = "http://" + url;
}
return url;
}
/**
* Checks the url for a trailing slash and adds one if none present
*
* @param url the url
* @return String the checked url
*/
protected String checkForTrainlingSlash(String url)
{
if (url.endsWith("/") == false)
{
url = url + "/";
}
return url;
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration.typepad;
import org.alfresco.repo.blogIntegration.BlogDetails;
import org.alfresco.repo.blogIntegration.DefaultBlogIntegrationImplementation;
/**
* Typepad integration implementation
*
* @author Roy Wetherall
*/
public class TypepadIntegration extends DefaultBlogIntegrationImplementation
{
/**
* @see org.alfresco.module.blogIntegration.DefaultBlogIntegrationImplementation#getEndpointURL(org.alfresco.module.blogIntegration.BlogDetails)
*/
@Override
protected String getEndpointURL(BlogDetails blogDetails)
{
return "http://www.typepad.com/t/api";
}
/**
* For some reason typepad returns a hash table rather than the expected boolean result.
*
* @see org.alfresco.module.blogIntegration.BlogIntegrationImplementation#deletePost(org.alfresco.module.blogIntegration.BlogDetails, java.lang.String)
*/
@Override
public boolean deletePost(BlogDetails blogDetails, String postId)
{
// NOTE: At the time of testing typepad.com failed when making this call, for now the implementation is
// being overriden to return success
return true;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.blogIntegration.wordpress;
import org.alfresco.repo.blogIntegration.BlogDetails;
import org.alfresco.repo.blogIntegration.DefaultBlogIntegrationImplementation;
/**
* @author Roy Wetherall
*/
public class WordPressIntegration extends DefaultBlogIntegrationImplementation
{
private static String ENDPOINT = "xmlrpc.php";
/**
* @see org.alfresco.module.blogIntegration.DefaultBlogIntegrationImplementation#getEndpointURL(org.alfresco.module.blogIntegration.BlogDetails)
*/
@Override
protected String getEndpointURL(BlogDetails blogDetails)
{
String endpoint = checkForProtocol(blogDetails.getUrl());
return checkForTrainlingSlash(endpoint) + ENDPOINT;
}
}