You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2020/07/15 16:25:10 UTC

[sling-org-apache-sling-app-cms] branch master updated (495ad3d -> c8b3135)

This is an automated email from the ASF dual-hosted git repository.

dklco pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git.


    from 495ad3d  Wrapped the buttons in the editor with an icon span to shrink button size
     new abc1f54  Internal improvement - cleaning up the ugly HTML in Java
     new 1df3fab  Adding test for CommonUtils
     new c8b3135  Minor - cleaning up frame sizing

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 core/pom.xml                                       |  4 +
 .../sling/cms/core/internal/CommonUtils.java       |  3 +-
 .../core/internal/filters/EditIncludeFilter.java   | 98 +++++++++++++++-------
 .../src/main/resources/res/editinclude/delete.html | 17 ++--
 .../main/resources/res/editinclude/droptarget.html |  7 +-
 .../src/main/resources/res/editinclude/edit.html   | 17 ++--
 .../src/main/resources/res/editinclude/end.html    | 13 +--
 .../src/main/resources/res/editinclude/header.html |  7 +-
 .../main/resources/res/editinclude/reorder.html    | 19 +++--
 .../src/main/resources/res/editinclude/start.html  | 11 +--
 .../sling/cms/core/internal/CommonUtilsTest.java}  | 29 ++++---
 ui/src/main/frontend/scss/editor.scss              |  6 +-
 12 files changed, 139 insertions(+), 92 deletions(-)
 copy reference/src/main/resources/jcr_root/apps/reference/components/general/cta/cta.jsp => core/src/main/resources/res/editinclude/delete.html (68%)
 copy Jenkinsfile => core/src/main/resources/res/editinclude/droptarget.html (88%)
 copy reference/src/main/resources/jcr_root/apps/reference/components/general/cta/cta.jsp => core/src/main/resources/res/editinclude/edit.html (67%)
 copy Jenkinsfile => core/src/main/resources/res/editinclude/end.html (80%)
 copy Jenkinsfile => core/src/main/resources/res/editinclude/header.html (74%)
 copy reference/src/main/resources/jcr_root/apps/reference/components/general/cta/cta.jsp => core/src/main/resources/res/editinclude/reorder.html (66%)
 copy Jenkinsfile => core/src/main/resources/res/editinclude/start.html (60%)
 copy core/src/{main/java/org/apache/sling/cms/core/internal/SimplePrincipal.java => test/java/org/apache/sling/cms/core/internal/CommonUtilsTest.java} (60%)


[sling-org-apache-sling-app-cms] 03/03: Minor - cleaning up frame sizing

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git

commit c8b3135aa714070b87fb2f4898f403b62c413443
Author: Dan Klco <dk...@apache.org>
AuthorDate: Wed Jul 15 11:19:13 2020 -0400

    Minor - cleaning up frame sizing
---
 ui/src/main/frontend/scss/editor.scss | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/ui/src/main/frontend/scss/editor.scss b/ui/src/main/frontend/scss/editor.scss
index cd7bac0..a000b9e 100644
--- a/ui/src/main/frontend/scss/editor.scss
+++ b/ui/src/main/frontend/scss/editor.scss
@@ -85,7 +85,7 @@
 
   .page-wrapper-frame {
     position: fixed;
-    top: 44px;
+    top: 48px;
     left: 0;
     bottom: 0;
     right: 0;
@@ -97,8 +97,10 @@
     overflow: hidden;
     z-index: 998;
     padding-top: 8px;
+    height: calc(100vh - 48px);
     @media screen and (max-width: $tablet) {
-      top: 104px;
+      top: 112px;
+      height: calc(100vh - 112px);
     }
   }
 


[sling-org-apache-sling-app-cms] 01/03: Internal improvement - cleaning up the ugly HTML in Java

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git

commit abc1f547f6852a0d92c050edb2c605b746eebf79
Author: Dan Klco <dk...@apache.org>
AuthorDate: Wed Jul 15 11:16:48 2020 -0400

    Internal improvement - cleaning up the ugly HTML in Java
