X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.jcr%2Fsrc%2Forg%2Fargeo%2Fjcr%2Ffs%2FBinaryChannel.java;h=d6550feeeb1b25509078c010bc817c0295630d9a;hb=8e5934c1ff5587a5156854839210cc93bb66fc41;hp=ff4b4a1b3b1055be35e80791f80971140a62bfa2;hpb=d8037dd6a59ff5d38d7c7182a9ef6c26c8001a4f;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.jcr/src/org/argeo/jcr/fs/BinaryChannel.java b/org.argeo.jcr/src/org/argeo/jcr/fs/BinaryChannel.java index ff4b4a1b3..d6550feee 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/fs/BinaryChannel.java +++ b/org.argeo.jcr/src/org/argeo/jcr/fs/BinaryChannel.java @@ -19,9 +19,9 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; -import org.apache.commons.io.IOUtils; import org.argeo.jcr.JcrUtils; +/** A read/write {@link SeekableByteChannel} based on a {@link Binary}. */ public class BinaryChannel implements SeekableByteChannel { private final Node file; private Binary binary; @@ -29,26 +29,37 @@ public class BinaryChannel implements SeekableByteChannel { private long position = 0; - // private ByteBuffer toWrite; private FileChannel fc = null; - public BinaryChannel(Node file) throws RepositoryException, IOException { + public BinaryChannel(Node file, Path path) throws RepositoryException, IOException { this.file = file; - // int capacity = 1024 * 1024; - // this.toWrite = ByteBuffer.allocate(capacity); - if (file.isNodeType(NodeType.NT_FILE)) { - if (file.hasNode(Property.JCR_CONTENT)) { - Node data = file.getNode(Property.JCR_CONTENT); - this.binary = data.getProperty(Property.JCR_DATA).getBinary(); - } else { - Node data = file.addNode(Property.JCR_CONTENT, NodeType.NT_RESOURCE); - try (InputStream in = new ByteArrayInputStream(new byte[0])) { - this.binary = data.getSession().getValueFactory().createBinary(in); + Session session = file.getSession(); + synchronized (session) { + if (file.isNodeType(NodeType.NT_FILE)) { + if (file.hasNode(Node.JCR_CONTENT)) { + Node data = file.getNode(Property.JCR_CONTENT); + this.binary = data.getProperty(Property.JCR_DATA).getBinary(); + } else { + Node data = file.addNode(Node.JCR_CONTENT, NodeType.NT_UNSTRUCTURED); + data.addMixin(NodeType.MIX_LAST_MODIFIED); + try (InputStream in = new ByteArrayInputStream(new byte[0])) { + this.binary = data.getSession().getValueFactory().createBinary(in); + } + data.setProperty(Property.JCR_DATA, this.binary); + + // MIME type + String mime = Files.probeContentType(path); + // String mime = fileTypeMap.getContentType(file.getName()); + data.setProperty(Property.JCR_MIMETYPE, mime); + + session.refresh(true); + session.save(); + session.notifyAll(); } + } else { + throw new IllegalArgumentException( + "Unsupported file node " + file + " (" + file.getPrimaryNodeType() + ")"); } - } else { - throw new IllegalArgumentException( - "Unsupported file node " + file + " (" + file.getPrimaryNodeType() + ")"); } } @@ -60,23 +71,27 @@ public class BinaryChannel implements SeekableByteChannel { @Override public synchronized void close() throws IOException { if (isModified()) { - Binary newBinary=null; + Binary newBinary = null; try { Session session = file.getSession(); - // byte[] arr = new byte[(int) position]; - // toWrite.flip(); - // toWrite.get(arr); - fc.position(0); - InputStream in = Channels.newInputStream(fc); - newBinary = session.getValueFactory().createBinary(in); - file.getNode(Property.JCR_CONTENT).setProperty(Property.JCR_DATA, newBinary); - session.save(); - open = false; + synchronized (session) { + fc.position(0); + InputStream in = Channels.newInputStream(fc); + newBinary = session.getValueFactory().createBinary(in); + file.getNode(Property.JCR_CONTENT).setProperty(Property.JCR_DATA, newBinary); + session.refresh(true); + session.save(); + open = false; + session.notifyAll(); + } } catch (RepositoryException e) { - throw new JcrFsException("Cannot close " + file, e); - }finally{ + throw new IOException("Cannot close " + file, e); + } finally { JcrUtils.closeQuietly(newBinary); - IOUtils.closeQuietly(fc); + // IOUtils.closeQuietly(fc); + if (fc != null) { + fc.close(); + } } } else { clearReadState(); @@ -92,25 +107,14 @@ public class BinaryChannel implements SeekableByteChannel { try { int read; -// int capacity = dst.capacity(); byte[] arr = dst.array(); read = binary.read(arr, position); - //dst.put(arr, 0, read); - - // try { - // byte[] arr = dst.array(); - // read = binary.read(arr, position); - // } catch (UnsupportedOperationException e) { - // int capacity = dst.capacity(); - // byte[] arr = new byte[capacity]; - // read = binary.read(arr, position); - // dst.put(arr); - // } + if (read != -1) position = position + read; return read; } catch (RepositoryException e) { - throw new JcrFsException("Cannot read into buffer", e); + throw new IOException("Cannot read into buffer", e); } } } @@ -119,15 +123,6 @@ public class BinaryChannel implements SeekableByteChannel { public int write(ByteBuffer src) throws IOException { int written = getFileChannel().write(src); return written; - // int byteCount = src.remaining(); - // if (toWrite.remaining() < byteCount) - // throw new JcrFsException("Write buffer is full"); - // toWrite.put(src); - // if (position < binarySize) - // position = binarySize + byteCount; - // else - // position = position + byteCount; - // return byteCount; } @Override @@ -156,7 +151,7 @@ public class BinaryChannel implements SeekableByteChannel { try { return binary.getSize(); } catch (RepositoryException e) { - throw new JcrFsException("Cannot get size", e); + throw new IOException("Cannot get size", e); } } } @@ -164,9 +159,6 @@ public class BinaryChannel implements SeekableByteChannel { @Override public SeekableByteChannel truncate(long size) throws IOException { getFileChannel().truncate(size); - // if (size != size()) - // throw new UnsupportedOperationException("Cannot truncate JCR - // binary"); return this; } @@ -174,24 +166,25 @@ public class BinaryChannel implements SeekableByteChannel { try { if (fc == null) { Path tempPath = Files.createTempFile(getClass().getSimpleName(), null); - fc = FileChannel.open(tempPath, StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.SPARSE); + fc = FileChannel.open(tempPath, StandardOpenOption.WRITE, StandardOpenOption.READ, + StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.SPARSE); ReadableByteChannel readChannel = Channels.newChannel(binary.getStream()); fc.transferFrom(readChannel, 0, binary.getSize()); clearReadState(); } return fc; } catch (RepositoryException e) { - throw new JcrFsException("Cannot get temp file channel", e); + throw new IOException("Cannot get temp file channel", e); } } private boolean isModified() { return fc != null; } - - private void clearReadState(){ + + private void clearReadState() { position = -1; JcrUtils.closeQuietly(binary); - binary=null; + binary = null; } }