Massive package refactoring
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / acr / ContentUtils.java
index 272a5c5a148d3f51b3315fad79918e4837aed3c9..a6acb8a34bc9505e2c44badbbfe65b94941c2d5e 100644 (file)
@@ -3,11 +3,24 @@ package org.argeo.cms.acr;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.StringJoiner;
 import java.util.function.BiConsumer;
 
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
 import javax.xml.namespace.QName;
 
 import org.argeo.api.acr.Content;
+import org.argeo.api.acr.ContentRepository;
+import org.argeo.api.acr.ContentSession;
+import org.argeo.api.acr.DName;
+import org.argeo.api.cms.CmsAuth;
+import org.argeo.api.cms.directory.Directory;
+import org.argeo.api.cms.directory.HierarchyUnit;
+import org.argeo.cms.CmsUserManager;
+import org.argeo.cms.osgi.useradmin.UserDirectory;
+import org.argeo.cms.util.CurrentSubject;
+import org.osgi.service.useradmin.Role;
 
 /** Utilities and routines around {@link Content}. */
 public class ContentUtils {
@@ -52,7 +65,9 @@ public class ContentUtils {
 //     }
 
        public static final char SLASH = '/';
+       public static final String SLASH_STRING = Character.toString(SLASH);
        public static final String ROOT_SLASH = "" + SLASH;
+       public static final String EMPTY = "";
 
        /**
         * Split a path (with '/' separator) in an array of length 2, the first part
@@ -72,15 +87,22 @@ public class ContentUtils {
                }
 
                if (parentIndex == -1) // no '/'
-                       return new String[] { "", path };
+                       return new String[] { EMPTY, path };
 
                return new String[] { parentIndex != 0 ? path.substring(0, parentIndex) : "" + SLASH,
                                path.substring(parentIndex + 1) };
        }
 
+       public static String toPath(List<String> segments) {
+               // TODO checks
+               StringJoiner sj = new StringJoiner("/");
+               segments.forEach((s) -> sj.add(s));
+               return sj.toString();
+       }
+
        public static List<String> toPathSegments(String path) {
                List<String> res = new ArrayList<>();
-               if ("".equals(path) || ROOT_SLASH.equals(path))
+               if (EMPTY.equals(path) || ROOT_SLASH.equals(path))
                        return res;
                collectPathSegments(path, res);
                return res;
@@ -88,10 +110,10 @@ public class ContentUtils {
 
        private static void collectPathSegments(String path, List<String> segments) {
                String[] parent = getParentPath(path);
-               if ("".equals(parent[1])) // root
+               if (EMPTY.equals(parent[1])) // root
                        return;
                segments.add(0, parent[1]);
-               if ("".equals(parent[0])) // end
+               if (EMPTY.equals(parent[0])) // end
                        return;
                collectPathSegments(parent[0], segments);
        }
@@ -101,6 +123,78 @@ public class ContentUtils {
                        throw new IllegalArgumentException("Path " + path + " contains //");
        }
 
+       /*
+        * DIRECTORY
+        */
+
+       public static Content roleToContent(CmsUserManager userManager, ContentSession contentSession, Role role) {
+               UserDirectory userDirectory = userManager.getDirectory(role);
+               String path = directoryPath(userDirectory) + userDirectory.getRolePath(role);
+               Content content = contentSession.get(path);
+               return content;
+       }
+
+       public static Content hierarchyUnitToContent(ContentSession contentSession, HierarchyUnit hierarchyUnit) {
+               Directory directory = hierarchyUnit.getDirectory();
+               StringJoiner relativePath = new StringJoiner(SLASH_STRING);
+               buildHierarchyUnitPath(hierarchyUnit, relativePath);
+               String path = directoryPath(directory) + relativePath.toString();
+               Content content = contentSession.get(path);
+               return content;
+       }
+
+       /** The path to this {@link Directory}. Ends with a /. */
+       private static String directoryPath(Directory directory) {
+               return CmsContentRepository.DIRECTORY_BASE + SLASH + directory.getName() + SLASH;
+       }
+
+       /** Recursively build a relative path of a {@link HierarchyUnit}. */
+       private static void buildHierarchyUnitPath(HierarchyUnit current, StringJoiner relativePath) {
+               if (current.getParent() == null) // directory
+                       return;
+               buildHierarchyUnitPath(current.getParent(), relativePath);
+               relativePath.add(current.getHierarchyUnitName());
+       }
+
+       /*
+        * CONSUMER UTILS
+        */
+
+       public static Content createCollections(ContentSession session, String path) {
+               if (session.exists(path)) {
+                       Content content = session.get(path);
+                       if (!content.isContentClass(DName.collection.qName())) {
+                               throw new IllegalStateException("Content " + path + " already exists, but is not a collection");
+                       } else {
+                               return content;
+                       }
+               } else {
+                       String[] parentPath = getParentPath(path);
+                       Content parent = createCollections(session, parentPath[0]);
+                       Content content = parent.add(parentPath[1], DName.collection.qName());
+                       return content;
+               }
+       }
+
+       public static ContentSession openDataAdminSession(ContentRepository repository) {
+               LoginContext loginContext;
+               try {
+                       loginContext = CmsAuth.DATA_ADMIN.newLoginContext();
+                       loginContext.login();
+               } catch (LoginException e1) {
+                       throw new RuntimeException("Could not login as data admin", e1);
+               } finally {
+               }
+
+               ClassLoader currentCl = Thread.currentThread().getContextClassLoader();
+               try {
+                       Thread.currentThread().setContextClassLoader(ContentUtils.class.getClassLoader());
+                       return CurrentSubject.callAs(loginContext.getSubject(), () -> repository.get());
+               } finally {
+                       Thread.currentThread().setContextClassLoader(currentCl);
+               }
+       }
+
        /** Singleton. */
        private ContentUtils() {