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