chemistry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From f...@apache.org
Subject svn commit: r1724079 - in /chemistry/opencmis/trunk: chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/ chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemi...
Date Mon, 11 Jan 2016 16:28:19 GMT
Author: fmui
Date: Mon Jan 11 16:28:18 2016
New Revision: 1724079

URL: http://svn.apache.org/viewvc?rev=1724079&view=rev
Log:
OpenCMIS client: added createOverwriteOutputStream() and createAppendOutputStream() to Document
interface

Added:
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/util/AppendOutputStream.java
Modified:
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/Document.java
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/DocumentImpl.java
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/ContentStreamUtils.java
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/OperationContextUtils.java
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/ContentStreamUtilsTest.java
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/OperationContextTest.java
    chemistry/opencmis/trunk/chemistry-opencmis-osgi/chemistry-opencmis-osgi-client/pom.xml
    chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/SetAndDeleteContentTest.java

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/Document.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/Document.java?rev=1724079&r1=1724078&r2=1724079&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/Document.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/Document.java
Mon Jan 11 16:28:18 2016
@@ -18,6 +18,7 @@
  */
 package org.apache.chemistry.opencmis.client.api;
 
+import java.io.OutputStream;
 import java.math.BigInteger;
 import java.util.List;
 import java.util.Map;
@@ -261,6 +262,66 @@ public interface Document extends Fileab
      */
     ObjectId deleteContentStream(boolean refresh);
 
