001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Florent Guillaume
016 */
017package org.nuxeo.ecm.core.blob;
018
019import java.io.IOException;
020import java.io.InputStream;
021import java.net.URI;
022import java.util.Map;
023import java.util.Set;
024
025import javax.servlet.http.HttpServletRequest;
026
027import org.nuxeo.ecm.core.api.Blob;
028import org.nuxeo.ecm.core.api.DocumentModel;
029import org.nuxeo.ecm.core.blob.binary.BinaryManager;
030import org.nuxeo.ecm.core.blob.binary.BinaryManagerStatus;
031import org.nuxeo.ecm.core.model.Document;
032
033/**
034 * Service managing the storage and retrieval of {@link Blob}s, through internally-registered {@link BlobProvider}s.
035 *
036 * @since 7.2
037 */
038public interface BlobManager {
039
040    /**
041     * Class describing information from a {@link Blob}, suitable for serialization and storage.
042     *
043     * @since 7.2
044     */
045    class BlobInfo {
046        public String key;
047
048        public String mimeType;
049
050        public String encoding;
051
052        public String filename;
053
054        public Long length;
055
056        public String digest;
057
058        /** Empty constructor. */
059        public BlobInfo() {
060        }
061
062        /**
063         * Copy constructor.
064         *
065         * @since 7.10
066         */
067        public BlobInfo(BlobInfo other) {
068            key = other.key;
069            mimeType = other.mimeType;
070            encoding = other.encoding;
071            filename = other.filename;
072            length = other.length;
073            digest = other.digest;
074        }
075    }
076
077    /**
078     * Hints for returning {@link URI}s appropriate for the expected usage.
079     *
080     * @since 7.3
081     */
082    enum UsageHint {
083        /** Obtaining an {@link InputStream}. */
084        STREAM, //
085        /** Downloading. */
086        DOWNLOAD, //
087        /** Viewing. */
088        VIEW, //
089        /** Editing. */
090        EDIT, //
091        /** Embedding / previewing. */
092        EMBED
093    }
094
095    /**
096     * Gets the blob provider with the given id.
097     *
098     * @param id the blob provider id
099     * @return the blob provider
100     */
101    BlobProvider getBlobProvider(String id);
102
103    /**
104     * Gets the blob provider for the given blob.
105     *
106     * @return the blob provider
107     * @since 7.4
108     */
109    BlobProvider getBlobProvider(Blob blob);
110
111    /**
112     * Reads a {@link Blob} from storage.
113     *
114     * @param blobInfo the blob information
115     * @param repositoryName the repository to which this blob belongs
116     * @return a managed blob
117     */
118    Blob readBlob(BlobInfo blobInfo, String repositoryName) throws IOException;
119
120    /**
121     * Writes a {@link Blob} to storage and returns its key.
122     *
123     * @param blob the blob
124     * @param doc the document to which this blob belongs
125     * @return the blob key
126     */
127    String writeBlob(Blob blob, Document doc) throws IOException;
128
129    /**
130     * INTERNAL - Gets an {@link InputStream} for the data of a managed blob. Used by internal implementations, regular
131     * callers should call {@link Blob#getStream}.
132     *
133     * @param blob the blob
134     * @return the stream
135     */
136    InputStream getStream(Blob blob) throws IOException;
137
138    /**
139     * Gets an {@link InputStream} for a thumbnail of a blob.
140     * <p>
141     * Like all {@link InputStream}, the result must be closed when done with it to avoid resource leaks.
142     *
143     * @param blob the blob
144     * @return the thumbnail stream
145     */
146    InputStream getThumbnail(Blob blob) throws IOException;
147
148    /**
149     * Gets an {@link URI} for the content of a blob.
150     *
151     * @param blob the blob
152     * @param hint {@link UsageHint}
153     * @param servletRequest the servlet request, or {@code null}
154     * @return the {@link URI}, or {@code null} if none available
155     */
156    URI getURI(Blob blob, UsageHint hint, HttpServletRequest servletRequest) throws IOException;
157
158    /**
159     * Gets a map of available MIME type conversions and corresponding {@link URI} for a blob.
160     *
161     * @return a map of MIME types and {@link URI}, which may be empty
162     */
163    Map<String, URI> getAvailableConversions(Blob blob, UsageHint hint) throws IOException;
164
165    /**
166     * Gets an {@link InputStream} for a conversion to the given MIME type.
167     * <p>
168     * Like all {@link InputStream}, the result must be closed when done with it to avoid resource leaks.
169     *
170     * @param blob the blob
171     * @param mimeType the MIME type to convert to
172     * @param doc the document that holds the blob
173     * @return the stream, or {@code null} if no conversion is available for the given MIME type
174     */
175    InputStream getConvertedStream(Blob blob, String mimeType, DocumentModel doc) throws IOException;
176
177    /**
178     * Get the map of blob providers
179     *
180     * @return the list of blob providers
181     * @since 7.3
182     */
183    Map<String, BlobProvider> getBlobProviders();
184
185    /**
186     * Freezes the blobs' versions on a document version when it is created via a check in.
187     *
188     * @param doc the new document version
189     * @since 7.3
190     */
191    void freezeVersion(Document doc);
192
193    /**
194     * Notifies the blob manager that a set of xpaths have changed on a document.
195     *
196     * @param doc the document
197     * @param xpaths the set of changed xpaths
198     * @since 7.3
199     */
200    void notifyChanges(Document doc, Set<String> xpaths);
201
202    /**
203     * Garbage collect the unused binaries.
204     *
205     * @param delete if {@code false} don't actually delete the garbage collected binaries (but still return statistics
206     *            about them), if {@code true} delete them
207     * @return a status about the number of garbage collected binaries
208     * @since 7.4
209     */
210    BinaryManagerStatus garbageCollectBinaries(boolean delete);
211
212    /**
213     * Checks if a garbage collection of the binaries in progress.
214     *
215     * @return {@code true} if a garbage collection of the binaries is in progress
216     * @since 7.4
217     */
218    boolean isBinariesGarbageCollectionInProgress();
219
220    /**
221     * INTERNAL. Marks a binary as referenced during garbage collection. Called back by repository implementations
222     * during {@link #garbageCollectBinaries}.
223     *
224     * @param key the binary key
225     * @param repositoryName the repository name
226     * @since 7.4
227     */
228    void markReferencedBinary(String key, String repositoryName);
229
230}