View Javadoc
1   package org.argeo.cms.internal.kernel;
2   
3   import java.io.IOException;
4   import java.net.URI;
5   import java.nio.file.FileSystem;
6   import java.nio.file.FileSystemAlreadyExistsException;
7   import java.nio.file.Path;
8   import java.util.HashMap;
9   import java.util.Map;
10  
11  import javax.jcr.Node;
12  import javax.jcr.Property;
13  import javax.jcr.Repository;
14  import javax.jcr.RepositoryException;
15  import javax.jcr.RepositoryFactory;
16  import javax.jcr.Session;
17  import javax.jcr.nodetype.NodeType;
18  
19  import org.argeo.api.NodeConstants;
20  import org.argeo.api.NodeUtils;
21  import org.argeo.cms.CmsException;
22  import org.argeo.cms.auth.CurrentUser;
23  import org.argeo.jackrabbit.fs.AbstractJackrabbitFsProvider;
24  import org.argeo.jcr.fs.JcrFileSystem;
25  import org.argeo.jcr.fs.JcrFileSystemProvider;
26  import org.argeo.jcr.fs.JcrFsException;
27  import org.osgi.framework.BundleContext;
28  import org.osgi.framework.FrameworkUtil;
29  
30  public class CmsFsProvider extends AbstractJackrabbitFsProvider {
31  	private Map<String, CmsFileSystem> fileSystems = new HashMap<>();
32  
33  	@Override
34  	public String getScheme() {
35  		return NodeConstants.SCHEME_NODE;
36  	}
37  
38  	@Override
39  	public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
40  		BundleContext bc = FrameworkUtil.getBundle(CmsFsProvider.class).getBundleContext();
41  		String username = CurrentUser.getUsername();
42  		if (username == null) {
43  			// TODO deal with anonymous
44  			return null;
45  		}
46  		if (fileSystems.containsKey(username))
47  			throw new FileSystemAlreadyExistsException("CMS file system already exists for user " + username);
48  
49  		try {
50  			String host = uri.getHost();
51  			if (host != null && !host.trim().equals("")) {
52  				URI repoUri = new URI("http", uri.getUserInfo(), uri.getHost(), uri.getPort(), "/jcr/node", null, null);
53  				RepositoryFactory repositoryFactory = bc.getService(bc.getServiceReference(RepositoryFactory.class));
54  				Repository repository = NodeUtils.getRepositoryByUri(repositoryFactory, repoUri.toString());
55  //				Session session = repository.login("main");
56  				CmsFileSystem fileSystem = new CmsFileSystem(this, repository);
57  				fileSystems.put(username, fileSystem);
58  				return fileSystem;
59  			} else {
60  				Repository repository = bc.getService(
61  						bc.getServiceReferences(Repository.class, "(cn=" + NodeConstants.EGO_REPOSITORY + ")").iterator().next());
62  //				Session session = repository.login();
63  				CmsFileSystem fileSystem = new CmsFileSystem(this, repository);
64  				fileSystems.put(username, fileSystem);
65  				return fileSystem;
66  			}
67  		} catch (Exception e) {
68  			throw new CmsException("Cannot open file system " + uri + " for user " + username, e);
69  		}
70  	}
71  
72  	@Override
73  	public FileSystem getFileSystem(URI uri) {
74  		return currentUserFileSystem();
75  	}
76  
77  	@Override
78  	public Path getPath(URI uri) {
79  		JcrFileSystem fileSystem = currentUserFileSystem();
80  		String path = uri.getPath();
81  		if (fileSystem == null)
82  			try {
83  				fileSystem = (JcrFileSystem) newFileSystem(uri, new HashMap<String, Object>());
84  			} catch (IOException e) {
85  				throw new JcrFsException("Could not autocreate file system", e);
86  			}
87  		return fileSystem.getPath(path);
88  	}
89  
90  	protected JcrFileSystem currentUserFileSystem() {
91  		String username = CurrentUser.getUsername();
92  		return fileSystems.get(username);
93  	}
94  
95  	public Node getUserHome(Repository repository) {
96  		try {
97  			Session session = repository.login(NodeConstants.HOME_WORKSPACE);
98  			return NodeUtils.getUserHome(session);
99  		} catch (RepositoryException e) {
100 			throw new IllegalStateException("Cannot get user home", e);
101 		}
102 	}
103 
104 	static class CmsFileSystem extends JcrFileSystem {
105 		public CmsFileSystem(JcrFileSystemProvider provider, Repository repository) throws IOException {
106 			super(provider, repository);
107 		}
108 
109 		public boolean skipNode(Node node) throws RepositoryException {
110 //			if (node.isNodeType(NodeType.NT_HIERARCHY_NODE) || node.isNodeType(NodeTypes.NODE_USER_HOME)
111 //					|| node.isNodeType(NodeTypes.NODE_GROUP_HOME))
112 			if (node.isNodeType(NodeType.NT_HIERARCHY_NODE))
113 				return false;
114 			// FIXME Better identifies home
115 			if (node.hasProperty(Property.JCR_ID))
116 				return false;
117 			return true;
118 		}
119 
120 	}
121 }