+    /**
+     * Creates an {@link OutputStream} stream object that can be used to
+     * overwrite the current content of the document.
+     * 
+     * @param filename
+     *            the file name
+     * @param mimeType
+     *            the MIME type
+     * @return the OutputStream object
+     * 
+     * @cmis 1.1
+     */
+    OutputStream createOverwriteOutputStream(String filename, String mimeType);
+
+    /**
+     * Creates an {@link OutputStream} stream object that can be used to
+     * overwrite the current content of the document.
+     * 
+     * @param filename
+     *            the file name
+     * @param mimeType
+     *            the MIME type
+     * @param bufferSize
+     *            buffer size in bytes
+     * @return the OutputStream object
+     * 
+     * @cmis 1.1
+     */
+    OutputStream createOverwriteOutputStream(String filename, String mimeType, int bufferSize);
+
+    /**
+     * Creates an {@link OutputStream} stream object that can be used to append
+     * content the current content of the document.
+     * 
+     * @param filename
+     *            the file name
+     * @param mimeType
+     *            the MIME type
+     * @return the OutputStream object
+     * 
+     * @cmis 1.1
+     */
+    OutputStream createAppendOutputStream();
+
+    /**
+     * Creates an {@link OutputStream} stream object that can be used to append
+     * content the current content of the document.
+     * 
+     * @param filename
+     *            the file name
+     * @param mimeType
+     *            the MIME type
+     * @param bufferSize
+     *            buffer size in bytes
+     * @return the OutputStream object
+     * 
+     * @cmis 1.1
+     */
+    OutputStream createAppendOutputStream(int bufferSize);
+
     // versioning service
 
     /**

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/DocumentImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/DocumentImpl.java?rev=1724079&r1=1724078&r2=1724079&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/DocumentImpl.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/DocumentImpl.java
Mon Jan 11 16:28:18 2016
@@ -22,6 +22,7 @@ import static org.apache.chemistry.openc
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.EnumSet;
@@ -39,6 +40,7 @@ import org.apache.chemistry.opencmis.cli
 import org.apache.chemistry.opencmis.client.api.Policy;
 import org.apache.chemistry.opencmis.client.api.Property;
 import org.apache.chemistry.opencmis.client.bindings.spi.LinkAccess;
+import org.apache.chemistry.opencmis.client.runtime.util.AppendOutputStream;
 import org.apache.chemistry.opencmis.commons.PropertyIds;
 import org.apache.chemistry.opencmis.commons.data.Ace;
 import org.apache.chemistry.opencmis.commons.data.ContentStream;
@@ -493,6 +495,10 @@ public class DocumentImpl extends Abstra
 
     @Override
     public ObjectId appendContentStream(ContentStream contentStream, boolean isLastChunk,
boolean refresh) {
+        if (getSession().getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
+            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0
repositories.");
+        }
+
         String newObjectId = null;
 
         readLock();
@@ -562,6 +568,42 @@ public class DocumentImpl extends Abstra
     }
 
     @Override
+    public OutputStream createOverwriteOutputStream(String filename, String mimeType) {
+        if (getSession().getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
+            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0
repositories.");
+        }
+
+        return new AppendOutputStream(getSession(), this, true, filename, mimeType);
+    }
+
+    @Override
+    public OutputStream createOverwriteOutputStream(String filename, String mimeType, int
bufferSize) {
+        if (getSession().getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
+            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0
repositories.");
+        }
+
+        return new AppendOutputStream(getSession(), this, true, filename, mimeType, bufferSize);
+    }
+
+    @Override
+    public OutputStream createAppendOutputStream() {
+        if (getSession().getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
+            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0
repositories.");
+        }
+
+        return new AppendOutputStream(getSession(), this, false, null, null);
+    }
+
+    @Override
+    public OutputStream createAppendOutputStream(int bufferSize) {
+        if (getSession().getRepositoryInfo().getCmisVersion() == CmisVersion.CMIS_1_0) {
+            throw new CmisNotSupportedException("This method is not supported for CMIS 1.0
repositories.");
+        }
+
+        return new AppendOutputStream(getSession(), this, false, null, null, bufferSize);
+    }
+
+    @Override
     public ObjectId checkIn(boolean major, Map<String, ?> properties, ContentStream
contentStream, String checkinComment) {
         return this.checkIn(major, properties, contentStream, checkinComment, null, null,
null);
     }

Added: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/util/AppendOutputStream.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/util/AppendOutputStream.java?rev=1724079&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/util/AppendOutputStream.java
(added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/util/AppendOutputStream.java
Mon Jan 11 16:28:18 2016
@@ -0,0 +1,300 @@
+/*
+ * 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.chemistry.opencmis.client.runtime.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.SequenceInputStream;
+
+import org.apache.chemistry.opencmis.client.api.Document;
+import org.apache.chemistry.opencmis.client.api.OperationContext;
+import org.apache.chemistry.opencmis.client.api.Session;
+import org.apache.chemistry.opencmis.client.util.ContentStreamUtils;
+import org.apache.chemistry.opencmis.client.util.OperationContextUtils;
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.spi.Holder;
+
+/**
+ * This OutputStream allows overwriting and appending to the content of a
+ * document.
+ * 
+ * This class is a convenience layer on top of the CMIS setContentStream() and
+ * appendContentStream() operations. It provides the glue to other (legacy)
+ * interfaces that know how to work with standard streams. However, calling
+ * setContentStream() and appendContentStream() directly provides more control
+ * and may be more efficient than using this class.
+ * 
+ * Data written to this stream is buffered. The default buffer size is 64 KiB.
+ * The data is send to the repository if the buffer is full, or {@link #flush()}
+ * is called, or {@link #close()} is called. Because sending data to the
+ * repository requires a HTTP call, this should be triggered only when
+ * necessary. Depending on the use case, the buffer size should be increased.
+ * 
+ * If the overwrite mode is enabled, the first call is a setContentStream()
+ * call, which overwrites the existing content. All following calls are
+ * appendContentStream() calls. If the overwrite mode is not enabled, all calls
+ * are appendContentStream() calls.
+ * 
+ * If the document is versioned, it's the responsibility of the caller to check
+ * it out and check it in. If the document is auto-versioned, each chunk of
+ * bytes may create a new version.
+ * 
+ * If the repository supports change tokens and the provided document has a
+ * non-empty change token property ({@code cmis:changeToken}), change tokens are
+ * respected.
+ * 
+ * This class is not thread safe.
+ */
+public class AppendOutputStream extends OutputStream {
+
+    public final static OperationContext DOCUMENT_OPERATION_CONTEXT = OperationContextUtils
+            .createMinimumOperationContext("cmis:contentStreamFileName", "cmis:contentStreamMimeType",
+                    "cmis:changeToken");
+
+    private final static int DEFAULT_BUFFER_SIZE = 64 * 1024;
+
+    private Session session;
+    private String repId;
+    private String documentId;
+    private String changeToken;
+    private boolean overwrite;
+    private String filename;
+    private String mimeType;
+    private byte[] buffer;
+    private int pos;
+    private boolean isClosed;
+
+    public AppendOutputStream(Session session, Document doc, boolean overwrite, String filename,
String mimeType) {
+        this(session, doc, overwrite, filename, mimeType, DEFAULT_BUFFER_SIZE);
+    }
+
+    /**
+     * Creates an OutputStream that appends content to a document.
+     * 
+     * @param session
+     *            the session object, must not be {@code null}
+     * @param doc
+     *            the document, must not be {@code null}
+     * @param overwrite
+     *            if {@code true} the first call to repository sets a new
+     *            content, if {@code false} the all calls append to the current
+     *            content
+     * @param filename
+     *            the file name, may be {@code null}
+     * @param mimeType
+     *            the MIME type, may be {@code null}
+     * @param bufferSize
+     *            buffer size
+     */
+    public AppendOutputStream(Session session, Document doc, boolean overwrite, String filename,
String mimeType,
+            int bufferSize) {
+        if (session == null) {
+            throw new IllegalArgumentException("Session must be set!");
+        }
+        if (doc == null) {
+            throw new IllegalArgumentException("Document must be set!");
+        }
+        if (bufferSize < 0) {
+            throw new IllegalArgumentException("Buffer size must be positive!");
+        }
+
+        if (filename == null) {
+            this.filename = doc.getContentStreamFileName();
+        } else {
+            this.filename = filename;
+        }
+
+        if (mimeType == null) {
+            this.mimeType = doc.getContentStreamMimeType();
+        } else {
+            this.mimeType = mimeType;
+        }
+
+        this.session = session;
+        this.repId = session.getRepositoryInfo().getId();
+        this.documentId = doc.getId();
+        this.changeToken = doc.getChangeToken();
+        this.overwrite = overwrite;
+        this.buffer = new byte[bufferSize];
+        this.pos = 0;
+        this.isClosed = false;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        if (isClosed) {
+            throw new IOException("Stream is already closed!");
+        }
+
+        if (pos + 1 > buffer.length) {
+            // not enough space in the buffer for the additional byte
+            // -> write buffer and the byte
+            send(new byte[] { (byte) (b & 0xFF) }, 0, 1, false);
+        } else {
+            buffer[pos++] = (byte) (b & 0xFF);
+        }
+    }
+
+    @Override
+    public void write(byte[] b) throws IOException {
+        write(b, 0, b.length);
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        if (isClosed) {
+            throw new IOException("Stream is already closed!");
+        }
+
+        if (b == null) {
+            throw new IllegalArgumentException("Data must not be null!");
+        } else if (off < 0 || off > b.length) {
+            throw new IndexOutOfBoundsException("Invalid offset!");
+        } else if (len < 0 || (off + len) > b.length || (off + len) < 0) {
+            throw new IndexOutOfBoundsException("Invalid length!");
+        } else if (len == 0) {
+            return;
+        }
+
+        if (pos + len > buffer.length) {
+            // not enough space in the buffer for the additional bytes
+            // -> write buffer and bytes
+            send(b, off, len, false);
+        } else {
+            System.arraycopy(b, off, buffer, pos, len);
+            pos += len;
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+        flush(false);
+    }
+
+    /**
+     * Appends (or sets) the current buffer to the document.
+     * 
+     * @param isLastChunk
+     *            indicates if this is the last chunk of the content
+     * @throws IOException
+     *             if an error occurs
+     */
+    public void flush(boolean isLastChunk) throws IOException {
+        if (isClosed) {
+            throw new IOException("Stream is already closed!");
+        }
+
+        send(isLastChunk);
+    }
+
+    /**
+     * Updates the document content with the provided content stream.
+     */
+    protected void send(boolean isLastChunk) throws IOException {
+        send(null, 0, 0, isLastChunk);
+    }
+
+    /**
+     * Updates the document content with the provided content stream.
+     */
+    protected void send(byte[] extraBytes, int extraOff, int extraLen, boolean isLastChunk)
throws IOException {
+
+        ContentStream contentStream = null;
+        if (extraBytes == null) {
+            if (pos == 0) {
+                // buffer is empty and no extra bytes -> nothing to do
+                return;
+            } else {
+                // buffer is not empty and no extra bytes -> send buffer
+                contentStream = ContentStreamUtils.createByteArrayContentStream(filename,
buffer, 0, pos, mimeType);
+            }
+        } else {
+            if (pos == 0) {
+                // buffer is empty but we have extra bytes
+                // -> only send extra bytes
+                contentStream = ContentStreamUtils.createByteArrayContentStream(filename,
extraBytes, extraOff,
+                        extraLen, mimeType);
+            } else {
+                // buffer is not empty and we have extra bytes
+                // -> send buffer and extra bytes
+                contentStream = ContentStreamUtils.createContentStream(filename, pos + extraLen,
mimeType,
+                        new ContentStreamUtils.AutoCloseInputStream(new SequenceInputStream(new
ByteArrayInputStream(
+                                buffer, 0, pos), new ByteArrayInputStream(extraBytes, extraOff,
extraLen))));
+            }
+        }
+
+        Holder<String> objectIdHolder = new Holder<String>(documentId);
+        Holder<String> changeTokenHolder = changeToken != null ? new Holder<String>(changeToken)
: null;
+
+        try {
+            if (overwrite) {
+                // start a new content stream
+                session.getBinding()
+                        .getObjectService()
+                        .setContentStream(repId, objectIdHolder, Boolean.TRUE, changeTokenHolder,
+                                session.getObjectFactory().convertContentStream(contentStream),
null);
+
+                // the following calls should append, not overwrite
+                overwrite = false;
+            } else {
+                // append to content stream
+                session.getBinding()
+                        .getObjectService()
+                        .appendContentStream(repId, objectIdHolder, changeTokenHolder,
+                                session.getObjectFactory().convertContentStream(contentStream),
isLastChunk, null);
+            }
+        } catch (Exception e) {
+            isClosed = true;
+            throw new IOException("Could not append to document: " + e.toString(), e);
+        }
+
+        if (objectIdHolder.getValue() != null) {
+            documentId = objectIdHolder.getValue();
+        }
+        if (changeTokenHolder != null) {
+            changeToken = changeTokenHolder.getValue();
+        }
+
+        pos = 0;
+    }
+
+    @Override
+    public void close() throws IOException {
+        close(true);
+    }
+
+    /**
+     * Closes the stream.
+     * 
+     * @param isLastChunk
+     *            indicates if this is the last chunk of the content
+     * @throws IOException
+     *             if an error occurs
+     */
+    public void close(boolean isLastChunk) throws IOException {
+        if (isClosed) {
+            throw new IOException("Stream is already closed!");
+        }
+
+        if (pos > 0) {
+            flush(isLastChunk);
+        }
+    }
+}

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/ContentStreamUtils.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/ContentStreamUtils.java?rev=1724079&r1=1724078&r2=1724079&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/ContentStreamUtils.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/ContentStreamUtils.java
Mon Jan 11 16:28:18 2016
@@ -120,8 +120,40 @@ public final class ContentStreamUtils {
             return createContentStream(filename, null, mimetype, null);
         }
 
-        return createContentStream(filename, contentBytes.length, mimetype, new AutoCloseInputStream(
-                new ByteArrayInputStream(contentBytes)));
+        return createByteArrayContentStream(filename, contentBytes, 0, contentBytes.length,
mimetype);
+    }
+
+    /**
+     * Creates a content stream object from a byte array.
+     * 
+     * @param filename
+     *            name of the content stream
+     * @param contentBytes
+     *            the content bytes
+     * @param offset
+     *            the offset in the content bytes
+     * @param length
+     *            the maximum number of bytes to read from the content bytes
+     * @param mimetype
+     *            content MIME type
+     * 
+     * @return a {@link MutableContentStream} object
+     * 
+     */
+    public static MutableContentStream createByteArrayContentStream(String filename, byte[]
contentBytes, int offset,
+            int length, String mimetype) {
+        if (contentBytes == null) {
+            return createContentStream(filename, null, mimetype, null);
+        }
+
+        if (offset < 0 || offset > contentBytes.length) {
+            throw new IndexOutOfBoundsException("Invalid offset!");
+        } else if (length < 0 || (offset + length) > contentBytes.length || (offset
+ length) < 0) {
+            throw new IndexOutOfBoundsException("Invalid length!");
+        }
+
+        return createContentStream(filename, length, mimetype, new AutoCloseInputStream(new
ByteArrayInputStream(
+                contentBytes, offset, length)));
     }
 
     // --- strings ---
