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     * @deprecated since 9.1, use {@link #writeBlob(Blob, Document, String)} instead
129     */
130    @Deprecated
131    default String writeBlob(Blob blob, Document doc) throws IOException {
132        return writeBlob(blob, doc, null);
133    }
134
135    /**
136     * Writes a {@link Blob} to storage and returns its key.
137     *
138     * @param blob the blob
139     * @param doc the document to which this blob belongs
140     * @param xpath the xpath of blob in doc
141     * @return the blob key
142     * @since 9.1
143     */
144    String writeBlob(Blob blob, Document doc, String xpath) throws IOException;
145
146    /**
147     * INTERNAL - Gets an {@link InputStream} for the data of a managed blob. Used by internal implementations, regular
148     * callers should call {@link Blob#getStream}.
149     *
150     * @param blob the blob
151     * @return the stream
152     */
153    InputStream getStream(Blob blob) throws IOException;
154
155    /**
156     * Gets an {@link InputStream} for a thumbnail of a blob.
157     * <p>
158     * Like all {@link InputStream}, the result must be closed when done with it to avoid resource leaks.
159     *
160     * @param blob the blob
161     * @return the thumbnail stream
162     */
163    InputStream getThumbnail(Blob blob) throws IOException;
164
165    /**
166     * Gets an {@link URI} for the content of a blob.
167     *
168     * @param blob the blob
169     * @param hint {@link UsageHint}
170     * @param servletRequest the servlet request, or {@code null}
171     * @return the {@link URI}, or {@code null} if none available
172     */
173    URI getURI(Blob blob, UsageHint hint, HttpServletRequest servletRequest) throws IOException;
174
175    /**
176     * Gets a map of available MIME type conversions and corresponding {@link URI} for a blob.
177     *
178     * @return a map of MIME types and {@link URI}, which may be empty
179     */
180    Map<String, URI> getAvailableConversions(Blob blob, UsageHint hint) throws IOException;
181
182    /**
183     * Gets an {@link InputStream} for a conversion to the given MIME type.
184     * <p>
185     * Like all {@link InputStream}, the result must be closed when done with it to avoid resource leaks.
186     *
187     * @param blob the blob
188     * @param mimeType the MIME type to convert to
189     * @param doc the document that holds the blob
190     * @return the stream, or {@code null} if no conversion is available for the given MIME type
191     */
192    InputStream getConvertedStream(Blob blob, String mimeType, DocumentModel doc) throws IOException;
193
194    /**
195     * Get the map of blob providers
196     *
197     * @return the list of blob providers
198     * @since 7.3
199     */
200    Map<String, BlobProvider> getBlobProviders();
201
202    /**
203     * Freezes the blobs' versions on a document version when it is created via a check in.
204     *
205     * @param doc the new document version
206     * @since 7.3
207     */
208    void freezeVersion(Document doc);
209
210    /**
211     * Notifies the blob manager that a set of xpaths have changed on a document.
212     *
213     * @param doc the document
214     * @param xpaths the set of changed xpaths
215     * @since 7.3
216     */
217    void notifyChanges(Document doc, Set<String> xpaths);
218
219    /**
220     * Garbage collect the unused binaries.
221     *
222     * @param delete if {@code false} don't actually delete the garbage collected binaries (but still return statistics
223     *            about them), if {@code true} delete them
224     * @return a status about the number of garbage collected binaries
225     * @since 7.4
226     */
227    BinaryManagerStatus garbageCollectBinaries(boolean delete);
228
229    /**
230     * Checks if a garbage collection of the binaries in progress.
231     *
232     * @return {@code true} if a garbage collection of the binaries is in progress
233     * @since 7.4
234     */
235    boolean isBinariesGarbageCollectionInProgress();
236
237    /**
238     * INTERNAL. Marks a binary as referenced during garbage collection. Called back by repository implementations
239     * during {@link #garbageCollectBinaries}.
240     *
241     * @param key the binary key
242     * @param repositoryName the repository name
243     * @since 7.4
244     */
245    void markReferencedBinary(String key, String repositoryName);
246
247}