---
 core/pom.xml                                       |  4 +
 .../core/internal/filters/EditIncludeFilter.java   | 98 +++++++++++++++-------
 .../src/main/resources/res/editinclude/delete.html | 25 ++++++
 .../main/resources/res/editinclude/droptarget.html | 17 ++++
 core/src/main/resources/res/editinclude/edit.html  | 25 ++++++
 core/src/main/resources/res/editinclude/end.html   | 23 +++++
 .../src/main/resources/res/editinclude/header.html | 17 ++++
 .../main/resources/res/editinclude/reorder.html    | 27 ++++++
 core/src/main/resources/res/editinclude/start.html | 21 +++++
 9 files changed, 225 insertions(+), 32 deletions(-)

diff --git a/core/pom.xml b/core/pom.xml
index a0c816c..bad86e7 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -229,5 +229,9 @@
             <groupId>javax.annotation</groupId>
             <artifactId>javax.annotation-api</artifactId>
         </dependency>
+        <dependency>
+            <artifactId>commons-text</artifactId>
+            <groupId>org.apache.commons</groupId>
+        </dependency>
     </dependencies>
 </project>
diff --git a/core/src/main/java/org/apache/sling/cms/core/internal/filters/EditIncludeFilter.java b/core/src/main/java/org/apache/sling/cms/core/internal/filters/EditIncludeFilter.java
index 0ad8703..38e4b39 100644
--- a/core/src/main/java/org/apache/sling/cms/core/internal/filters/EditIncludeFilter.java
+++ b/core/src/main/java/org/apache/sling/cms/core/internal/filters/EditIncludeFilter.java
@@ -17,9 +17,14 @@
 package org.apache.sling.cms.core.internal.filters;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
 import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Optional;
 
 import javax.servlet.Filter;
@@ -29,7 +34,9 @@ import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringSubstitutor;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.Resource;
@@ -37,6 +44,11 @@ import org.apache.sling.cms.CMSConstants;
 import org.apache.sling.cms.Component;
 import org.apache.sling.cms.EditableResource;
 import org.apache.sling.cms.core.internal.models.EditableResourceImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Filter for injecting the request attributes and markup to enable the Sling
