You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2015/10/31 13:24:27 UTC
svn commit: r1711615 - in
/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src:
main/java/org/apache/chemistry/opencmis/client/util/
test/java/org/apache/chemistry/opencmis/client/runtime/
Author: fmui
Date: Sat Oct 31 12:24:27 2015
New Revision: 1711615
URL: http://svn.apache.org/viewvc?rev=1711615&view=rev
Log:
added ContentStreamUtils
Added:
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/test/java/org/apache/chemistry/opencmis/client/runtime/ContentStreamUtilsTest.java
Modified:
chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/FileUtils.java
Added: 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=1711615&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/ContentStreamUtils.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/ContentStreamUtils.java Sat Oct 31 12:24:27 2015
@@ -0,0 +1,413 @@
+/*
+ * 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.util;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.data.MutableContentStream;
+import org.apache.chemistry.opencmis.commons.impl.IOUtils;
+import org.apache.chemistry.opencmis.commons.impl.MimeTypes;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
+
+/**
+ * Methods to create {@link ContentStream} objects.
+ */
+public final class ContentStreamUtils {
+
+ private static final String OCTETSTREAM = "application/octet-stream";
+
+ private ContentStreamUtils() {
+ }
+
+ // --- generic ---
+
+ /**
+ * Creates a content stream object for an InputStream.
+ *
+ * @param filename
+ * name of the content stream
+ * @param length
+ * length of the stream in bytes
+ * @param mimetype
+ * content MIME type
+ * @param stream
+ * the InputStream
+ *
+ * @return a {@link MutableContentStream} object
+ */
+ public static MutableContentStream createContentStream(String filename, long length, String mimetype,
+ InputStream stream) {
+ return createContentStream(filename, length < 0 ? null : BigInteger.valueOf(length), mimetype, stream);
+ }
+
+ /**
+ * Creates a content stream object for an InputStream.
+ *
+ * @param filename
+ * name of the content stream
+ * @param length
+ * length of the stream in bytes
+ * @param mimetype
+ * content MIME type
+ * @param stream
+ * the InputStream
+ *
+ * @return a {@link MutableContentStream} object
+ */
+ public static MutableContentStream createContentStream(String filename, BigInteger length, String mimetype,
+ InputStream stream) {
+ return new ContentStreamImpl(checkFilename(filename), length, checkMIMEType(mimetype), stream);
+ }
+
+ // --- byte arrays ---
+
+ /**
+ * Creates a content stream object from a byte array.
+ *
+ * The MIME type is set to "application/octet-stream".
+ *
+ * @param filename
+ * name of the content stream
+ * @param contentBytes
+ * content bytes
+ *
+ * @return a {@link MutableContentStream} object
+ */
+ public static MutableContentStream createByteArrayContentStream(String filename, byte[] contentBytes) {
+ return createByteArrayContentStream(filename, contentBytes, OCTETSTREAM);
+ }
+
+ /**
+ * Creates a content stream object from a byte array.
+ *
+ * @param filename
+ * name of the content stream
+ * @param contentBytes
+ * the content bytes
+ * @param mimetype
+ * content MIME type
+ *
+ * @return a {@link MutableContentStream} object
+ *
+ */
+ public static MutableContentStream createByteArrayContentStream(String filename, byte[] contentBytes,
+ String mimetype) {
+ if (contentBytes == null) {
+ return createContentStream(filename, null, mimetype, null);
+ }
+
+ return createContentStream(filename, contentBytes.length, mimetype, new AutoCloseInputStream(
+ new ByteArrayInputStream(contentBytes)));
+ }
+
+ // --- strings ---
+
+ /**
+ * Creates a content stream object from a string.
+ *
+ * The MIME type is set to "text/plain".
+ *
+ * @param filename
+ * name of the content stream
+ * @param content
+ * the content string
+ *
+ * @return a {@link MutableContentStream} object
+ */
+ public static MutableContentStream createTextContentStream(String filename, String content) {
+ return createTextContentStream(filename, content, "text/plain; charset=UTF-8");
+ }
+
+ /**
+ * Creates a content stream object from a string.
+ *
+ * @param filename
+ * name of the content stream
+ * @param content
+ * the content string
+ * @param mimetype
+ * content MIME type
+ *
+ * @return a {@link MutableContentStream} object
+ */
+ public static MutableContentStream createTextContentStream(String filename, String content, String mimetype) {
+ byte[] contentBytes = IOUtils.toUTF8Bytes(content);
+ return createByteArrayContentStream(filename, contentBytes, checkMIMEType(mimetype));
+ }
+
+ // --- files ---
+
+ /**
+ * Creates a content stream object from file.
+ *
+ * The MIME type is guessed from the file name and the content.
+ *
+ * @param file
+ * the file
+ *
+ * @return a {@link MutableContentStream} object
+ */
+ public static MutableContentStream createFileContentStream(File file) throws FileNotFoundException {
+ return createFileContentStream(file.getName(), file, MimeTypes.getMIMEType(file));
+ }
+
+ /**
+ * Creates a content stream object from file.
+ *
+ * The MIME type is guessed from the file name and the content.
+ *
+ * @param filename
+ * name of the content stream
+ * @param file
+ * the file
+ *
+ * @return a {@link MutableContentStream} object
+ */
+ public static MutableContentStream createFileContentStream(String filename, File file) throws FileNotFoundException {
+ return createFileContentStream(filename, file, MimeTypes.getMIMEType(file));
+ }
+
+ /**
+ * Creates a content stream object from file.
+ *
+ * @param file
+ * the file
+ * @param mimetype
+ * content MIME type
+ *
+ * @return a {@link MutableContentStream} object
+ */
+ public static MutableContentStream createFileContentStream(File file, String mimetype) throws FileNotFoundException {
+ return createFileContentStream(file.getName(), file, mimetype);
+ }
+
+ /**
+ * Creates a content stream object from file.
+ *
+ * @param filename
+ * name of the content stream
+ * @param file
+ * the file
+ * @param mimetype
+ * content MIME type
+ *
+ * @return a {@link MutableContentStream} object
+ */
+ public static MutableContentStream createFileContentStream(String filename, File file, String mimetype)
+ throws FileNotFoundException {
+ return createContentStream(filename, file.length(), mimetype, new AutoCloseInputStream(new BufferedInputStream(
+ new FileInputStream(file))));
+ }
+
+ // --- helpers ---
+
+ private static String checkFilename(String filename) {
+ if (filename == null || filename.length() == 0) {
+ return "content";
+ }
+
+ return filename;
+ }
+
+ private static String checkMIMEType(String mimetype) {
+ if (mimetype == null) {
+ return OCTETSTREAM;
+ }
+
+ String result = mimetype.trim();
+ if (result.length() < 3) {
+ return OCTETSTREAM;
+ }
+
+ return result;
+ }
+
+ // --- classes ---
+
+ /**
+ * InputStream that gets closed when the end of the stream is reached or the
+ * underlying stream throws an exception.
+ */
+ public static class AutoCloseInputStream extends InputStream {
+
+ protected InputStream stream;
+
+ public AutoCloseInputStream(InputStream in) {
+ stream = in;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (stream != null) {
+ int b = -1;
+
+ try {
+ b = stream.read();
+ } catch (IOException ioe) {
+ closeQuietly();
+ throw ioe;
+ }
+
+ if (b == -1) {
+ close();
+ }
+
+ return b;
+ } else {
+ throw new IOException("Stream is already closed!");
+ }
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ if (stream != null) {
+ int l = -1;
+
+ try {
+ l = stream.read(b);
+ } catch (IOException ioe) {
+ closeQuietly();
+ throw ioe;
+ }
+
+ if (l == -1) {
+ close();
+ }
+
+ return l;
+ } else {
+ throw new IOException("Stream is already closed!");
+ }
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (stream != null) {
+ int l = -1;
+
+ try {
+ l = stream.read(b, off, len);
+ } catch (IOException ioe) {
+ closeQuietly();
+ throw ioe;
+ }
+
+ if (l == -1) {
+ close();
+ }
+
+ return l;
+ } else {
+ throw new IOException("Stream is already closed!");
+ }
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ if (stream != null) {
+ try {
+ return stream.skip(n);
+ } catch (IOException ioe) {
+ closeQuietly();
+ throw ioe;
+ }
+ } else {
+ throw new IOException("Stream is already closed!");
+ }
+ }
+
+ @Override
+ public int available() throws IOException {
+ if (stream != null) {
+ try {
+ return stream.available();
+ } catch (IOException ioe) {
+ closeQuietly();
+ throw ioe;
+ }
+ } else {
+ throw new IOException("Stream is already closed!");
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (stream != null) {
+ stream.close();
+ stream = null;
+ }
+ }
+
+ public void closeQuietly() {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (final IOException ioe) {
+ // ignore
+ } finally {
+ stream = null;
+ }
+ }
+ }
+
+ @Override
+ public synchronized void mark(int readlimit) {
+ if (stream != null) {
+ stream.mark(readlimit);
+ }
+ }
+
+ @Override
+ public synchronized void reset() throws IOException {
+ if (stream != null) {
+ try {
+ stream.reset();
+ } catch (IOException ioe) {
+ closeQuietly();
+ throw ioe;
+ }
+ } else {
+ throw new IOException("Stream is already closed!");
+ }
+ }
+
+ @Override
+ public boolean markSupported() {
+ if (stream != null) {
+ return stream.markSupported();
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ closeQuietly();
+ super.finalize();
+ }
+ }
+}
Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/FileUtils.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/FileUtils.java?rev=1711615&r1=1711614&r2=1711615&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/FileUtils.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/FileUtils.java Sat Oct 31 12:24:27 2015
@@ -18,15 +18,11 @@
*/
package org.apache.chemistry.opencmis.client.util;
-import java.io.ByteArrayInputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.PrintStream;
-import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
@@ -41,10 +37,7 @@ import org.apache.chemistry.opencmis.com
import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
import org.apache.chemistry.opencmis.commons.impl.IOUtils;
-import org.apache.chemistry.opencmis.commons.impl.MimeTypes;
-import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
/**
* A set of utility methods that simplify file and folder operations.
@@ -126,25 +119,17 @@ public final class FileUtils {
Folder parentFolder = getFolder(parentIdOrPath, session);
String name = file.getName();
- String mimetype = MimeTypes.getMIMEType(file);
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, type);
properties.put(PropertyIds.NAME, name);
- InputStream stream = new FileInputStream(file);
- ContentStream contentStream = new ContentStreamImpl(name, BigInteger.valueOf(file.length()), mimetype, stream);
+ ContentStream contentStream = ContentStreamUtils.createFileContentStream(name, file);
try {
return parentFolder.createDocument(properties, contentStream, versioningState);
} finally {
- if (stream != null) {
- try {
- stream.close();
- } catch (IOException ioe) {
- throw new CmisRuntimeException("Cannot close source stream!", ioe);
- }
- }
+ IOUtils.closeQuietly(contentStream);
}
}
@@ -177,16 +162,13 @@ public final class FileUtils {
properties.put(PropertyIds.OBJECT_TYPE_ID, type);
properties.put(PropertyIds.NAME, name);
- byte[] contentBytes = new byte[0];
- if (content != null) {
- contentBytes = IOUtils.toUTF8Bytes(content);
- }
-
- ByteArrayInputStream bais = new ByteArrayInputStream(contentBytes);
- ContentStream contentStream = new ContentStreamImpl(name, BigInteger.valueOf(contentBytes.length),
- "text/plain", bais);
+ ContentStream contentStream = ContentStreamUtils.createTextContentStream(name, content);
- return parentFolder.createDocument(properties, contentStream, versioningState);
+ try {
+ return parentFolder.createDocument(properties, contentStream, versioningState);
+ } finally {
+ IOUtils.closeQuietly(contentStream);
+ }
}
/**
Added: 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=1711615&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/ContentStreamUtilsTest.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/ContentStreamUtilsTest.java Sat Oct 31 12:24:27 2015
@@ -0,0 +1,160 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import org.apache.chemistry.opencmis.client.util.ContentStreamUtils;
+import org.apache.chemistry.opencmis.client.util.ContentStreamUtils.AutoCloseInputStream;
+import org.apache.chemistry.opencmis.commons.data.MutableContentStream;
+import org.apache.chemistry.opencmis.commons.impl.IOUtils;
+import org.junit.Test;
+
+public class ContentStreamUtilsTest {
+
+ private static final String CONTENT = "content";
+ private static final byte[] CONTENT_BYTES = IOUtils.toUTF8Bytes(CONTENT);
+
+ @Test
+ public void testTextContentStream() throws IOException {
+ MutableContentStream contentStream = ContentStreamUtils.createTextContentStream("filename", CONTENT);
+
+ assertNotNull(contentStream);
+ assertEquals("filename", contentStream.getFileName());
+ assertEquals("text/plain; charset=UTF-8", contentStream.getMimeType());
+ assertEquals(CONTENT_BYTES.length, contentStream.getLength());
+ assertNotNull(contentStream.getStream());
+ assertTrue(contentStream.getStream() instanceof ContentStreamUtils.AutoCloseInputStream);
+
+ AutoCloseInputStream in = (AutoCloseInputStream) contentStream.getStream();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ if (in.markSupported()) {
+ in.mark(1024);
+ in.read();
+ in.reset();
+ }
+
+ assertEquals(CONTENT_BYTES.length, in.available());
+
+ IOUtils.copy(in, out);
+
+ assertArrayEquals(CONTENT_BYTES, out.toByteArray());
+
+ try {
+ in.read();
+ fail();
+ } catch (IOException ioe) {
+ // excpeted
+ }
+
+ assertFalse(in.markSupported());
+ }
+
+ @Test
+ public void testEmptyContentStream() throws IOException {
+ MutableContentStream contentStream = ContentStreamUtils.createByteArrayContentStream(null, new byte[0]);
+
+ assertNotNull(contentStream);
+ assertEquals("content", contentStream.getFileName());
+ assertEquals("application/octet-stream", contentStream.getMimeType());
+ assertEquals(0, contentStream.getLength());
+ assertEquals(BigInteger.ZERO, contentStream.getBigLength());
+ assertNotNull(contentStream.getStream());
+
+ InputStream in = (InputStream) contentStream.getStream();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ IOUtils.copy(in, out);
+
+ assertEquals(0, out.toByteArray().length);
+
+ contentStream.setFileName("myFile");
+ assertEquals("myFile", contentStream.getFileName());
+ contentStream.setMimeType("mime/type");
+ assertEquals("mime/type", contentStream.getMimeType());
+
+ try {
+ in.read();
+ fail();
+ } catch (IOException ioe) {
+ // excpeted
+ }
+ }
+
+ @Test
+ public void testNullContentStream() throws IOException {
+ MutableContentStream contentStream = ContentStreamUtils.createByteArrayContentStream(null, null, null);
+
+ assertNotNull(contentStream);
+ assertEquals("content", contentStream.getFileName());
+ assertEquals("application/octet-stream", contentStream.getMimeType());
+ assertEquals(-1, contentStream.getLength());
+ assertNull(contentStream.getBigLength());
+ assertNull(contentStream.getStream());
+ }
+
+ @Test
+ public void testFileContentStream() throws IOException {
+ File tmpFile = File.createTempFile("test", ".txt");
+
+ FileOutputStream fos = new FileOutputStream(tmpFile);
+ fos.write(CONTENT_BYTES);
+ fos.close();
+
+ MutableContentStream contentStream = ContentStreamUtils.createFileContentStream(tmpFile);
+
+ assertNotNull(contentStream);
+ assertEquals(tmpFile.getName(), contentStream.getFileName());
+ assertTrue(contentStream.getMimeType().toLowerCase(Locale.ENGLISH).startsWith("text/plain"));
+ assertEquals(CONTENT_BYTES.length, contentStream.getLength());
+ assertNotNull(contentStream.getStream());
+ assertTrue(contentStream.getStream() instanceof ContentStreamUtils.AutoCloseInputStream);
+
+ AutoCloseInputStream in = (AutoCloseInputStream) contentStream.getStream();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ IOUtils.copy(in, out);
+
+ assertArrayEquals(CONTENT_BYTES, out.toByteArray());
+
+ try {
+ in.read();
+ fail();
+ } catch (IOException ioe) {
+ // excpeted
+ }
+
+ in.closeQuietly();
+ }
+}