Introduce directory content provider
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / acr / directory / DirectoryContentProvider.java
diff --git a/org.argeo.cms/src/org/argeo/cms/acr/directory/DirectoryContentProvider.java b/org.argeo.cms/src/org/argeo/cms/acr/directory/DirectoryContentProvider.java
new file mode 100644 (file)
index 0000000..60ef675
--- /dev/null
@@ -0,0 +1,145 @@
+package org.argeo.cms.acr.directory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import javax.xml.namespace.QName;
+
+import org.argeo.api.acr.Content;
+import org.argeo.api.acr.ContentName;
+import org.argeo.api.acr.ContentNotFoundException;
+import org.argeo.api.acr.CrName;
+import org.argeo.api.acr.spi.ContentProvider;
+import org.argeo.api.acr.spi.ProvidedContent;
+import org.argeo.api.acr.spi.ProvidedSession;
+import org.argeo.cms.CmsUserManager;
+import org.argeo.cms.acr.AbstractContent;
+import org.argeo.cms.acr.ContentUtils;
+import org.argeo.osgi.useradmin.HierarchyUnit;
+import org.argeo.osgi.useradmin.LdapNameUtils;
+import org.argeo.osgi.useradmin.UserDirectory;
+import org.osgi.service.useradmin.User;
+
+public class DirectoryContentProvider implements ContentProvider {
+       private String mountPath;
+       private String mountName;
+
+       private CmsUserManager userManager;
+
+       public DirectoryContentProvider(String mountPath, CmsUserManager userManager) {
+               this.mountPath = mountPath;
+               List<String> mountSegments = ContentUtils.toPathSegments(mountPath);
+               this.mountName = mountSegments.get(mountSegments.size() - 1);
+               this.userManager = userManager;
+       }
+
+       @Override
+       public ProvidedContent get(ProvidedSession session, String relativePath) {
+               List<String> segments = ContentUtils.toPathSegments(relativePath);
+               if (segments.size() == 0)
+                       return new UserManagerContent(session);
+               String userDirectoryDn = segments.get(0);
+               UserDirectory userDirectory = null;
+               userDirectories: for (UserDirectory ud : userManager.getUserDirectories()) {
+                       if (userDirectoryDn.equals(ud.getBasePath())) {
+                               userDirectory = ud;
+                               break userDirectories;
+                       }
+               }
+               if (userDirectory == null)
+                       throw new ContentNotFoundException("Cannot find user directory " + userDirectoryDn);
+               if (segments.size() == 1) {
+                       return new HierarchyUnitContent(session, this, userDirectory);
+               } else {
+                       LdapName dn;
+                       try {
+                               dn = LdapNameUtils.toLdapName(userDirectoryDn);
+                               for (int i = 1; i < segments.size(); i++) {
+                                       dn.add(segments.get(i));
+                               }
+                       } catch (InvalidNameException e) {
+                               throw new IllegalStateException("Cannot interpret " + segments + " as DN", e);
+                       }
+                       User user = userManager.getUser(dn.toString());
+                       if (user != null) {
+                               HierarchyUnit parent = userDirectory.getHierarchyUnit(user);
+                               return new RoleContent(session, this, new HierarchyUnitContent(session, this, parent), user);
+                       }
+                       HierarchyUnit hierarchyUnit = userDirectory.getHierarchyUnit(dn.toString());
+                       if (hierarchyUnit == null)
+                               throw new ContentNotFoundException("Cannot find " + dn);
+                       return new HierarchyUnitContent(session, this, hierarchyUnit);
+               }
+       }
+
+       @Override
+       public boolean exists(ProvidedSession session, String relativePath) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public String getMountPath() {
+               return mountPath;
+       }
+
+       @Override
+       public String getNamespaceURI(String prefix) {
+               if (CrName.LDAP_DEFAULT_PREFIX.equals(prefix))
+                       return CrName.LDAP_NAMESPACE_URI;
+               throw new IllegalArgumentException("Only prefix " + CrName.LDAP_DEFAULT_PREFIX + " is supported");
+       }
+
+       @Override
+       public Iterator<String> getPrefixes(String namespaceURI) {
+               if (CrName.LDAP_NAMESPACE_URI.equals(namespaceURI))
+                       return Collections.singletonList(CrName.LDAP_DEFAULT_PREFIX).iterator();
+               throw new IllegalArgumentException("Only namespace URI " + CrName.LDAP_NAMESPACE_URI + " is supported");
+       }
+
+       public void setUserManager(CmsUserManager userManager) {
+               this.userManager = userManager;
+       }
+       
+       UserManagerContent getRootContent(ProvidedSession session) {
+               return new UserManagerContent(session);
+       }
+
+       class UserManagerContent extends AbstractContent {
+
+               public UserManagerContent(ProvidedSession session) {
+                       super(session);
+               }
+
+               @Override
+               public ContentProvider getProvider() {
+                       return DirectoryContentProvider.this;
+               }
+
+               @Override
+               public QName getName() {
+                       return new ContentName(mountName);
+               }
+
+               @Override
+               public Content getParent() {
+                       return null;
+               }
+
+               @Override
+               public Iterator<Content> iterator() {
+                       List<Content> res = new ArrayList<>();
+                       for (UserDirectory userDirectory : userManager.getUserDirectories()) {
+                               HierarchyUnitContent content = new HierarchyUnitContent(getSession(), DirectoryContentProvider.this,
+                                               userDirectory);
+                               res.add(content);
+                       }
+                       return res.iterator();
+               }
+
+       }
+}