@@ -357,8 +389,13 @@ public final class ContentStreamUtils {
         @Override
         public void close() throws IOException {
             if (stream != null) {
-                stream.close();
-                stream = null;
+                try {
+                    stream.close();
+                } catch (final IOException ioe) {
+                    throw ioe;
+                } finally {
+                    stream = null;
+                }
             }
         }
 

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/OperationContextUtils.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/OperationContextUtils.java?rev=1724079&r1=1724078&r2=1724079&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/OperationContextUtils.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/OperationContextUtils.java
Mon Jan 11 16:28:18 2016
@@ -54,7 +54,8 @@ public final class OperationContextUtils
     }
 
     /**
-     * Creates a new OperationContext object with the given parameters.
+     * Creates a new OperationContext object with the given parameters. Caching
+     * is enabled.
      */
     public static OperationContext createOperationContext(Set<String> filter, boolean
includeAcls,
             boolean includeAllowableActions, boolean includePolicies, IncludeRelationships
includeRelationships,
@@ -66,13 +67,28 @@ public final class OperationContextUtils
 
     /**
      * Creates a new OperationContext object that only selects the bare minimum.
+     * Caching is enabled.
      */
     public static OperationContext createMinimumOperationContext() {
+        return createMinimumOperationContext((String[]) null);
+    }
+
+    /**
+     * Creates a new OperationContext object that only selects the bare minimum
+     * plus the provided properties. Caching is enabled.
+     */
+    public static OperationContext createMinimumOperationContext(String... property) {
         Set<String> filter = new HashSet<String>();
         filter.add(PropertyIds.OBJECT_ID);
         filter.add(PropertyIds.OBJECT_TYPE_ID);
         filter.add(PropertyIds.BASE_TYPE_ID);
 
+        if (property != null) {
+            for (String prop : property) {
+                filter.add(prop);
+            }
+        }
+
         return new OperationContextImpl(filter, false, false, false, IncludeRelationships.NONE,
                 Collections.singleton(RENDITION_NONE), false, null, true, 100);
     }

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/ContentStreamUtilsTest.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/ContentStreamUtilsTest.java?rev=1724079&r1=1724078&r2=1724079&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/ContentStreamUtilsTest.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/ContentStreamUtilsTest.java
Mon Jan 11 16:28:18 2016
@@ -125,6 +125,21 @@ public class ContentStreamUtilsTest {
     }
 
     @Test
+    public void testByteArrayContentStream() throws IOException {
+        byte[] content = IOUtils.toUTF8Bytes("1234567890");
+
+        MutableContentStream contentStream = ContentStreamUtils.createByteArrayContentStream("array",
content, 2, 5,
+                "text/plain");
+
+        assertNotNull(contentStream);
+        assertEquals("array", contentStream.getFileName());
+        assertEquals("text/plain", contentStream.getMimeType());
+        assertEquals(5, contentStream.getLength());
+        assertNotNull(contentStream.getBigLength());
+        assertNotNull(contentStream.getStream());
+    }
+
+    @Test
     public void testFileContentStream() throws IOException {
         File tmpFile = File.createTempFile("test", ".txt");
 

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/OperationContextTest.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/OperationContextTest.java?rev=1724079&r1=1724078&r2=1724079&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/OperationContextTest.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/OperationContextTest.java
Mon Jan 11 16:28:18 2016
@@ -19,10 +19,12 @@
 package org.apache.chemistry.opencmis.client.runtime;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
 import java.util.Set;
 
+import org.apache.chemistry.opencmis.client.api.OperationContext;
+import org.apache.chemistry.opencmis.client.util.OperationContextUtils;
 import org.junit.Test;
 
 public class OperationContextTest {
@@ -72,4 +74,36 @@ public class OperationContextTest {
         assertEquals(1, filter.size());
         assertTrue(filter.contains("cmis:none"));
     }
+
+    @Test
+    public void testOperationContextUtils() {
+        OperationContext oc1 = OperationContextUtils.createMinimumOperationContext();
+        assertNotNull(oc1);
+
+        assertEquals(3, oc1.getFilter().size());
+        assertFalse(oc1.isIncludeAllowableActions());
+        assertFalse(oc1.isIncludeAcls());
+        assertFalse(oc1.isIncludePolicies());
+        assertFalse(oc1.isIncludePathSegments());
+
+        OperationContext oc2 = OperationContextUtils.createMinimumOperationContext("abc",
"xyz");
+        assertNotNull(oc2);
+
+        assertEquals(5, oc2.getFilter().size());
+        assertTrue(oc2.getFilter().contains("abc"));
+        assertTrue(oc2.getFilter().contains("xyz"));
+        assertFalse(oc2.isIncludeAllowableActions());
+        assertFalse(oc2.isIncludeAcls());
+        assertFalse(oc2.isIncludePolicies());
+        assertFalse(oc2.isIncludePathSegments());
+
+        OperationContext oc3 = OperationContextUtils.createMaximumOperationContext();
+        assertNotNull(oc3);
+
+        assertTrue(oc3.getFilter().contains("*"));
+        assertTrue(oc3.isIncludeAllowableActions());
+        assertTrue(oc3.isIncludeAcls());
+        assertTrue(oc3.isIncludePolicies());
+        assertFalse(oc3.isIncludePathSegments());
+    }
 }

Modified: chemistry/opencmis/trunk/chemistry-opencmis-osgi/chemistry-opencmis-osgi-client/pom.xml
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-osgi/chemistry-opencmis-osgi-client/pom.xml?rev=1724079&r1=1724078&r2=1724079&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-osgi/chemistry-opencmis-osgi-client/pom.xml
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-osgi/chemistry-opencmis-osgi-client/pom.xml
Mon Jan 11 16:28:18 2016
@@ -63,6 +63,7 @@
                         <_exportcontents>
                             org.apache.chemistry.opencmis.client;version=${project.version},
                             org.apache.chemistry.opencmis.client.api.*;version=${project.version},
+                            org.apache.chemistry.opencmis.client.util.*;version=${project.version},
                             org.apache.chemistry.opencmis.client.bindings;version=${project.version},
                             org.apache.chemistry.opencmis.client.bindings.spi.*;version=${project.version},
                             org.apache.chemistry.opencmis.commons.impl.*;version=${project.version};-noimport:=true,

Modified: chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/SetAndDeleteContentTest.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/SetAndDeleteContentTest.java?rev=1724079&r1=1724078&r2=1724079&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/SetAndDeleteContentTest.java
(original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-tck/src/main/java/org/apache/chemistry/opencmis/tck/tests/crud/SetAndDeleteContentTest.java
Mon Jan 11 16:28:18 2016
@@ -25,6 +25,7 @@ import static org.apache.chemistry.openc
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
 
@@ -190,6 +191,11 @@ public class SetAndDeleteContentTest ext
                         addResult(createResult(UNEXPECTED_EXCEPTION, "Document content couldn't
be read! Exception: "
                                 + e.getMessage(), e, true));
                     }
+
+                    // test append stream
+                    testAppendStream(session, testFolder, 16 * 1024);
+                    testAppendStream(session, testFolder, 8);
+                    testAppendStream(session, testFolder, 0);
                 } catch (CmisNotSupportedException e) {
                     addResult(createResult(WARNING, "appendContentStream() is not supported!"));
                 }
@@ -207,6 +213,70 @@ public class SetAndDeleteContentTest ext
         }
     }
 
