You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2018/07/24 16:45:31 UTC

svn commit: r1836570 - in /jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api: binary/ binary/BinaryDownload.java binary/BinaryDownloadOptions.java binary/BinaryUpload.java binary/package-info.java package-info.java

Author: reschke
Date: Tue Jul 24 16:45:31 2018
New Revision: 1836570

URL: http://svn.apache.org/viewvc?rev=1836570&view=rev
Log:
JCR-4335: API for direct binary access

Added:
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownload.java   (with props)
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownloadOptions.java   (with props)
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryUpload.java   (with props)
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/package-info.java   (with props)
Modified:
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/package-info.java

Added: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownload.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownload.java?rev=1836570&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownload.java (added)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownload.java Tue Jul 24 16:45:31 2018
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jackrabbit.api.binary;
+
+import java.net.URI;
+
+import javax.jcr.Binary;
+import javax.jcr.RepositoryException;
+
+import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * This extension interface provides a mechanism whereby a client can download
+ * a {@link Binary} directly from a storage location.
+ */
+@ProviderType
+public interface BinaryDownload extends Binary {
+    /**
+     * Get a URI for downloading a {@link Binary} directly from a storage
+     * location with the provided {@link BinaryDownloadOptions}. This is
+     * probably a signed URI with a short TTL (time to live), although the API
+     * does not require it to be so.
+     * <p>
+     * The implementation will attempt to apply the specified {@code
+     * downloadOptions} to the subsequent download. For example, if the caller
+     * knows that the URI refers to a specific type of content, the caller can
+     * specify that content type by setting the internet media type and
+     * character encoding in the {@code downloadOptions}. The caller may also
+     * use a default instance obtained via {@link BinaryDownloadOptions#DEFAULT}
+     * in which case the caller is indicating that the default behavior of the
+     * service provider is acceptable.
+     *
+     * @param downloadOptions
+     *            A {@link BinaryDownloadOptions} instance which is used to
+     *            request specific options on the binary to be downloaded.
+     *            {@link BinaryDownloadOptions#DEFAULT} should be used if the
+     *            caller wishes to accept the service provider's default
+     *            behavior.
+     * @return A URI for downloading the binary directly, or {@code null} if the
+     *         binary cannot be downloaded directly or if the underlying
+     *         implementation does not support this capability.
+     * @throws RepositoryException if an error occurs trying to locate the
+     *             binary.
+     */
+    @Nullable
+    URI getURI(BinaryDownloadOptions downloadOptions)
+            throws RepositoryException;
+}

