diff --git a/ccm-cms/src/main/java/org/librecms/ui/CmsApplication.java b/ccm-cms/src/main/java/org/librecms/ui/CmsApplication.java
index 8bc4c238b..74aead65b 100644
--- a/ccm-cms/src/main/java/org/librecms/ui/CmsApplication.java
+++ b/ccm-cms/src/main/java/org/librecms/ui/CmsApplication.java
@@ -20,7 +20,6 @@ package org.librecms.ui;
import org.libreccm.ui.IsAuthenticatedFilter;
-import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
@@ -28,7 +27,7 @@ import javax.ws.rs.core.Application;
/**
* The CMS application acts as entry point for all CMS related user interfaces.
- *
+ *
* @author Jens Pelzetter
*/
@ApplicationPath("/@cms")
@@ -36,12 +35,13 @@ public class CmsApplication extends Application {
@Override
public Set> getClasses() {
- final Set> classes = new HashSet<>();
-
- classes.add(IsAuthenticatedFilter.class);
- classes.add(CmsController.class);
-
- return classes;
+ return Set.of(
+ IsAuthenticatedFilter.class,
+ CmsController.class,
+ ContentSectionsController.class,
+ PagesController.class,
+ SearchController.class
+ );
}
}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/CmsController.java b/ccm-cms/src/main/java/org/librecms/ui/CmsController.java
index 708157619..eb1d85281 100644
--- a/ccm-cms/src/main/java/org/librecms/ui/CmsController.java
+++ b/ccm-cms/src/main/java/org/librecms/ui/CmsController.java
@@ -18,31 +18,17 @@
*/
package org.librecms.ui;
-import org.libreccm.api.Identifier;
-import org.libreccm.api.IdentifierParser;
-import org.libreccm.core.CoreConstants;
import org.libreccm.security.AuthorizationRequired;
-import org.libreccm.security.PermissionChecker;
-import org.libreccm.security.RequiresPrivilege;
-import org.librecms.contentsection.ContentSection;
-import org.librecms.contentsection.ContentSectionManager;
-import org.librecms.contentsection.ContentSectionRepository;
-import org.librecms.contentsection.Folder;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.Objects;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
-import javax.transaction.Transactional;
-import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
-import javax.ws.rs.POST;
import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
@@ -57,21 +43,9 @@ import javax.ws.rs.core.Response;
@Path("/")
public class CmsController {
- @Inject
- private ContentSectionRepository sectionRepo;
-
- @Inject
- private ContentSectionManager sectionManager;
-
@Inject
private HttpServletRequest request;
- @Inject
- private IdentifierParser identifierParser;
-
- @Inject
- private PermissionChecker permissionChecker;
-
/**
* Redirects requests to the root path ({@code /@cms} or {@code /@cms/}) to
* the {@code /@cms/contentsections}.
@@ -103,217 +77,4 @@ public class CmsController {
}
}
- /**
- * Shows all available content sections.
- *
- * @return The template to use.
- */
- @GET
- @Path("/contentsections/")
- @AuthorizationRequired
- public String getContentSections() {
- return "org/librecms/ui/cms/contentsections-list.xhtml";
- }
-
- /**
- * Creates a new content section.
- *
- * @param sectionName The name of the new section.
- *
- * @return Redirect to the content sections list.
- */
- @POST
- @Path("/contentsections/new")
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- @Transactional(Transactional.TxType.REQUIRED)
- public String createContentSection(
- @FormParam("sectionName") final String sectionName
- ) {
- sectionManager.createContentSection(sectionName);
-
- return "redirect:/contentsections/";
- }
-
- /**
- * Renames a content section.
- *
- * @param identifierParam The identifier (see {@link Identifier} and
- * {@link IdentifierParser}) of the content section
- * to rename.
- * @param sectionName The new name of the content section.
- *
- * @return Redirect to the list of content sections.
- */
- @POST
- @Path("/contentsections/{sectionIdentifier}/rename")
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- @Transactional(Transactional.TxType.REQUIRED)
- public String renameContentSection(
- @PathParam("sectionIdentifier") final String identifierParam,
- @FormParam("sectionName") final String sectionName
- ) {
- final ContentSection section = findContentSection(identifierParam);
-
- sectionManager.renameContentSection(section, sectionName);
-
- return "redirect:/contentsections/";
- }
-
- /**
- * Deletes a content section. The content section must be empty (no items,
- * assets or folders in it).
- *
- * @param identifierParam The identifier (see {@link Identifier} and
- * {@link IdentifierParser}) of the content section
- * to delete.
- * @param confirmed A string which must contain the value {@code true}
- * to be sure that the user confirmed the deletion of
- * the content section.
- *
- * @return Redirect to the list of content sections.
- */
- @POST
- @Path("/contentsections/{sectionIdentifier}/delete")
- @AuthorizationRequired
- @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
- @Transactional(Transactional.TxType.REQUIRED)
- public String deleteContentSection(
- @PathParam("sectionIdentifier") final String identifierParam,
- @FormParam("confirmed") final String confirmed
- ) {
- if (Objects.equals(confirmed, "true")) {
- final ContentSection section = findContentSection(identifierParam);
-
- if (!canDelete(section)) {
- throw new WebApplicationException(
- String.format(
- "ContentSection %s is not empty and can't be deleted.",
- section.getLabel()
- ),
- Response.Status.BAD_REQUEST
- );
- }
-
- sectionManager.deleteContentSection(section);
- }
-
- return "redirect:/contentsections/";
- }
-
- /**
- * ToDo: Show UI for managing pages.
- *
- * @return Placeholder
- */
- @GET
- @Path("/pages")
- @AuthorizationRequired
- public String getPages() {
- return "org/librecms/ui/cms/pages.xhtml";
- }
-
- /**
- * ToDo: Search for content items (and assets?) in all content sections.
- *
- * @return Placeholder
- */
- @GET
- @Path("/search")
- @AuthorizationRequired
- public String getSearch() {
- return "org/librecms/ui/cms/search.xhtml";
- }
-
- /**
- * Helper function for retrieving a content section by an identifier.
- *
- * @param identifierParam The identifier paramter.
- *
- * @return The content section if a section identified by the provided
- * identifier exists.
- *
- * @throws WebApplicationException A {@link WebApplicationException} with
- * {@link Response.Status#NOT_FOUND} status
- * code if there is not content section
- * identified by the provided identifier.
- *
- * @see IdentifierParser
- * @see Identifier
- */
- private ContentSection findContentSection(final String identifierParam) {
- final Identifier identifier = identifierParser.parseIdentifier(
- identifierParam
- );
-
- final ContentSection section;
- switch (identifier.getType()) {
- case ID:
- section = sectionRepo.findById(
- Long.parseLong(identifier.getIdentifier())
- ).orElseThrow(
- () -> new WebApplicationException(
- String.format(
- "No ContentSection identified by ID %s "
- + "available.",
- identifierParam
- ),
- Response.Status.NOT_FOUND
- )
- );
- break;
- case UUID:
- section = sectionRepo
- .findByUuid(identifier.getIdentifier())
- .orElseThrow(
- () -> new WebApplicationException(
- String.format(
- "No ContentSection identifed UUID %s "
- + "available.",
- identifierParam
- ),
- Response.Status.NOT_FOUND
- )
- );
- break;
- default:
- section = sectionRepo
- .findByLabel(identifier.getIdentifier())
- .orElseThrow(
- () -> new WebApplicationException(
- String.format(
- "No ContentSection with name %s "
- + "available.",
- identifierParam
- ),
- Response.Status.NOT_FOUND
- )
- );
- break;
- }
-
- return section;
- }
-
- /**
- * Helper function to determine of a content section can be deleted. Checks
- * if the {@link ContentSection#rootAssetsFolder} and the
- * {@link ContentSection#rootDocumentsFolder} are empty.
- *
- * @param section The section
- *
- * @return {@code true} if the content section is empty can be deleted,
- * {@code false} is not.
- */
- protected boolean canDelete(final ContentSection section) {
- final Folder rootAssetsFolder = section.getRootAssetsFolder();
- final Folder rootDocumentsFolder = section.getRootDocumentsFolder();
-
- return rootAssetsFolder.getSubFolders().isEmpty()
- && rootAssetsFolder.getObjects().isEmpty()
- && rootDocumentsFolder.getSubFolders().isEmpty()
- && rootDocumentsFolder.getObjects().isEmpty();
- }
-
}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsController.java b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsController.java
new file mode 100644
index 000000000..f320a8521
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsController.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2021 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.ui;
+
+import org.libreccm.api.Identifier;
+import org.libreccm.api.IdentifierParser;
+import org.libreccm.core.CoreConstants;
+import org.libreccm.security.AuthorizationRequired;
+import org.libreccm.security.PermissionChecker;
+import org.libreccm.security.RequiresPrivilege;
+import org.librecms.contentsection.ContentSection;
+import org.librecms.contentsection.ContentSectionManager;
+import org.librecms.contentsection.ContentSectionRepository;
+import org.librecms.contentsection.Folder;
+
+import java.util.Objects;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.mvc.Controller;
+import javax.transaction.Transactional;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Controller
+@Path("/")
+public class ContentSectionsController {
+
+ @Inject
+ private ContentSectionRepository sectionRepo;
+
+ @Inject
+ private ContentSectionManager sectionManager;
+
+ @Inject
+ private IdentifierParser identifierParser;
+
+ @Inject
+ private PermissionChecker permissionChecker;
+
+ /**
+ * Shows all available content sections.
+ *
+ * @return The template to use.
+ */
+ @GET
+ @Path("/")
+ @AuthorizationRequired
+ public String getContentSections() {
+ return "org/librecms/ui/cms/contentsections-list.xhtml";
+ }
+
+ /**
+ * Creates a new content section.
+ *
+ * @param sectionName The name of the new section.
+ *
+ * @return Redirect to the content sections list.
+ */
+ @POST
+ @Path("/new")
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String createContentSection(
+ @FormParam("sectionName") final String sectionName
+ ) {
+ sectionManager.createContentSection(sectionName);
+
+ return "redirect:/contentsections/";
+ }
+
+ /**
+ * Renames a content section.
+ *
+ * @param identifierParam The identifier (see {@link Identifier} and
+ * {@link IdentifierParser}) of the content section
+ * to rename.
+ * @param sectionName The new name of the content section.
+ *
+ * @return Redirect to the list of content sections.
+ */
+ @POST
+ @Path("/{sectionIdentifier}/rename")
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String renameContentSection(
+ @PathParam("sectionIdentifier") final String identifierParam,
+ @FormParam("sectionName") final String sectionName
+ ) {
+ final ContentSection section = findContentSection(identifierParam);
+
+ sectionManager.renameContentSection(section, sectionName);
+
+ return "redirect:/contentsections/";
+ }
+
+ /**
+ * Deletes a content section. The content section must be empty (no items,
+ * assets or folders in it).
+ *
+ * @param identifierParam The identifier (see {@link Identifier} and
+ * {@link IdentifierParser}) of the content section
+ * to delete.
+ * @param confirmed A string which must contain the value {@code true}
+ * to be sure that the user confirmed the deletion of
+ * the content section.
+ *
+ * @return Redirect to the list of content sections.
+ */
+ @POST
+ @Path("/{sectionIdentifier}/delete")
+ @AuthorizationRequired
+ @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String deleteContentSection(
+ @PathParam("sectionIdentifier") final String identifierParam,
+ @FormParam("confirmed") final String confirmed
+ ) {
+ if (Objects.equals(confirmed, "true")) {
+ final ContentSection section = findContentSection(identifierParam);
+
+ if (!canDelete(section)) {
+ throw new WebApplicationException(
+ String.format(
+ "ContentSection %s is not empty and can't be deleted.",
+ section.getLabel()
+ ),
+ Response.Status.BAD_REQUEST
+ );
+ }
+
+ sectionManager.deleteContentSection(section);
+ }
+
+ return "redirect:/contentsections/";
+ }
+
+ /**
+ * Helper function for retrieving a content section by an identifier.
+ *
+ * @param identifierParam The identifier paramter.
+ *
+ * @return The content section if a section identified by the provided
+ * identifier exists.
+ *
+ * @throws WebApplicationException A {@link WebApplicationException} with
+ * {@link Response.Status#NOT_FOUND} status
+ * code if there is not content section
+ * identified by the provided identifier.
+ *
+ * @see IdentifierParser
+ * @see Identifier
+ */
+ private ContentSection findContentSection(final String identifierParam) {
+ final Identifier identifier = identifierParser.parseIdentifier(
+ identifierParam
+ );
+
+ final ContentSection section;
+ switch (identifier.getType()) {
+ case ID:
+ section = sectionRepo.findById(
+ Long.parseLong(identifier.getIdentifier())
+ ).orElseThrow(
+ () -> new WebApplicationException(
+ String.format(
+ "No ContentSection identified by ID %s "
+ + "available.",
+ identifierParam
+ ),
+ Response.Status.NOT_FOUND
+ )
+ );
+ break;
+ case UUID:
+ section = sectionRepo
+ .findByUuid(identifier.getIdentifier())
+ .orElseThrow(
+ () -> new WebApplicationException(
+ String.format(
+ "No ContentSection identifed UUID %s "
+ + "available.",
+ identifierParam
+ ),
+ Response.Status.NOT_FOUND
+ )
+ );
+ break;
+ default:
+ section = sectionRepo
+ .findByLabel(identifier.getIdentifier())
+ .orElseThrow(
+ () -> new WebApplicationException(
+ String.format(
+ "No ContentSection with name %s "
+ + "available.",
+ identifierParam
+ ),
+ Response.Status.NOT_FOUND
+ )
+ );
+ break;
+ }
+
+ return section;
+ }
+
+ /**
+ * Helper function to determine of a content section can be deleted. Checks
+ * if the {@link ContentSection#rootAssetsFolder} and the
+ * {@link ContentSection#rootDocumentsFolder} are empty.
+ *
+ * @param section The section
+ *
+ * @return {@code true} if the content section is empty can be deleted,
+ * {@code false} is not.
+ */
+ protected boolean canDelete(final ContentSection section) {
+ final Folder rootAssetsFolder = section.getRootAssetsFolder();
+ final Folder rootDocumentsFolder = section.getRootDocumentsFolder();
+
+ return rootAssetsFolder.getSubFolders().isEmpty()
+ && rootAssetsFolder.getObjects().isEmpty()
+ && rootDocumentsFolder.getSubFolders().isEmpty()
+ && rootDocumentsFolder.getObjects().isEmpty();
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsTableModel.java b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsTableModel.java
index 02a7fc65f..cfff37306 100644
--- a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsTableModel.java
+++ b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsTableModel.java
@@ -46,7 +46,7 @@ public class ContentSectionsTableModel {
* The controller.
*/
@Inject
- private CmsController controller;
+ private ContentSectionsController controller;
/**
* Repository for content sections.
diff --git a/ccm-cms/src/main/java/org/librecms/ui/PagesController.java b/ccm-cms/src/main/java/org/librecms/ui/PagesController.java
new file mode 100644
index 000000000..0566dd5e5
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/PagesController.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.ui;
+
+import org.libreccm.security.AuthorizationRequired;
+
+import javax.enterprise.context.RequestScoped;
+import javax.mvc.Controller;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Controller
+@Path("/pages")
+public class PagesController {
+
+ /**
+ * ToDo: Show UI for managing pages.
+ *
+ * @return Placeholder
+ */
+ @GET
+ @Path("/")
+ @AuthorizationRequired
+ public String getPages() {
+ return "org/librecms/ui/cms/pages.xhtml";
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/SearchController.java b/ccm-cms/src/main/java/org/librecms/ui/SearchController.java
new file mode 100644
index 000000000..27c124f9a
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/SearchController.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.librecms.ui;
+
+import org.libreccm.security.AuthorizationRequired;
+
+import javax.enterprise.context.RequestScoped;
+import javax.mvc.Controller;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Controller
+@Path("/search")
+public class SearchController {
+
+ /**
+ * ToDo: Search for content items (and assets?) in all content sections.
+ *
+ * @return Placeholder
+ */
+ @GET
+ @Path("/")
+ @AuthorizationRequired
+ public String getSearch() {
+ return "org/librecms/ui/cms/search.xhtml";
+ }
+
+}