Added: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/fixtures/nodestore/SegmentMemoryNodeStoreFixture.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/fixtures/nodestore/SegmentMemoryNodeStoreFixture.java?rev=1838617&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/fixtures/nodestore/SegmentMemoryNodeStoreFixture.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/fixtures/nodestore/SegmentMemoryNodeStoreFixture.java
 Wed Aug 22 08:51:41 2018
@@ -0,0 +1,141 @@
+/*
+ * 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.oak.jcr.binary.fixtures.nodestore;
+
+import java.io.File;
+import java.io.IOException;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.core.data.DataStore;
+import org.apache.jackrabbit.oak.fixture.NodeStoreFixture;
+import 
org.apache.jackrabbit.oak.jcr.binary.fixtures.datastore.DataStoreFixture;
+import org.apache.jackrabbit.oak.jcr.util.ComponentHolder;
+import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreBlobStore;
+import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
+import org.apache.jackrabbit.oak.segment.file.FileStoreBuilder;
+import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
+import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
+
+/**
+ * Creates a repository with
+ * - SegmentNodeStore, storing data in-memory
+ * - an optional DataStore provided by DataStoreFixture
+ */
+public class SegmentMemoryNodeStoreFixture extends NodeStoreFixture implements 
ComponentHolder {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final DataStoreFixture dataStoreFixture;
+
+    private final Table<NodeStore, String, Object> components = 
HashBasedTable.create();
+
+    public SegmentMemoryNodeStoreFixture(@Nullable DataStoreFixture 
dataStoreFixture) {
+        this.dataStoreFixture = dataStoreFixture;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        // if a DataStore is configured, it must be available for our 
NodeStore to be available
+        return dataStoreFixture == null || dataStoreFixture.isAvailable();
+    }
+
+    @Override
+    public NodeStore createNodeStore() {
+        try {
+            log.info("Creating NodeStore using " + toString());
+
+            File fileStoreRoot = FixtureUtils.createTempFolder();
+            FileStoreBuilder fileStoreBuilder = 
FileStoreBuilder.fileStoreBuilder(fileStoreRoot)
+                .withNodeDeduplicationCacheSize(16384)
+                .withMaxFileSize(256)
+                .withMemoryMapping(false);
+
+            File dataStoreFolder = null;
+            BlobStore blobStore = null;
+            DataStore dataStore = null;
+            if (dataStoreFixture != null) {
+                dataStore = dataStoreFixture.createDataStore();
+
+                // init with a new folder inside a temporary one
+                dataStoreFolder = FixtureUtils.createTempFolder();
+                dataStore.init(dataStoreFolder.getAbsolutePath());
+
+                blobStore = new DataStoreBlobStore(dataStore);
+                fileStoreBuilder.withBlobStore(blobStore);
+            }
+
+            FileStore fileStore = fileStoreBuilder.build();
+            NodeStore nodeStore = 
SegmentNodeStoreBuilders.builder(fileStore).build();
+
+            // track all main components
+            if (dataStore != null) {
+                components.put(nodeStore, DataStore.class.getName(), 
dataStore);
+                components.put(nodeStore, DataStore.class.getName() + 
":folder", dataStoreFolder);
+            }
+            if (blobStore != null) {
+                components.put(nodeStore, BlobStore.class.getName(), 
blobStore);
+            }
+            components.put(nodeStore, FileStore.class.getName(), fileStore);
+            components.put(nodeStore, FileStore.class.getName() + ":root", 
fileStoreRoot);
+
+            return nodeStore;
+
+        } catch (IOException | InvalidFileStoreVersionException | 
RepositoryException e) {
+            throw new AssertionError("Cannot create test repo fixture " + 
toString(), e);
+        }
+    }
+
+    @Override
+    public void dispose(NodeStore nodeStore) {
+        try {
+            File fileStoreRoot = (File) components.get(nodeStore, 
FileStore.class.getName() + ":root");
+            FileUtils.deleteQuietly(fileStoreRoot);
+
+            DataStore dataStore = (DataStore) components.get(nodeStore, 
DataStore.class.getName());
+            if (dataStore != null && dataStoreFixture != null) {
+                dataStoreFixture.dispose(dataStore);
+
+                File dataStoreFolder = (File) components.get(nodeStore, 
DataStore.class.getName() + ":folder");
+                FileUtils.deleteQuietly(dataStoreFolder);
+            }
+        } finally {
+            components.row(nodeStore).clear();
+        }
+    }
+
+    @Override
+    public String toString() {
+        // for nice Junit parameterized test labels
+        return FixtureUtils.getFixtureLabel(this, dataStoreFixture);
+    }
+
+    @Override
+    public <T> T get(NodeStore nodeStore, String componentName) {
+        return (T) components.get(nodeStore, componentName);
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/fixtures/nodestore/SegmentMemoryNodeStoreFixture.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/BinaryAccessTestUtils.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/BinaryAccessTestUtils.java?rev=1838617&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/BinaryAccessTestUtils.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/BinaryAccessTestUtils.java
 Wed Aug 22 08:51:41 2018
@@ -0,0 +1,131 @@
+/*
+ * 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.oak.jcr.binary.util;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.blob.cloud.azure.blobstorage.AzureDataStore;
+import org.apache.jackrabbit.oak.blob.cloud.s3.S3DataStore;
+import org.apache.jackrabbit.oak.commons.IOUtils;
+import 
org.apache.jackrabbit.oak.plugins.blob.datastore.directaccess.ConfigurableDataRecordAccessProvider;
+import org.jetbrains.annotations.Nullable;
+
+/** Utility methods to test Binary direct HTTP access */
+public class BinaryAccessTestUtils {
+
+    /** Creates an nt:file based on the content, saves the session and 
retrieves the Binary value again. */
+    public static Binary storeBinaryAndRetrieve(Session session, String path, 
Content content) throws RepositoryException {
+        Binary binary = 
session.getValueFactory().createBinary(content.getStream());
+        storeBinary(session, path, binary);
+
+        return getBinary(session, path);
+    }
+
+    /** Creates an nt:file with a binary at the given path and saves the 
session. */
+    public static void storeBinary(Session session, String path, Binary 
binary) throws RepositoryException {
+        putBinary(session, path, binary);
+        session.save();
+    }
+
+    /** Creates an nt:file with a binary at the given path. Does not save the 
session. */
+    public static void putBinary(Session session, String ntFilePath, Binary 
binary) throws RepositoryException {
+        Node ntResource;
+        if (session.nodeExists(ntFilePath + "/" + JcrConstants.JCR_CONTENT)) {
+            ntResource = session.getNode(ntFilePath + "/" + 
JcrConstants.JCR_CONTENT);
+        } else {
+            Node file = session.getRootNode().addNode(ntFilePath.substring(1), 
JcrConstants.NT_FILE);
+            ntResource = file.addNode(JcrConstants.JCR_CONTENT, 
JcrConstants.NT_RESOURCE);
+        }
+
+        ntResource.setProperty(JcrConstants.JCR_DATA, binary);
+    }
+
+    /** Retrieves the Binary from the jcr:data of an nt:file */
+    public static Binary getBinary(Session session, String ntFilePath) throws 
RepositoryException {
+        return session.getNode(ntFilePath)
+                .getNode(JcrConstants.JCR_CONTENT)
+                .getProperty(JcrConstants.JCR_DATA)
+                .getBinary();
+    }
+
+    /**
+     * Uploads data via HTTP put to the provided URI.
+     *
+     * @param uri The URI to upload to.
+     * @param contentLength Value to set in the Content-Length header.
+     * @param in - The input stream to upload.
+     * @return HTTP response code from the upload request.  Note that a 
successful
+     * response for S3 is 200 - OK whereas for Azure it is 201 - Created.
+     * @throws IOException
+     */
+    public static int httpPut(@Nullable URI uri, long contentLength, 
InputStream in) throws IOException  {
+        // this weird combination of @Nullable and assertNotNull() is for IDEs 
not warning in test methods
+        assertNotNull(uri);
+
+        HttpURLConnection connection = (HttpURLConnection) 
uri.toURL().openConnection();
+        connection.setDoOutput(true);
+        connection.setRequestMethod("PUT");
+        connection.setRequestProperty("Content-Length", 
String.valueOf(contentLength));
+        connection.setRequestProperty("Date", 
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssX")
+                .withZone(ZoneOffset.UTC)
+                .format(Instant.now()));
+
+        OutputStream putStream = connection.getOutputStream();
+        IOUtils.copy(in, putStream);
+        putStream.close();
+        return connection.getResponseCode();
+    }
+
+    public static boolean isSuccessfulHttpPut(int code, 
ConfigurableDataRecordAccessProvider dataStore) {
+        if (dataStore instanceof S3DataStore) {
+            return 200 == code;
+        }
+        else if (dataStore instanceof AzureDataStore) {
+            return 201 == code;
+        }
+        return 200 == code;
+    }
+
+    public static boolean isFailedHttpPut(int code) {
+        return code >= 400 && code < 500;
+    }
+
+    public static InputStream httpGet(@Nullable URI uri) throws IOException  {
+        // this weird combination of @Nullable and assertNotNull() is for IDEs 
not warning in test methods
+        assertNotNull("HTTP download URI is null", uri);
+
+        HttpURLConnection conn = (HttpURLConnection) 
uri.toURL().openConnection();
+        return conn.getInputStream();
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/BinaryAccessTestUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/Content.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/Content.java?rev=1838617&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/Content.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/Content.java
 Wed Aug 22 08:51:41 2018
@@ -0,0 +1,104 @@
+/*
+ * 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.oak.jcr.binary.util;
+
+import static 
org.apache.jackrabbit.oak.jcr.binary.util.BinaryAccessTestUtils.httpPut;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Random;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+
+public class Content {
+    private static final Charset CHARSET = StandardCharsets.UTF_8;
+    private final String content;
+    private final byte[] bytes;
+
+    private Content(String content) {
+        this.content = content;
+        this.bytes = content.getBytes(CHARSET);
+    }
+
+    public static Content createRandom(long size) {
+          return new Content(getRandomString(size));
+    }
+
+    public long size() {
+        return bytes.length;
+    }
+
+    public InputStream getStream() {
+        return new ByteArrayInputStream(bytes);
+    }
+
+    @Override
+    public String toString() {
+        return content;
+    }
+
+    public void assertEqualsWith(InputStream stream) throws IOException {
+        StringWriter writer = new StringWriter();
+        IOUtils.copy(stream, writer, CHARSET);
+        // converting to string gives us a diff in assertEquals() if it's not 
equal
+        Assert.assertEquals(content, writer.toString());
+    }
+
+    /** Uploads this data via HTTP PUT to the provided URI and returns the 
HTTP status code */
+    public int httpPUT(URI uri) throws IOException {
+        return httpPut(uri, size(), getStream());
+    }
+
+    /** Uploads a sub range of this data via HTTP PUT. */
+    public int httpPUT(URI uri, long offset, long length) throws IOException {
+        ByteArrayInputStream partStream = new ByteArrayInputStream(bytes, 
(int) offset, (int) length);
+        return httpPut(uri, length, partStream);
+    }
+
+    private static String getRandomString(long size) {
+        //noinspection SpellCheckingInspection
+        String base = 
"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+/";
+        StringWriter writer = new StringWriter();
+        Random random = new Random();
+        if (size > 256) {
+            final String str256 = getRandomString(255);
+            // add newlines for better diffs in failing junit test results
+            while (size >= 256) {
+                writer.write(str256);
+                writer.write('\n');
+                size -= 256;
+            }
+            if (size > 0) {
+                writer.write(str256.substring(0, (int)size));
+            }
+        }
+        else {
+            for (long i = 0; i < size; i++) {
+                writer.append(base.charAt(random.nextInt(base.length())));
+            }
+        }
+        return writer.toString();
+    }
+
+}

Propchange: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/binary/util/Content.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/util/ComponentHolder.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/util/ComponentHolder.java?rev=1838617&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/util/ComponentHolder.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/util/ComponentHolder.java
 Wed Aug 22 08:51:41 2018
@@ -0,0 +1,38 @@
+/*
+ * 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.oak.jcr.util;
+
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+
+/**
+ * Holds components associated with a NodeStore. To be optionally implemented
+ * by NodeStoreFixtures. Allows test classes to access inner parts of Oak.
+ */
+public interface ComponentHolder {
+
+    /**
+     * Get a component (BlobStore, folder, etc.) associated with a NodeStore.
+     *
+     * @param nodeStore the owning NodeStore
+     * @param componentName class or other name of the component
+     * @param <T> type of the result
+     * @return component or null
+     */
+    <T> T get(NodeStore nodeStore, String componentName);
+}

Propchange: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/util/ComponentHolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-parent/pom.xml
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-parent/pom.xml?rev=1838617&r1=1838616&r2=1838617&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-parent/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-parent/pom.xml Wed Aug 22 08:51:41 2018
@@ -43,7 +43,7 @@
     <project.reporting.outputEncoding>
       ${project.build.sourceEncoding}
     </project.reporting.outputEncoding>
-    <jackrabbit.version>2.17.4</jackrabbit.version>
+    <jackrabbit.version>2.17.5</jackrabbit.version>
     <mongo.host>127.0.0.1</mongo.host>
     <mongo.port>27017</mongo.port>
     <mongo.db>MongoMKDB</mongo.db>

Modified: 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/BinaryImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/BinaryImpl.java?rev=1838617&r1=1838616&r2=1838617&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/BinaryImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/BinaryImpl.java
 Wed Aug 22 08:51:41 2018
@@ -20,20 +20,26 @@ import static com.google.common.base.Obj
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URI;
 
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 
 import com.google.common.base.Objects;
 import org.apache.jackrabbit.api.ReferenceBinary;
+import org.apache.jackrabbit.api.binary.BinaryDownload;
+import org.apache.jackrabbit.api.binary.BinaryDownloadOptions;
+import org.apache.jackrabbit.oak.api.Blob;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 /**
  * TODO document
  */
-class BinaryImpl implements ReferenceBinary {
+class BinaryImpl implements ReferenceBinary, BinaryDownload {
     private static final Logger LOG = 
LoggerFactory.getLogger(BinaryImpl.class);
 
     private final ValueImpl value;
@@ -83,6 +89,26 @@ class BinaryImpl implements ReferenceBin
         // nothing to do
     }
 
+    @Nullable
+    @Override
+    public URI getURI(@NotNull BinaryDownloadOptions downloadOptions)
+            throws RepositoryException {
+        if (null == getReference()) {
+            // Binary is inlined, we cannot return a URI for it
+            return null;
+        }
+
+        // ValueFactoryImpl.getBlobId() will only return a blobId for a 
BinaryImpl, which
+        // a client cannot spoof, so we know that the id in question is valid 
and can be
+        // trusted, so we can safely give out a URI to the binary for 
downloading.
+        Blob blob = getBinaryValue().getBlob();
+        String blobId = blob.getContentIdentity();
+        if (null != blobId) {
+            return value.getDownloadURI(blob, downloadOptions);
+        }
+        return null;
+    }
+
     //---------------------------------------------------< ReferenceBinary >--
 
     @Override @Nullable

Modified: 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/PartialValueFactory.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/PartialValueFactory.java?rev=1838617&r1=1838616&r2=1838617&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/PartialValueFactory.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/PartialValueFactory.java
 Wed Aug 22 08:51:41 2018
@@ -69,7 +69,7 @@ public class PartialValueFactory {
     public static final BlobAccessProvider DEFAULT_BLOB_ACCESS_PROVIDER = new 
DefaultBlobAccessProvider();
 
     @NotNull
-    protected final NamePathMapper namePathMapper;
+    private final NamePathMapper namePathMapper;
 
     @NotNull
     private final BlobAccessProvider blobAccessProvider;
@@ -101,11 +101,19 @@ public class PartialValueFactory {
     }
 
     @NotNull
-    public BlobAccessProvider getBlobAccessProvider() {
+    BlobAccessProvider getBlobAccessProvider() {
         return blobAccessProvider;
     }
 
     /**
+     * @return the {@link NamePathMapper} used by this value factory.
+     */
+    @NotNull
+    public NamePathMapper getNamePathMapper() {
+        return namePathMapper;
+    }
+
+    /**
      * Utility method for creating a {@code Value} based on a
      * {@code PropertyState}.
      *

Modified: 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/ValueFactoryImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/ValueFactoryImpl.java?rev=1838617&r1=1838616&r2=1838617&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/ValueFactoryImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/ValueFactoryImpl.java
 Wed Aug 22 08:51:41 2018
@@ -20,6 +20,7 @@ import static com.google.common.base.Pre
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URI;
 import java.util.List;
 
 import javax.jcr.Binary;
@@ -29,24 +30,28 @@ import javax.jcr.Value;
 import javax.jcr.ValueFactory;
 import javax.jcr.ValueFormatException;
 
+import org.apache.jackrabbit.api.JackrabbitValueFactory;
 import org.apache.jackrabbit.api.ReferenceBinary;
+import org.apache.jackrabbit.api.binary.BinaryUpload;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.PropertyValue;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.blob.BlobAccessProvider;
+import org.apache.jackrabbit.oak.api.blob.BlobUpload;
 import org.apache.jackrabbit.oak.commons.PerfLogger;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.memory.BinaryPropertyState;
 import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
 import org.apache.jackrabbit.oak.plugins.value.ErrorValue;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.slf4j.LoggerFactory;
 
 /**
  * Implementation of {@link ValueFactory} interface.
  */
-public class ValueFactoryImpl extends PartialValueFactory implements 
ValueFactory {
+public class ValueFactoryImpl extends PartialValueFactory implements 
JackrabbitValueFactory {
 
     private static final PerfLogger binOpsLogger = new PerfLogger(
             
LoggerFactory.getLogger("org.apache.jackrabbit.oak.jcr.operations.binary.perf"));
@@ -199,6 +204,44 @@ public class ValueFactoryImpl extends Pa
         }
     }
 
+    @Override
+    @Nullable
+    public BinaryUpload initiateBinaryUpload(long maxSize, int maxParts) {
+        BlobUpload upload = 
getBlobAccessProvider().initiateBlobUpload(maxSize, maxParts);
+        if (null == upload) {
+            return null;
+        }
+
+        return new BinaryUpload() {
+            @Override
+            @NotNull
+            public Iterable<URI> getUploadURIs() {
+                return upload.getUploadURIs();
+            }
+
+            @Override
+            public long getMinPartSize() {
+                return upload.getMinPartSize();
+            }
+
+            @Override
+            public long getMaxPartSize() {
+                return upload.getMaxPartSize();
+            }
+
+            @Override
+            @NotNull
+            public String getUploadToken() { return upload.getUploadToken(); }
+        };
+    }
+
+    @Override
+    @Nullable
+    public Binary completeBinaryUpload(@NotNull String uploadToken) throws 
RepositoryException {
+        return createBinary(
+                getBlobAccessProvider().completeBlobUpload(uploadToken));
+    }
+
     @NotNull
     private ValueImpl createBinaryValue(@NotNull InputStream value) throws 
IOException, RepositoryException {
         long start = binOpsLogger.start();
@@ -209,6 +252,20 @@ public class ValueFactoryImpl extends Pa
 
     @NotNull
     private ValueImpl createBinaryValue(@NotNull Blob blob) throws 
RepositoryException {
-        return new ValueImpl(BinaryPropertyState.binaryProperty("", blob), 
namePathMapper, getBlobAccessProvider());
+        return new ValueImpl(BinaryPropertyState.binaryProperty("", blob),
+                getNamePathMapper(), getBlobAccessProvider());
+    }
+
+    @Nullable
+    public Binary createBinary(Blob blob) throws RepositoryException {
+        return null != blob ? createBinaryValue(blob).getBinary() : null;
+    }
+
+    @Nullable
+    public Blob getBlob(Binary binary) throws RepositoryException {
+        if (binary instanceof BinaryImpl) {
+            return ((BinaryImpl) binary).getBinaryValue().getBlob();
+        }
+        return null;
     }
 }

Modified: 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/ValueImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/ValueImpl.java?rev=1838617&r1=1838616&r2=1838617&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/ValueImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-spi/src/main/java/org/apache/jackrabbit/oak/plugins/value/jcr/ValueImpl.java
 Wed Aug 22 08:51:41 2018
@@ -22,6 +22,7 @@ import static com.google.common.base.Pre
 
 import java.io.InputStream;
 import java.math.BigDecimal;
+import java.net.URI;
 import java.util.Calendar;
 
 import javax.jcr.Binary;
@@ -32,16 +33,19 @@ import javax.jcr.ValueFormatException;
 
 import com.google.common.base.Objects;
 import org.apache.jackrabbit.api.JackrabbitValue;
+import org.apache.jackrabbit.api.binary.BinaryDownloadOptions;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.IllegalRepositoryStateException;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.api.blob.BlobAccessProvider;
+import org.apache.jackrabbit.oak.api.blob.BlobDownloadOptions;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.value.Conversions;
 import org.apache.jackrabbit.oak.plugins.value.ErrorValue;
 import org.apache.jackrabbit.oak.plugins.value.OakValue;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -386,6 +390,21 @@ class ValueImpl implements JackrabbitVal
         }
     }
 
+    @Nullable
+    URI getDownloadURI(@NotNull Blob blob, @NotNull BinaryDownloadOptions 
downloadOptions) {
+        if (blobAccessProvider == null) {
+            return null;
+        } else {
+            return blobAccessProvider.getDownloadURI(blob,
+                    new BlobDownloadOptions(
+                            downloadOptions.getMediaType(),
+                            downloadOptions.getCharacterEncoding(),
+                            downloadOptions.getFileName(),
+                            downloadOptions.getDispositionType())
+                    );
+        }
+    }
+
     //------------------------------------------------------------< private 
>---
 
     private <T> T getValue(Type<T> type, int index) throws RepositoryException 
{


Reply via email to