001/*
002 * (C) Copyright 2006-2011 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 */
019
020package org.nuxeo.ecm.core.blob.binary;
021
022import java.io.File;
023import java.io.FileInputStream;
024import java.io.IOException;
025import java.io.InputStream;
026import java.io.Serializable;
027
028import org.apache.logging.log4j.LogManager;
029import org.apache.logging.log4j.Logger;
030import org.nuxeo.ecm.core.blob.BlobManager;
031import org.nuxeo.ecm.core.blob.BlobProvider;
032import org.nuxeo.runtime.api.Framework;
033
034/**
035 * A binary object that can be read, and has a length and a digest.
036 *
037 * @author Florent Guillaume
038 * @author Bogdan Stefanescu
039 */
040public class Binary implements Serializable {
041
042    private static final long serialVersionUID = 1L;
043
044    private static final Logger log = LogManager.getLogger(Binary.class);
045
046    protected final String digest;
047
048    protected final String blobProviderId;
049
050    protected transient File file;
051
052    protected Binary(String digest, String blobProviderId) {
053        this(null, digest, blobProviderId);
054    }
055
056    public Binary(File file, String digest, String blobProviderId) {
057        this.file = file;
058        this.digest = digest;
059        this.blobProviderId = blobProviderId;
060    }
061
062    /**
063     * Gets the digest algorithm from the digest length.
064     *
065     * @since 7.4
066     */
067    public String getDigestAlgorithm() {
068        // Cannot use current digest algorithm of the binary manager here since it might have changed after the binary
069        // storage
070        String digest = getDigest();
071        if (digest == null) {
072            return null;
073        }
074        return AbstractBinaryManager.DIGESTS_BY_LENGTH.get(digest.length());
075    }
076
077    /**
078     * Gets a string representation of the hex digest of the binary.
079     *
080     * @return the digest, characters are in the range {@code [0-9a-f]}
081     */
082    public String getDigest() {
083        return digest;
084    }
085
086    /**
087     * Gets the blob provider which created this blob.
088     * <p>
089     * This is usually the repository name.
090     *
091     * @return the blob provider id
092     * @since 7.3
093     */
094    public String getBlobProviderId() {
095        return blobProviderId;
096    }
097
098    /**
099     * Gets an input stream for the binary.
100     *
101     * @return the input stream
102     * @throws IOException
103     */
104    public InputStream getStream() throws IOException {
105        return new FileInputStream(file);
106    }
107
108    @Override
109    public String toString() {
110        return getClass().getSimpleName() + '(' + digest + ')';
111    }
112
113    public File getFile() {
114        return file;
115    }
116
117    private void writeObject(java.io.ObjectOutputStream oos) throws IOException, ClassNotFoundException {
118        oos.defaultWriteObject();
119    }
120
121    private void readObject(java.io.ObjectInputStream ois) throws IOException, ClassNotFoundException {
122        ois.defaultReadObject();
123        file = recomputeFile();
124    }
125
126    /**
127     * Recomputes the file attribute by getting it from a new Binary for the same digest.
128     */
129    protected File recomputeFile() {
130        BlobManager bm = Framework.getService(BlobManager.class);
131        BlobProvider bp = bm.getBlobProvider(blobProviderId);
132        Binary binary = bp.getBinaryManager().getBinary(digest);
133        if (binary == null) {
134            log.warn("Cannot fetch binary with digest " + digest);
135            return null;
136        }
137        return binary.file;
138    }
139
140}