1 /*
2 * ModeShape (http://www.modeshape.org)
3 * See the COPYRIGHT.txt file distributed with this work for information
4 * regarding copyright ownership. Some portions may be licensed
5 * to Red Hat, Inc. under one or more contributor license agreements.
6 * See the AUTHORS.txt file in the distribution for a full listing of
7 * individual contributors.
8 *
9 * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10 * is licensed to you under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * ModeShape is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this software; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23 */
24 package org.modeshape.jcr;
25
26 import java.io.IOException;
27 import java.io.InputStream;
28 import org.modeshape.graph.property.Binary;
29
30 /**
31 * An implementation of JCR 2.0 Binary that wraps a graph {@link Binary} value object.
32 */
33 class JcrBinary implements javax.jcr.Binary, org.modeshape.jcr.api.Binary {
34
35 private final Binary binary;
36
37 JcrBinary( Binary binary ) {
38 this.binary = binary;
39 assert this.binary != null;
40 }
41
42 Binary binary() {
43 return this.binary;
44 }
45
46 /**
47 * {@inheritDoc}
48 *
49 * @see org.modeshape.jcr.api.Binary#dispose()
50 */
51 @Override
52 public void dispose() {
53 this.binary.release();
54 }
55
56 /**
57 * {@inheritDoc}
58 *
59 * @see org.modeshape.jcr.api.Binary#getSize()
60 */
61 @Override
62 public long getSize() {
63 try {
64 this.binary.acquire();
65 return this.binary.getSize();
66 } finally {
67 this.binary.release();
68 }
69 }
70
71 /**
72 * {@inheritDoc}
73 *
74 * @see org.modeshape.jcr.api.Binary#getStream()
75 */
76 @Override
77 public InputStream getStream() {
78 return new SelfClosingInputStream(this.binary);
79 }
80
81 /**
82 * {@inheritDoc}
83 *
84 * @see org.modeshape.jcr.api.Binary#read(byte[], long)
85 */
86 @Override
87 public int read( byte[] b,
88 long position ) throws IOException {
89 if (getSize() <= position) return -1;
90 InputStream stream = null;
91 IOException error = null;
92 try {
93 stream = getStream();
94 // Read/skip the next 'position' bytes ...
95 long skip = position;
96 while (skip > 0) {
97 long skipped = stream.skip(skip);
98 if (skipped <= 0) return -1;
99 skip -= skipped;
100 }
101 return stream.read(b);
102 } catch (IOException e) {
103 error = e;
104 throw e;
105 } finally {
106 if (stream != null) {
107 try {
108 stream.close();
109 } catch (RuntimeException t) {
110 // Only throw if we've not already thrown an exception ...
111 if (error == null) throw t;
112 } catch (IOException t) {
113 // Only throw if we've not already thrown an exception ...
114 if (error == null) throw t;
115 }
116 }
117 }
118 }
119
120 }