+    private void testAppendStream(Session session, Folder testFolder, int bufferSize) {
+        CmisTestResult f;
+
+        // create an empty document
+        Document doc = createDocument(session, testFolder, "appendstreamtest.txt", "");
+        Document workDoc = doc;
+
+        boolean checkedout = false;
+        DocumentTypeDefinition docType = (DocumentTypeDefinition) doc.getType();
+
+        if (Boolean.TRUE.equals(docType.isVersionable())) {
+            workDoc = (Document) session.getObject(doc.checkOut(), SELECT_ALL_NO_CACHE_OC);
+            checkedout = true;
+        }
+
+        try {
+            // create an overwrite OutputStream
+            OutputStream out1 = workDoc.createOverwriteOutputStream("appendstreamtest", "text/plain",
bufferSize);
+
+            out1.write(IOUtils.toUTF8Bytes("line 1\n"));
+            out1.write(IOUtils.toUTF8Bytes("line 2\n"));
+            out1.flush();
+
+            out1.write(IOUtils.toUTF8Bytes("line 3\n"));
+            out1.close();
+
+            // check document content
+            workDoc.refresh();
+            String content1 = getStringFromContentStream(workDoc.getContentStream());
+
+            f = createResult(FAILURE, "Overwrite OutputStream: wrong content!");
+            addResult(assertEquals("line 1\nline 2\nline 3\n", content1, null, f));
+
+            // create an append OutputStream
+            OutputStream out2 = workDoc.createAppendOutputStream(bufferSize);
+
+            out2.write(IOUtils.toUTF8Bytes("line 4\n"));
+            out2.write(IOUtils.toUTF8Bytes("line 5\n"));
+            out2.flush();
+
+            out2.write(IOUtils.toUTF8Bytes("line 6\n"));
+            out2.close();
+
+            // check document content
+            workDoc.refresh();
+            String content2 = getStringFromContentStream(workDoc.getContentStream());
+
+            f = createResult(FAILURE, "Overwrite OutputStream: wrong content!");
+            addResult(assertEquals("line 1\nline 2\nline 3\nline 4\nline 5\nline 6\n", content2,
null, f));
+
+        } catch (IOException e) {
+            addResult(createResult(UNEXPECTED_EXCEPTION, "Appending content via an OutputStream
failed! Exception: "
+                    + e.getMessage(), e, false));
+        } finally {
+            // cancel a possible check out
+            if (checkedout) {
+                workDoc.cancelCheckOut();
+            }
+
+            // remove the document
+            deleteObject(doc);
+        }
+    }
+
     private CapabilityContentStreamUpdates getContentStreamUpdatesCapbility(Session session)
{
         if (session.getRepositoryInfo().getCapabilities() == null) {
             return null;



Mime
View raw message