diff --git a/config/alfresco/opencmis-context.xml b/config/alfresco/opencmis-context.xml
index b4c85792cf..dc13a17ead 100644
--- a/config/alfresco/opencmis-context.xml
+++ b/config/alfresco/opencmis-context.xml
@@ -33,10 +33,32 @@
+
+
+
+
+
+
+
+
+
+ ${server.transaction.mode.readOnly}
+ ${server.transaction.mode.readOnly}
+ PROPAGATION_SUPPORTS, readOnly
+ PROPAGATION_SUPPORTS, readOnly
+ ${server.transaction.mode.default}
+
+
+
+
+
+
+
+
diff --git a/source/java/org/alfresco/opencmis/AlfrescoCmisExceptionInterceptor.java b/source/java/org/alfresco/opencmis/AlfrescoCmisExceptionInterceptor.java
new file mode 100644
index 0000000000..a2ebb3b22b
--- /dev/null
+++ b/source/java/org/alfresco/opencmis/AlfrescoCmisExceptionInterceptor.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2005-2010 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.opencmis;
+
+import org.alfresco.repo.node.integrity.IntegrityException;
+import org.alfresco.repo.security.authentication.AuthenticationException;
+import org.alfresco.repo.security.permissions.AccessDeniedException;
+import org.alfresco.service.cmr.coci.CheckOutCheckInServiceException;
+import org.alfresco.service.cmr.model.FileExistsException;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisVersioningException;
+
+/**
+ * Interceptor to catch various exceptions and translate them into CMIS-related exceptions
+ *
+ * TODO: Externalize messages
+ * TODO: Use ExceptionStackUtil to dig out exceptions of interest regardless of depth
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+public class AlfrescoCmisExceptionInterceptor implements MethodInterceptor
+{
+ public Object invoke(MethodInvocation mi) throws Throwable
+ {
+ try
+ {
+ return mi.proceed();
+ }
+ catch (AuthenticationException e)
+ {
+ throw new CmisPermissionDeniedException(e.getMessage(), e);
+ }
+ catch (CheckOutCheckInServiceException e)
+ {
+ throw new CmisVersioningException("Check out failed: " + e.getMessage(), e);
+ }
+ catch (FileExistsException fee)
+ {
+ throw new CmisContentAlreadyExistsException("An object with this name already exists!", fee);
+ }
+ catch (IntegrityException ie)
+ {
+ throw new CmisConstraintException("Constraint violation: " + ie.getMessage(), ie);
+ }
+ catch (AccessDeniedException ade)
+ {
+ throw new CmisPermissionDeniedException("Permission denied!", ade);
+ }
+ catch (Exception e)
+ {
+ if (e instanceof CmisBaseException)
+ {
+ throw (CmisBaseException) e;
+ }
+ else
+ {
+ throw new CmisRuntimeException(e.getMessage(), e);
+ }
+ }
+ }
+}
diff --git a/source/java/org/alfresco/opencmis/AlfrescoCmisService.java b/source/java/org/alfresco/opencmis/AlfrescoCmisService.java
index de55dd1e47..29d17046dc 100644
--- a/source/java/org/alfresco/opencmis/AlfrescoCmisService.java
+++ b/source/java/org/alfresco/opencmis/AlfrescoCmisService.java
@@ -18,3083 +18,31 @@
*/
package org.alfresco.opencmis;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.math.BigInteger;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.transaction.Status;
-import javax.transaction.UserTransaction;
-
-import org.alfresco.cmis.CMISInvalidArgumentException;
-import org.alfresco.model.ContentModel;
-import org.alfresco.opencmis.dictionary.CMISNodeInfo;
-import org.alfresco.opencmis.dictionary.CMISObjectVariant;
-import org.alfresco.opencmis.dictionary.FolderTypeDefintionWrapper;
-import org.alfresco.opencmis.dictionary.PropertyDefinitionWrapper;
-import org.alfresco.opencmis.dictionary.TypeDefinitionWrapper;
-import org.alfresco.query.PagingRequest;
-import org.alfresco.query.PagingResults;
-import org.alfresco.repo.content.encoding.ContentCharsetFinder;
-import org.alfresco.repo.node.getchildren.GetChildrenCannedQuery;
-import org.alfresco.repo.node.integrity.IntegrityException;
-import org.alfresco.repo.search.QueryParameterDefImpl;
-import org.alfresco.repo.security.authentication.AuthenticationException;
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.alfresco.repo.security.authentication.Authorization;
-import org.alfresco.repo.security.permissions.AccessDeniedException;
-import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
-import org.alfresco.repo.version.VersionModel;
-import org.alfresco.service.cmr.coci.CheckOutCheckInServiceException;
-import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
-import org.alfresco.service.cmr.model.FileExistsException;
-import org.alfresco.service.cmr.model.FileInfo;
-import org.alfresco.service.cmr.model.FileNotFoundException;
-import org.alfresco.service.cmr.repository.AssociationRef;
-import org.alfresco.service.cmr.repository.ChildAssociationRef;
-import org.alfresco.service.cmr.repository.ContentWriter;
-import org.alfresco.service.cmr.repository.InvalidNodeRefException;
-import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.cmr.search.QueryParameterDefinition;
-import org.alfresco.service.cmr.search.ResultSet;
-import org.alfresco.service.cmr.search.SearchParameters;
-import org.alfresco.service.cmr.search.SearchService;
-import org.alfresco.service.cmr.version.Version;
-import org.alfresco.service.cmr.version.VersionHistory;
-import org.alfresco.service.cmr.version.VersionType;
-import org.alfresco.service.namespace.NamespaceService;
-import org.alfresco.service.namespace.QName;
-import org.alfresco.service.namespace.RegexQNamePattern;
-import org.alfresco.util.Pair;
-import org.alfresco.util.TempFileProvider;
-import org.apache.chemistry.opencmis.commons.PropertyIds;
-import org.apache.chemistry.opencmis.commons.data.Acl;
-import org.apache.chemistry.opencmis.commons.data.AllowableActions;
-import org.apache.chemistry.opencmis.commons.data.ContentStream;
-import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
-import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData;
-import org.apache.chemistry.opencmis.commons.data.ObjectData;
-import org.apache.chemistry.opencmis.commons.data.ObjectInFolderContainer;
-import org.apache.chemistry.opencmis.commons.data.ObjectInFolderData;
-import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList;
-import org.apache.chemistry.opencmis.commons.data.ObjectList;
-import org.apache.chemistry.opencmis.commons.data.ObjectParentData;
-import org.apache.chemistry.opencmis.commons.data.Properties;
-import org.apache.chemistry.opencmis.commons.data.RenditionData;
-import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
-import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
-import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
-import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
-import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
-import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
-import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
-import org.apache.chemistry.opencmis.commons.enums.ContentStreamAllowed;
-import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
-import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection;
-import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
-import org.apache.chemistry.opencmis.commons.enums.VersioningState;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisStreamNotSupportedException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisVersioningException;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.FailedToDeleteDataImpl;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderContainerImpl;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderDataImpl;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderListImpl;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectParentDataImpl;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionListImpl;
-import org.apache.chemistry.opencmis.commons.impl.server.AbstractCmisService;
-import org.apache.chemistry.opencmis.commons.impl.server.ObjectInfoImpl;
-import org.apache.chemistry.opencmis.commons.impl.server.RenditionInfoImpl;
import org.apache.chemistry.opencmis.commons.server.CallContext;
-import org.apache.chemistry.opencmis.commons.server.ObjectInfo;
-import org.apache.chemistry.opencmis.commons.server.RenditionInfo;
-import org.apache.chemistry.opencmis.commons.spi.Holder;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
/**
- * OpenCMIS service object.
+ * Extended interface for lifecycle management
*
- * @author florian.mueller
- * @since
+ * @author Derek Hulley
+ * @since 4.0
*/
-public class AlfrescoCmisService extends AbstractCmisService
+public interface AlfrescoCmisService extends CmisService
{
- private static Log logger = LogFactory.getLog(AlfrescoCmisService.class);
-
- private static final QName PARAM_PARENT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "parent");
- private static final QName PARAM_USERNAME = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "username");
- private static final String LUCENE_QUERY_CHECKEDOUT = "+@cm\\:workingCopyOwner:${cm:username}";
- private static final String LUCENE_QUERY_CHECKEDOUT_IN_FOLDER = "+@cm\\:workingCopyOwner:${cm:username} +PARENT:\"${cm:parent}\"";
-
- private static final String MIN_FILTER = "cmis:name,cmis:baseTypeId,cmis:objectTypeId,"
- + "cmis:createdBy,cmis:creationDate,cmis:lastModifiedBy,cmis:lastModificationDate,"
- + "cmis:contentStreamLength,cmis:contentStreamMimeType,cmis:contentStreamFileName,"
- + "cmis:contentStreamId";
-
- private CMISConnector connector;
- private CallContext context;
- private UserTransaction txn;
- private Map nodeInfoMap;
- private Map objectInfoMap;
-
- public AlfrescoCmisService(CMISConnector connector)
- {
- this.connector = connector;
- nodeInfoMap = new HashMap();
- objectInfoMap = new HashMap();
- }
-
- protected void beginCall(CallContext context)
- {
- this.context = context;
-
- if (connector.openHttpSession())
- {
- // create a session -> set a cookie
- // if the CMIS client supports cookies that might help in clustered
- // environments
- ((HttpServletRequest) context.get(CallContext.HTTP_SERVLET_REQUEST)).getSession();
- }
-
- AuthenticationUtil.pushAuthentication();
-
- try
- {
- String currentUser = connector.getAuthenticationService().getCurrentUserName();
- String user = context.getUsername();
- String password = context.getPassword();
-
- if (currentUser == null)
- {
- Authorization auth = new Authorization(user, password);
-
- if (auth.isTicket())
- {
- connector.getAuthenticationService().validate(auth.getTicket());
- }
- else
- {
- connector.getAuthenticationService().authenticate(auth.getUserName(), auth.getPasswordCharArray());
- }
-
- }
- else if (currentUser.equals(connector.getProxyUser()))
- {
- if (user != null && user.length() > 0)
- {
- AuthenticationUtil.setFullyAuthenticatedUser(user);
- }
- }
- }
- catch (AuthenticationException ae)
- {
- throw new CmisPermissionDeniedException(ae.getMessage(), ae);
- }
-
- // start read-only transaction
- try
- {
- beginReadOnlyTransaction();
- }
- catch (Exception e)
- {
- AuthenticationUtil.popAuthentication();
-
- if (e instanceof CmisBaseException)
- {
- throw (CmisBaseException) e;
- }
- else
- {
- throw new CmisRuntimeException(e.getMessage(), e);
- }
- }
- }
-
- @Override
- public void close()
- {
- try
- {
- endReadOnlyTransaction();
- }
- catch (Exception e)
- {
- if (e instanceof CmisBaseException)
- {
- throw (CmisBaseException) e;
- }
- else
- {
- throw new CmisRuntimeException(e.getMessage(), e);
- }
- }
- finally
- {
- AuthenticationUtil.popAuthentication();
- context = null;
- nodeInfoMap.clear();
- objectInfoMap.clear();
- }
- }
-
/**
- * Begins the embracing read-only transaction.
+ * Called directly before any CMIS method is used
*/
- protected void beginReadOnlyTransaction()
- {
- txn = null;
- try
- {
- txn = connector.getTransactionService().getNonPropagatingUserTransaction(true);
- txn.begin();
- }
- catch (Exception e)
- {
- throw new CmisRuntimeException(e.getMessage(), e);
- }
- }
-
+ void beforeCall();
+
/**
- * Ends embracing read-only transaction.
+ * Called directly after any CMIS method is used
*/
- protected void endReadOnlyTransaction()
- {
- try
- {
- if (txn != null)
- {
- // there isn't anything to commit, really
- // we just have to end the transaction
- if (txn.getStatus() == Status.STATUS_MARKED_ROLLBACK)
- {
- txn.rollback();
- }
- else
- {
- txn.commit();
- }
- txn = null;
- }
- }
- catch (Exception e)
- {
- throw new CmisRuntimeException(e.getMessage(), e);
- }
- }
-
- protected CMISNodeInfoImpl createNodeInfo(NodeRef nodeRef)
- {
- if (logger.isDebugEnabled())
- {
- logger.debug(
- "createNodeInfo: \n" +
- " current user: " + AuthenticationUtil.getFullyAuthenticatedUser() + "\n" +
- " running as: " + AuthenticationUtil.getRunAsUser() + "\n" +
- " nodeRef: " + nodeRef);
- }
-
- CMISNodeInfoImpl result = connector.createNodeInfo(nodeRef);
- nodeInfoMap.put(result.getObjectId(), result);
-
- return result;
- }
-
- protected CMISNodeInfo createNodeInfo(AssociationRef assocRef)
- {
- if (logger.isDebugEnabled())
- {
- logger.debug(
- "createNodeInfo: \n" +
- " current user: " + AuthenticationUtil.getFullyAuthenticatedUser() + "\n" +
- " running as: " + AuthenticationUtil.getRunAsUser() + "\n" +
- " assocRef: " + assocRef);
- }
-
- CMISNodeInfoImpl result = connector.createNodeInfo(assocRef);
- nodeInfoMap.put(result.getObjectId(), result);
-
- return result;
- }
-
- protected CMISNodeInfo getOrCreateNodeInfo(String objectId)
- {
- CMISNodeInfo result = nodeInfoMap.get(objectId);
- if (result == null)
- {
- result = connector.createNodeInfo(objectId);
- nodeInfoMap.put(objectId, result);
- }
-
- return result;
- }
-
- protected CMISNodeInfo getOrCreateNodeInfo(String objectId, String what)
- {
- CMISNodeInfo result = getOrCreateNodeInfo(objectId);
- if (result instanceof CMISNodeInfoImpl)
- {
- ((CMISNodeInfoImpl) result).checkIfUseful(what);
- }
-
- return result;
- }
-
- protected CMISNodeInfo getOrCreateFolderInfo(String folderId, String what)
- {
- CMISNodeInfo result = getOrCreateNodeInfo(folderId);
- if (result instanceof CMISNodeInfoImpl)
- {
- ((CMISNodeInfoImpl) result).checkIfFolder(what);
- }
-
- return result;
- }
-
- protected CMISNodeInfo addNodeInfo(CMISNodeInfo info)
- {
- nodeInfoMap.put(info.getObjectId(), info);
-
- return info;
- }
-
- // --- repository service ---
-
- @Override
- public List getRepositoryInfos(ExtensionsData extension)
- {
- return Collections.singletonList(connector.getRepositoryInfo());
- }
-
- @Override
- public RepositoryInfo getRepositoryInfo(String repositoryId, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- return connector.getRepositoryInfo();
- }
-
- @Override
- public TypeDefinitionList getTypeChildren(
- String repositoryId, String typeId, Boolean includePropertyDefinitions,
- BigInteger maxItems, BigInteger skipCount, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // convert BigIntegers to int
- int max = (maxItems == null ? Integer.MAX_VALUE : maxItems.intValue());
- int skip = (skipCount == null || skipCount.intValue() < 0 ? 0 : skipCount.intValue());
-
- // set up the result
- TypeDefinitionListImpl result = new TypeDefinitionListImpl();
- List list = new ArrayList();
- result.setList(list);
-
- // get the types from the dictionary
- List childrenList;
- if (typeId == null)
- {
- childrenList = connector.getOpenCMISDictionaryService().getBaseTypes();
- }
- else
- {
- TypeDefinitionWrapper tdw = connector.getOpenCMISDictionaryService().findType(typeId);
- if (tdw == null)
- {
- throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
- }
- childrenList = tdw.getChildren();
- }
-
- // create result
- if (max > 0)
- {
- int lastIndex = (max + skip > childrenList.size() ? childrenList.size() : max + skip) - 1;
- for (int i = skip; i <= lastIndex; i++)
- {
- list.add(childrenList.get(i).getTypeDefinition(includePropertyDefinitions));
- }
- }
-
- result.setHasMoreItems(childrenList.size() - skip > result.getList().size());
- result.setNumItems(BigInteger.valueOf(childrenList.size()));
-
- return result;
- }
-
- @Override
- public TypeDefinition getTypeDefinition(String repositoryId, String typeId, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // find the type
- TypeDefinitionWrapper tdw = connector.getOpenCMISDictionaryService().findType(typeId);
- if (tdw == null)
- {
- throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
- }
-
- // return type definition
- return tdw.getTypeDefinition(true);
- }
-
- @Override
- public List getTypeDescendants(
- String repositoryId, String typeId, BigInteger depth,
- Boolean includePropertyDefinitions, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- List result = new ArrayList();
-
- // check depth
- int d = (depth == null ? -1 : depth.intValue());
- if (d == 0)
- {
- throw new CmisInvalidArgumentException("Depth must not be 0!");
- }
-
- if (typeId == null)
- {
- for (TypeDefinitionWrapper tdw : connector.getOpenCMISDictionaryService().getBaseTypes())
- {
- result.add(getTypesDescendants(d, tdw, includePropertyDefinitions));
- }
- }
- else
- {
- TypeDefinitionWrapper tdw = connector.getOpenCMISDictionaryService().findType(typeId);
- if (tdw == null)
- {
- throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
- }
-
- if (tdw.getChildren() != null)
- {
- for (TypeDefinitionWrapper child : tdw.getChildren())
- {
- result.add(getTypesDescendants(d, child, includePropertyDefinitions));
- }
- }
- }
-
- return result;
- }
-
+ void afterCall();
+
/**
- * Gathers the type descendants tree.
- */
- private TypeDefinitionContainer getTypesDescendants(
- int depth, TypeDefinitionWrapper tdw, boolean includePropertyDefinitions)
- {
- TypeDefinitionContainerImpl result = new TypeDefinitionContainerImpl();
-
- result.setTypeDefinition(tdw.getTypeDefinition(includePropertyDefinitions));
-
- if (depth != 0)
- {
- if (tdw.getChildren() != null)
- {
- result.setChildren(new ArrayList());
- for (TypeDefinitionWrapper tdc : tdw.getChildren())
- {
- result.getChildren().add(
- getTypesDescendants(depth < 0 ? -1 : depth - 1, tdc, includePropertyDefinitions));
- }
- }
- }
-
- return result;
- }
-
- // --- navigation service ---
-
- @Override
- public ObjectInFolderList getChildren(
- String repositoryId, String folderId, String filter, String orderBy,
- Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
- Boolean includePathSegment, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension)
- {
- long start = System.currentTimeMillis();
-
- checkRepositoryId(repositoryId);
-
- // convert BigIntegers to int
- int max = (maxItems == null ? Integer.MAX_VALUE : maxItems.intValue());
- int skip = (skipCount == null || skipCount.intValue() < 0 ? 0 : skipCount.intValue());
-
- ObjectInFolderListImpl result = new ObjectInFolderListImpl();
- List list = new ArrayList();
- result.setObjects(list);
-
- // get the children references
- NodeRef folderNodeRef = getOrCreateFolderInfo(folderId, "Folder").getNodeRef();
-
- // convert orderBy to sortProps
- List> sortProps = null;
- if (orderBy != null)
- {
- sortProps = new ArrayList>(1);
-
- String[] parts = orderBy.split(",");
- int len = parts.length;
- final int origLen = len;
-
- if (origLen > 0)
- {
- int maxSortProps = GetChildrenCannedQuery.MAX_FILTER_SORT_PROPS;
- if (len > maxSortProps)
- {
- if (logger.isDebugEnabled())
- {
- logger.debug(
- "Too many sort properties in 'orderBy' - ignore those above max (max="
- + maxSortProps + ",actual=" + len + ")");
- }
- len = maxSortProps;
- }
- for (int i = 0; i < len; i++)
- {
- String[] sort = parts[i].split(" +");
-
- if (sort.length > 0)
- {
- PropertyDefinitionWrapper propDef = connector.getOpenCMISDictionaryService()
- .findPropertyByQueryName(sort[0]);
- if (propDef != null)
- {
- QName sortProp = propDef.getPropertyAccessor().getMappedProperty();
- if (sortProp != null)
- {
- boolean sortAsc = (sort.length == 1) || sort[1].equalsIgnoreCase("asc");
- sortProps.add(new Pair(sortProp, sortAsc));
- }
- else
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Ignore sort property '" + sort[0] + " - mapping not found");
- }
- }
- }
- else
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Ignore sort property '" + sort[0] + " - query name not found");
- }
- }
- }
- }
- }
-
- if (sortProps.size() < origLen)
- {
- logger.warn("Sort properties trimmed - either too many and/or not found: \n" + " orig: " + orderBy
- + "\n" + " final: " + sortProps);
- }
- }
-
- PagingRequest pageRequest = new PagingRequest(skip, max, null);
- pageRequest.setRequestTotalCountMax(skip + 10000); // TODO make this optional/configurable
- // - affects whether numItems may be returned
-
- PagingResults pageOfNodeInfos = connector.getFileFolderService().list(
- folderNodeRef, true, true,
- null, sortProps, pageRequest);
-
- if (max > 0)
- {
- for (FileInfo child : pageOfNodeInfos.getPage())
- {
- try
- {
- // create a child CMIS object
- CMISNodeInfo ni = createNodeInfo(child.getNodeRef());
- ObjectData object = connector.createCMISObject(ni, child, filter, includeAllowableActions,
- includeRelationships, renditionFilter, false, false);
-
- if (context.isObjectInfoRequired())
- {
- getObjectInfo(repositoryId, ni.getObjectId(), includeRelationships);
- }
-
- ObjectInFolderDataImpl childData = new ObjectInFolderDataImpl();
- childData.setObject(object);
-
- // include path segment
- if (includePathSegment)
- {
- childData.setPathSegment(child.getName());
- }
-
- // add it
- list.add(childData);
- }
- catch (InvalidNodeRefException e)
- {
- // ignore invalid children
- }
- }
- }
-
- // has more ?
- result.setHasMoreItems(pageOfNodeInfos.hasMoreItems());
-
- // total count ?
- Pair totalCounts = pageOfNodeInfos.getTotalResultCount();
- if (totalCounts != null)
- {
- Integer totalCountLower = totalCounts.getFirst();
- Integer totalCountUpper = totalCounts.getSecond();
- if ((totalCountLower != null) && (totalCountLower.equals(totalCountUpper)))
- {
- result.setNumItems(BigInteger.valueOf(totalCountLower));
- }
- }
-
- if (logger.isDebugEnabled())
- {
- logger.debug("getChildren: " + list.size() + " in " + (System.currentTimeMillis() - start) + " msecs");
- }
-
- return result;
- }
-
- @Override
- public List getDescendants(
- String repositoryId, String folderId, BigInteger depth,
- String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
- String renditionFilter, Boolean includePathSegment, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- List result = new ArrayList();
-
- getDescendantsTree(
- repositoryId,
- getOrCreateFolderInfo(folderId, "Folder").getNodeRef(),
- depth.intValue(),
- filter,
- includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, false,
- result);
-
- return result;
- }
-
- @Override
- public List getFolderTree(
- String repositoryId, String folderId, BigInteger depth,
- String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
- String renditionFilter, Boolean includePathSegment, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- List result = new ArrayList();
-
- getDescendantsTree(
- repositoryId,
- getOrCreateFolderInfo(folderId, "Folder").getNodeRef(),
- depth.intValue(),
- filter, includeAllowableActions, includeRelationships, renditionFilter, includePathSegment, true,
- result);
-
- return result;
- }
-
- private void getDescendantsTree(
- String repositoryId, NodeRef folderNodeRef, int depth, String filter,
- Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
- Boolean includePathSegment, boolean foldersOnly, List list)
- {
- // get the children references
- List childrenList = connector.getNodeService().getChildAssocs(folderNodeRef);
- for (ChildAssociationRef child : childrenList)
- {
- try
- {
- TypeDefinitionWrapper type = connector.getType(child.getChildRef());
- if (type == null)
- {
- continue;
- }
-
- boolean isFolder = (type instanceof FolderTypeDefintionWrapper);
-
- if (foldersOnly && !isFolder)
- {
- continue;
- }
-
- // create a child CMIS object
- ObjectInFolderDataImpl object = new ObjectInFolderDataImpl();
- CMISNodeInfo ni = createNodeInfo(child.getChildRef());
- object.setObject(connector.createCMISObject(
- ni, filter, includeAllowableActions, includeRelationships,
- renditionFilter, false, false));
- if (context.isObjectInfoRequired())
- {
- getObjectInfo(repositoryId, ni.getObjectId(), includeRelationships);
- }
-
- if (includePathSegment)
- {
- object.setPathSegment(connector.getName(child.getChildRef()));
- }
-
- // create the container
- ObjectInFolderContainerImpl container = new ObjectInFolderContainerImpl();
- container.setObject(object);
-
- if ((depth != 1) && isFolder)
- {
- container.setChildren(new ArrayList());
- getDescendantsTree(
- repositoryId,
- child.getChildRef(),
- depth - 1, filter, includeAllowableActions,
- includeRelationships, renditionFilter, includePathSegment, foldersOnly,
- container.getChildren());
- }
-
- // add it
- list.add(container);
- }
- catch (InvalidNodeRefException e)
- {
- // ignore invalid children
- }
- }
- }
-
- @Override
- public ObjectData getFolderParent(String repositoryId, String folderId, String filter, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // get the node ref
- CMISNodeInfo info = getOrCreateFolderInfo(folderId, "Folder");
-
- // the root folder has no parent
- if (info.isRootFolder())
- {
- throw new CmisInvalidArgumentException("Root folder has no parent!");
- }
-
- // get the parent
- List parentInfos = info.getParents();
- if (parentInfos.isEmpty())
- {
- throw new CmisRuntimeException("Folder has no parent and is not the root folder?!");
- }
-
- CMISNodeInfo parentInfo = addNodeInfo(parentInfos.get(0));
-
- ObjectData result = connector.createCMISObject(
- parentInfo, filter, false, IncludeRelationships.NONE,
- CMISConnector.RENDITION_NONE, false, false);
- if (context.isObjectInfoRequired())
- {
- getObjectInfo(
- repositoryId,
- parentInfo.getObjectId(),
- IncludeRelationships.NONE);
- }
-
- return result;
- }
-
- @Override
- public List getObjectParents(
- String repositoryId, String objectId, String filter,
- Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
- Boolean includeRelativePathSegment, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- List result = new ArrayList();
-
- // what kind of object is it?
- CMISNodeInfo info = getOrCreateNodeInfo(objectId, "Object");
-
- // relationships are not filed
- if (info.isRelationship())
- {
- throw new CmisConstraintException("Relationships are not fileable!");
- }
-
- if (info.isFolder() && !info.isRootFolder())
- {
- List parentInfos = info.getParents();
- if (!parentInfos.isEmpty())
- {
- CMISNodeInfo parentInfo = addNodeInfo(parentInfos.get(0));
-
- ObjectData object = connector.createCMISObject(
- parentInfo, filter, includeAllowableActions,
- includeRelationships, renditionFilter, false, false);
- if (context.isObjectInfoRequired())
- {
- getObjectInfo(repositoryId, object.getId(), includeRelationships);
- }
-
- ObjectParentDataImpl objectParent = new ObjectParentDataImpl();
- objectParent.setObject(object);
-
- // include relative path segment
- if (includeRelativePathSegment)
- {
- objectParent.setRelativePathSegment(info.getName());
- }
-
- result.add(objectParent);
- }
- }
- else if (info.isCurrentVersion() || info.isPWC())
- {
- List parentInfos = info.getParents();
- for (CMISNodeInfo parentInfo : parentInfos)
- {
- addNodeInfo(parentInfo);
-
- ObjectData object = connector.createCMISObject(
- parentInfo, filter, includeAllowableActions,
- includeRelationships, renditionFilter, false, false);
- if (context.isObjectInfoRequired())
- {
- getObjectInfo(repositoryId, object.getId(), includeRelationships);
- }
-
- ObjectParentDataImpl objectParent = new ObjectParentDataImpl();
- objectParent.setObject(object);
-
- // include relative path segment
- if (includeRelativePathSegment)
- {
- objectParent.setRelativePathSegment(info.getName());
- }
-
- result.add(objectParent);
- }
- }
-
- return result;
- }
-
- @Override
- public ObjectList getCheckedOutDocs(
- String repositoryId, String folderId, String filter, String orderBy,
- Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
- BigInteger maxItems, BigInteger skipCount, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // convert BigIntegers to int
- int max = (maxItems == null ? Integer.MAX_VALUE : maxItems.intValue());
- int skip = (skipCount == null || skipCount.intValue() < 0 ? 0 : skipCount.intValue());
-
- // prepare query
- SearchParameters params = new SearchParameters();
- params.setLanguage(SearchService.LANGUAGE_LUCENE);
- QueryParameterDefinition usernameDef = new QueryParameterDefImpl(
- PARAM_USERNAME,
- connector.getDictionaryService().getDataType(DataTypeDefinition.TEXT),
- true,
- AuthenticationUtil.getFullyAuthenticatedUser());
- params.addQueryParameterDefinition(usernameDef);
-
- if (folderId == null)
- {
- params.setQuery(LUCENE_QUERY_CHECKEDOUT);
- params.addStore(connector.getRootStoreRef());
- }
- else
- {
- CMISNodeInfo folderInfo = getOrCreateFolderInfo(folderId, "Folder");
-
- params.setQuery(LUCENE_QUERY_CHECKEDOUT_IN_FOLDER);
- params.addStore(folderInfo.getNodeRef().getStoreRef());
- QueryParameterDefinition parentDef = new QueryParameterDefImpl(
- PARAM_PARENT,
- connector.getDictionaryService().getDataType(DataTypeDefinition.NODE_REF),
- true,
- folderInfo.getNodeRef().toString());
- params.addQueryParameterDefinition(parentDef);
- }
-
- // set up order
- if (orderBy != null)
- {
- String[] parts = orderBy.split(",");
- for (int i = 0; i < parts.length; i++)
- {
- String[] sort = parts[i].split(" +");
-
- if (sort.length < 1)
- {
- continue;
- }
-
- PropertyDefinitionWrapper propDef = connector.getOpenCMISDictionaryService().findPropertyByQueryName(sort[0]);
- if (propDef != null)
- {
- if (propDef.getPropertyDefinition().isOrderable())
- {
- QName sortProp = propDef.getPropertyAccessor().getMappedProperty();
- if (sortProp != null)
- {
- boolean sortAsc = (sort.length == 1) || sort[1].equalsIgnoreCase("asc");
- params.addSort(propDef.getPropertyLuceneBuilder().getLuceneFieldName(), sortAsc);
- }
- else
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Ignore sort property '" + sort[0] + " - mapping not found");
- }
- }
- }
- else
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Ignore sort property '" + sort[0] + " - not orderable");
- }
- }
- }
- else
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("Ignore sort property '" + sort[0] + " - query name not found");
- }
- }
- }
- }
-
- // execute query
- ResultSet resultSet = null;
- List nodeRefs;
- try
- {
- resultSet = connector.getSearchService().query(params);
- nodeRefs = resultSet.getNodeRefs();
- }
- finally
- {
- if (resultSet != null)
- {
- resultSet.close();
- }
- }
-
- // collect results
- ObjectListImpl result = new ObjectListImpl();
- List list = new ArrayList();
- result.setObjects(list);
-
- int skipCounter = skip;
- if (max > 0)
- {
- for (NodeRef nodeRef : nodeRefs)
- {
- if (skipCounter > 0)
- {
- skipCounter--;
- continue;
- }
-
- if (list.size() == max)
- {
- break;
- }
-
- try
- {
- // create a CMIS object
- CMISNodeInfo ni = createNodeInfo(nodeRef);
- ObjectData object = connector.createCMISObject(
- ni, filter, includeAllowableActions,
- includeRelationships, renditionFilter, false, false);
-
- if (context.isObjectInfoRequired())
- {
- getObjectInfo(repositoryId, ni.getObjectId(), includeRelationships);
- }
-
- // add it
- list.add(object);
- }
- catch (InvalidNodeRefException e)
- {
- // ignore invalid objects
- }
- }
- }
-
- // has more ?
- result.setHasMoreItems(nodeRefs.size() - skip > list.size());
-
- return result;
- }
-
- // --- object service ---
-
- @Override
- public String create(
- String repositoryId, Properties properties, String folderId, ContentStream contentStream,
- VersioningState versioningState, List policies, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // check properties
- if (properties == null || properties.getProperties() == null)
- {
- throw new CmisInvalidArgumentException("Properties must be set!");
- }
-
- // get the type
- String objectTypeId = connector.getObjectTypeIdProperty(properties);
-
- // find the type
- TypeDefinitionWrapper type = connector.getOpenCMISDictionaryService().findType(objectTypeId);
- if (type == null)
- {
- throw new CmisInvalidArgumentException("Type '" + objectTypeId + "' is unknown!");
- }
-
- // create object
- String newId = null;
- switch (type.getBaseTypeId())
- {
- case CMIS_DOCUMENT:
- newId = createDocument(repositoryId, properties, folderId, contentStream, versioningState, policies, null,
- null, extension);
- break;
- case CMIS_FOLDER:
- newId = createFolder(repositoryId, properties, folderId, policies, null, null, extension);
- break;
- case CMIS_POLICY:
- newId = createPolicy(repositoryId, properties, folderId, policies, null, null, extension);
- break;
- }
-
- // check new object id
- if (newId == null)
- {
- throw new CmisRuntimeException("Creation failed!");
- }
-
- if (context.isObjectInfoRequired())
- {
- try
- {
- getObjectInfo(repositoryId, newId, "*", IncludeRelationships.NONE);
- }
- catch (InvalidNodeRefException e)
- {
- throw new CmisRuntimeException("Creation failed! New object not found!");
- }
- }
-
- // return the new object id
- return newId;
- }
-
- @Override
- public String createFolder(String repositoryId, final Properties properties, String folderId,
- final List policies, final Acl addAces, final Acl removeAces, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // get the parent folder node ref
- final CMISNodeInfo parentInfo = getOrCreateFolderInfo(folderId, "Folder");
-
- // get name and type
- final String name = connector.getNameProperty(properties, null);
- final String objectTypeId = connector.getObjectTypeIdProperty(properties);
- final TypeDefinitionWrapper type = connector.getTypeForCreate(objectTypeId, BaseTypeId.CMIS_FOLDER);
-
- connector.checkChildObjectType(parentInfo, type.getTypeId());
-
- // run transaction
- endReadOnlyTransaction();
- NodeRef newNodeRef = connector.getTransactionService().getRetryingTransactionHelper()
- .doInTransaction(new RetryingTransactionCallback()
- {
- public NodeRef execute() throws Exception
- {
- try
- {
- NodeRef nodeRef = connector.getFileFolderService()
- .create(parentInfo.getNodeRef(), name, type.getAlfrescoClass()).getNodeRef();
-
- connector.setProperties(nodeRef, type, properties, new String[] { PropertyIds.NAME,
- PropertyIds.OBJECT_TYPE_ID });
- connector.applyPolicies(nodeRef, type, policies);
- connector.applyACL(nodeRef, type, addAces, removeAces);
-
- return nodeRef;
- }
- catch (FileExistsException fee)
- {
- throw new CmisContentAlreadyExistsException("An object with this name already exists!", fee);
- }
- catch (IntegrityException ie)
- {
- throw new CmisConstraintException("Constraint violation: " + ie.getMessage(), ie);
- }
- catch (AccessDeniedException ade)
- {
- throw new CmisPermissionDeniedException("Permission denied!", ade);
- }
- };
- }, false, true);
- beginReadOnlyTransaction();
-
- return newNodeRef.toString();
- }
-
- @Override
- public String createDocument(
- String repositoryId, final Properties properties, String folderId,
- final ContentStream contentStream, final VersioningState versioningState, final List policies,
- final Acl addAces, final Acl removeAces, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // get the parent folder node ref
- final CMISNodeInfo parentInfo = getOrCreateFolderInfo(folderId, "Parent folder");
-
- // get name and type
- final String name = connector.getNameProperty(properties, null);
- final String objectTypeId = connector.getObjectTypeIdProperty(properties);
- final TypeDefinitionWrapper type = connector.getTypeForCreate(objectTypeId, BaseTypeId.CMIS_DOCUMENT);
-
- connector.checkChildObjectType(parentInfo, type.getTypeId());
-
- DocumentTypeDefinition docType = (DocumentTypeDefinition) type.getTypeDefinition(false);
-
- if ((docType.getContentStreamAllowed() == ContentStreamAllowed.NOTALLOWED) && (contentStream != null))
- {
- throw new CmisConstraintException("This document type does not support content!");
- }
-
- if ((docType.getContentStreamAllowed() == ContentStreamAllowed.REQUIRED) && (contentStream == null))
- {
- throw new CmisConstraintException("This document type does requires content!");
- }
-
- if (docType.isVersionable() && (versioningState == VersioningState.NONE))
- {
- throw new CmisConstraintException("This document type is versionable!");
- }
-
- if (!docType.isVersionable() && (versioningState != VersioningState.NONE))
- {
- throw new CmisConstraintException("This document type is not versionable!");
- }
-
- // copy stream to temp file
- final File tempFile = copyToTempFile(contentStream);
- final Charset encoding = (tempFile == null ? null : getEncoding(tempFile, contentStream.getMimeType()));
-
- // run transaction
- endReadOnlyTransaction();
- NodeRef newNodeRef = connector.getTransactionService().getRetryingTransactionHelper()
- .doInTransaction(new RetryingTransactionCallback()
- {
- public NodeRef execute() throws Exception
- {
- try
- {
- NodeRef nodeRef = connector.getFileFolderService()
- .create(parentInfo.getNodeRef(), name, type.getAlfrescoClass()).getNodeRef();
-
- connector.setProperties(nodeRef, type, properties, new String[] { PropertyIds.NAME,
- PropertyIds.OBJECT_TYPE_ID });
- connector.applyPolicies(nodeRef, type, policies);
- connector.applyACL(nodeRef, type, addAces, removeAces);
-
- // handle content
- if (contentStream != null)
- {
- // write content
- ContentWriter writer = connector.getFileFolderService().getWriter(nodeRef);
- writer.setMimetype(contentStream.getMimeType());
- writer.setEncoding(encoding.name());
- writer.putContent(tempFile);
- }
-
- connector.applyVersioningState(nodeRef, versioningState);
-
- return nodeRef;
- }
- catch (FileExistsException fee)
- {
- removeTempFile(tempFile);
- throw new CmisContentAlreadyExistsException("An object with this name already exists!", fee);
- }
- catch (IntegrityException ie)
- {
- removeTempFile(tempFile);
- throw new CmisConstraintException("Constraint violation: " + ie.getMessage(), ie);
- }
- catch (AccessDeniedException ade)
- {
- removeTempFile(tempFile);
- throw new CmisPermissionDeniedException("Permission denied!", ade);
- }
- };
- }, false, true);
- beginReadOnlyTransaction();
-
- removeTempFile(tempFile);
-
- return connector.createObjectId(newNodeRef);
- }
-
- @Override
- public String createDocumentFromSource(
- String repositoryId, String sourceId, final Properties properties,
- String folderId, final VersioningState versioningState, final List policies, final Acl addAces,
- final Acl removeAces, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // get the parent folder node ref
- final CMISNodeInfo parentInfo = getOrCreateFolderInfo(folderId, "Parent folder");
-
- // get source
- CMISNodeInfo info = getOrCreateNodeInfo(sourceId, "Source");
-
- // check source
- if (info.isVariant(CMISObjectVariant.ASSOC))
- {
- throw new CmisConstraintException("Source object is not a document!");
- }
-
- final NodeRef sourceNodeRef = info.getNodeRef();
- if (!info.isDocument())
- {
- throw new CmisConstraintException("Source object is not a document!");
- }
-
- // get name and type
- final String name = connector.getNameProperty(properties, info.getName());
-
- final TypeDefinitionWrapper type = info.getType();
- connector.checkChildObjectType(parentInfo, type.getTypeId());
-
- // run transaction
- endReadOnlyTransaction();
- NodeRef newNodeRef = connector.getTransactionService().getRetryingTransactionHelper()
- .doInTransaction(new RetryingTransactionCallback()
- {
- public NodeRef execute() throws Exception
- {
- try
- {
- NodeRef newDocumentNodeRef = connector.getFileFolderService()
- .copy(sourceNodeRef, parentInfo.getNodeRef(), name).getNodeRef();
-
- connector.setProperties(newDocumentNodeRef, type, properties, new String[] {
- PropertyIds.NAME, PropertyIds.OBJECT_TYPE_ID });
- connector.applyPolicies(newDocumentNodeRef, type, policies);
- connector.applyACL(newDocumentNodeRef, type, addAces, removeAces);
- connector.applyVersioningState(newDocumentNodeRef, versioningState);
-
- return newDocumentNodeRef;
- }
- catch (FileExistsException fee)
- {
- throw new CmisContentAlreadyExistsException("An object with this name already exists!", fee);
- }
- catch (IntegrityException ie)
- {
- throw new CmisConstraintException("Constraint violation: " + ie.getMessage(), ie);
- }
- catch (AccessDeniedException ade)
- {
- throw new CmisPermissionDeniedException("Permission denied!", ade);
- }
- };
- }, false, true);
- beginReadOnlyTransaction();
-
- return connector.createObjectId(newNodeRef);
- }
-
- @Override
- public String createPolicy(
- String repositoryId, Properties properties, String folderId, List policies,
- Acl addAces, Acl removeAces, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // get the parent folder
- getOrCreateFolderInfo(folderId, "Parent Folder");
-
- String objectTypeId = connector.getObjectTypeIdProperty(properties);
- connector.getTypeForCreate(objectTypeId, BaseTypeId.CMIS_POLICY);
-
- // we should never get here - policies are not creatable!
- throw new CmisRuntimeException("Polcies cannot be created!");
- }
-
- @Override
- public String createRelationship(
- String repositoryId, Properties properties, List policies, Acl addAces,
- Acl removeAces, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- // get type
- String objectTypeId = connector.getObjectTypeIdProperty(properties);
- final TypeDefinitionWrapper type = connector.getTypeForCreate(objectTypeId, BaseTypeId.CMIS_RELATIONSHIP);
-
- // get source object
- String sourceId = connector.getSourceIdProperty(properties);
- CMISNodeInfo sourceInfo = getOrCreateNodeInfo(sourceId, "Source");
-
- if (!sourceInfo.isVariant(CMISObjectVariant.CURRENT_VERSION) && !sourceInfo.isVariant(CMISObjectVariant.FOLDER))
- {
- throw new CmisInvalidArgumentException("Source is not the latest version of a document or a folder object!");
- }
-
- final NodeRef sourceNodeRef = sourceInfo.getNodeRef();
-
- // get target object
- String targetId = connector.getTargetIdProperty(properties);
- CMISNodeInfo targetInfo = getOrCreateNodeInfo(targetId, "Target");
-
- if (!targetInfo.isVariant(CMISObjectVariant.CURRENT_VERSION) && !targetInfo.isVariant(CMISObjectVariant.FOLDER))
- {
- throw new CmisInvalidArgumentException(
- "Target is not the latest version of a document or a folder object!!");
- }
-
- final NodeRef targetNodeRef = targetInfo.getNodeRef();
-
- // check policies and ACLs
- if ((policies != null) && (!policies.isEmpty()))
- {
- throw new CmisConstraintException("Relationships are not policy controllable!");
- }
-
- if ((addAces != null) && (addAces.getAces() != null) && (!addAces.getAces().isEmpty()))
- {
- throw new CmisConstraintException("Relationships are not ACL controllable!");
- }
-
- if ((removeAces != null) && (removeAces.getAces() != null) && (!removeAces.getAces().isEmpty()))
- {
- throw new CmisConstraintException("Relationships are not ACL controllable!");
- }
-
- // create relationship
- endReadOnlyTransaction();
- AssociationRef assocRef = connector.getTransactionService().getRetryingTransactionHelper()
- .doInTransaction(new RetryingTransactionCallback()
- {
- public AssociationRef execute() throws Exception
- {
- try
- {
- return connector.getNodeService().createAssociation(sourceNodeRef, targetNodeRef,
- type.getAlfrescoClass());
- }
- catch (IntegrityException ie)
- {
- throw new CmisConstraintException("Constraint violation: " + ie.getMessage(), ie);
- }
- catch (AccessDeniedException ade)
- {
- throw new CmisPermissionDeniedException("Permission denied!", ade);
- }
- };
- }, false, true);
- beginReadOnlyTransaction();
-
- return CMISConnector.ASSOC_ID_PREFIX + assocRef.getId();
- }
-
- @Override
- public void setContentStream(
- String repositoryId, Holder objectId, Boolean overwriteFlag,
- Holder changeToken, final ContentStream contentStream, ExtensionsData extension)
- {
- checkRepositoryId(repositoryId);
-
- CMISNodeInfo info = getOrCreateNodeInfo(objectId.getValue(), "Object");
-
- if (!info.isVariant(CMISObjectVariant.CURRENT_VERSION) && !info.isVariant(CMISObjectVariant.PWC))
- {
- throw new CmisStreamNotSupportedException("Content can only be set ondocuments!");
- }
-
- final NodeRef nodeRef = info.getNodeRef();
-
- if (((DocumentTypeDefinition) info.getType().getTypeDefinition(false)).getContentStreamAllowed() == ContentStreamAllowed.NOTALLOWED)
- {
- throw new CmisStreamNotSupportedException("Document type doesn't allow content!");
- }
-
- boolean existed = connector.getContentService().getReader(nodeRef, ContentModel.PROP_CONTENT) != null;
- if (existed && !overwriteFlag)
- {
- throw new CmisContentAlreadyExistsException("Content already exists!");
- }
-
- if ((contentStream == null) || (contentStream.getStream() == null))
- {
- throw new CmisInvalidArgumentException("No content!");
- }
-
- // copy stream to temp file
- final File tempFile = copyToTempFile(contentStream);
- final Charset encoding = getEncoding(tempFile, contentStream.getMimeType());
-
- endReadOnlyTransaction();
- connector.getTransactionService().getRetryingTransactionHelper()
- .doInTransaction(new RetryingTransactionCallback