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