@@ -46,12 +58,29 @@ import org.apache.sling.cms.core.internal.models.EditableResourceImpl;
         "sling.filter.scope=component" })
 public class EditIncludeFilter implements Filter {
 
-    private static final String BUTTON_CLASSES = "level-item button is-small has-text-black-ter action-button";
+    private static final Logger log = LoggerFactory.getLogger(EditIncludeFilter.class);
 
     public static final String ENABLED_ATTR_NAME = "cmsEditEnabled";
 
     public static final String WRITE_DROP_TARGET_ATTR_NAME = "writeDropTarget";
 
+    private static final String ENTRY_BASE = "res/editinclude/";
+
+    private Map<String, String> templates = new HashMap<>();
+
+    @Activate
+    public void activate(ComponentContext context) throws IOException {
+        Bundle bundle = context.getBundleContext().getBundle();
+        Enumeration<String> entries = bundle.getEntryPaths(ENTRY_BASE);
+        while (entries.hasMoreElements()) {
+            String en = entries.nextElement();
+            log.info("Loaded template: {}", en);
+            try (InputStream is = bundle.getEntry(en).openStream()) {
+                templates.put(en.replace(ENTRY_BASE, ""), IOUtils.toString(is, StandardCharsets.UTF_8));
+            }
+        }
+    }
+
     @Override
     public void destroy() {
         // Nothing required
@@ -137,8 +166,10 @@ public class EditIncludeFilter implements Filter {
     }
 
     private void writeDropTarget(Resource resource, PrintWriter writer, String order) {
-        writer.write("<div class=\"sling-cms-droptarget\" data-path=\"" + resource.getParent().getPath()
-                + "\" data-order=\"" + order + "\"></div>");
+        Map<String, Object> replacements = new HashMap<>();
+        replacements.put("parentPath", resource.getParent().getPath());
+        replacements.put("order", order);
+        writeTemplate(writer, replacements, "droptarget.html");
     }
 
     private void writeEditorMarkup(Resource resource, PrintWriter writer, boolean draggable) {
@@ -153,36 +184,33 @@ public class EditIncludeFilter implements Filter {
         String title = StringUtils.isNotEmpty(component.getTitle()) ? component.getTitle()
                 : StringUtils.substringAfterLast(resource.getResourceType(), "/");
 
-        writer.write("<div class=\"sling-cms-component\" data-reload=\"" + component.isReloadPage()
-                + "\" data-component=\"" + component.getResource().getPath() + "\" data-sling-cms-title=\"" + title
-                + "\" data-sling-cms-resource-path=\"" + resource.getPath() + "\" data-sling-cms-resource-type=\""
-                + resource.getResourceType() + "\" data-sling-cms-edit=\"" + editPath
-                + "\" data-sling-cms-resource-name=\"" + component.getResource().getName()
-                + "\"><div class=\"sling-cms-editor\" draggable=\"" + draggable + "\">");
-        writer.write(
-                "<div class=\"level has-background-light\"><div class=\"level-left\"><div class=\"field has-addons\">");
-
-        writer.write("<div class=\"control\"><a href=\"/cms/editor/edit.html" + resource.getPath() + "?editor="
-                + editPath + "\" class=\"" + BUTTON_CLASSES + "\"  title=\"Edit " + title
-                + "\"><span class=\"icon\"><span class=\"jam jam-pencil-f\"><span class=\"is-vhidden\">Edit " + title
-                + "</span></span></span></a></div>");
+        Map<String, Object> replacements = new HashMap<>();
+        replacements.put("componentPath", component.getResource().getPath());
+        replacements.put("draggable", draggable);
+        replacements.put("editPath", editPath);
+        replacements.put("reload", component.isReloadPage());
+        replacements.put("resourceName", component.getResource().getName());
+        replacements.put("resourcePath", resource.getPath());
+        replacements.put("resourceType", resource.getResourceType());
+        replacements.put("title", title);
+
+        writeTemplate(writer, replacements, "start.html");
+        writeTemplate(writer, replacements, "edit.html");
         if (!first || !last) {
-            writer.write("<div class=\"control\"><a href=\"/cms/editor/reorder.html" + resource.getPath()
-                    + "\" class=\"" + BUTTON_CLASSES + "\" title=\"Reorder " + title
-                    + "\"><span class=\"icon\"><span class=\"jam jam-arrows-v\"><span class=\"is-vhidden\">Reorder " + title
-                    + "</span></span></span></a></div>");
+            writeTemplate(writer, replacements, "reorder.html");
         }
         if (!resource.getName().equals(JcrConstants.JCR_CONTENT) && exists) {
-            writer.write("<div class=\"control\"><a href=\"/cms/editor/delete.html" + resource.getPath() + "\" class=\""
-                    + BUTTON_CLASSES
-                    + "\" title=\"Delete Component\"><span class=\"icon\"><span class=\"jam jam-trash\"><span class=\"is-vhidden\">Delete "
-                    + title + "</span></span></span></a></div>");
+            writeTemplate(writer, replacements, "delete.html");
         }
+        writeTemplate(writer, replacements, "end.html");
+    }
 
-        writer.write("</div></div>");
-        writer.write(
-                "<div class=\"level-right\"><div class=\"level-item has-text-black-ter\">" + title + "</div></div>");
-        writer.write("</div></div>");
+    private void writeTemplate(PrintWriter writer, Map<String, Object> replacements, String templateName) {
+        StringSubstitutor sub = new StringSubstitutor(replacements);
+        String template = templates.get(templateName);
+        String result = sub.replace(template);
+        log.info("Using: {} and {} to create {}", templateName, replacements, result);
+        writer.write(result);
     }
 
     private boolean writeHeader(SlingHttpServletRequest request, PrintWriter writer, boolean includeEnd) {
@@ -202,10 +230,16 @@ public class EditIncludeFilter implements Filter {
             includeEnd = true;
             String title = StringUtils.isNotEmpty(component.getTitle()) ? component.getTitle()
                     : StringUtils.substringAfterLast(resource.getResourceType(), "/");
-            writer.write("<div class=\"sling-cms-component\" data-reload=\"" + component.isReloadPage()
-                    + "\" data-component=\"" + component.getResource().getPath() + "\" data-sling-cms-title=\"" + title
-                    + "\" data-sling-cms-resource-path=\"" + resource.getPath() + "\" data-sling-cms-resource-type=\""
-                    + resource.getResourceType() + "\" data-sling-cms-edit=\"" + editPath + "\">");
+
+            Map<String, Object> replacements = new HashMap<>();
+            replacements.put("componentPath", component.getResource().getPath());
+            replacements.put("editPath", editPath);
+            replacements.put("reload", component.isReloadPage());
+            replacements.put("resourceName", component.getResource().getName());
+            replacements.put("resourcePath", resource.getPath());
+            replacements.put("resourceType", resource.getResourceType());
+            replacements.put("title", title);
+            writeTemplate(writer, replacements, "header.html");
         }
 
         return includeEnd;
diff --git a/core/src/main/resources/res/editinclude/delete.html b/core/src/main/resources/res/editinclude/delete.html
new file mode 100644
index 0000000..b1fada7
--- /dev/null
+++ b/core/src/main/resources/res/editinclude/delete.html
@@ -0,0 +1,25 @@
+<!-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ */ --><div class="control">
+    <a href="/cms/editor/delete.html${resourcePath}" class="level-item button is-small has-text-black-ter action-button" title="Delete Component">
+        <span class="icon">
+            <span class="jam jam-trash">
+                <span class="is-vhidden">Delete ${title}</span>
+            </span>
+        </span>
+    </a>
+</div>
\ No newline at end of file
diff --git a/core/src/main/resources/res/editinclude/droptarget.html b/core/src/main/resources/res/editinclude/droptarget.html
new file mode 100644
index 0000000..82d3372
--- /dev/null
+++ b/core/src/main/resources/res/editinclude/droptarget.html
@@ -0,0 +1,17 @@
+<!-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ */ --><div class="sling-cms-droptarget" data-path="${parentPath}" data-order="${order}"></div>
\ No newline at end of file
diff --git a/core/src/main/resources/res/editinclude/edit.html b/core/src/main/resources/res/editinclude/edit.html
new file mode 100644
index 0000000..d20ca39
--- /dev/null
+++ b/core/src/main/resources/res/editinclude/edit.html
@@ -0,0 +1,25 @@
+<!-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ */ --><div class="control">
+    <a href="/cms/editor/edit.html${resourcePath}?editor=${editPath}" class="level-item button is-small has-text-black-ter action-button"  title="Edit ${title}">
+        <span class="icon">
+            <span class="jam jam-pencil-f">
+                <span class="is-vhidden">Edit ${title}</span>
+            </span>
+        </span>
+    </a>
+</div>
\ No newline at end of file
diff --git a/core/src/main/resources/res/editinclude/end.html b/core/src/main/resources/res/editinclude/end.html
new file mode 100644
index 0000000..9d4a48e
--- /dev/null
+++ b/core/src/main/resources/res/editinclude/end.html
@@ -0,0 +1,23 @@
+<!-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ */ -->            </div>  
+        </div>
+        <div class="level-right">
+            <div class="level-item has-text-black-ter">${title}</div>
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/core/src/main/resources/res/editinclude/header.html b/core/src/main/resources/res/editinclude/header.html
new file mode 100644
index 0000000..a2f7713
--- /dev/null
+++ b/core/src/main/resources/res/editinclude/header.html
@@ -0,0 +1,17 @@
+<!-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ */ --><div class="sling-cms-component" data-reload="${reload}" data-component="${componentPath}" data-sling-cms-title="${title}" data-sling-cms-resource-path="${resourcePath}" data-sling-cms-resource-type="${resourceType}" data-sling-cms-edit="${editPath}">
\ No newline at end of file
diff --git a/core/src/main/resources/res/editinclude/reorder.html b/core/src/main/resources/res/editinclude/reorder.html
new file mode 100644
index 0000000..95bcfd1
--- /dev/null
+++ b/core/src/main/resources/res/editinclude/reorder.html
@@ -0,0 +1,27 @@
+<!-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ */ --><div class="control">
+    <a href="/cms/editor/reorder.html${resourcePath}" class="level-item button is-small has-text-black-ter action-button" title="Reorder ${title}">
+        <span class="icon">
+            <span class="jam jam-arrows-v">
+                <span class="is-vhidden">
+                    Reorder ${title}
+                </span>
+            </span>
+        </span>
+    </a>
+</div>
\ No newline at end of file
diff --git a/core/src/main/resources/res/editinclude/start.html b/core/src/main/resources/res/editinclude/start.html
new file mode 100644
index 0000000..34e4ce6
--- /dev/null
+++ b/core/src/main/resources/res/editinclude/start.html
@@ -0,0 +1,21 @@
+<!-- /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ */ --><div class="sling-cms-component" data-reload="${reload}" data-component="${componentPath}" data-sling-cms-title="${title}" data-sling-cms-resource-path="${resourcePath}" data-sling-cms-resource-type="${resourceType}" data-sling-cms-edit="${editPath}" data-sling-cms-resource-name="${resourceName}">
+    <div class="sling-cms-editor" draggable="${draggable}">
+        <div class="level has-background-light">
+            <div class="level-left">
+                <div class="field has-addons">
\ No newline at end of file


[sling-org-apache-sling-app-cms] 02/03: Adding test for CommonUtils

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git

commit 1df3fab5f79a560fff7ccaf430614a2a2d24a6d9
Author: Dan Klco <dk...@apache.org>
AuthorDate: Wed Jul 15 11:19:01 2020 -0400

    Adding test for CommonUtils
---
 .../sling/cms/core/internal/CommonUtils.java       |  3 +-
 .../sling/cms/core/internal/CommonUtilsTest.java   | 40 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/apache/sling/cms/core/internal/CommonUtils.java b/core/src/main/java/org/apache/sling/cms/core/internal/CommonUtils.java
index 29992ab..cb5062e 100644
--- a/core/src/main/java/org/apache/sling/cms/core/internal/CommonUtils.java
+++ b/core/src/main/java/org/apache/sling/cms/core/internal/CommonUtils.java
@@ -24,6 +24,7 @@ import javax.jcr.Session;
 import org.apache.jackrabbit.api.JackrabbitSession;
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -34,7 +35,7 @@ public class CommonUtils {
     private CommonUtils() {
     }
 
-    public static final UserManager getUserManager(ResourceResolver resolver) throws RepositoryException {
+    public static final UserManager getUserManager(@NotNull ResourceResolver resolver) throws RepositoryException {
         return Optional.ofNullable(resolver.adaptTo(Session.class)).map(session -> {
             UserManager userManager = null;
             if (session instanceof JackrabbitSession) {
diff --git a/core/src/test/java/org/apache/sling/cms/core/internal/CommonUtilsTest.java b/core/src/test/java/org/apache/sling/cms/core/internal/CommonUtilsTest.java
new file mode 100644
index 0000000..afbff93
--- /dev/null
+++ b/core/src/test/java/org/apache/sling/cms/core/internal/CommonUtilsTest.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.cms.core.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class CommonUtilsTest {
+
+    @Test
+    public void testGetUserManagerNullSession() {
+        try {
+            CommonUtils.getUserManager(Mockito.mock(ResourceResolver.class));
+            fail();
+        } catch (RepositoryException re) {
+            assertEquals("Failed to get user manager", re.getMessage());
+        }
+    }
+
+}
\ No newline at end of file