This project has retired. For details please refer to its
Attic page.
JcrBinary xref
1/*2 * Licensed to the Apache Software Foundation (ASF) under one3 * or more contributor license agreements. See the NOTICE file4 * distributed with this work for additional information5 * regarding copyright ownership. The ASF licenses this file6 * to you under the Apache License, Version 2.0 (the7 * "License"); you may not use this file except in compliance8 * with the License. You may obtain a copy of the License at9 *10 * http://www.apache.org/licenses/LICENSE-2.011 *12 * Unless required by applicable law or agreed to in writing,13 * software distributed under the License is distributed on an14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY15 * KIND, either express or implied. See the License for the16 * specific language governing permissions and limitations17 * under the License.18 */1920package org.apache.chemistry.opencmis.jcr;
2122import javax.jcr.Binary;
23import javax.jcr.RepositoryException;
24import java.io.ByteArrayInputStream;
25import java.io.File;
26import java.io.FileInputStream;
27import java.io.FileNotFoundException;
28import java.io.FileOutputStream;
29import java.io.IOException;
30import java.io.InputStream;
31import java.io.OutputStream;
32import java.io.RandomAccessFile;
3334/**35 * <code>JcrBinary</code> implements the JCR <code>Binary</code> interface.36 * This is mostly a copy from org.apache.jackrabbit.value.BinaryImpl in37 * Apache Jackrabbit's jcr-commons module. 38 */39publicclassJcrBinary implements Binary {
4041/**42 * empty array43 */44privatestaticfinal byte[] EMPTY_BYTE_ARRAY = new byte[0];
4546/**47 * max size for keeping tmp data in memory48 */49privatestaticfinalint MAX_BUFFER_SIZE = 0x10000;
5051/**52 * underlying tmp file53 */54privatefinal File tmpFile;
5556/**57 * buffer for small-sized data58 */59private byte[] buffer = EMPTY_BYTE_ARRAY;
6061publicstaticfinal Binary EMPTY = newJcrBinary(EMPTY_BYTE_ARRAY);
6263/**64 * Creates a new <code>JcrBinary</code> instance from an <code>InputStream</code>.65 * The contents of the stream is spooled to a temporary file or to a byte buffer66 * if its size is smaller than {@link #MAX_BUFFER_SIZE}.67 * The input stream is closed by this implementation.68 *69 * @param in stream to be represented as a <code>JcrBinary</code> instance70 * @throws IOException if an error occurs while reading from the stream or71 * writing to the temporary file72 */73publicJcrBinary(InputStream in) throws IOException {
74 byte[] spoolBuffer = new byte[0x2000];
75int read;
76int len = 0;
77 OutputStream out = null;
78 File spoolFile = null;
79try {
80while ((read = in.read(spoolBuffer)) > 0) {
81if (out != null) {
82// spool to temp file83 out.write(spoolBuffer, 0, read);
84 len += read;
85 }
86elseif (len + read > MAX_BUFFER_SIZE) {
87// threshold for keeping data in memory exceeded;88// create temp file and spool buffer contents8990 spoolFile = File.createTempFile("bin", null, null);
91 out = new FileOutputStream(spoolFile);
92 out.write(buffer, 0, len);
93 out.write(spoolBuffer, 0, read);
94 buffer = null;
95 len += read;
96 }
97else {
98// reallocate new buffer and spool old buffer contents99 byte[] newBuffer = new byte[len + read];
100 System.arraycopy(buffer, 0, newBuffer, 0, len);
101 System.arraycopy(spoolBuffer, 0, newBuffer, len, read);
102 buffer = newBuffer;
103 len += read;
104 }
105 }
106 }
107finally {
108 in.close();
109if (out != null) {
110 out.close();
111 }
112 }
113114// init fields115 tmpFile = spoolFile;
116 }
117118/**119 * Creates a new <code>JcrBinary</code> instance from a <code>byte[]</code> array.120 * 121 * @param buffer byte array to be represented as a <code>JcrBinary</code> instance122 */123publicJcrBinary(byte[] buffer) {
124if (buffer == null) {
125thrownew IllegalArgumentException("buffer must be non-null");
126 }
127this.buffer = buffer;
128 tmpFile = null;
129 }
130131public InputStream getStream() throws RepositoryException {
132if (tmpFile != null) {
133try {
134// this instance is backed by a temp file135returnnew FileInputStream(tmpFile);
136 }
137catch (FileNotFoundException e) {
138thrownew RepositoryException("already disposed");
139 }
140 }
141else {
142// this instance is backed by an in-memory buffer143returnnew ByteArrayInputStream(buffer);
144 }
145 }
146147publicint read(byte[] b, long position) throws IOException, RepositoryException {
148if (tmpFile != null) {
149// this instance is backed by a temp file150 RandomAccessFile raf = new RandomAccessFile(tmpFile, "r");
151try {
152 raf.seek(position);
153return raf.read(b);
154 }
155finally {
156 raf.close();
157 }
158 }
159else {
160// this instance is backed by an in-memory buffer161int length = Math.min(b.length, buffer.length - (int) position);
162if (length > 0) {
163 System.arraycopy(buffer, (int) position, b, 0, length);
164return length;
165 }
166else {
167return -1;
168 }
169 }
170 }
171172publiclong getSize() throws RepositoryException {
173if (tmpFile != null) {
174// this instance is backed by a temp file175return tmpFile.exists() ? tmpFile.length() : -1;
176 }
177else {
178// this instance is backed by an in-memory buffer179return buffer.length;
180 }
181 }
182183publicvoid dispose() {
184if (tmpFile != null) {
185// this instance is backed by a temp file186 tmpFile.delete();
187 }
188else {
189// this instance is backed by an in-memory buffer190 buffer = EMPTY_BYTE_ARRAY;
191 }
192 }
193194 }