You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2014/08/28 12:46:17 UTC

svn commit: r1621115 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/value/ oak-jcr/sr...

Author: mduerig
Date: Thu Aug 28 10:46:17 2014
New Revision: 1621115

URL: http://svn.apache.org/r1621115
Log:
OAK-2052: Node.setProperty(String, Value) fails for binary non ValueImpls
Copy non ValueImpl binaries byte wise

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlob.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/value/
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlobTest.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/BinaryPropertyState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/BinaryPropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/BinaryPropertyState.java?rev=1621115&r1=1621114&r2=1621115&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/BinaryPropertyState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/BinaryPropertyState.java Thu Aug 28 10:46:17 2014
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.plugin
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import javax.annotation.Nonnull;
+import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 
 import org.apache.jackrabbit.oak.api.Blob;
@@ -78,7 +79,7 @@ public class BinaryPropertyState extends
      * @return  The new property state of type {@link Type#BINARY}
      */
     public static PropertyState binaryProperty(
-            @Nonnull String name, @Nonnull Value value) {
+            @Nonnull String name, @Nonnull Value value) throws RepositoryException {
         return new BinaryPropertyState(name, ValueImpl.getBlob(value));
     }
 

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlob.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlob.java?rev=1621115&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlob.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlob.java Thu Aug 28 10:46:17 2014
@@ -0,0 +1,96 @@
+/*
+ * 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.plugins.value;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.annotation.Nonnull;
+import javax.jcr.Binary;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.oak.api.Blob;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This Blob implementation is based on an underlying {@link javax.jcr.Binary}.
+ * <p>
+ * Any error accessing the underlying binary in {@link #getNewStream()} will be
+ * deferred to the returned input stream.
+ */
+public class BinaryBasedBlob implements Blob {
+    private static final Logger LOG = LoggerFactory.getLogger(BinaryBasedBlob.class);
+
+    private final Binary binary;
+
+    public BinaryBasedBlob(Binary binary) {
+        this.binary = binary;
+    }
+
+    /**
+     * Delegates to {@link Binary#getStream()} and returns an input stream the always
+     * throws an {@code IOException} if the underlying binary failed to produce one.
+     */
+    @Nonnull
+    @Override
+    public InputStream getNewStream() {
+        try {
+            return binary.getStream();
+        } catch (final RepositoryException e) {
+            LOG.warn("Error retrieving stream from binary", e);
+            return new InputStream() {
+                @Override
+                public int read() throws IOException {
+                    throw new IOException(e);
+                }
+            };
+        }
+    }
+
+    /**
+     * Delegates to {@link Binary#getSize()} and returns -1 if that fails.
+     */
+    @Override
+    public long length() {
+        try {
+            return binary.getSize();
+        } catch (RepositoryException e) {
+            LOG.warn("Error determining length of binary", e);
+            return -1;
+        }
+    }
+
+    /**
+     * @return  {@code null}
+     */
+    @Override
+    public String getReference() {
+        return null;
+    }
+
+    /**
+     * @return  {@code null}
+     */
+    @Override
+    public String getContentIdentity() {
+        return null;
+    }
+}

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueImpl.java?rev=1621115&r1=1621114&r2=1621115&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/value/ValueImpl.java Thu Aug 28 10:46:17 2014
@@ -41,9 +41,12 @@ import org.apache.jackrabbit.oak.namepat
  */
 public class ValueImpl implements JackrabbitValue {
 
-    public static Blob getBlob(Value value) {
-        checkState(value instanceof ValueImpl);
-        return ((ValueImpl) value).getBlob();
+    public static Blob getBlob(Value value) throws RepositoryException {
+        if (value instanceof ValueImpl) {
+            return ((ValueImpl) value).getBlob();
+        } else {
+            return new BinaryBasedBlob(value.getBinary());
+        }
     }
 
     private final PropertyState propertyState;

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlobTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlobTest.java?rev=1621115&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlobTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/value/BinaryBasedBlobTest.java Thu Aug 28 10:46:17 2014
@@ -0,0 +1,120 @@
+/*
+ * 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.plugins.value;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.jcr.Binary;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.oak.api.Blob;
+import org.junit.Test;
+
+public class BinaryBasedBlobTest {
+
+    @Test
+    public void getStream() throws RepositoryException, IOException {
+        byte[] bytes = "just a test".getBytes();
+        Binary binary = new TestBinary(bytes);
+        Blob blob = new BinaryBasedBlob(binary);
+
+        assertEquals(bytes.length, blob.length());
+
+        InputStream expected = binary.getStream();
+        InputStream actual = blob.getNewStream();
+        try {
+            for (int e = expected.read(); e != -1; e = expected.read()) {
+                assertEquals(e, actual.read());
+            }
+            assertEquals(-1, actual.read());
+
+        } finally {
+            expected.close();
+            actual.close();
+        }
+    }
+
+    @Test
+    public void getStreamWithError() throws IOException {
+        Blob blob = new BinaryBasedBlob(new FailingBinary());
+
+        assertEquals(-1, blob.length());
+        InputStream ins = blob.getNewStream();
+        try {
+            ins.read();
+            fail();
+        } catch (IOException ignored) {
+        } finally {
+            ins.close();
+        }
+    }
+
+    private static class TestBinary implements Binary {
+        private final byte[] data;
+
+        public TestBinary(byte[] data) {
+            this.data = data;
+        }
+
+        @Override
+        public InputStream getStream() throws RepositoryException {
+            return new ByteArrayInputStream(data);
+        }
+
+        @Override
+        public int read(byte[] b, long position) throws IOException, RepositoryException {
+            return getStream().read(b, (int) position, b.length);
+        }
+
+        @Override
+        public long getSize() throws RepositoryException {
+            return data.length;
+        }
+
+        @Override
+        public void dispose() { }
+    }
+
+    private static class FailingBinary implements Binary {
+        @Override
+        public InputStream getStream() throws RepositoryException {
+            throw new RepositoryException("no stream");
+        }
+
+        @Override
+        public int read(byte[] b, long position) throws IOException, RepositoryException {
+            throw new RepositoryException("no stream");
+        }
+
+        @Override
+        public long getSize() throws RepositoryException {
+            return -1;
+        }
+
+        @Override
+        public void dispose() { }
+    }
+
+}

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java?rev=1621115&r1=1621114&r2=1621115&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java Thu Aug 28 10:46:17 2014
@@ -976,7 +976,6 @@ public class RepositoryTest extends Abst
         addProperty(parentNode, "bigBinary", getAdminSession().getValueFactory().createValue(bin));
     }
 
-    @Ignore("OAK-2052")  // FIXME OAK-2052
     @Test
     public void addAlienBinaryProperty() throws RepositoryException, IOException {
         Session session = getAdminSession();
@@ -984,6 +983,9 @@ public class RepositoryTest extends Abst
         Value value = new QValueValue(qValue, new DefaultNamePathResolver(session));
         getNode(TEST_PATH).setProperty("binary", value);
         session.save();
+
+        Value valueAgain = getNode(TEST_PATH).getProperty("binary").getValue();
+        assertEqualStream(value.getBinary().getStream(), valueAgain.getBinary().getStream());
     }
 
     @Test