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