Propchange: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownload.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownloadOptions.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownloadOptions.java?rev=1836570&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownloadOptions.java (added)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownloadOptions.java Tue Jul 24 16:45:31 2018
@@ -0,0 +1,319 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.api.binary;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Specifies the options to be used when obtaining a direct download URI via
+ * {@link BinaryDownload#getURI(BinaryDownloadOptions)}.  Setting these options
+ * allows the caller to instruct the service provider that these options should
+ * be applied to the response to a request made with the URI returned.
+ * <p>
+ * To specify download options, obtain a {@link BinaryDownloadOptionsBuilder}
+ * via the {@link #builder()} method, then specify the options desired and
+ * get the object via {@link BinaryDownloadOptionsBuilder#build()}.
+ * <p>
+ * If no options are needed, use {@link BinaryDownloadOptions#DEFAULT} which
+ * instructs the implementation to use the service provider default behavior.
+ */
+@ProviderType
+public final class BinaryDownloadOptions {
+    private final String mediaType;
+    private final String characterEncoding;
+    private final String fileName;
+    private final String dispositionType;
+
+    private BinaryDownloadOptions(final String mediaType,
+                                  final String characterEncoding,
+                                  final String fileName,
+                                  final String dispositionType) {
+        this.mediaType = mediaType;
+        this.characterEncoding = characterEncoding;
+        this.fileName = fileName;
+        this.dispositionType = dispositionType;
+    }
+
+    /**
+     * Provides a default instance of this class.  Using the default instance
+     * indicates that the caller is willing to accept the service provider
+     * default behavior.
+     */
+    public static final BinaryDownloadOptions DEFAULT =
+            BinaryDownloadOptions.builder().build();
+
+    /**
+     * Returns the internet media type that should be assumed for the binary that is to be
+     * downloaded.  This value should be a valid {@code jcr:mimeType}.  This
+     * value can be set by calling {@link
+     * BinaryDownloadOptionsBuilder#withMediaType(String)} when building an
+     * instance of this class.
+     *
+     * @return A String representation of the internet media type, or {@code null} if no
+     *         type has been specified.
+     * @see <a href="https://docs.adobe.com/content/docs/en/spec/jcr/2.0/3_Repository_Model.html#3.7.11.10%20mix:mimeType">
+     *     JCR 2.0 Repository Model - jcr:mimeType</a>
+     */
+    @Nullable
+    public final String getMediaType() {
+        return mediaType;
+    }
+
+    /**
+     * Returns the character encoding that should be assumed for the binary that
+     * is to be downloaded.  This value should be a valid {@code jcr:encoding}.
+     * It can be set by calling {@link
+     * BinaryDownloadOptionsBuilder#withCharacterEncoding(String)} when building an
+     * instance of this class.
+     *
+     * @return The character encoding, or {@code null} if no
+     *         encoding has been specified.
+     * @see <a href="https://docs.adobe.com/content/docs/en/spec/jcr/2.0/3_Repository_Model.html#3.7.11.10%20mix:mimeType">
+     *     JCR 2.0 Repository Model - jcr:encoding</a>
+     */
+    @Nullable
+    public final String getCharacterEncoding() {
+        return characterEncoding;
+    }
+
+    /**
+     * Returns the filename that should be assumed for the binary that is to be
+     * downloaded.  This value can be set by calling {@link
+     * BinaryDownloadOptionsBuilder#withFileName(String)} when building an
+     * instance of this class.
+     *
+     * @return The file name, or {@code null} if no
+     * file name has been specified.
+     */
+    @Nullable
+    public final String getFileName() {
+        return fileName;
+    }
+
+    /**
+     * Returns the disposition type that should be assumed for the binary that
+     * is to be downloaded.  This value can be set by calling {@link
+     * BinaryDownloadOptionsBuilder#withDispositionTypeInline()} or {@link
+     * BinaryDownloadOptionsBuilder#withDispositionTypeAttachment()} when
+     * building an instance of this class.  The default value of this setting is
+     * "inline".
+     *
+     * @return The disposition type.
+     * @see <a href="https://tools.ietf.org/html/rfc6266#section-4.2">RFC 6266, Section 4.2</a> 
+     */
+    @NotNull
+    public final String getDispositionType() {
+        return dispositionType;
+    }
+
+    /**
+     * Returns a {@link BinaryDownloadOptionsBuilder} instance to be used for
+     * creating an instance of this class.
+     *
+     * @return A builder instance.
+     */
+    @NotNull
+    public static BinaryDownloadOptionsBuilder builder() {
+        return new BinaryDownloadOptionsBuilder();
+    }
+
+    /**
+     * Used to build an instance of {@link BinaryDownloadOptions} with the
+     * options set as desired by the caller.
+     */
+    public static final class BinaryDownloadOptionsBuilder {
+        private String mediaType = null;
+        private String characterEncoding = null;
+        private String fileName = null;
+        private DispositionType dispositionType = DispositionType.INLINE;
+
+        private BinaryDownloadOptionsBuilder() { }
+
+        /**
+         * Sets the internet media type of the {@link BinaryDownloadOptions} object to be
+         * built.  This value should be a valid {@code jcr:mimeType}.
+         * <p>
+         * Calling this method has the effect of instructing the service
+         * provider to set {@code mediaType} as the internet media type
+         * in the {@code Content-Type} header field of the response to a request
+         * issued with a URI obtained by calling {@link
+         * BinaryDownload#getURI(BinaryDownloadOptions)}.  This value can be
+         * later retrieved by calling {@link
+         * BinaryDownloadOptions#getMediaType()} on the instance returned from a
+         * call to {@link #build()}.
+         * <p>
+         * Note that if the internet media type defines a "charset" parameter
+         * (as many textual types do), the caller may also wish to set the
+         * character encoding which is done separately.  See {@link
+         * #withCharacterEncoding(String)}.
+         * <p>
+         * The caller should ensure that the internet media type set is valid; the
+         * implementation does not perform any validation of this setting.
+         * <p>
+         * If no internet media type is provided, no {@code Content-Type} header field will be
+         * specified to the service provider.
+         *
+         * @param mediaType The internet media type.
+         * @return The calling instance.
+         * @see <a href="https://docs.adobe.com/content/docs/en/spec/jcr/2.0/3_Repository_Model.html#3.7.11.10%20mix:mimeType">
+         *     JCR 2.0 Repository Model - jcr:mimeType</a>
+         */
+        @NotNull
+        public BinaryDownloadOptionsBuilder withMediaType(@NotNull String mediaType) {
+            this.mediaType = mediaType;
+            return this;
+        }
+
+        /**
+         * Sets the character encoding of the {@link BinaryDownloadOptions} object to be
+         * built.  This value should be a valid {@code jcr:encoding}.
+         * <p>
+         * Calling this method has the effect of instructing the service
+         * provider to set {@code charecterEncoding} as the "charset" parameter
+         * of the content type in the {@code Content-Type} header field of the
+         * response to a request issued with a URI obtained by calling {@link
+         * BinaryDownload#getURI(BinaryDownloadOptions)}.  This value can be
+         * later retrieved by calling {@link
+         * BinaryDownloadOptions#getCharacterEncoding()} on the instance returned by a
+         * call to {@link #build()}.
+         * <p>
+         * Note that setting the character encoding only makes sense if the internet media type has
+         * also been set.  See {@link
+         * #withMediaType(String)}.
+         * <p>
+         * The caller should ensure that the proper character encoding has been set for
+         * the internet media type; the implementation does not perform any validation of
+         * these settings.
+         *
+         * @param characterEncoding A String representation of the jcr:encoding.
+         * @return The calling instance.
+         * @see <a href="https://docs.adobe.com/content/docs/en/spec/jcr/2.0/3_Repository_Model.html#3.7.11.10%20mix:mimeType">
+         *     JCR 2.0 Repository Model - jcr:encoding</a>
+         */
+        @NotNull
+        public BinaryDownloadOptionsBuilder withCharacterEncoding(@NotNull String characterEncoding) {
+            this.characterEncoding = characterEncoding;
+            return this;
+        }
+
+        /**
+         * Sets the filename of the {@link BinaryDownloadOptions} object to be
+         * built.
+         * <p>
+         * Calling this method has the effect of instructing the service
+         * provider to set {@code fileName} as the filename in the {@code
+         * Content-Disposition} header of the response to a request issued with
+         * a URI obtained by calling {@link
+         * BinaryDownload#getURI(BinaryDownloadOptions)}.  This value can be
+         * later retrieved by calling {@link
+         * BinaryDownloadOptions#getFileName()} on the instance returned by a
+         * call to {@link #build()}.
+         * <p>
+         *
+         * @param fileName The filename.
+         * @return The calling instance.
+         * @see <a href="https://tools.ietf.org/html/rfc6266#section-4.3">RFC 6266, Section 4.3</a> 
+         */
+        @NotNull
+        public BinaryDownloadOptionsBuilder withFileName(@NotNull String fileName) {
+            this.fileName = fileName;
+            return this;
+        }
+
+        /**
+         * Sets the disposition type of the {@link BinaryDownloadOptions} object
+         * to be built to {@code inline}.
+         * <p>
+         * Calling this method has the effect of instructing the service
+         * provider to set the disposition type in the {@code
+         * Content-Disposition} header of the response to {@code inline}.  This
+         * value can be later retrieved by calling {@link
+         * BinaryDownloadOptions#getDispositionType()} on the instance built by
+         * calling {@link #build()}.
+         * <p>
+         * If this value is not set, the default value of {@code inline}
+         * will be used.
+         *
+         * @return The calling instance.
+         */
+        @NotNull
+        public BinaryDownloadOptionsBuilder withDispositionTypeInline() {
+            dispositionType = DispositionType.INLINE;
+            return this;
+        }
+
+        /**
+         * Sets the disposition type of the {@link BinaryDownloadOptions} object
+         * to be built to {@code attachment}.
+         * <p>
+         * Calling this method has the effect of instructing the service
+         * provider to set the disposition type in the {@code
+         * Content-Disposition} header of the response to {@code attachment}.
+         * This value can later be retrieved by calling {@link
+         * BinaryDownloadOptions#getDispositionType()} on the instance built by
+         * calling {@link #build()}.
+         * <p>
+         * If this value is not set, the default value of {@code inline}
+         * will be used.
+         *
+         * @return The calling instance.
+         */
+        @NotNull
+        public BinaryDownloadOptionsBuilder withDispositionTypeAttachment() {
+            dispositionType = DispositionType.ATTACHMENT;
+            return this;
+        }
+
+        /**
+         * Construct a {@link BinaryDownloadOptions} instance with the
+         * properties specified to the builder.
+         *
+         * @return A new {@link BinaryDownloadOptions} instance built with the
+         *         properties specified to the builder.
+         */
+        @NotNull
+        public BinaryDownloadOptions build() {
+            return new BinaryDownloadOptions(mediaType,
+                    characterEncoding,
+                    fileName,
+                    null != dispositionType
+                            ? dispositionType.toString()
+                            : DispositionType.INLINE.toString()
+            );
+        }
+
+        private enum DispositionType {
+            INLINE("inline"),
+            ATTACHMENT("attachment");
+
+            private final String value;
+
+            DispositionType(final String value) {
+                this.value = value;
+            }
+
+            @Override
+            public String toString() {
+                return value;
+            }
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryDownloadOptions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryUpload.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryUpload.java?rev=1836570&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryUpload.java (added)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryUpload.java Tue Jul 24 16:45:31 2018
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jackrabbit.api.binary;
+
+import java.net.URI;
+
+import org.apache.jackrabbit.api.JackrabbitValueFactory;
+import org.jetbrains.annotations.NotNull;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * This extension interface provides a mechanism whereby a client can upload a
+ * binary directly to a storage location.  An object of this type can be
+ * created by a call to {@link
+ * JackrabbitValueFactory#initiateBinaryUpload(long, int)} which will return an
+ * object of this type if the underlying implementation supports direct upload
+ * functionality.  When calling this method, the client indicates the expected
+ * size of the binary and the number of URIs that it is willing to accept.  The
+ * implementation will attempt to create an instance of this class that is
+ * suited to enabling the client to complete the upload successfully.
+ * <p>
+ * Using an instance of this class, a client can then use one or more of the
+ * included URIs for uploading the binary directly by calling {@link
+ * #getUploadURIs()} and iterating through the URIs returned.  Multi-part
+ * uploads are supported by the interface, although they may not be supported
+ * by the underlying implementation.
+ * <p>
+ * Once a client finishes uploading the binary data, the client must then call
+ * {@link JackrabbitValueFactory#completeBinaryUpload(String)} to complete the
+ * upload.  This call requires an upload token which can be obtained from an
+ * instance of this class by calling {@link #getUploadToken()}.
+ * <p>
+ * Below is the detailed direct binary upload algorithm for the remote client.
+ * <p>
+ * In this example the following variables are used:
+ * <ul>
+ *     <li>{@code fileSize}: the actual binary size (must be known at this
+ *     point)
+ *     <li>{@code minPartSize}: the value from {@link #getMinPartSize()}
+ *     <li>{@code maxPartSize}: the value from {@link #getMaxPartSize()}
+ *     <li>{@code numUploadURIs}: the number of entries in {@link
+ *     #getUploadURIs()}
+ *     <li>{@code uploadURIs}: the entries in {@link #getUploadURIs()}
+ *     <li>{@code partSize}: the part size to be used in the upload (to be
+ *     determined in the algorithm)
+ * </ul>
+ *
+ * Steps:
+ * <ol>
+ *     <li>If (fileSize divided by maxPartSize) is larger than numUploadURIs,
+ *     then the client cannot proceed and will have to request a new set of URIs
+ *     with the right fileSize as maxSize
+ *     <li>If fileSize is smaller than minPartSize, then take the first provided
+ *     upload URI to upload the entire binary, with partSize = fileSize</li>
+ *     <li>
+ *         (optional) If the client has more information to optimize, the
+ *         partSize can be chosen, under the condition that all of these are
+ *         true for the partSize:
+ *         <ol>
+ *             <li>larger than minPartSize
+ *             <li>smaller or equal than maxPartSize (unless it is -1 =
+ *             unlimited)
+ *             <li>larger than fileSize divided by numUploadURIs
+ *         </ol>
+ *     </li>
+ *     <li>Otherwise all part URIs are to be used and the partSize = fileSize
+ *     divided by numUploadURIs (integer division, discard modulo which will be
+ *     the last part)
+ *     <li>Upload: segment the binary into partSize, for each segment take the
+ *     next URI from uploadURIs (strictly in order), proceed with a standard
+ *     HTTP PUT for each (for "http(s)" URIs, otherwise currently unspecified),
+ *     and for the last part use whatever segment size is left
+ *     <li>If a segment fails during upload, retry (up to a certain time out)
+ *     <li>After the upload has finished successfully, notify the application,
+ *     for example through a complete request, passing the {@link
+ *     #getUploadToken() upload token}, and the application will call {@link
+ *     JackrabbitValueFactory#completeBinaryUpload(String)} with the token
+ * </ol>
+ *
+ * <h2>JSON view</h2>
+ *
+ * A JSON representation of this interface as passed back to a remote client
+ * might look like this:
+ * <pre>
+ * {
+ *     "uploadToken": "aaaa-bbbb-cccc-dddd-eeee-ffff-gggg-hhhh",
+ *     "minPartSize": 10485760,
+ *     "maxPartSize": 104857600,
+ *     "uploadURIs": [
+ *         "http://server.com/upload/1",
+ *         "http://server.com/upload/2",
+ *         "http://server.com/upload/3",
+ *         "http://server.com/upload/4"
+ *     ]
+ * }
+ * </pre>
+ * */
+@ProviderType
+public interface BinaryUpload {
+    /**
+     * Returns an Iterable of URIs that can be used for uploading binary data
+     * directly to a storage location.  The first URI can be used for uploading
+     * binary data as a single entity, or multiple URIs can be used if the
+     * client wishes to do multi-part uploads.
+     * <p>
+     * Clients are not necessarily required to use all of the URIs provided.  A
+     * client may choose to use fewer, or even only one of the URIs.  However,
+     * regardless of the number of URIs used, they must be consumed in sequence.
+     * For example, if a client wishes to upload a binary in three parts and
+     * there are five URIs returned, the client must use the first URI to
+     * upload the first part, the second URI to upload the second part, and
+     * the third URI to upload the third part.  The client is not required to
+     * use the fourth and fifth URIs.  However, using the second URI to upload
+     * the third part may result in either an upload failure or a corrupted
+     * upload; likewise, skipping the second URI to use subsequent URIs may
+     * result in either an upload failure or a corrupted upload.
+     * <p>
+     * Clients should be aware that some storage providers have limitations on
+     * the minimum and maximum size of a binary payload for a single upload, so
+     * clients should take these limitations into account when deciding how many
+     * of the URIs to use.  Underlying implementations may also choose to
+     * enforce their own limitations.
+     * <p>
+     * While the API supports multi-part uploading via multiple upload URIs,
+     * implementations are not required to support multi-part uploading.  If the
+     * underlying implementation does not support multi-part uploading, a single
+     * URI will be returned regardless of the size of the data being uploaded.
+     * <p>
+     * Some storage providers also support multi-part uploads by reusing a
+     * single URI multiple times, in which case the implementation may also
+     * return a single URI regardless of the size of the data being uploaded.
+     * <p>
+     * You should consult both the DataStore implementation documentation and
+     * the storage service provider documentation for details on such matters as
+     * multi-part upload support, upload minimum and maximum sizes, etc.
+     *
+     * @return Iterable of URIs that can be used for uploading directly to a
+     *         storage location.
+     */
+    @NotNull
+    Iterable<URI> getUploadURIs();
+
+    /**
+     * The smallest part size a client may upload for a multi-part upload, not
+     * counting the final part.  This is usually either a service provider or
+     * implementation limitation.
+     * <p>
+     * Note that the API offers no guarantees that uploading parts of this size
+     * can successfully complete the requested upload using the URIs provided
+     * via {@link #getUploadURIs()}.  In other words, clients wishing to perform
+     * a multi-part upload must split the upload into parts of at least this
+     * size, but the sizes may need to be larger in order to successfully
+     * complete the upload.
+     *
+     * @return The smallest size acceptable for multi-part uploads.
+     */
+    long getMinPartSize();
+
+    /**
+     * The largest part size a client may upload for a multi-part upload.  This
+     * is usually either a service provider or implementation limitation.
+     * <p>
+     * The API guarantees that a client can successfully complete a direct
+     * upload of the binary data of the requested size using the provided URIs
+     * by splitting the binary data into parts of the size returned by this
+     * method.
+     * <p>
+     * The client is not required to use part sizes of this size; smaller sizes
+     * may be used so long as they are at least as large as the size returned by
+     * {@link #getMinPartSize()}.
+     * <p>
+     * If the binary size specified by a client when calling {@link
+     * JackrabbitValueFactory#initiateBinaryUpload(long, int)} ends up being
+     * smaller than the actual size of the binary being uploaded, these API
+     * guarantees no longer apply, and it may not be possible to complete the
+     * upload using the URIs provided.  In such cases, the client should restart
+     * the transaction using the correct size.
+     *
+     * @return The maximum size of an upload part for multi-part uploads.
+     */
+    long getMaxPartSize();
+
+    /**
+     * Returns the upload token to be used in a subsequent call to {@link
+     * JackrabbitValueFactory#completeBinaryUpload(String)}.  This upload token
+     * is used by the implementation to identify this upload.  Clients should
+     * treat the upload token as an immutable string, as the underlying
+     * implementation may choose to implement techniques to detect tampering and
+     * reject the upload if the token is modified.
+     *
+     * @return This upload's unique upload token.
+     */
+    @NotNull
+    String getUploadToken();
+}

Propchange: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/BinaryUpload.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/package-info.java?rev=1836570&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/package-info.java (added)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/package-info.java Tue Jul 24 16:45:31 2018
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Interfaces related to direct upload/download of binaries.
+ */
+@Version("1.0.0")
+package org.apache.jackrabbit.api.binary;
+
+import org.osgi.annotation.versioning.Version;
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/binary/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/package-info.java?rev=1836570&r1=1836569&r2=1836570&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/package-info.java (original)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/package-info.java Tue Jul 24 16:45:31 2018
@@ -18,5 +18,5 @@
 /**
  * Jackrabbit extensions for JCR core interfaces
  */
-@org.osgi.annotation.versioning.Version("2.4.1")
+@org.osgi.annotation.versioning.Version("2.5.0")
 package org.apache.jackrabbit.api;