Remove dependency to OSGi user admin from API
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / acr / ContentUtils.java
index 0513a0d3e4354a447c125b21559da75953fe873a..b3f81454734be5e1d2e86cc1805c8d272fdad86c 100644 (file)
@@ -1,10 +1,13 @@
 package org.argeo.cms.acr;
 
 import java.io.PrintStream;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 import java.util.StringJoiner;
+import java.util.StringTokenizer;
 import java.util.function.BiConsumer;
 
 import javax.security.auth.login.LoginContext;
@@ -16,12 +19,14 @@ 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.CmsConstants;
+import org.argeo.api.cms.CmsSession;
 import org.argeo.api.cms.directory.CmsDirectory;
+import org.argeo.api.cms.directory.CmsRole;
 import org.argeo.api.cms.directory.CmsUserManager;
 import org.argeo.api.cms.directory.HierarchyUnit;
 import org.argeo.api.cms.directory.UserDirectory;
 import org.argeo.cms.util.CurrentSubject;
-import org.osgi.service.useradmin.Role;
 
 /** Utilities and routines around {@link Content}. */
 public class ContentUtils {
@@ -50,15 +55,20 @@ public class ContentUtils {
                        sb.append("  ");
                }
                String prefix = sb.toString();
-               out.println(prefix + content.getName());
-               for (QName key : content.keySet()) {
-                       out.println(prefix + " " + key + "=" + content.get(key));
-               }
+               String txt = "";
                if (printText) {
                        if (content.hasText()) {
-                               out.println("<![CDATA[" + content.getText().trim() + "]]>");
+                               final int MAX_LENGTH = 64;
+                               txt = content.getText().trim();
+                               if (txt.length() > MAX_LENGTH)
+                                       txt = txt.substring(0, 64) + " ...";
+                               txt = " : " + txt;
                        }
                }
+               out.println(prefix + content.getName() + txt);
+               for (QName key : content.keySet()) {
+                       out.println(prefix + " " + key + "=" + content.get(key));
+               }
        }
 
 //     public static <T> boolean isString(T t) {
@@ -123,11 +133,21 @@ public class ContentUtils {
                        throw new IllegalArgumentException("Path " + path + " contains //");
        }
 
+       /** The last element of a path. */
+       public static String lastPathElement(String path) {
+               if (path.charAt(path.length() - 1) == '/')
+                       throw new IllegalArgumentException("Path " + path + " cannot end with '/'");
+               int index = path.lastIndexOf('/');
+               if (index < 0)
+                       return path;
+               return path.substring(index + 1);
+       }
+
        /*
         * DIRECTORY
         */
 
-       public static Content roleToContent(CmsUserManager userManager, ContentSession contentSession, Role role) {
+       public static Content roleToContent(CmsUserManager userManager, ContentSession contentSession, CmsRole role) {
                UserDirectory userDirectory = userManager.getDirectory(role);
                String path = directoryPath(userDirectory) + userDirectory.getRolePath(role);
                Content content = contentSession.get(path);
@@ -176,7 +196,7 @@ public class ContentUtils {
                }
        }
 
-       public static ContentSession openDataAdminSession(ContentRepository repository) {
+       public static ContentSession openDataAdminSession(ContentRepository contentRepository) {
                LoginContext loginContext;
                try {
                        loginContext = CmsAuth.DATA_ADMIN.newLoginContext();
@@ -189,12 +209,16 @@ public class ContentUtils {
                ClassLoader currentCl = Thread.currentThread().getContextClassLoader();
                try {
                        Thread.currentThread().setContextClassLoader(ContentUtils.class.getClassLoader());
-                       return CurrentSubject.callAs(loginContext.getSubject(), () -> repository.get());
+                       return CurrentSubject.callAs(loginContext.getSubject(), () -> contentRepository.get());
                } finally {
                        Thread.currentThread().setContextClassLoader(currentCl);
                }
        }
 
+       public static ContentSession openSession(ContentRepository contentRepository, CmsSession cmsSession) {
+               return CurrentSubject.callAs(cmsSession.getSubject(), () -> contentRepository.get());
+       }
+
        /**
         * Constructs a relative path between a base path and a given path.
         * 
@@ -212,6 +236,33 @@ public class ContentUtils {
                return relativePath;
        }
 
+       /** A path in the node repository */
+       public static String getDataPath(Content node) {
+               // TODO make it more configurable?
+               StringBuilder buf = new StringBuilder(CmsConstants.PATH_API_ACR);
+               buf.append(node.getPath());
+               return buf.toString();
+       }
+
+       /** A path in the node repository */
+       public static String getDataPathForUrl(Content node) {
+               return cleanPathForUrl(getDataPath(node));
+       }
+
+       /** Clean reserved URL characters for use in HTTP links. */
+       public static String cleanPathForUrl(String path) {
+               StringTokenizer st = new StringTokenizer(path, "/");
+               StringBuilder sb = new StringBuilder();
+               while (st.hasMoreElements()) {
+                       sb.append('/');
+                       String encoded = URLEncoder.encode(st.nextToken(), StandardCharsets.UTF_8);
+                       encoded = encoded.replace("+", "%20");
+                       sb.append(encoded);
+
+               }
+               return sb.toString();
+       }
+
        /** Singleton. */
        private ContentUtils() {