/* ===============================================================================
*
* Part of the InfoGlue Content Management Platform (www.infoglue.org)
*
* ===============================================================================
*
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2, as published by the
* Free Software Foundation. See the file LICENSE.html for more information.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, including 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. / 59 Temple
* Place, Suite 330 / Boston, MA 02111-1307 / USA.
*
* ===============================================================================
*/
package org.infoglue.cms.webservices;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.exolab.castor.jdo.Database;
import org.infoglue.cms.controllers.kernel.impl.simple.AccessRightController;
import org.infoglue.cms.controllers.kernel.impl.simple.CastorDatabaseService;
import org.infoglue.cms.controllers.kernel.impl.simple.CategoryController;
import org.infoglue.cms.controllers.kernel.impl.simple.ContentCategoryController;
import org.infoglue.cms.controllers.kernel.impl.simple.ContentController;
import org.infoglue.cms.controllers.kernel.impl.simple.ContentControllerProxy;
import org.infoglue.cms.controllers.kernel.impl.simple.ContentStateController;
import org.infoglue.cms.controllers.kernel.impl.simple.ContentVersionController;
import org.infoglue.cms.controllers.kernel.impl.simple.ContentVersionControllerProxy;
import org.infoglue.cms.controllers.kernel.impl.simple.DigitalAssetController;
import org.infoglue.cms.controllers.kernel.impl.simple.EventController;
import org.infoglue.cms.controllers.kernel.impl.simple.InterceptionPointController;
import org.infoglue.cms.controllers.kernel.impl.simple.PublicationController;
import org.infoglue.cms.controllers.kernel.impl.simple.ServerNodeController;
import org.infoglue.cms.controllers.kernel.impl.simple.UserControllerProxy;
import org.infoglue.cms.entities.content.Content;
import org.infoglue.cms.entities.content.ContentVO;
import org.infoglue.cms.entities.content.ContentVersion;
import org.infoglue.cms.entities.content.ContentVersionVO;
import org.infoglue.cms.entities.content.DigitalAssetVO;
import org.infoglue.cms.entities.management.AccessRight;
import org.infoglue.cms.entities.management.AccessRightGroup;
import org.infoglue.cms.entities.management.AccessRightGroupVO;
import org.infoglue.cms.entities.management.AccessRightRole;
import org.infoglue.cms.entities.management.AccessRightRoleVO;
import org.infoglue.cms.entities.management.AccessRightUser;
import org.infoglue.cms.entities.management.AccessRightUserVO;
import org.infoglue.cms.entities.management.AccessRightVO;
import org.infoglue.cms.entities.management.Category;
import org.infoglue.cms.entities.management.CategoryVO;
import org.infoglue.cms.entities.management.InterceptionPoint;
import org.infoglue.cms.entities.publishing.PublicationVO;
import org.infoglue.cms.entities.workflow.EventVO;
import org.infoglue.cms.exception.SystemException;
import org.infoglue.cms.security.InfoGluePrincipal;
import org.infoglue.cms.util.dom.DOMBuilder;
import org.infoglue.cms.webservices.elements.CreatedEntityBean;
import org.infoglue.cms.webservices.elements.RemoteAttachment;
import org.infoglue.cms.webservices.elements.StatusBean;
import org.infoglue.deliver.util.webservices.DynamicWebserviceSerializer;
/**
* This class is responsible for letting an external application call InfoGlue
* API:s remotely. It handles api:s to manage contents and associated entities.
*
* @author Mattias Bogeblad
*/
public class RemoteContentServiceImpl extends RemoteInfoGlueService
{
private final static Logger logger = Logger.getLogger(RemoteContentServiceImpl.class.getName());
/**
* The principal executing the workflow.
*/
private InfoGluePrincipal principal;
private static ContentControllerProxy contentControllerProxy = ContentControllerProxy.getController();
private static ContentVersionControllerProxy contentVersionControllerProxy = ContentVersionControllerProxy.getController();
/**
* Gets a content version from the cms. Very useful for getting the latest working version.
*/
public ContentVersionVO getContentVersion(final String principalName, final Object[] inputsArray)
{
if(!ServerNodeController.getController().getIsIPAllowed(getRequest()))
{
logger.error("A client with IP " + getRequest().getRemoteAddr() + " was denied access to the webservice. Could be a hack attempt or you have just not configured the allowed IP-addresses correct.");
return null;
}
if(logger.isInfoEnabled())
{
logger.info("**************************************");
logger.info("* Getting content through webservice *");
logger.info("**************************************");
}
ContentVersionVO contentVersionVO = null;
try
{
final DynamicWebserviceSerializer serializer = new DynamicWebserviceSerializer();
@SuppressWarnings("unchecked")
Map<String, Object> args = (Map<String, Object>) serializer.deserialize(inputsArray);
logger.info("args:" + args);
Integer contentId = (Integer)args.get("contentId");
Integer languageId = (Integer)args.get("languageId");
if(logger.isInfoEnabled())
{
logger.info("principalName:" + principalName);
logger.info("contentId:" + contentId);
logger.info("languageId:" + languageId);
}
initializePrincipal(principalName);
contentVersionVO = contentVersionControllerProxy.getACLatestActiveContentVersionVO(this.principal, contentId, languageId);
}
catch(Throwable t)
{
logger.error("En error occurred when we tried to get the contentVersionVO:" + t.getMessage());
logger.warn("En error occurred when we tried to get the contentVersionVO:" + t.getMessage(), t);
}
return contentVersionVO;
}
/**
* Inserts a new Content including versions etc.
*/
public int createContent(final String principalName, ContentVO contentVO, int parentContentId, int contentTypeDefinitionId, int repositoryId)
{
if(!ServerNodeController.getController().getIsIPAllowed(getRequest()))
{
logger.error("A client with IP " + getRequest().getRemoteAddr() + " was denied access to the webservice. Could be a hack attempt or you have just not configured the allowed IP-addresses correct.");
return -1;
}
int newContentId = 0;
logger.info("***************************************");
logger.info("Creating content through webservice....");
logger.info("***************************************");
logger.info("parentContentId:" + parentContentId);
logger.info("contentTypeDefinitionId:" + contentTypeDefinitionId);
logger.info("repositoryId:" + repositoryId);
try
{
initializePrincipal(principalName);
ContentVO newContentVO = contentControllerProxy.acCreate(this.principal, new Integer(parentContentId), new Integer(contentTypeDefinitionId), new Integer(repositoryId), contentVO);
newContentId = newContentVO.getId().intValue();
}
catch(Exception e)
{
logger.error("En error occurred when we tried to create a new content:" + e.getMessage(), e);
}
updateCaches();
return newContentId;
}
/**
* Inserts a new ContentVersion.
*/
public int createContentVersion(final String principalName, ContentVersionVO contentVersionVO, int contentId, int languageId)
{
if(!ServerNodeController.getController().getIsIPAllowed(getRequest()))
{
logger.error("A client with IP " + getRequest().getRemoteAddr() + " was denied access to the webservice. Could be a hack attempt or you have just not configured the allowed IP-addresses correct.");
return -1;
}
int newContentVersionId = 0;
logger.info("***************************************");
logger.info("Creating content through webservice....");
logger.info("***************************************");
try
{
initializePrincipal(principalName);
ContentVersionVO newContentVersionVO = contentVersionControllerProxy.acCreate(this.principal, new Integer(contentId), new Integer(languageId), contentVersionVO);
newContentVersionId = newContentVersionVO.getId().intValue();
}
catch(Exception e)
{
logger.error("En error occurred when we tried to create a new contentVersion:" + e.getMessage());
logger.warn("En error occurred when we tried to create a new contentVersion:" + e.getMessage(), e);
}
updateCaches();
return newContentVersionId;
}
/**
* Inserts a new Content including versions etc.
*/
public StatusBean createContents(final String principalName, final Object[] inputsArray/*List contents*/)
{
if(!ServerNodeController.getController().getIsIPAllowed(getRequest()))
{
logger.error("A client with IP " + getRequest().getRemoteAddr() + " was denied access to the webservice. Could be a hack attempt or you have just not configured the allowed IP-addresses correct.");
return new StatusBean(false, "You are not allowed to talk to this service");
}
StatusBean statusBean = new StatusBean(true, "ok");
List<Integer> newContentIdList = new ArrayList<Integer>();
logger.info("****************************************");
logger.info("Creating contents through webservice....");
logger.info("****************************************");
logger.info("principalName:" + principalName);
logger.info("inputsArray:" + inputsArray);
//logger.warn("contents:" + contents);
try
{
final DynamicWebserviceSerializer serializer = new DynamicWebserviceSerializer();
@SuppressWarnings("unchecked")
List<Map<String, Object>> contents = (List<Map<String, Object>>) serializer.deserialize(inputsArray);
logger.info("contents:" + contents);
initializePrincipal(principalName);
Iterator<Map<String, Object>> contentIterator = contents.iterator();
while(contentIterator.hasNext())
{
//String value = (String)contentIterator.next();
//logger.info("value:" + value);
Map<String, Object> content = contentIterator.next();
String name = (String)content.get("name");
Integer contentTypeDefinitionId = (Integer)content.get("contentTypeDefinitionId");
Integer repositoryId = (Integer)content.get("repositoryId");
Integer parentContentId = (Integer)content.get("parentContentId");
String contentPath = (String)content.get("contentPath");
String creatorName = (String)content.get("creatorName");
Boolean isBranch = (Boolean)content.get("isBranch");
Integer isProtected = (Integer)content.get("isProtected");
Date expireDateTime = null;
Object expireDateTimeObject = content.get("expireDateTime");
if(expireDateTimeObject != null)
{
if(expireDateTimeObject instanceof Date)
expireDateTime = (Date)expireDateTimeObject;
else if(expireDateTimeObject instanceof Calendar)
expireDateTime = ((Calendar)expireDateTimeObject).getTime();
}
Date publishDateTime = null;
Object publishDateTimeObject = content.get("publishDateTime");
if(publishDateTimeObject != null)
{
if(publishDateTimeObject instanceof Date)
publishDateTime = (Date)publishDateTimeObject;
else if(publishDateTimeObject instanceof Calendar)
publishDateTime = ((Calendar)publishDateTimeObject).getTime();
}
logger.info("name:" + name);
logger.info("contentTypeDefinitionId:" + contentTypeDefinitionId);
logger.info("repositoryId:" + repositoryId);
logger.info("parentContentId:" + parentContentId);
logger.info("contentPath:" + contentPath);
if(contentPath != null && !contentPath.equals(""))
{
Database db = CastorDatabaseService.getDatabase();
beginTransaction(db);
try
{
if(parentContentId != null)
{
StringBuffer path = new StringBuffer();
Content parentContent = ContentController.getContentController().getContentWithId(parentContentId, db);
path.insert(0, parentContent.getName() + "/");
while(parentContent.getParentContent() != null)
{
parentContent = parentContent.getParentContent();
if(parentContent != null && parentContent.getParentContent() != null)
path.insert(0, parentContent.getName() + "/");
}
contentPath = path.toString() + contentPath;
}
ContentVO parentContentVO = ContentController.getContentController().getContentVOWithPath(repositoryId, contentPath, true, this.principal, db);
parentContentId = parentContentVO.getId();
commitTransaction(db);
}
catch(Exception e)
{
logger.error("An error occurred so we should not complete the transaction:" + e, e);
rollbackTransaction(db);
throw new SystemException(e.getMessage());
}
}
ContentVO contentVO = new ContentVO();
contentVO.setName(name);
contentVO.setContentTypeDefinitionId(contentTypeDefinitionId);
contentVO.setRepositoryId(repositoryId);
contentVO.setParentContentId(parentContentId);
if(expireDateTime != null)
contentVO.setExpireDateTime(expireDateTime);
if(isBranch != null)
contentVO.setIsBranch(isBranch);
if(isProtected != null)
contentVO.setIsProtected(isProtected);
if(publishDateTime != null)
contentVO.setPublishDateTime(publishDateTime);
if(creatorName != null)
contentVO.setCreatorName(creatorName);
else if(contentVO.getCreatorName() == null)
contentVO.setCreatorName(this.principal.getName());
ContentVO newContentVO = contentControllerProxy.acCreate(this.principal, contentVO.getParentContentId(), contentVO.getContentTypeDefinitionId(), contentVO.getRepositoryId(), contentVO);
if(newContentVO != null)
statusBean.getCreatedBeans().add(new CreatedEntityBean(ContentVO.class.getName(), new Long(newContentVO.getId())));
@SuppressWarnings("unchecked")
List<Map<String, Object>> contentVersions = (List<Map<String, Object>>)content.get("contentVersions");
if (contentVersions == null)
{
logger.info("Content had no versions. Maybe its a folder. IsBranch: " + isBranch);
}
else
{
Iterator<Map<String, Object>> contentVersionIterator = contentVersions.iterator();
while(contentVersionIterator.hasNext())
{
Map<String, Object> contentVersion = contentVersionIterator.next();
Integer languageId = (Integer)contentVersion.get("languageId");
Integer stateId = (Integer)contentVersion.get("stateId");
Boolean allowHTMLContent = (Boolean)contentVersion.get("allowHTMLContent");
Boolean allowExternalLinks = (Boolean)contentVersion.get("allowExternalLinks");
Boolean allowDollarSigns = (Boolean)contentVersion.get("allowDollarSigns");
Boolean allowAnchorSigns = (Boolean)contentVersion.get("allowAnchorSigns");
if(allowHTMLContent == null)
allowHTMLContent = new Boolean(false);
if(allowExternalLinks == null)
allowExternalLinks = new Boolean(false);
if(allowDollarSigns == null)
allowDollarSigns = new Boolean(false);
if(allowAnchorSigns == null)
allowAnchorSigns = new Boolean(true);
logger.info("languageId:" + languageId);
logger.info("stateId:" + stateId);
logger.info("allowHTMLContent:" + allowHTMLContent);
logger.info("allowExternalLinks:" + allowExternalLinks);
logger.info("allowDollarSigns:" + allowDollarSigns);
logger.info("allowAnchorSigns:" + allowAnchorSigns);
ContentVersionVO contentVersionVO = new ContentVersionVO();
contentVersionVO.setLanguageId(languageId);
if(contentVersionVO.getVersionModifier() == null)
contentVersionVO.setVersionModifier(this.principal.getName());
@SuppressWarnings("unchecked")
Map<String, String> attributes = (Map<String, String>)contentVersion.get("contentVersionAttributes");
DOMBuilder domBuilder = new DOMBuilder();
Document document = domBuilder.createDocument();
Element rootElement = domBuilder.addElement(document, "root");
domBuilder.addAttribute(rootElement, "xmlns", "x-schema:Schema.xml");
Element attributesRoot = domBuilder.addElement(rootElement, "attributes");
Iterator<String> attributesIterator = attributes.keySet().iterator();
while(attributesIterator.hasNext())
{
String attributeName = attributesIterator.next();
String attributeValue = attributes.get(attributeName);
attributeValue = cleanAttributeValue(attributeValue, allowHTMLContent, allowExternalLinks, allowDollarSigns, allowAnchorSigns);
Element attribute = domBuilder.addElement(attributesRoot, attributeName);
domBuilder.addCDATAElement(attribute, attributeValue);
}
contentVersionVO.setVersionValue(document.asXML());
ContentVersionVO newContentVersionVO = contentVersionControllerProxy.acCreate(this.principal, newContentVO.getId(), languageId, contentVersionVO);
Integer newContentVersionId = newContentVersionVO.getId();
statusBean.getCreatedBeans().add(new CreatedEntityBean(ContentVersionVO.class.getName(), new Long(newContentVersionId)));
@SuppressWarnings("unchecked")
List<RemoteAttachment> digitalAssets = (List<RemoteAttachment>)contentVersion.get("digitalAssets");
logger.info("digitalAssets:" + digitalAssets);
if(digitalAssets != null)
{
Iterator<RemoteAttachment> digitalAssetIterator = digitalAssets.iterator();
while(digitalAssetIterator.hasNext())
{
RemoteAttachment remoteAttachment = digitalAssetIterator.next();
logger.info("digitalAssets in ws:" + remoteAttachment);
DigitalAssetVO newAsset = new DigitalAssetVO();
newAsset.setAssetContentType(remoteAttachment.getContentType());
newAsset.setAssetKey(remoteAttachment.getName());
newAsset.setAssetFileName(remoteAttachment.getFileName());
newAsset.setAssetFilePath(remoteAttachment.getFilePath());
newAsset.setAssetFileSize(new Integer(new Long(remoteAttachment.getBytes().length).intValue()));
//is = new FileInputStream(renamedFile);
InputStream is = new ByteArrayInputStream(remoteAttachment.getBytes());
DigitalAssetVO newDigitalAssetVO = DigitalAssetController.create(newAsset, is, newContentVersionId, principal);
if(newDigitalAssetVO != null)
statusBean.getCreatedBeans().add(new CreatedEntityBean(DigitalAssetVO.class.getName(), new Long(newDigitalAssetVO.getId())));
}
}
@SuppressWarnings("unchecked")
List<String> contentCategories = (List<String>)contentVersion.get("contentCategories");
logger.info("contentCategories:" + contentCategories);
if(contentCategories != null)
{
Iterator<String> contentCategoriesIterator = contentCategories.iterator();
while(contentCategoriesIterator.hasNext())
{
String contentCategoryString = contentCategoriesIterator.next();
String[] split = contentCategoryString.split("=");
String categoryKey = split[0];
String fullCategoryName = split[1];
logger.info("categoryKey:" + categoryKey);
logger.info("fullCategoryName:" + fullCategoryName);
CategoryVO categoryVO = CategoryController.getController().findByPath(fullCategoryName);
logger.info("categoryVO:" + categoryVO);
List<CategoryVO> categoryVOList = new ArrayList<CategoryVO>();
categoryVOList.add(categoryVO);
Database db = beginTransaction();
try
{
ContentVersion latestContentVersion = ContentVersionController.getContentVersionController().getContentVersionWithId(newContentVersionVO.getId(), db);
logger.info("Adding categoryKey:" + categoryKey + " to " + newContentVersionVO.getId() + ":" + categoryVO);
//ContentCategoryController.getController().create(categoryVOList, newContentVersionVO, categoryKey);
final List<Category> categories = categoryVOListToCategoryList(categoryVOList, db);
ContentCategoryController.getController().create(categories, latestContentVersion, categoryKey, db);
commitTransaction(db);
}
catch (Exception e)
{
logger.warn("Error in contentCategory loop: " + e.getMessage(), e);
rollbackTransaction(db);
throw new SystemException(e.getMessage());
}
}
}
//Should we also change state on newly created content version?
if(stateId != null && !stateId.equals(ContentVersionVO.WORKING_STATE))
{
List<EventVO> events = new ArrayList<EventVO>();
ContentStateController.changeState(newContentVersionId, stateId, "Remote update from deliver", false, this.principal, newContentVO.getId(), events);
if(stateId.equals(ContentVersionVO.PUBLISHED_STATE))
{
PublicationVO publicationVO = new PublicationVO();
publicationVO.setName("Direct publication by " + this.principal.getName());
publicationVO.setDescription("Direct publication from deliver");
publicationVO.setRepositoryId(repositoryId);
publicationVO = PublicationController.getController().createAndPublish(publicationVO, events, false, this.principal);
}
}
}
}
@SuppressWarnings("unchecked")
List<Map<String, Object>> accessRights = (List<Map<String, Object>>)content.get("accessRights");
if(accessRights != null)
{
Iterator<Map<String, Object>> accessRightsIterator = accessRights.iterator();
while(accessRightsIterator.hasNext())
{
Map<String, Object> accessRightMap = accessRightsIterator.next();
String interceptionPointName = (String)accessRightMap.get("interceptionPointName");
String parameters = (String)accessRightMap.get("parameters");
Database db = CastorDatabaseService.getDatabase();
beginTransaction(db);
try
{
InterceptionPoint interceptionPoint = InterceptionPointController.getController().getInterceptionPointWithName(interceptionPointName, db);
logger.info("interceptionPointName:" + interceptionPointName);
logger.info("parameters:" + parameters);
AccessRightVO accessRightVO = new AccessRightVO();
accessRightVO.setParameters("" + newContentVO.getId());
AccessRight accessRight = AccessRightController.getController().create(accessRightVO, interceptionPoint, db);
@SuppressWarnings("unchecked")
List<String> accessRightRoles = (List<String>)accessRightMap.get("accessRightRoles");
if(accessRightRoles != null)
{
Iterator<String> accessRightRolesIterator = accessRightRoles.iterator();
while(accessRightRolesIterator.hasNext())
{
//Map accessRightRoleMap = (Map)accessRightRolesIterator.next();
String roleName = accessRightRolesIterator.next();
AccessRightRoleVO accessRightRoleVO = new AccessRightRoleVO();
accessRightRoleVO.setRoleName(roleName);
AccessRightRole accessRightRole = AccessRightController.getController().createAccessRightRole(db, accessRightRoleVO, accessRight);
@SuppressWarnings("unchecked")
Collection<AccessRightRole> roles = accessRight.getRoles();
roles.add(accessRightRole);
}
}
@SuppressWarnings("unchecked")
List<String> accessRightGroups = (List<String>)accessRightMap.get("accessRightGroups");
if(accessRightGroups != null)
{
Iterator<String> accessRightGroupsIterator = accessRightGroups.iterator();
while(accessRightGroupsIterator.hasNext())
{
String groupName = accessRightGroupsIterator.next();
AccessRightGroupVO accessRightGroupVO = new AccessRightGroupVO();
accessRightGroupVO.setGroupName(groupName);
AccessRightGroup accessRightGroup = AccessRightController.getController().createAccessRightGroup(db, accessRightGroupVO, accessRight);
@SuppressWarnings("unchecked")
Collection<AccessRightGroup> groups = accessRight.getGroups();
groups.add(accessRightGroup);
}
}
@SuppressWarnings("unchecked")
List<String> accessRightUsers = (List<String>)accessRightMap.get("accessRightUsers");
if(accessRightUsers != null)
{
Iterator<String> accessRightUsersIterator = accessRightUsers.iterator();
while(accessRightUsersIterator.hasNext())
{
String userName = accessRightUsersIterator.next();
AccessRightUserVO accessRightUserVO = new AccessRightUserVO();
accessRightUserVO.setUserName(userName);
AccessRightUser accessRightUser = AccessRightController.getController().createAccessRightUser(db, accessRightUserVO, accessRight);
@SuppressWarnings("unchecked")
Collection<AccessRightUser> users = accessRight.getUsers();
users.add(accessRightUser);
}
}
commitTransaction(db);
}
catch (Exception ex)
{
logger.error("An error occurred so we should not complete the transaction. Message: " + ex.getMessage());
logger.warn("An error occurred so we should not complete the transaction.", ex);
rollbackTransaction(db);
throw new SystemException(ex.getMessage());
}
}
}
newContentIdList.add(newContentVO.getId());
}
logger.info("Done with contents..");
}
catch(Throwable e)
{
statusBean.setStatus(false);
statusBean.setMessage("En error occurred when we tried to create a new content:" + e.getMessage());
logger.error("En error occurred when we tried to create a new content:" + e.getMessage());
logger.warn("En error occurred when we tried to create a new content:" + e.getMessage(), e);
}
updateCaches();
return statusBean;
}
/**
*
* @param db the database to use in the operation.
* @param categoryVOList
* @return
* @throws Exception
*/
private List<Category> categoryVOListToCategoryList(final List<CategoryVO> categoryVOList, Database db) throws Exception
{
final List<Category> result = new ArrayList<Category>();
for (Iterator<CategoryVO> i = categoryVOList.iterator(); i.hasNext(); )
{
CategoryVO categoryVO = i.next();
result.add(CategoryController.getController().findById(categoryVO.getCategoryId(), db));
}
return result;
}
/**
* Updates a content.
*/
public Boolean updateContent(final String principalName, final Object[] inputsArray)
{
if(!ServerNodeController.getController().getIsIPAllowed(getRequest()))
{
logger.error("A client with IP " + getRequest().getRemoteAddr() + " was denied access to the webservice. Could be a hack attempt or you have just not configured the allowed IP-addresses correct.");
return new Boolean(false);
}
Boolean status = new Boolean(true);
logger.info("****************************************");
logger.info("Updating content through webservice....");
logger.info("****************************************");
logger.info("principalName:" + principalName);
logger.info("inputsArray:" + inputsArray);
//logger.warn("contents:" + contents);
try
{
final DynamicWebserviceSerializer serializer = new DynamicWebserviceSerializer();
@SuppressWarnings("unchecked")
Map<String, Object> content = (Map<String, Object>) serializer.deserialize(inputsArray);
logger.info("content:" + content);
initializePrincipal(principalName);
Integer contentId = (Integer)content.get("contentId");
String name = (String)content.get("name");
Date expireDateTime = null;
Object expireDateTimeObject = content.get("expireDateTime");
if(expireDateTimeObject != null)
{
if(expireDateTimeObject instanceof Date)
expireDateTime = (Date)expireDateTimeObject;
else if(expireDateTimeObject instanceof Calendar)
expireDateTime = ((Calendar)expireDateTimeObject).getTime();
}
Date publishDateTime = null;
Object publishDateTimeObject = content.get("publishDateTime");
if(publishDateTimeObject != null)
{
if(publishDateTimeObject instanceof Date)
publishDateTime = (Date)publishDateTimeObject;
else if(publishDateTimeObject instanceof Calendar)
publishDateTime = ((Calendar)publishDateTimeObject).getTime();
}
logger.info("contentId:" + contentId);
logger.info("name:" + name);
logger.info("publishDateTime:" + publishDateTime);
logger.info("expireDateTime:" + expireDateTime);
ContentVO contentVO = ContentController.getContentController().getContentVOWithId(contentId);
if(name != null)
contentVO.setName(name);
if(publishDateTime != null)
contentVO.setPublishDateTime(publishDateTime);
if(expireDateTime != null)
contentVO.setExpireDateTime(expireDateTime);
@SuppressWarnings("unused")
ContentVO newContentVO = contentControllerProxy.acUpdate(this.principal, contentVO, null);
logger.info("Done with contents..");
}
catch(Throwable e)
{
status = new Boolean(false);
logger.error("En error occurred when we tried to create a new content:" + e.getMessage());
logger.warn("En error occurred when we tried to create a new content:" + e.getMessage(), e);
}
updateCaches();
return status;
}
/**
* Updates a content.
*/
public Boolean updateContentVersion(final String principalName, final Object[] inputsArray)
{
if(!ServerNodeController.getController().getIsIPAllowed(getRequest()))
{
logger.error("A client with IP " + getRequest().getRemoteAddr() + " was denied access to the webservice. Could be a hack attempt or you have just not configured the allowed IP-addresses correct.");
return new Boolean(false);
}
Boolean status = new Boolean(true);
logger.info("****************************************");
logger.info("Updating content versions through webservice....");
logger.info("****************************************");
logger.info("principalName:" + principalName);
logger.info("inputsArray:" + inputsArray);
//logger.warn("contents:" + contents);
try
{
final DynamicWebserviceSerializer serializer = new DynamicWebserviceSerializer();
@SuppressWarnings("unchecked")
Map<String, Object> contentVersion = (Map<String, Object>) serializer.deserialize(inputsArray);
logger.info("contentVersion:" + contentVersion);
initializePrincipal(principalName);
Integer contentVersionId = (Integer)contentVersion.get("contentVersionId");
Integer contentId = (Integer)contentVersion.get("contentId");
Integer languageId = (Integer)contentVersion.get("languageId");
Integer stateId = (Integer)contentVersion.get("stateId");
String versionComment = (String)contentVersion.get("versionComment");
Boolean allowHTMLContent = (Boolean)contentVersion.get("allowHTMLContent");
Boolean allowExternalLinks = (Boolean)contentVersion.get("allowExternalLinks");
Boolean allowDollarSigns = (Boolean)contentVersion.get("allowDollarSigns");
Boolean allowAnchorSigns = (Boolean)contentVersion.get("allowAnchorSigns");
Boolean keepExistingAttributes = (Boolean)contentVersion.get("keepExistingAttributes");
Boolean keepExistingCategories = (Boolean)contentVersion.get("keepExistingCategories");
Boolean updateExistingAssets = (Boolean)contentVersion.get("updateExistingAssets");
Boolean createVersionIfNotExists = (Boolean)contentVersion.get("createVersionIfNotExists");
if(allowHTMLContent == null)
allowHTMLContent = new Boolean(false);
if(allowExternalLinks == null)
allowExternalLinks = new Boolean(false);
if(keepExistingCategories == null)
keepExistingCategories = new Boolean(true);
if(updateExistingAssets == null)
updateExistingAssets = new Boolean(true);
if(allowDollarSigns == null)
allowDollarSigns = new Boolean(false);
if(allowAnchorSigns == null)
allowAnchorSigns = new Boolean(true);
if(createVersionIfNotExists == null)
createVersionIfNotExists = new Boolean(true);
logger.info("contentVersionId:" + contentVersionId);
logger.info("contentId:" + contentId);
logger.info("languageId:" + languageId);
logger.info("stateId:" + stateId);
logger.info("keepExistingAttributes:" + keepExistingAttributes);
logger.info("keepExistingCategories:" + keepExistingCategories);
logger.info("updateExistingAssets:" + updateExistingAssets);
logger.info("versionComment:" + versionComment);
logger.info("allowHTMLContent:" + allowHTMLContent);
logger.info("allowExternalLinks:" + allowExternalLinks);
logger.info("allowDollarSigns:" + allowDollarSigns);
logger.info("allowAnchorSigns:" + allowAnchorSigns);
logger.info("createVersionIfNotExists:" + createVersionIfNotExists);
ContentVersionVO contentVersionVO = null;
if(contentVersionId != null)
contentVersionVO = ContentVersionController.getContentVersionController().getContentVersionVOWithId(contentVersionId);
else
contentVersionVO = ContentVersionController.getContentVersionController().getLatestActiveContentVersionVO(contentId, languageId);
if(contentVersionVO != null)
{
try
{
logger.info("contentVersionVO:" + contentVersionVO);
contentVersionVO = ContentStateController.changeState(contentVersionVO.getId(), ContentVersionVO.WORKING_STATE, "Remote update from deliver", false, this.principal, contentVersionVO.getContentId(), new ArrayList<EventVO>());
}
catch (Exception e)
{
logger.error("Error when changing state to working: " + e.getMessage(), e);
}
if (logger.isInfoEnabled())
{
logger.info("contentVersionVO (after state change):" + contentVersionVO);
}
}
boolean isNewlyCreatedVersion;
if(contentVersionVO == null)
{
logger.info("createVersionIfNotExists:" + createVersionIfNotExists);
if(createVersionIfNotExists)
{
ContentVersionVO newContentVersionVO = new ContentVersionVO();
newContentVersionVO.setVersionComment(versionComment);
newContentVersionVO.setModifiedDateTime(new Date());
newContentVersionVO.setVersionModifier("" + principalName);
contentVersionVO = contentVersionControllerProxy.acCreate(this.principal, contentId, languageId, newContentVersionVO);
isNewlyCreatedVersion = true;
logger.info("contentVersionVO (newly created):" + contentVersionVO);
}
else
return new Boolean(false);
}
else
{
contentVersionVO.setVersionComment(versionComment);
contentVersionVO.setModifiedDateTime(new Date());
contentVersionVO.setVersionModifier("" + principalName);
isNewlyCreatedVersion = false;
}
@SuppressWarnings("unchecked")
Map<String, String> attributes = (Map<String, String>)contentVersion.get("contentVersionAttributes");
if(attributes != null && attributes.size() > 0)
{
DOMBuilder domBuilder = new DOMBuilder();
Element attributesRoot = null;
Document document = null;
if (keepExistingAttributes && !isNewlyCreatedVersion)
{
String existingXML = contentVersionVO.getVersionValue();
document = domBuilder.getDocument(existingXML);
attributesRoot = (Element)document.getRootElement().element("attributes");
}
else
{
document = domBuilder.createDocument();
Element rootElement = domBuilder.addElement(document, "root");
domBuilder.addAttribute(rootElement, "xmlns", "x-schema:Schema.xml");
attributesRoot = domBuilder.addElement(rootElement, "attributes");
}
if(logger.isDebugEnabled())
logger.info("attributesRoot:" + attributesRoot);
Iterator<String> attributesIterator = attributes.keySet().iterator();
while(attributesIterator.hasNext())
{
String attributeName = attributesIterator.next();
String attributeValue = attributes.get(attributeName);
attributeValue = cleanAttributeValue(attributeValue, allowHTMLContent, allowExternalLinks, allowDollarSigns, allowAnchorSigns);
if(keepExistingAttributes)
{
Element attribute = attributesRoot.element(attributeName);
if (attribute == null)
{
attribute = domBuilder.addElement(attributesRoot, attributeName);
}
attribute.clearContent();
domBuilder.addCDATAElement(attribute, attributeValue);
}
else
{
Element attribute = domBuilder.addElement(attributesRoot, attributeName);
domBuilder.addCDATAElement(attribute, attributeValue);
}
}
contentVersionVO.setVersionValue(document.asXML());
}
ContentVersionControllerProxy.getController().acUpdate(principal, contentId, languageId, contentVersionVO);
//Assets now
@SuppressWarnings("unchecked")
List<RemoteAttachment> digitalAssets = (List<RemoteAttachment>)contentVersion.get("digitalAssets");
if(digitalAssets != null)
{
logger.info("digitalAssets:" + digitalAssets.size());
Iterator<RemoteAttachment> digitalAssetIterator = digitalAssets.iterator();
while(digitalAssetIterator.hasNext())
{
RemoteAttachment remoteAttachment = digitalAssetIterator.next();
logger.info("digitalAssets in ws:" + remoteAttachment);
InputStream is = new ByteArrayInputStream(remoteAttachment.getBytes());
DigitalAssetVO existingAssetVO = DigitalAssetController.getLatestDigitalAssetVO(contentVersionVO.getId(), remoteAttachment.getName());
if(updateExistingAssets && existingAssetVO != null)
{
ContentVersionController.getContentVersionController().deleteDigitalAssetRelation(contentVersionVO.getId(), existingAssetVO.getId(), principal);
DigitalAssetVO digitalAssetVO = new DigitalAssetVO();
digitalAssetVO.setAssetContentType(remoteAttachment.getContentType());
digitalAssetVO.setAssetKey(remoteAttachment.getName());
digitalAssetVO.setAssetFileName(remoteAttachment.getFileName());
digitalAssetVO.setAssetFilePath(remoteAttachment.getFilePath());
digitalAssetVO.setAssetFileSize(new Integer(new Long(remoteAttachment.getBytes().length).intValue()));
DigitalAssetController.create(digitalAssetVO, is, contentVersionVO.getContentVersionId(), principal);
}
else
{
DigitalAssetVO newAsset = new DigitalAssetVO();
newAsset.setAssetContentType(remoteAttachment.getContentType());
newAsset.setAssetKey(remoteAttachment.getName());
newAsset.setAssetFileName(remoteAttachment.getFileName());
newAsset.setAssetFilePath(remoteAttachment.getFilePath());
newAsset.setAssetFileSize(new Integer(new Long(remoteAttachment.getBytes().length).intValue()));
DigitalAssetController.create(newAsset, is, contentVersionVO.getContentVersionId(), principal);
}
}
}
if(!keepExistingCategories)
{
ContentCategoryController.getController().deleteByContentVersion(contentVersionVO.getId()); // .deleteByContentVersion(contentVersionVO.getId(), db);
}
@SuppressWarnings("unchecked")
List<String> contentCategories = (List<String>)contentVersion.get("contentCategories");
logger.info("contentCategories:" + contentCategories);
if(contentCategories != null)
{
Iterator<String> contentCategoriesIterator = contentCategories.iterator();
while(contentCategoriesIterator.hasNext())
{
String contentCategoryString = contentCategoriesIterator.next();
String[] split = contentCategoryString.split("=");
String categoryKey = split[0];
String fullCategoryName = split[1];
logger.info("categoryKey:" + categoryKey);
logger.info("fullCategoryName:" + fullCategoryName);
CategoryVO categoryVO = CategoryController.getController().findByPath(fullCategoryName);
logger.info("categoryVO:" + categoryVO);
List<CategoryVO> categoryVOList = new ArrayList<CategoryVO>();
categoryVOList.add(categoryVO);
Database db = beginTransaction();
try
{
ContentVersion latestContentVersion = ContentVersionController.getContentVersionController().getContentVersionWithId(contentVersionVO.getId(), db);
logger.info("Adding categoryKey:" + categoryKey + " to " + contentVersionVO.getId() + ":" + categoryVO);
//ContentCategoryController.getController().create(categoryVOList, newContentVersionVO, categoryKey);
final List<Category> categories = (List<Category>)categoryVOListToCategoryList(categoryVOList, db);
ContentCategoryController.getController().create(categories, latestContentVersion, categoryKey, db);
commitTransaction(db);
}
catch (Exception e)
{
logger.warn("An error occurred so we should not complete the transaction:" + e);
rollbackTransaction(db);
throw new SystemException(e.getMessage());
}
}
}
//Should we also change state on newly created content version?
if(stateId != null && !stateId.equals(ContentVersionVO.WORKING_STATE))
{
List<EventVO> events = new ArrayList<EventVO>();
ContentStateController.changeState(contentVersionVO.getId(), stateId, "Remote update from deliver", false, this.principal, contentVersionVO.getContentId(), events);
if(stateId.equals(ContentVersionVO.PUBLISHED_STATE))
{
PublicationVO publicationVO = new PublicationVO();
publicationVO.setName("Direct publication by " + this.principal.getName());
publicationVO.setDescription("Direct publication from deliver");
ContentVO contentVO = ContentController.getContentController().getContentVOWithId(contentVersionVO.getContentId());
publicationVO.setRepositoryId(contentVO.getRepositoryId());
publicationVO = PublicationController.getController().createAndPublish(publicationVO, events, false, this.principal);
}
}
logger.info("Done with contentVersion..");
}
catch(Throwable e)
{
status = new Boolean(false);
logger.error("En error occurred when we tried to create a new content:" + e.getMessage());
logger.warn("En error occurred when we tried to create a new content:" + e.getMessage(), e);
}
updateCaches();
return status;
}
/**
* Deletes a digital asset.
*/
public Boolean deleteDigitalAsset(final String principalName, final Object[] inputsArray)
{
if(!ServerNodeController.getController().getIsIPAllowed(getRequest()))
{
logger.error("A client with IP " + getRequest().getRemoteAddr() + " was denied access to the webservice. Could be a hack attempt or you have just not configured the allowed IP-addresses correct.");
return new Boolean(false);
}
Boolean status = new Boolean(true);
logger.info("****************************************");
logger.info("Updating content through webservice....");
logger.info("****************************************");
logger.info("principalName:" + principalName);
logger.info("inputsArray:" + inputsArray);
//logger.warn("contents:" + contents);
try
{
final DynamicWebserviceSerializer serializer = new DynamicWebserviceSerializer();
@SuppressWarnings("unchecked")
Map<String, Object> digitalAsset = (Map<String, Object>) serializer.deserialize(inputsArray);
logger.info("digitalAsset:" + digitalAsset);
initializePrincipal(principalName);
Integer contentVersionId = (Integer)digitalAsset.get("contentVersionId");
Integer contentId = (Integer)digitalAsset.get("contentId");
Integer languageId = (Integer)digitalAsset.get("languageId");
String assetKey = (String)digitalAsset.get("assetKey");
logger.info("contentVersionId:" + contentVersionId);
logger.info("contentId:" + contentId);
logger.info("languageId:" + languageId);
logger.info("assetKey:" + assetKey);
ContentVersionController.getContentVersionController().deleteDigitalAsset(contentId, languageId, assetKey);
logger.info("Done with contents..");
}
catch(Throwable e)
{
status = new Boolean(false);
logger.error("En error occurred when we tried to delete a digitalAsset:" + e.getMessage());
logger.warn("En error occurred when we tried to delete a digitalAsset:" + e.getMessage(), e);
}
updateCaches();
return status;
}
/**
* Deletes a content.
*/
public Boolean deleteContent(final String principalName, final Object[] inputsArray)
{
if(!ServerNodeController.getController().getIsIPAllowed(getRequest()))
{
logger.error("A client with IP " + getRequest().getRemoteAddr() + " was denied access to the webservice. Could be a hack attempt or you have just not configured the allowed IP-addresses correct.");
return new Boolean(false);
}
Boolean status = new Boolean(true);
logger.info("****************************************");
logger.info("Updating content through webservice....");
logger.info("****************************************");
logger.info("principalName:" + principalName);
logger.info("inputsArray:" + inputsArray);
//logger.warn("contents:" + contents);
try
{
final DynamicWebserviceSerializer serializer = new DynamicWebserviceSerializer();
@SuppressWarnings("unchecked")
Map<String, Object> content = (Map<String, Object>) serializer.deserialize(inputsArray);
logger.info("content:" + content);
initializePrincipal(principalName);
Integer contentId = (Integer)content.get("contentId");
//Boolean skipRelationCheck = (Boolean)content.get("skipRelationCheck");
//Boolean skipServiceBindings = (Boolean)content.get("skipServiceBindings");
Boolean forceDelete = (Boolean)content.get("forceDelete");
if(forceDelete == null)
forceDelete = new Boolean(false);
logger.info("contentId:" + contentId);
ContentVO contentVO = new ContentVO();
contentVO.setContentId(contentId);
if(forceDelete.booleanValue())
{
ContentVO currentContentVO = ContentControllerProxy.getContentController().getContentVOWithId(contentId);
@SuppressWarnings("unchecked")
List<ContentVersionVO> contentVersionsVOList = ContentVersionController.getContentVersionController().getPublishedActiveContentVersionVOList(contentId);
List<EventVO> events = new ArrayList<EventVO>();
Iterator<ContentVersionVO> it = contentVersionsVOList.iterator();
while(it.hasNext())
{
ContentVersionVO contentVersionVO = it.next();
EventVO eventVO = new EventVO();
eventVO.setDescription("Unpublished before forced deletion");
eventVO.setEntityClass(ContentVersion.class.getName());
eventVO.setEntityId(contentVersionVO.getContentVersionId());
eventVO.setName(contentVersionVO.getContentName() + "(" + contentVersionVO.getLanguageName() + ")");
eventVO.setTypeId(EventVO.UNPUBLISH_LATEST);
eventVO = EventController.create(eventVO, currentContentVO.getRepositoryId(), principal);
events.add(eventVO);
}
PublicationVO publicationVO = new PublicationVO();
publicationVO.setName("Direct publication by " + this.principal.getName());
publicationVO.setDescription("Unpublished all versions before forced deletion");
//publicationVO.setPublisher(this.getInfoGluePrincipal().getName());
publicationVO.setRepositoryId(currentContentVO.getRepositoryId());
publicationVO = PublicationController.getController().createAndPublish(publicationVO, events, true, this.principal);
}
ContentController.getContentController().delete(contentVO, principal, forceDelete.booleanValue());
logger.info("Done with contents..");
}
catch(Throwable e)
{
status = new Boolean(false);
logger.error("En error occurred when we tried to delete a digitalAsset:" + e.getMessage());
logger.warn("En error occurred when we tried to delete a digitalAsset:" + e.getMessage(), e);
}
updateCaches();
return status;
}
/**
* Deletes a content.
*/
public Boolean deleteContentVersion(final String principalName, final Object[] inputsArray)
{
if(!ServerNodeController.getController().getIsIPAllowed(getRequest()))
{
logger.error("A client with IP " + getRequest().getRemoteAddr() + " was denied access to the webservice. Could be a hack attempt or you have just not configured the allowed IP-addresses correct.");
return new Boolean(false);
}
Boolean status = new Boolean(true);
logger.info("****************************************");
logger.info("Updating content through webservice....");
logger.info("****************************************");
logger.info("principalName:" + principalName);
logger.info("inputsArray:" + inputsArray);
//logger.warn("contents:" + contents);
try
{
final DynamicWebserviceSerializer serializer = new DynamicWebserviceSerializer();
@SuppressWarnings("unchecked")
Map<String, Object> digitalAsset = (Map<String, Object>) serializer.deserialize(inputsArray);
logger.info("digitalAsset:" + digitalAsset);
initializePrincipal(principalName);
Integer contentVersionId = (Integer)digitalAsset.get("contentVersionId");
logger.info("contentVersionId:" + contentVersionId);
ContentVersionVO contentVersionVO = new ContentVersionVO();
contentVersionVO.setContentVersionId(contentVersionId);
ContentVersionController.getContentVersionController().delete(contentVersionVO);
logger.info("Done with contents..");
}
catch(Throwable e)
{
status = new Boolean(false);
logger.error("En error occurred when we tried to delete a digitalAsset:" + e.getMessage());
logger.warn("En error occurred when we tried to delete a digitalAsset:" + e.getMessage(), e);
}
updateCaches();
return status;
}
/**
* Checks if the principal exists and if the principal is allowed to create the workflow.
*
* @param userName the name of the user.
* @param workflowName the name of the workflow to create.
* @throws SystemException if the principal doesn't exists or doesn't have permission to create the workflow.
*/
private void initializePrincipal(final String userName) throws SystemException
{
try
{
principal = UserControllerProxy.getController().getUser(userName);
}
catch(SystemException e)
{
throw e;
}
catch(Exception e)
{
throw new SystemException(e);
}
if(principal == null)
{
throw new SystemException("No such principal [" + userName + "].");
}
}
}