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