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.BlobInfo;
031import org.nuxeo.ecm.core.blob.BlobManager;
032import org.nuxeo.ecm.core.blob.BlobProvider;
033
034/**
035 * Adapter between the {@link BinaryManager} and a {@link BlobProvider} for the {@link BlobManager}.
036 * <p>
037 * Can be used by legacy implementations of a {@link BinaryManager} to provide a {@link BlobProvider} implementation.
038 *
039 * @since 7.3
040 */
041public class BinaryBlobProvider implements BlobProvider {
042
043    private static final Log log = LogFactory.getLog(BinaryBlobProvider.class);
044
045    protected final BinaryManager binaryManager;
046
047    protected boolean supportsUserUpdate;
048
049    public BinaryBlobProvider(BinaryManager binaryManager) {
050        this.binaryManager = binaryManager;
051    }
052
053    @Override
054    public void initialize(String blobProviderId, Map<String, String> properties) throws IOException {
055        binaryManager.initialize(blobProviderId, properties);
056        supportsUserUpdate = supportsUserUpdateDefaultTrue(properties);
057    }
058
059    @Override
060    public boolean supportsUserUpdate() {
061        return supportsUserUpdate;
062    }
063
064    protected boolean supportsUserUpdateDefaultTrue(Map<String, String> properties) {
065        return !Boolean.parseBoolean(properties.get(PREVENT_USER_UPDATE));
066    }
067
068    /**
069     * Closes the adapted {@link BinaryManager}.
070     */
071    @Override
072    public void close() {
073        binaryManager.close();
074    }
075
076    @Override
077    public BinaryManager getBinaryManager() {
078        return binaryManager;
079    }
080
081    @Override
082    public Blob readBlob(BlobInfo blobInfo) throws IOException {
083        String digest = blobInfo.key;
084        // strip prefix
085        int colon = digest.indexOf(':');
086        if (colon >= 0) {
087            digest = digest.substring(colon + 1);
088        }
089        Binary binary = binaryManager.getBinary(digest);
090        if (binary == null) {
091            throw new IOException("Unknown binary: " + digest);
092        }
093        long length;
094        if (blobInfo.length == null) {
095            log.error("Missing blob length for: " + blobInfo.key);
096            // to avoid crashing, get the length from the binary's file (may be costly)
097            File file = binary.getFile();
098            length = file == null ? -1 : file.length();
099        } else {
100            length = blobInfo.length.longValue();
101        }
102        return new BinaryBlob(binary, blobInfo.key, blobInfo.filename, blobInfo.mimeType, blobInfo.encoding,
103                blobInfo.digest, length);
104    }
105
106    @Override
107    public String writeBlob(Blob blob) throws IOException {
108        // writes the blob and return its digest
109        return binaryManager.getBinary(blob).getDigest();
110    }
111
112}