package com.constellio.app.api.cmis.requests.versioning; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.chemistry.opencmis.commons.data.ContentStream; import org.apache.chemistry.opencmis.commons.enums.Action; import org.apache.chemistry.opencmis.commons.server.CallContext; import org.apache.chemistry.opencmis.commons.spi.Holder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.constellio.app.api.cmis.CmisExceptions.CmisExceptions_InvalidArgument; import com.constellio.app.api.cmis.binding.collection.ConstellioCollectionRepository; import com.constellio.app.api.cmis.binding.global.ConstellioCmisContextParameters; import com.constellio.app.api.cmis.binding.utils.CmisContentUtils; import com.constellio.app.api.cmis.binding.utils.ContentCmisDocument; import com.constellio.app.api.cmis.requests.CmisCollectionRequest; import com.constellio.app.extensions.api.cmis.params.GetObjectParams; import com.constellio.app.extensions.api.cmis.params.UpdateDocumentParams; import com.constellio.app.services.factories.AppLayerFactory; import com.constellio.data.io.services.facades.IOServices; import com.constellio.model.entities.records.Content; import com.constellio.model.entities.records.wrappers.User; import com.constellio.model.entities.schemas.MetadataSchemaTypes; import com.constellio.model.services.contents.ContentManager; import com.constellio.model.services.contents.ContentVersionDataSummary; import com.constellio.model.services.records.RecordServices; import com.constellio.model.services.records.RecordServicesException; public class ChangeContentStreamRequest extends CmisCollectionRequest<Boolean> { private static final String TEMP_FILE_RESOURCE_NAME = "ChangeContentStreamRequest-TempFile"; private static final String COPY_TO_TEMP_FILE = "ChangeContentStreamRequest-CopyToTempFile"; private static final String READ_TEMP_FILE = "ChangeContentStreamRequest-ReadTempFile"; private static final Logger LOGGER = LoggerFactory.getLogger(CmisCollectionRequest.class); private static final int BUFFER_SIZE = 64 * 1024; private final Holder<String> objectId; private final Boolean overwriteFlag; private final ContentStream contentStream; private final boolean append; public ChangeContentStreamRequest(ConstellioCollectionRepository repository, AppLayerFactory appLayerFactory, CallContext context, Holder<String> objectId, Boolean overwriteFlag, ContentStream contentStream, boolean append) { super(context, repository, appLayerFactory); this.objectId = objectId; this.overwriteFlag = overwriteFlag; this.contentStream = contentStream; this.append = append; } /** * CMIS setContentStream, deleteContentStream, and appendContentStream. */ @Override public Boolean process() { if (objectId == null) { throw new CmisExceptions_InvalidArgument("Id"); } RecordServices recordServices = modelLayerFactory.newRecordServices(); MetadataSchemaTypes types = modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(collection); ContentCmisDocument contentCmisDocument = CmisContentUtils.getContent(objectId.getValue(), recordServices, types); ensureUserHasAllowableActionsOnRecord(contentCmisDocument.getRecord(), Action.CAN_SET_CONTENT_STREAM); Content content = contentCmisDocument.getContent(); IOServices ioServices = modelLayerFactory.getIOServicesFactory().newIOServices(); ContentManager contentManager = modelLayerFactory.getContentManager(); // UpdateDocumentParams params = new UpdateDocumentParams(user, contentCmisDocument.getRecord()); // appLayerFactory.getExtensions().forCollection(collection).onUpdateCMISDocument(params); setContent(user, recordServices, contentCmisDocument, content, ioServices, contentManager); return true; } private void setContent(User user, RecordServices recordServices, ContentCmisDocument contentCmisDocument, Content content, IOServices ioServices, ContentManager contentManager) { File file = null; OutputStream out = null; InputStream inFromCopy = null; try { file = ioServices.newTemporaryFile(TEMP_FILE_RESOURCE_NAME); out = ioServices.newFileOutputStream(file, COPY_TO_TEMP_FILE); ioServices.copy(contentStream.getStream(), out); ioServices.closeQuietly(out); inFromCopy = ioServices.newFileInputStream(file, READ_TEMP_FILE); if (content.getCheckoutUserId() != null) { if (user.getId().equals(content.getCheckoutUserId())) { ContentVersionDataSummary dataSummary = uploadContent(inFromCopy, contentStream.getFileName()); content.updateCheckedOutContentWithName(dataSummary, contentStream.getFileName()); } else { throw new RuntimeException("TODO : Cannot modify content checked out by other user"); } } else { ContentVersionDataSummary dataSummary = uploadContent(inFromCopy, contentStream.getFileName()); content.updateContentWithName(user, dataSummary, false, contentStream.getFileName()); } recordServices.update(contentCmisDocument.getRecord(), user); } catch (IOException | RecordServicesException e) { throw new RuntimeException(e); } finally { ioServices.closeQuietly(out); ioServices.closeQuietly(inFromCopy); ioServices.deleteQuietly(file); } } @Override protected Logger getLogger() { return LOGGER; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } }