001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.blob.binary;
020
021import static org.nuxeo.ecm.core.blob.BlobProviderDescriptor.PREVENT_USER_UPDATE;
022
023import java.io.File;
024import java.io.IOException;
025import java.util.Map;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.nuxeo.ecm.core.api.Blob;
030import org.nuxeo.ecm.core.blob.BlobManager;
031import org.nuxeo.ecm.core.blob.BlobManager.BlobInfo;
032import org.nuxeo.ecm.core.blob.BlobProvider;
033import org.nuxeo.ecm.core.model.Document;
034
035/**
036 * Adapter between the {@link BinaryManager} and a {@link BlobProvider} for the {@link BlobManager}.
037 * <p>
038 * Can be used by legacy implementations of a {@link BinaryManager} to provide a {@link BlobProvider} implementation.
039 *
040 * @since 7.3
041 */
042public class BinaryBlobProvider implements BlobProvider {
043
044    private static final Log log = LogFactory.getLog(BinaryBlobProvider.class);
045
046    protected final BinaryManager binaryManager;
047
048    protected boolean supportsUserUpdate;
049
050    public BinaryBlobProvider(BinaryManager binaryManager) {
051        this.binaryManager = binaryManager;
052    }
053
054    @Override
055    public void initialize(String blobProviderId, Map<String, String> properties) throws IOException {
056        binaryManager.initialize(blobProviderId, properties);
057        supportsUserUpdate = supportsUserUpdateDefaultTrue(properties);
058    }
059
060    @Override
061    public boolean supportsUserUpdate() {
062        return supportsUserUpdate;
063    }
064
065    protected boolean supportsUserUpdateDefaultTrue(Map<String, String> properties) {
066        return !Boolean.parseBoolean(properties.get(PREVENT_USER_UPDATE));
067    }
068
069    /**
070     * Closes the adapted {@link BinaryManager}.
071     */
072    @Override
073    public void close() {
074        binaryManager.close();
075    }
076
077    @Override
078    public BinaryManager getBinaryManager() {
079        return binaryManager;
080    }
081
082    @Override
083    public Blob readBlob(BlobInfo blobInfo) throws IOException {
084        String digest = blobInfo.key;
085        // strip prefix
086        int colon = digest.indexOf(':');
087        if (colon >= 0) {
088            digest = digest.substring(colon + 1);
089        }
090        Binary binary = binaryManager.getBinary(digest);
091        if (binary == null) {
092            throw new IOException("Unknown binary: " + digest);
093        }
094        long length;
095        if (blobInfo.length == null) {
096            log.error("Missing blob length for: " + blobInfo.key);
097            // to avoid crashing, get the length from the binary's file (may be costly)
098            File file = binary.getFile();
099            length = file == null ? -1 : file.length();
100        } else {
101            length = blobInfo.length.longValue();
102        }
103        return new BinaryBlob(binary, blobInfo.key, blobInfo.filename, blobInfo.mimeType, blobInfo.encoding,
104                blobInfo.digest, length);
105    }
106
107    @Override
108    public String writeBlob(Blob blob, Document doc) throws IOException {
109        // writes the blob and return its digest
110        return binaryManager.getBinary(blob).getDigest();
111    }
112
113}