All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bonitasoft.engine.api.impl.DocumentAPIImpl Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2019 Bonitasoft S.A.
 * Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble
 * This library 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
 * version 2.1 of the License.
 * This library 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 this
 * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301, USA.
 **/
package org.bonitasoft.engine.api.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.bonitasoft.engine.api.DocumentAPI;
import org.bonitasoft.engine.api.impl.transaction.document.GetDocumentByNameAtProcessInstantiation;
import org.bonitasoft.engine.bpm.document.*;
import org.bonitasoft.engine.commons.exceptions.SBonitaException;
import org.bonitasoft.engine.commons.exceptions.SObjectAlreadyExistsException;
import org.bonitasoft.engine.commons.exceptions.SObjectNotFoundException;
import org.bonitasoft.engine.core.document.api.DocumentService;
import org.bonitasoft.engine.core.document.api.impl.DocumentHelper;
import org.bonitasoft.engine.core.document.model.AbstractSMappedDocument;
import org.bonitasoft.engine.core.document.model.SDocument;
import org.bonitasoft.engine.core.document.model.SMappedDocument;
import org.bonitasoft.engine.core.document.model.builder.SDocumentBuilderFactory;
import org.bonitasoft.engine.core.process.definition.ProcessDefinitionService;
import org.bonitasoft.engine.core.process.instance.api.ActivityInstanceService;
import org.bonitasoft.engine.core.process.instance.api.ProcessInstanceService;
import org.bonitasoft.engine.core.process.instance.model.archive.SAActivityInstance;
import org.bonitasoft.engine.exception.*;
import org.bonitasoft.engine.persistence.OrderAndField;
import org.bonitasoft.engine.persistence.SBonitaReadException;
import org.bonitasoft.engine.search.SearchOptions;
import org.bonitasoft.engine.search.SearchResult;
import org.bonitasoft.engine.search.descriptor.SearchEntitiesDescriptor;
import org.bonitasoft.engine.search.document.SearchArchivedDocuments;
import org.bonitasoft.engine.search.document.SearchArchivedDocumentsSupervisedBy;
import org.bonitasoft.engine.search.document.SearchDocuments;
import org.bonitasoft.engine.search.document.SearchDocumentsSupervisedBy;
import org.bonitasoft.engine.service.ModelConvertor;
import org.bonitasoft.engine.service.ServiceAccessor;
import org.bonitasoft.engine.service.ServiceAccessorSingleton;

/**
 * @author Baptiste Mesta
 */
public class DocumentAPIImpl implements DocumentAPI {

    public DocumentAPIImpl() {
    }

    @Override
    public Document attachDocument(final long processInstanceId, final String documentName, final String fileName,
            final String mimeType, final String url)
            throws DocumentAttachmentException {
        final DocumentValue documentValue = new DocumentValue(url);
        documentValue.setFileName(fileName);
        documentValue.setMimeType(mimeType);
        try {
            return addDocument(processInstanceId, documentName, null, documentValue);
        } catch (final BonitaException e) {
            throw new DocumentAttachmentException(e);
        }
    }

    /*
     * If the target document is a list of document then we append it to the list
     * If the target document is a list of document and the index is set on the document value then we insert the
     * element in the list at the specified index
     * If the target single document or is non existent in the definition we create it
     * If the target single document and is already existent an exception is thrown
     */
    @Override
    public Document addDocument(final long processInstanceId, final String documentName, final String description,
            final DocumentValue documentValue)
            throws DocumentAttachmentException, AlreadyExistsException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();

        final DocumentHelper documentHelper = new DocumentHelper(documentService,
                serviceAccessor.getProcessDefinitionService(),
                serviceAccessor.getProcessInstanceService());
        final SDocument sDocument = buildSDocument(documentValue);
        int index = documentValue.getIndex();
        try {
            if (documentHelper.isListDefinedInDefinition(documentName, processInstanceId)) {
                final List allDocumentOfTheList = documentHelper
                        .getAllDocumentOfTheList(processInstanceId, documentName);
                if (index == -1) {
                    index = allDocumentOfTheList.size();
                } else {
                    if (index > allDocumentOfTheList.size()) {
                        throw new DocumentAttachmentException(
                                "Can't attach a document on the list " + documentName + " on process instance "
                                        + processInstanceId + " the index is out of range, list size is "
                                        + allDocumentOfTheList.size());
                    }
                    for (int i = index; i < allDocumentOfTheList.size(); i++) {
                        documentService.updateDocumentIndex(allDocumentOfTheList.get(i), i + 1);
                    }
                }
            } else {
                if (index >= 0) {
                    throw new DocumentAttachmentException(
                            "Unable to add a document with an index if it is a single document");
                }
            }
            final SMappedDocument mappedDocument = documentService.attachDocumentToProcessInstance(sDocument,
                    processInstanceId, documentName, description,
                    index);
            return ModelConvertor.toDocument(mappedDocument, documentService);

        } catch (final SObjectAlreadyExistsException e) {
            throw new AlreadyExistsException(e.getMessage());
        } catch (final SBonitaException e) {
            throw new DocumentAttachmentException(e);
        }

    }

    @Override
    public Document updateDocument(final long documentId, final DocumentValue documentValue)
            throws DocumentAttachmentException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        try {
            final SMappedDocument document = documentService.updateDocument(documentId, buildSDocument(documentValue));
            return ModelConvertor.toDocument(document, documentService);
        } catch (final SBonitaException e) {
            throw new DocumentAttachmentException(e);
        }
    }

    private SDocument buildSDocument(final DocumentValue documentValue) {
        if (documentValue.hasContent()) {
            return buildProcessDocument(documentValue.getFileName(), documentValue.getMimeType(), getUserId(),
                    documentValue.getContent());
        }
        return buildExternalProcessDocumentReference(documentValue.getFileName(), documentValue.getMimeType(),
                getUserId(), documentValue.getUrl());
    }

    private long getUserId() {
        return APIUtils.getUserId();
    }

    private SDocument buildExternalProcessDocumentReference(final String fileName, final String mimeType,
            final long authorId, final String url) {
        return new SDocumentBuilderFactory()
                .createNewExternalProcessDocumentReference(fileName, mimeType, authorId, url).done();
    }

    private SDocument buildProcessDocument(final String fileName, final String mimeType, final long authorId,
            final byte[] content) {
        return new SDocumentBuilderFactory().createNewProcessDocument(fileName, mimeType, authorId, content).done();
    }

    @Override
    public Document attachDocument(final long processInstanceId, final String documentName, final String fileName,
            final String mimeType,
            final byte[] documentContent) throws DocumentAttachmentException {
        final DocumentValue documentValue = new DocumentValue(documentContent, mimeType, fileName);
        try {
            return addDocument(processInstanceId, documentName, null, documentValue);
        } catch (final BonitaException e) {
            throw new DocumentAttachmentException(e);
        }
    }

    ServiceAccessor getServiceAccessor() {
        return ServiceAccessorSingleton.getInstance();
    }

    @Override
    public Document attachNewDocumentVersion(final long processInstanceId, final String documentName,
            final String fileName, final String mimeType,
            final String url) throws DocumentAttachmentException {
        final DocumentService documentService = getServiceAccessor().getDocumentService();
        try {
            return ModelConvertor.toDocument(
                    documentService.updateDocument(documentService.getMappedDocument(processInstanceId, documentName),
                            buildExternalProcessDocumentReference(fileName, mimeType, getUserId(), url)),
                    documentService);
        } catch (final Exception e) {
            throw new DocumentAttachmentException(e);
        }
    }

    @Override
    public Document attachNewDocumentVersion(final long processInstanceId, final String documentName,
            final String contentFileName,
            final String contentMimeType, final byte[] documentContent) throws DocumentAttachmentException {
        final DocumentService documentService = getServiceAccessor().getDocumentService();
        try {
            return ModelConvertor.toDocument(
                    documentService.updateDocument(documentService.getMappedDocument(processInstanceId, documentName),
                            buildProcessDocument(contentFileName, contentMimeType, getUserId(), documentContent)),
                    documentService);
        } catch (final Exception e) {
            throw new DocumentAttachmentException(e);
        }
    }

    @Override
    public Document getDocument(final long documentId) throws DocumentNotFoundException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        try {
            return ModelConvertor.toDocument(documentService.getMappedDocument(documentId), documentService);
        } catch (final SObjectNotFoundException | SBonitaReadException e) {
            throw new DocumentNotFoundException(e);
        }
    }

    @Override
    public List getLastVersionOfDocuments(final long processInstanceId, final int pageIndex,
            final int numberPerPage,
            final DocumentCriterion pagingCriterion) throws DocumentException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();

        final OrderAndField orderAndField = OrderAndFields.getOrderAndFieldForDocument(pagingCriterion);
        try {
            final List mappedDocuments = documentService.getDocumentsOfProcessInstance(
                    processInstanceId, pageIndex, numberPerPage,
                    orderAndField.getField(), orderAndField.getOrder());
            if (mappedDocuments != null && !mappedDocuments.isEmpty()) {
                final List result = new ArrayList<>(mappedDocuments.size());
                for (final SMappedDocument mappedDocument : mappedDocuments) {
                    result.add(ModelConvertor.toDocument(mappedDocument, documentService));
                }
                return result;
            }
            return Collections.emptyList();
        } catch (final SBonitaReadException e) {
            throw new DocumentException(e);
        }
    }

    @Override
    public byte[] getDocumentContent(final String documentStorageId) throws DocumentNotFoundException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        try {
            return documentService.getDocumentContent(documentStorageId);
        } catch (final SObjectNotFoundException sbe) {
            throw new DocumentNotFoundException(sbe);
        }
    }

    @Override
    public Document getLastDocument(final long processInstanceId, final String documentName)
            throws DocumentNotFoundException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        try {
            return ModelConvertor.toDocument(documentService.getMappedDocument(processInstanceId, documentName),
                    documentService);
        } catch (final SObjectNotFoundException | SBonitaReadException sbe) {
            throw new DocumentNotFoundException(sbe);
        }
    }

    @Override
    public long getNumberOfDocuments(final long processInstanceId) throws DocumentException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        try {
            return documentService.getNumberOfDocumentsOfProcessInstance(processInstanceId);
        } catch (final SBonitaReadException e) {
            throw new DocumentException(e);
        }
    }

    @Override
    public Document getDocumentAtProcessInstantiation(final long processInstanceId, final String documentName)
            throws DocumentNotFoundException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        final ProcessInstanceService processInstanceService = serviceAccessor.getProcessInstanceService();
        final SearchEntitiesDescriptor searchEntitiesDescriptor = serviceAccessor.getSearchEntitiesDescriptor();

        try {
            final GetDocumentByNameAtProcessInstantiation transactionContent = new GetDocumentByNameAtProcessInstantiation(
                    documentService,
                    processInstanceService, serviceAccessor.getProcessDefinitionService(), searchEntitiesDescriptor,
                    processInstanceId, documentName);
            transactionContent.execute();
            final AbstractSMappedDocument attachment = transactionContent.getResult();
            return ModelConvertor.toDocument(attachment, documentService);
        } catch (final SBonitaException sbe) {
            throw new DocumentNotFoundException(sbe);
        }
    }

    @Override
    public Document getDocumentAtActivityInstanceCompletion(final long activityInstanceId, final String documentName)
            throws DocumentNotFoundException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        final ActivityInstanceService activityInstanceService = serviceAccessor.getActivityInstanceService();
        try {
            final SAActivityInstance instance = activityInstanceService
                    .getMostRecentArchivedActivityInstance(activityInstanceId);
            final AbstractSMappedDocument document = documentService.getMappedDocument(instance.getRootContainerId(),
                    documentName, instance.getArchiveDate());
            return ModelConvertor.toDocument(document, documentService);
        } catch (final SBonitaException sbe) {
            throw new DocumentNotFoundException(sbe);
        }
    }

    @Override
    public SearchResult searchDocuments(final SearchOptions searchOptions) throws SearchException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();

        final SearchEntitiesDescriptor searchEntitiesDescriptor = serviceAccessor.getSearchEntitiesDescriptor();
        final DocumentService documentService = serviceAccessor.getDocumentService();

        final SearchDocuments searchDocuments = new SearchDocuments(documentService,
                searchEntitiesDescriptor.getSearchDocumentDescriptor(),
                searchOptions);
        try {
            searchDocuments.execute();
        } catch (final SBonitaException e) {
            throw new SearchException(e);
        }
        return searchDocuments.getResult();
    }

    @Override
    public SearchResult searchDocumentsSupervisedBy(final long userId, final SearchOptions searchOptions)
            throws SearchException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();

        final SearchEntitiesDescriptor searchEntitiesDescriptor = serviceAccessor.getSearchEntitiesDescriptor();
        final DocumentService documentService = serviceAccessor.getDocumentService();

        final SearchDocumentsSupervisedBy searchDocuments = new SearchDocumentsSupervisedBy(documentService,
                searchEntitiesDescriptor.getSearchDocumentDescriptor(), searchOptions, userId);
        try {
            searchDocuments.execute();
        } catch (final SBonitaException e) {
            throw new SearchException(e);
        }
        return searchDocuments.getResult();
    }

    @Override
    public SearchResult searchArchivedDocuments(final SearchOptions searchOptions)
            throws SearchException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();

        final SearchEntitiesDescriptor searchEntitiesDescriptor = serviceAccessor.getSearchEntitiesDescriptor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        final SearchArchivedDocuments searchDocuments = new SearchArchivedDocuments(documentService,
                searchEntitiesDescriptor.getSearchArchivedDocumentDescriptor(), searchOptions);
        try {
            searchDocuments.execute();
        } catch (final SBonitaException e) {
            throw new SearchException(e);
        }
        return searchDocuments.getResult();
    }

    @Override
    public SearchResult searchArchivedDocumentsSupervisedBy(final long userId,
            final SearchOptions searchOptions) throws SearchException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();

        final SearchEntitiesDescriptor searchEntitiesDescriptor = serviceAccessor.getSearchEntitiesDescriptor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        final SearchArchivedDocumentsSupervisedBy searchDocuments = new SearchArchivedDocumentsSupervisedBy(userId,
                documentService,
                searchEntitiesDescriptor.getSearchArchivedDocumentDescriptor(), searchOptions);
        try {
            searchDocuments.execute();
        } catch (final SBonitaException e) {
            throw new SearchException(e);
        }
        return searchDocuments.getResult();
    }

    @Override
    public ArchivedDocument getArchivedVersionOfProcessDocument(final long sourceObjectId)
            throws ArchivedDocumentNotFoundException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();

        try {
            return ModelConvertor.toArchivedDocument(
                    documentService.getArchivedVersionOfProcessDocument(sourceObjectId), documentService);
        } catch (final SObjectNotFoundException e) {
            throw new ArchivedDocumentNotFoundException(e);
        }
    }

    @Override
    public ArchivedDocument getArchivedProcessDocument(final long archivedProcessDocumentId)
            throws ArchivedDocumentNotFoundException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        try {
            return ModelConvertor.toArchivedDocument(documentService.getArchivedDocument(archivedProcessDocumentId),
                    documentService);
        } catch (final SObjectNotFoundException e) {
            throw new ArchivedDocumentNotFoundException(e);
        }
    }

    @Override
    public Document removeDocument(final long documentId) throws DocumentNotFoundException, DeletionException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        final DocumentHelper documentHelper = new DocumentHelper(documentService,
                serviceAccessor.getProcessDefinitionService(),
                serviceAccessor.getProcessInstanceService());
        try {
            final SMappedDocument document = documentService.getMappedDocument(documentId);
            final int index = document.getIndex();
            if (index != -1) {
                //document is in list
                final List allDocumentOfTheList = documentHelper
                        .getAllDocumentOfTheList(document.getProcessInstanceId(), document.getName());

                for (int i = index + 1; i < allDocumentOfTheList.size(); i++) {
                    documentService.updateDocumentIndex(allDocumentOfTheList.get(i), i - 1);

                }
            }
            documentService.removeCurrentVersion(document);
            return ModelConvertor.toDocument(document, documentService);
        } catch (final SObjectNotFoundException e) {
            throw new DocumentNotFoundException(
                    "Unable to delete the document " + documentId + " because it does not exists", e);
        } catch (final SBonitaException e) {
            throw new DeletionException("Unable to delete the document " + documentId, e);
        }
    }

    @Override
    public List getDocumentList(final long processInstanceId, final String name, final int fromIndex,
            final int numberOfResult)
            throws DocumentNotFoundException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        final ProcessDefinitionService processDefinitionService = serviceAccessor.getProcessDefinitionService();
        final ProcessInstanceService processInstanceService = serviceAccessor.getProcessInstanceService();
        final DocumentHelper documentHelper = new DocumentHelper(documentService, processDefinitionService,
                processInstanceService);
        try {
            final List documentList = documentService.getDocumentList(name, processInstanceId,
                    fromIndex, numberOfResult);
            if (documentList.isEmpty()
                    && !documentHelper.isListDefinedInDefinition(name, processInstanceId)) {
                throw new DocumentNotFoundException("doc not found");
            }
            return ModelConvertor.toDocuments(new ArrayList<>(documentList), documentService);
        } catch (final org.bonitasoft.engine.commons.exceptions.SObjectNotFoundException e) {
            throw new DocumentNotFoundException(e);
        } catch (final SBonitaReadException e) {
            throw new RetrieveException(e);
        }
    }

    @Override
    public void setDocumentList(final long processInstanceId, final String name,
            final List documentsValues) throws DocumentException {
        final ServiceAccessor serviceAccessor = getServiceAccessor();
        final DocumentHelper documentHelper = new DocumentHelper(serviceAccessor.getDocumentService(),
                serviceAccessor.getProcessDefinitionService(),
                serviceAccessor.getProcessInstanceService());
        try {
            documentHelper.setDocumentList(documentsValues, name, processInstanceId, getUserId());
        } catch (final SBonitaException e) {
            throw new DocumentException("Unable to set the list " + name + " on process instance " + processInstanceId,
                    e);
        }
    }

    @Override
    public void deleteContentOfArchivedDocument(final long archivedDocumentId)
            throws DocumentException, DocumentNotFoundException {
        final ServiceAccessor serviceAccessor = ServiceAccessorSingleton.getInstance();
        final DocumentService documentService = serviceAccessor.getDocumentService();
        try {
            documentService.deleteContentOfArchivedDocument(archivedDocumentId);
        } catch (final SObjectNotFoundException e) {
            throw new DocumentNotFoundException("The document with id " + archivedDocumentId + " could not be found",
                    e);
        } catch (final SBonitaException e) {
            throw new DocumentException("Unable to delete content of all version of the document " + archivedDocumentId,
                    e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy