package com.constellio.app.api.cmis.binding.global;
import static com.constellio.model.entities.CorePermissions.USE_EXTERNAL_APIS_FOR_COLLECTION;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.chemistry.opencmis.commons.data.Acl;
import org.apache.chemistry.opencmis.commons.data.AllowableActions;
import org.apache.chemistry.opencmis.commons.data.BulkUpdateObjectIdAndChangeToken;
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.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.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.IncludeRelationships;
import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
import org.apache.chemistry.opencmis.commons.impl.server.AbstractCmisService;
import org.apache.chemistry.opencmis.commons.server.CallContext;
import org.apache.chemistry.opencmis.commons.spi.Holder;
import org.apache.chemistry.opencmis.server.support.wrapper.CallContextAwareCmisService;
import com.constellio.app.api.cmis.binding.collection.ConstellioCollectionRepository;
import com.constellio.app.api.cmis.requests.acl.ApplyAclRequest;
import com.constellio.app.api.cmis.requests.acl.GetAclRequest;
import com.constellio.app.api.cmis.requests.discovery.QueryUnsupportedRequest;
import com.constellio.app.api.cmis.requests.navigation.GetChildrenRequest;
import com.constellio.app.api.cmis.requests.navigation.GetDescendantsUnsupportedRequest;
import com.constellio.app.api.cmis.requests.navigation.GetFolderParentUnsupportedRequest;
import com.constellio.app.api.cmis.requests.navigation.GetObjectByPathRequest;
import com.constellio.app.api.cmis.requests.navigation.GetObjectParentsRequest;
import com.constellio.app.api.cmis.requests.object.AllowableActionsRequest;
import com.constellio.app.api.cmis.requests.object.BulkUpdatePropertiesRequest;
import com.constellio.app.api.cmis.requests.object.CreateDocumentRequest;
import com.constellio.app.api.cmis.requests.object.CreateFolderRequest;
import com.constellio.app.api.cmis.requests.object.CreateObjectRequest;
import com.constellio.app.api.cmis.requests.object.DeleteObjectRequest;
import com.constellio.app.api.cmis.requests.object.DeleteTreeRequest;
import com.constellio.app.api.cmis.requests.object.GetContentStreamRequest;
import com.constellio.app.api.cmis.requests.object.GetObjectRequest;
import com.constellio.app.api.cmis.requests.object.MoveObjectRequest;
import com.constellio.app.api.cmis.requests.object.UpdatePropertiesRequest;
import com.constellio.app.api.cmis.requests.objectType.GetTypeChildrenRequest;
import com.constellio.app.api.cmis.requests.objectType.GetTypeDefinitionRequest;
import com.constellio.app.api.cmis.requests.objectType.GetTypeDescendantsRequest;
import com.constellio.app.api.cmis.requests.repository.GetRepositoryInfoRequest;
import com.constellio.app.api.cmis.requests.versioning.CancelCheckOutUnsupportedRequest;
import com.constellio.app.api.cmis.requests.versioning.ChangeContentStreamRequest;
import com.constellio.app.api.cmis.requests.versioning.CheckInRequest;
import com.constellio.app.api.cmis.requests.versioning.CheckOutRequest;
import com.constellio.app.api.cmis.requests.versioning.GetAllVersionsRequest;
import com.constellio.app.api.cmis.requests.versioning.GetObjectOfLatestVersionUnsupportedRequest;
import com.constellio.app.api.cmis.requests.versioning.GetPropertiesOfLatestVersionRequest;
import com.constellio.app.services.factories.AppLayerFactory;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.entities.security.global.UserCredential;
import com.constellio.model.services.users.UserServices;
public class ConstellioCmisRequests extends AbstractCmisService implements CallContextAwareCmisService {
private final AppLayerFactory appLayerFactory;
private final CmisCacheManager repositoryManager;
private CallContext context;
/**
* The role of this class is to dispatch the service call to the correct constellio collection repository
*/
public ConstellioCmisRequests(AppLayerFactory appLayerFactory,
final CmisCacheManager repositoryManager) {
this.appLayerFactory = appLayerFactory;
this.repositoryManager = repositoryManager;
}
@Override
public CallContext getCallContext() {
return context;
}
/**
* This method should only be called by the service factory.
*/
@Override
public void setCallContext(CallContext context) {
this.context = context;
}
// --- repository service ---
@Override
public RepositoryInfo getRepositoryInfo(String repositoryId, ExtensionsData extension) {
ConstellioCollectionRepository repository = getConstellioCollectionRepository(repositoryId);
return new GetRepositoryInfoRequest(repository, appLayerFactory, repositoryId, extension, getCallContext())
.processRequest();
}
@Override
public List<RepositoryInfo> getRepositoryInfos(ExtensionsData extension) {
List<RepositoryInfo> result = new ArrayList<RepositoryInfo>();
UserServices userServices = appLayerFactory.getModelLayerFactory().newUserServices();
UserCredential userCredential = ConstellioCmisRequestFactory.authenticateUserFromContext(context, userServices);
CallContext callContext = getCallContext();
for (ConstellioCollectionRepository fsr : repositoryManager.getRepositories()) {
String collection = fsr.getCollection();
if (userCredential.getCollections().contains(collection)) {
User user = userServices.getUserInCollection(userCredential.getUsername(), collection);
if (userCredential.isSystemAdmin() || user.has(USE_EXTERNAL_APIS_FOR_COLLECTION).globally()) {
result.add(new GetRepositoryInfoRequest(fsr, appLayerFactory, collection, extension, callContext)
.processRequest());
}
}
}
return result;
}
@Override
public TypeDefinitionList getTypeChildren(String repositoryId, String typeId, Boolean includePropertyDefinitions,
BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
return new GetTypeChildrenRequest(getConstellioCollectionRepository(repositoryId), getCallContext(), typeId, maxItems,
includePropertyDefinitions, skipCount, appLayerFactory).processRequest();
}
@Override
public TypeDefinition getTypeDefinition(String repositoryId, String typeId, ExtensionsData extension) {
return new GetTypeDefinitionRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
getCallContext(),
typeId).processRequest();
}
@Override
public List<TypeDefinitionContainer> getTypeDescendants(String repositoryId, String typeId, BigInteger depth,
Boolean includePropertyDefinitions, ExtensionsData extension) {
return new GetTypeDescendantsRequest(getConstellioCollectionRepository(repositoryId), getCallContext(), typeId, depth,
includePropertyDefinitions, appLayerFactory).processRequest();
}
// --- 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) {
return new GetChildrenRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
folderId, filter, includeAllowableActions, includePathSegment, maxItems, skipCount, this).processRequest();
}
@Override
public List<ObjectInFolderContainer> getDescendants(String repositoryId, String folderId, BigInteger depth, String filter,
Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
Boolean includePathSegment, ExtensionsData extension) {
return new GetDescendantsUnsupportedRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
getCallContext(),
folderId, depth, filter, includeAllowableActions, includePathSegment, this, false).processRequest();
}
@Override
public ObjectData getFolderParent(String repositoryId, String folderId, String filter, ExtensionsData extension) {
GetObjectParentsRequest getObjectParentsRequest = new GetObjectParentsRequest(getConstellioCollectionRepository(
repositoryId),
appLayerFactory, getCallContext(), folderId, filter, null, null, this);
return new GetFolderParentUnsupportedRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
getObjectParentsRequest, getCallContext(), folderId, filter, this).processRequest();
}
@Override
public List<ObjectInFolderContainer> getFolderTree(String repositoryId, String folderId, BigInteger depth, String filter,
Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
Boolean includePathSegment, ExtensionsData extension) {
return new GetDescendantsUnsupportedRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
getCallContext(),
folderId, depth, filter, includeAllowableActions, includePathSegment, this, true).processRequest();
}
@Override
public List<ObjectParentData> getObjectParents(String repositoryId, String objectId, String filter,
Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
Boolean includeRelativePathSegment, ExtensionsData extension) {
return new GetObjectParentsRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
getCallContext(),
objectId, filter, includeAllowableActions, includeRelativePathSegment, this).processRequest();
}
@Override
public ObjectList getCheckedOutDocs(String repositoryId, String folderId, String filter, String orderBy,
Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
ObjectListImpl result = new ObjectListImpl();
result.setHasMoreItems(false);
result.setNumItems(BigInteger.ZERO);
List<ObjectData> emptyList = Collections.emptyList();
result.setObjects(emptyList);
return result;
}
// --- object service ---
@Override
public String create(String repositoryId, Properties properties, String folderId, ContentStream contentStream,
VersioningState versioningState, List<String> policies, ExtensionsData extension) {
CreateFolderRequest createFolderRequest = new CreateFolderRequest(getConstellioCollectionRepository(repositoryId),
appLayerFactory, getCallContext(), properties, folderId);
CreateDocumentRequest createDocumentRequest = new CreateDocumentRequest(getConstellioCollectionRepository(repositoryId),
appLayerFactory, getCallContext(), properties, folderId, contentStream, versioningState);
ObjectData object = new CreateObjectRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
createFolderRequest, createDocumentRequest, getCallContext(), properties, folderId, contentStream,
versioningState, this).processRequest();
return object.getId();
}
@Override
public String createDocument(String repositoryId, Properties properties, String folderId, ContentStream contentStream,
VersioningState versioningState, List<String> policies, Acl addAces, Acl removeAces, ExtensionsData extension) {
return new CreateDocumentRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
properties, folderId, contentStream, versioningState).processRequest().getDocumentId();
}
@Override
public String createFolder(String repositoryId, Properties properties, String folderId, List<String> policies, Acl addAces,
Acl removeAces, ExtensionsData extension) {
return new CreateFolderRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
properties, folderId).processRequest();
}
@Override
public void deleteObjectOrCancelCheckOut(String repositoryId, String objectId, Boolean allVersions,
ExtensionsData extension) {
new DeleteObjectRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(), objectId)
.processRequest();
}
@Override
public FailedToDeleteData deleteTree(String repositoryId, String folderId, Boolean allVersions, UnfileObject unfileObjects,
Boolean continueOnFailure, ExtensionsData extension) {
return new DeleteTreeRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
folderId,
continueOnFailure).processRequest();
}
@Override
public AllowableActions getAllowableActions(String repositoryId, String objectId, ExtensionsData extension) {
return new AllowableActionsRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
getCallContext(),
objectId).processRequest();
}
@Override
public ContentStream getContentStream(String repositoryId, String objectId, String streamId, BigInteger offset,
BigInteger length, ExtensionsData extension) {
ContentStream contentStream = new GetContentStreamRequest(getConstellioCollectionRepository(repositoryId),
appLayerFactory,
getCallContext(), objectId, offset, length).processRequest();
return contentStream;
}
@Override
public ObjectData getObject(String repositoryId, String objectId, String filter, Boolean includeAllowableActions,
IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds, Boolean includeAcl,
ExtensionsData extension) {
return new GetObjectRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
objectId,
null, filter, includeAllowableActions, includeAcl, this).processRequest();
}
@Override
public ObjectData getObjectByPath(String repositoryId, String path, String filter, Boolean includeAllowableActions,
IncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds, Boolean includeAcl,
ExtensionsData extension) {
return new GetObjectByPathRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
path, filter, includeAllowableActions, includeAcl, this).processRequest();
}
@Override
public Properties getProperties(String repositoryId, String objectId, String filter, ExtensionsData extension) {
ObjectData object = new GetObjectRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
getCallContext(), objectId, null, filter, false, false, this).processRequest();
return object.getProperties();
}
@Override
public List<RenditionData> getRenditions(String repositoryId, String objectId, String renditionFilter, BigInteger maxItems,
BigInteger skipCount, ExtensionsData extension) {
return Collections.emptyList();
}
@Override
public void moveObject(String repositoryId, Holder<String> objectId, String targetFolderId, String sourceFolderId,
ExtensionsData extension) {
new MoveObjectRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(), objectId,
targetFolderId, this).processRequest();
}
@Override
public void setContentStream(String repositoryId, Holder<String> objectId, Boolean overwriteFlag, Holder<String> changeToken,
ContentStream contentStream, ExtensionsData extension) {
new ChangeContentStreamRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
objectId, overwriteFlag, contentStream, false).processRequest();
}
@Override
public void appendContentStream(String repositoryId, Holder<String> objectId, Holder<String> changeToken,
ContentStream contentStream, boolean isLastChunk, ExtensionsData extension) {
new ChangeContentStreamRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
objectId, true, contentStream, true).processRequest();
}
@Override
public void deleteContentStream(String repositoryId, Holder<String> objectId, Holder<String> changeToken,
ExtensionsData extension) {
new ChangeContentStreamRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
objectId, true, null, false).processRequest();
}
@Override
public void updateProperties(String repositoryId, Holder<String> objectId, Holder<String> changeToken, Properties properties,
ExtensionsData extension) {
new UpdatePropertiesRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
objectId,
properties, this).processRequest();
}
@Override
public List<BulkUpdateObjectIdAndChangeToken> bulkUpdateProperties(String repositoryId,
List<BulkUpdateObjectIdAndChangeToken> objectIdAndChangeToken, Properties properties,
List<String> addSecondaryTypeIds, List<String> removeSecondaryTypeIds, ExtensionsData extension) {
UpdatePropertiesRequest updatePropertiesRequest = new UpdatePropertiesRequest(getConstellioCollectionRepository(
repositoryId),
appLayerFactory, getCallContext(), null, properties, this);
return new BulkUpdatePropertiesRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
updatePropertiesRequest, getCallContext(), objectIdAndChangeToken, properties, this).processRequest();
}
// --- versioning service ---
@Override
public List<ObjectData> getAllVersions(String repositoryId, String objectId, String versionSeriesId, String filter,
Boolean includeAllowableActions, ExtensionsData extension) {
return new GetAllVersionsRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
repositoryId, objectId, versionSeriesId, filter, includeAllowableActions, extension, this).processRequest();
}
@Override
public void checkOut(String repositoryId, Holder<String> objectId, ExtensionsData extension, Holder<Boolean> contentCopied) {
new CheckOutRequest(getConstellioCollectionRepository(repositoryId), context, appLayerFactory, repositoryId,
objectId,
extension,
contentCopied).processRequest();
}
@Override
public void cancelCheckOut(String repositoryId, String objectId, ExtensionsData extension) {
new CancelCheckOutUnsupportedRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
repositoryId, objectId, extension).processRequest();
}
@Override
public void checkIn(String repositoryId, Holder<String> objectId, Boolean major, Properties properties,
ContentStream contentStream, String checkinComment, List<String> policies, Acl addAces, Acl removeAces,
ExtensionsData extension) {
new CheckInRequest(getConstellioCollectionRepository(repositoryId), getCallContext(), appLayerFactory, repositoryId,
objectId, major, properties, contentStream, checkinComment, policies, addAces, removeAces, extension)
.processRequest();
}
@Override
public ObjectData getObjectOfLatestVersion(String repositoryId, String objectId, String versionSeriesId, Boolean major,
String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
Boolean includePolicyIds, Boolean includeAcl, ExtensionsData extension) {
return new GetObjectOfLatestVersionUnsupportedRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
getCallContext(), objectId, versionSeriesId, major, filter, includeAllowableActions, includeRelationships,
renditionFilter, includePolicyIds, includeAcl, extension, this).processRequest();
}
@Override
public Properties getPropertiesOfLatestVersion(String repositoryId, String objectId, String versionSeriesId, Boolean major,
String filter, ExtensionsData extension) {
return new GetPropertiesOfLatestVersionRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory,
getCallContext(), objectId, versionSeriesId, major, filter, extension).processRequest();
}
// --- ACL service ---
@Override
public Acl getAcl(String repositoryId, String objectId, Boolean onlyBasicPermissions, ExtensionsData extension) {
return new GetAclRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(), objectId)
.processRequest();
}
@Override
public Acl applyAcl(String repositoryId, String objectId, Acl addAces, Acl removeAces, AclPropagation aclPropagation,
ExtensionsData extension) {
return new ApplyAclRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
repositoryId, objectId, addAces, removeAces, aclPropagation, extension).processRequest();
}
@Override
public Acl applyAcl(String repositoryId, String objectId, Acl aces, AclPropagation aclPropagation) {
return new ApplyAclRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
repositoryId, objectId, aces, aclPropagation).processRequest();
}
// --- discovery service ---
@Override
public ObjectList query(String repositoryId, String statement, Boolean searchAllVersions, Boolean includeAllowableActions,
IncludeRelationships includeRelationships, String renditionFilter, BigInteger maxItems, BigInteger skipCount,
ExtensionsData extension) {
return new QueryUnsupportedRequest(getConstellioCollectionRepository(repositoryId), appLayerFactory, getCallContext(),
statement,
includeAllowableActions, maxItems, skipCount, this).processRequest();
}
// --- Utils ---
private ConstellioCollectionRepository getConstellioCollectionRepository(String repositoryId) {
return repositoryManager.getCollectionRepository(repositoryId);
}
}