View Javadoc
1   package org.argeo.jcr.fs;
2   
3   import java.io.IOException;
4   import java.nio.file.FileStore;
5   import java.nio.file.attribute.FileAttributeView;
6   import java.nio.file.attribute.FileStoreAttributeView;
7   import java.util.Arrays;
8   
9   import javax.jcr.Node;
10  import javax.jcr.RepositoryException;
11  import javax.jcr.Session;
12  import javax.jcr.Workspace;
13  
14  import org.argeo.jcr.JcrUtils;
15  
16  /** A {@link FileStore} implementation based on JCR {@link Workspace}. */
17  public class WorkspaceFileStore extends FileStore {
18  	private final String mountPath;
19  	private final Workspace workspace;
20  	private final int mountDepth;
21  
22  	public WorkspaceFileStore(String mountPath, Workspace workspace) {
23  		if ("/".equals(mountPath) || "".equals(mountPath))
24  			throw new IllegalArgumentException(
25  					"Mount path '" + mountPath + "' is unsupported, use null for the base file store");
26  		if (mountPath != null && !mountPath.startsWith(JcrPath.separator))
27  			throw new IllegalArgumentException("Mount path '" + mountPath + "' cannot end with /");
28  		if (mountPath != null && mountPath.endsWith(JcrPath.separator))
29  			throw new IllegalArgumentException("Mount path '" + mountPath + "' cannot end with /");
30  		this.mountPath = mountPath;
31  		if (mountPath == null)
32  			mountDepth = 0;
33  		else {
34  			mountDepth = mountPath.split(JcrPath.separator).length - 1;
35  		}
36  		this.workspace = workspace;
37  	}
38  
39  	public void close() {
40  		JcrUtils.logoutQuietly(workspace.getSession());
41  	}
42  
43  	@Override
44  	public String name() {
45  		return workspace.getName();
46  	}
47  
48  	@Override
49  	public String type() {
50  		return "workspace";
51  	}
52  
53  	@Override
54  	public boolean isReadOnly() {
55  		return false;
56  	}
57  
58  	@Override
59  	public long getTotalSpace() throws IOException {
60  		return 0;
61  	}
62  
63  	@Override
64  	public long getUsableSpace() throws IOException {
65  		return 0;
66  	}
67  
68  	@Override
69  	public long getUnallocatedSpace() throws IOException {
70  		return 0;
71  	}
72  
73  	@Override
74  	public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
75  		return false;
76  	}
77  
78  	@Override
79  	public boolean supportsFileAttributeView(String name) {
80  		return false;
81  	}
82  
83  	@Override
84  	public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
85  		return null;
86  	}
87  
88  	@Override
89  	public Object getAttribute(String attribute) throws IOException {
90  		return workspace.getSession().getRepository().getDescriptor(attribute);
91  	}
92  
93  	public Workspace getWorkspace() {
94  		return workspace;
95  	}
96  
97  	public String toFsPath(Node node) throws RepositoryException {
98  		String nodeWorkspaceName = node.getSession().getWorkspace().getName();
99  		if (!nodeWorkspaceName.equals(workspace.getName()))
100 			throw new IllegalArgumentException("Icompatible " + node + " from workspace '" + nodeWorkspaceName
101 					+ "' in file store '" + workspace.getName() + "'");
102 		return mountPath == null ? node.getPath() : mountPath + node.getPath();
103 	}
104 
105 	public boolean isBase() {
106 		return mountPath == null;
107 	}
108 
109 	Node toNode(String[] fullPath) throws RepositoryException {
110 		String jcrPath = toJcrPath(fullPath);
111 		Session session = workspace.getSession();
112 		if (!session.itemExists(jcrPath))
113 			return null;
114 		Node node = session.getNode(jcrPath);
115 		return node;
116 	}
117 
118 	private String toJcrPath(String[] path) {
119 		if (path == null)
120 			return "/";
121 		if (path.length < mountDepth)
122 			throw new IllegalArgumentException(
123 					"Path " + Arrays.asList(path) + " is no compatible with mount " + mountPath);
124 
125 		if (!isBase()) {
126 			// check mount compatibility
127 			StringBuilder mount = new StringBuilder();
128 			mount.append('/');
129 			for (int i = 0; i < mountDepth; i++) {
130 				if (i != 0)
131 					mount.append('/');
132 				mount.append(Text.escapeIllegalJcrChars(path[i]));
133 			}
134 			if (!mountPath.equals(mount.toString()))
135 				throw new IllegalArgumentException(
136 						"Path " + Arrays.asList(path) + " is no compatible with mount " + mountPath);
137 		}
138 
139 		StringBuilder sb = new StringBuilder();
140 		sb.append('/');
141 		for (int i = mountDepth; i < path.length; i++) {
142 			if (i != mountDepth)
143 				sb.append('/');
144 			sb.append(Text.escapeIllegalJcrChars(path[i]));
145 		}
146 		return sb.toString();
147 	}
148 
149 }