1 package org
.argeo
.jcr
.fs
;
3 import java
.io
.IOException
;
4 import java
.nio
.channels
.SeekableByteChannel
;
5 import java
.nio
.file
.AccessMode
;
6 import java
.nio
.file
.CopyOption
;
7 import java
.nio
.file
.DirectoryNotEmptyException
;
8 import java
.nio
.file
.DirectoryStream
;
9 import java
.nio
.file
.DirectoryStream
.Filter
;
10 import java
.nio
.file
.FileStore
;
11 import java
.nio
.file
.LinkOption
;
12 import java
.nio
.file
.NoSuchFileException
;
13 import java
.nio
.file
.OpenOption
;
14 import java
.nio
.file
.Path
;
15 import java
.nio
.file
.attribute
.BasicFileAttributes
;
16 import java
.nio
.file
.attribute
.FileAttribute
;
17 import java
.nio
.file
.attribute
.FileAttributeView
;
18 import java
.nio
.file
.spi
.FileSystemProvider
;
19 import java
.util
.Calendar
;
20 import java
.util
.HashMap
;
24 import javax
.jcr
.Node
;
25 import javax
.jcr
.Property
;
26 import javax
.jcr
.PropertyIterator
;
27 import javax
.jcr
.PropertyType
;
28 import javax
.jcr
.RepositoryException
;
29 import javax
.jcr
.Session
;
30 import javax
.jcr
.nodetype
.NodeType
;
31 import javax
.jcr
.nodetype
.PropertyDefinition
;
33 import org
.apache
.commons
.io
.FileExistsException
;
34 import org
.argeo
.jcr
.JcrUtils
;
36 public abstract class JcrFileSystemProvider
extends FileSystemProvider
{
38 public SeekableByteChannel
newByteChannel(Path path
, Set
<?
extends OpenOption
> options
, FileAttribute
<?
>... attrs
)
41 Node node
= toNode(path
);
43 Node parent
= toNode(path
.getParent());
45 throw new JcrFsException("No parent directory for " + path
);
46 if (parent
.getPrimaryNodeType().isNodeType(NodeType
.NT_FILE
)
47 || parent
.getPrimaryNodeType().isNodeType(NodeType
.NT_LINKED_FILE
))
48 throw new JcrFsException(path
+ " parent is a file");
50 String fileName
= path
.getFileName().toString();
51 fileName
= Text
.escapeIllegalJcrChars(fileName
);
52 node
= parent
.addNode(fileName
, NodeType
.NT_FILE
);
53 node
.addMixin(NodeType
.MIX_CREATED
);
54 node
.addMixin(NodeType
.MIX_LAST_MODIFIED
);
56 if (!node
.isNodeType(NodeType
.NT_FILE
))
57 throw new UnsupportedOperationException(node
+ " must be a file");
58 return new BinaryChannel(node
);
59 } catch (RepositoryException e
) {
60 throw new JcrFsException("Cannot read file", e
);
65 public DirectoryStream
<Path
> newDirectoryStream(Path dir
, Filter
<?
super Path
> filter
) throws IOException
{
67 Node base
= toNode(dir
);
68 return new NodeDirectoryStream((JcrFileSystem
) dir
.getFileSystem(), base
.getNodes(), filter
);
69 } catch (RepositoryException e
) {
70 throw new JcrFsException("Cannot list directory", e
);
75 public void createDirectory(Path dir
, FileAttribute
<?
>... attrs
) throws IOException
{
77 Node node
= toNode(dir
);
79 Node parent
= toNode(dir
.getParent());
81 throw new IOException("Parent of " + dir
+ " does not exist");
82 if (parent
.getPrimaryNodeType().isNodeType(NodeType
.NT_FILE
)
83 || parent
.getPrimaryNodeType().isNodeType(NodeType
.NT_LINKED_FILE
))
84 throw new JcrFsException(dir
+ " parent is a file");
85 String fileName
= dir
.getFileName().toString();
86 fileName
= Text
.escapeIllegalJcrChars(fileName
);
87 node
= parent
.addNode(fileName
, NodeType
.NT_FOLDER
);
88 node
.addMixin(NodeType
.MIX_CREATED
);
89 node
.addMixin(NodeType
.MIX_LAST_MODIFIED
);
90 node
.getSession().save();
92 if (!node
.getPrimaryNodeType().isNodeType(NodeType
.NT_FOLDER
))
93 throw new FileExistsException(dir
+ " exists and is not a directory");
95 } catch (RepositoryException e
) {
96 throw new JcrFsException("Cannot create directory " + dir
, e
);
102 public void delete(Path path
) throws IOException
{
104 Node node
= toNode(path
);
106 throw new NoSuchFileException(path
+ " does not exist");
107 Session session
= node
.getSession();
108 if (node
.getPrimaryNodeType().isNodeType(NodeType
.NT_FILE
))
110 else if (node
.getPrimaryNodeType().isNodeType(NodeType
.NT_FOLDER
)) {
111 if (node
.hasNodes())// TODO check only files
112 throw new DirectoryNotEmptyException(path
.toString());
116 } catch (RepositoryException e
) {
117 throw new JcrFsException("Cannot delete " + path
, e
);
123 public void copy(Path source
, Path target
, CopyOption
... options
) throws IOException
{
125 Node sourceNode
= toNode(source
);
126 Node targetNode
= toNode(target
);
127 JcrUtils
.copy(sourceNode
, targetNode
);
128 sourceNode
.getSession().save();
129 } catch (RepositoryException e
) {
130 throw new JcrFsException("Cannot copy from " + source
+ " to " + target
, e
);
135 public void move(Path source
, Path target
, CopyOption
... options
) throws IOException
{
137 Node sourceNode
= toNode(source
);
138 Session session
= sourceNode
.getSession();
139 session
.move(sourceNode
.getPath(), target
.toString());
141 } catch (RepositoryException e
) {
142 throw new JcrFsException("Cannot move from " + source
+ " to " + target
, e
);
147 public boolean isSameFile(Path path
, Path path2
) throws IOException
{
148 if (path
.getFileSystem() != path2
.getFileSystem())
150 boolean equ
= path
.equals(path2
);
155 Node node
= toNode(path
);
156 Node node2
= toNode(path2
);
157 return node
.isSame(node2
);
158 } catch (RepositoryException e
) {
159 throw new JcrFsException("Cannot check whether " + path
+ " and " + path2
+ " are same", e
);
166 public boolean isHidden(Path path
) throws IOException
{
171 public FileStore
getFileStore(Path path
) throws IOException
{
172 Session session
= ((JcrFileSystem
) path
.getFileSystem()).getSession();
173 return new WorkSpaceFileStore(session
.getWorkspace());
177 public void checkAccess(Path path
, AccessMode
... modes
) throws IOException
{
179 Session session
= ((JcrFileSystem
) path
.getFileSystem()).getSession();
180 if (!session
.itemExists(path
.toString()))
181 throw new NoSuchFileException(path
+ " does not exist");
182 // TODO check access via JCR api
183 } catch (RepositoryException e
) {
184 throw new JcrFsException("Cannot delete " + path
, e
);
189 public <V
extends FileAttributeView
> V
getFileAttributeView(Path path
, Class
<V
> type
, LinkOption
... options
) {
190 throw new UnsupportedOperationException();
193 @SuppressWarnings("unchecked")
195 public <A
extends BasicFileAttributes
> A
readAttributes(Path path
, Class
<A
> type
, LinkOption
... options
)
198 // TODO check if assignable
199 Node node
= toNode(path
);
200 return (A
) new JcrBasicfileAttributes(node
);
201 } catch (RepositoryException e
) {
202 throw new JcrFsException("Cannot read basic attributes of " + path
, e
);
207 public Map
<String
, Object
> readAttributes(Path path
, String attributes
, LinkOption
... options
) throws IOException
{
209 Node node
= toNode(path
);
210 String pattern
= attributes
.replace(',', '|');
211 Map
<String
, Object
> res
= new HashMap
<String
, Object
>();
212 PropertyIterator it
= node
.getProperties(pattern
);
213 props
: while (it
.hasNext()) {
214 Property prop
= it
.nextProperty();
215 PropertyDefinition pd
= prop
.getDefinition();
218 int requiredType
= pd
.getRequiredType();
219 switch (requiredType
) {
220 case PropertyType
.LONG
:
221 res
.put(prop
.getName(), prop
.getLong());
223 case PropertyType
.DOUBLE
:
224 res
.put(prop
.getName(), prop
.getDouble());
226 case PropertyType
.BOOLEAN
:
227 res
.put(prop
.getName(), prop
.getBoolean());
229 case PropertyType
.DATE
:
230 res
.put(prop
.getName(), prop
.getDate());
232 case PropertyType
.BINARY
:
233 byte[] arr
= JcrUtils
.getBinaryAsBytes(prop
);
234 res
.put(prop
.getName(), arr
);
237 res
.put(prop
.getName(), prop
.getString());
241 } catch (RepositoryException e
) {
242 throw new JcrFsException("Cannot read attributes of " + path
, e
);
247 public void setAttribute(Path path
, String attribute
, Object value
, LinkOption
... options
) throws IOException
{
249 Node node
= toNode(path
);
250 if (value
instanceof byte[]) {
251 JcrUtils
.setBinaryAsBytes(node
, attribute
, (byte[]) value
);
252 } else if (value
instanceof Calendar
) {
253 node
.setProperty(attribute
, (Calendar
) value
);
255 node
.setProperty(attribute
, value
.toString());
257 node
.getSession().save();
258 } catch (RepositoryException e
) {
259 throw new JcrFsException("Cannot set attribute " + attribute
+ " on " + path
, e
);
263 protected Node
toNode(Path path
) throws RepositoryException
{
264 return ((JcrPath
) path
).getNode();