View Javadoc
1   package org.argeo.jackrabbit.fs;
2   
3   import java.io.IOException;
4   import java.net.URI;
5   import java.net.URISyntaxException;
6   import java.nio.file.DirectoryStream;
7   import java.nio.file.FileSystem;
8   import java.nio.file.FileSystemAlreadyExistsException;
9   import java.nio.file.Files;
10  import java.nio.file.Path;
11  import java.util.HashMap;
12  import java.util.Map;
13  
14  import javax.jcr.Repository;
15  import javax.jcr.RepositoryFactory;
16  import javax.jcr.Session;
17  
18  import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory;
19  import org.argeo.jcr.ArgeoJcrException;
20  import org.argeo.jcr.fs.JcrFileSystem;
21  import org.argeo.jcr.fs.JcrFsException;
22  
23  /**
24   * A file system provider based on a JCR repository remotely accessed via the
25   * DAVEX protocol.
26   */
27  public class DavexFsProvider extends AbstractJackrabbitFsProvider {
28  //	final static String JACKRABBIT_REPOSITORY_URI = "org.apache.jackrabbit.repository.uri";
29  //	final static String JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = "org.apache.jackrabbit.spi2davex.WorkspaceNameDefault";
30  
31  	private Map<String, JcrFileSystem> fileSystems = new HashMap<>();
32  
33  	@Override
34  	public String getScheme() {
35  		return "davex";
36  	}
37  
38  	@Override
39  	public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
40  		if (uri.getHost() == null)
41  			throw new ArgeoJcrException("An host should be provided");
42  		try {
43  			URI repoUri = new URI("http", uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), null, null);
44  			String repoKey = repoUri.toString();
45  			if (fileSystems.containsKey(repoKey))
46  				throw new FileSystemAlreadyExistsException("CMS file system already exists for " + repoKey);
47  			RepositoryFactory repositoryFactory = new ClientDavexRepositoryFactory();
48  			return tryGetRepo(repositoryFactory, repoUri, "home");
49  		} catch (Exception e) {
50  			throw new ArgeoJcrException("Cannot open file system " + uri, e);
51  		}
52  	}
53  
54  	private JcrFileSystem tryGetRepo(RepositoryFactory repositoryFactory, URI repoUri, String workspace)
55  			throws IOException {
56  		Map<String, String> params = new HashMap<String, String>();
57  		params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, repoUri.toString());
58  		params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, "main");
59  		Repository repository = null;
60  		Session session = null;
61  		try {
62  			repository = repositoryFactory.getRepository(params);
63  			if (repository != null)
64  				session = repository.login(workspace);
65  		} catch (Exception e) {
66  			// silent
67  		}
68  
69  		if (session == null) {
70  			if (repoUri.getPath() == null || repoUri.getPath().equals("/"))
71  				return null;
72  			String repoUriStr = repoUri.toString();
73  			if (repoUriStr.endsWith("/"))
74  				repoUriStr = repoUriStr.substring(0, repoUriStr.length() - 1);
75  			String nextRepoUriStr = repoUriStr.substring(0, repoUriStr.lastIndexOf('/'));
76  			String nextWorkspace = repoUriStr.substring(repoUriStr.lastIndexOf('/') + 1);
77  			URI nextUri;
78  			try {
79  				nextUri = new URI(nextRepoUriStr);
80  			} catch (URISyntaxException e) {
81  				throw new ArgeoJcrException("Badly formatted URI", e);
82  			}
83  			return tryGetRepo(repositoryFactory, nextUri, nextWorkspace);
84  		} else {
85  			JcrFileSystem fileSystem = new JcrFileSystem(this, repository);
86  			fileSystems.put(repoUri.toString() + "/" + workspace, fileSystem);
87  			return fileSystem;
88  		}
89  	}
90  
91  	@Override
92  	public FileSystem getFileSystem(URI uri) {
93  		return currentUserFileSystem(uri);
94  	}
95  
96  	@Override
97  	public Path getPath(URI uri) {
98  		JcrFileSystem fileSystem = currentUserFileSystem(uri);
99  		if (fileSystem == null)
100 			try {
101 				fileSystem = (JcrFileSystem) newFileSystem(uri, new HashMap<String, Object>());
102 			} catch (IOException e) {
103 				throw new JcrFsException("Could not autocreate file system", e);
104 			}
105 		URI repoUri = null;
106 		try {
107 			repoUri = new URI("http", uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), null, null);
108 		} catch (URISyntaxException e) {
109 			throw new IllegalArgumentException(e);
110 		}
111 		String uriStr = repoUri.toString();
112 		String localPath = null;
113 		for (String key : fileSystems.keySet()) {
114 			if (uriStr.startsWith(key)) {
115 				localPath = uriStr.toString().substring(key.length());
116 			}
117 		}
118 		if ("".equals(localPath))
119 			localPath = "/";
120 		return fileSystem.getPath(localPath);
121 	}
122 
123 	private JcrFileSystem currentUserFileSystem(URI uri) {
124 		for (String key : fileSystems.keySet()) {
125 			if (uri.toString().startsWith(key))
126 				return fileSystems.get(key);
127 		}
128 		return null;
129 	}
130 
131 	public static void main(String args[]) {
132 		try {
133 			DavexFsProvider fsProvider = new DavexFsProvider();
134 			Path path = fsProvider.getPath(new URI("davex://root:demo@localhost:7070/jcr/ego/"));
135 			System.out.println(path);
136 			DirectoryStream<Path> ds = Files.newDirectoryStream(path);
137 			for (Path p : ds) {
138 				System.out.println("- " + p);
139 			}
140 		} catch (Exception e) {
141 			e.printStackTrace();
142 		}
143 	}
144 }