diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoriesController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoriesController.java index c51537c66..f79eda73a 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoriesController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoriesController.java @@ -18,12 +18,28 @@ */ package org.libreccm.ui.admin.categories; +import org.libreccm.api.Identifier; +import org.libreccm.api.IdentifierParser; +import org.libreccm.categorization.Category; +import org.libreccm.categorization.CategoryManager; +import org.libreccm.categorization.CategoryRepository; import org.libreccm.core.CoreConstants; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; +import org.libreccm.ui.Message; +import org.libreccm.ui.MessageType; +import org.libreccm.ui.admin.AdminMessages; + +import java.util.Arrays; +import java.util.Locale; +import java.util.Optional; import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; import javax.mvc.Controller; +import javax.mvc.Models; +import javax.transaction.Transactional; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -38,118 +54,548 @@ import javax.ws.rs.PathParam; @Path("/categorymanager/categories") public class CategoriesController { + @Inject + private AdminMessages adminMessages; + + @Inject + private CategoryDetailsModel categoryDetailsModel; + + @Inject + private CategoryManager categoryManager; + + @Inject + private CategoryRepository categoryRepository; + + @Inject + private IdentifierParser identifierParser; + + @Inject + private Models models; + @GET @Path("/{categoryIdentifier}") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) public String getCategory( @PathParam("categoryIdentifier") final String categoryIdentifier ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + categoryIdentifier + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + categoryDetailsModel.setCategory(result.get()); + return "org/libreccm/ui/admin/categories/category-details.xhtml"; + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifier) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } @GET @Path("/{categoryIdentifier}/edit") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) public String editCategory( @PathParam("categoryIdentifier") final String categoryIdentifier ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + categoryIdentifier + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + categoryDetailsModel.setCategory(result.get()); + return "org/libreccm/ui/admin/categories/category-form.xhtml"; + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifier) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } @GET @Path("/{categoryIdentifier}/subcategories/new") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) public String newSubCategory( @PathParam("categoryIdentifier") final String categoryIdentifier ) { - throw new UnsupportedOperationException(); + return "org/libreccm/ui/admin/categories/category-form.xhtml"; } @POST @Path("/{categoryIdentifier}/subcategories/move") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) public String moveSubCategory( - @PathParam("categoryIdentifier") final String categoryIdentifier + @PathParam("categoryIdentifier") final String categoryIdentifierParam, + @FormParam("targetIdentifier") final String targetIdentifierParam ) { - throw new UnsupportedOperationException(); + final Identifier categoryIdentifier = identifierParser.parseIdentifier( + categoryIdentifierParam + ); + final Optional categoryResult; + switch (categoryIdentifier.getType()) { + case ID: + categoryResult = categoryRepository.findById( + Long.parseLong(categoryIdentifier.getIdentifier()) + ); + break; + default: + categoryResult = categoryRepository.findByUuid( + categoryIdentifier.getIdentifier() + ); + break; + } + if (!categoryResult.isPresent()) { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifierParam) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } + + final Identifier targetIdentifier = identifierParser.parseIdentifier( + targetIdentifierParam + ); + + final Optional targetResult; + switch (targetIdentifier.getType()) { + case ID: + targetResult = categoryRepository.findById( + Long.parseLong(targetIdentifier.getIdentifier()) + ); + break; + default: + targetResult = categoryRepository.findByUuid( + targetIdentifier.getIdentifier() + ); + break; + } + if (!categoryResult.isPresent()) { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(targetIdentifierParam) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } + + final Category category = categoryResult.get(); + final Category oldParent = category.getParentCategory(); + if (oldParent == null) { + return String.format( + "redirect:categorymanager/categories/ID-%d", + category.getObjectId() + ); + } + final Category target = targetResult.get(); + + categoryManager.removeSubCategoryFromCategory(category, oldParent); + categoryManager.addSubCategoryToCategory(category, target); + + return String.format( + "redirect:categorymanager/categories/ID-%d", target.getObjectId() + ); } @POST @Path("/{categoryIdentifier}/subcategories/remove") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) public String removeSubCategory( @PathParam("categoryIdentifier") final String categoryIdentifier ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + categoryIdentifier + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Category category = result.get(); + final Category parentCategory = category.getParentCategory(); + if (parentCategory == null) { + return String.format( + "redirect:categorymanager/categories/ID-%d", + category.getObjectId() + ); + } + categoryManager.removeSubCategoryFromCategory(category, + parentCategory + ); + categoryRepository.delete(category); + return String.format( + "redirect:categorymanager/categories/ID-%d", + parentCategory.getObjectId() + ); + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifier) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } @POST @Path("/{categoryIdentifier}/title/add") @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) public String addTitle( - @PathParam("categorySystemIdentifier") - final String categorySystemIdentifier + @PathParam("categoryIdentifier") + final String categoryIdentifierParam, + @FormParam("locale") final String localeParam, + @FormParam("value") final String value ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + categoryIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Category category = result.get(); + + final Locale locale = new Locale(localeParam); + category.getTitle().addValue(locale, value); + categoryRepository.save(category); + return String.format( + "redirect:categorymanager/categories/ID-%d", + category.getObjectId() + ); + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifierParam) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } @POST @Path("/{categoryIdentifier}/title/${locale}/edit") @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) public String editTitle( - @PathParam("categorySystemIdentifier") - final String categorySystemIdentifier, - @PathParam("locale") final String localeParam + @PathParam("categoryIdentifier") + final String categoryIdentifierParam, + @PathParam("locale") final String localeParam, + @FormParam("value") final String value ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + categoryIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Category category = result.get(); + + final Locale locale = new Locale(localeParam); + category.getTitle().addValue(locale, value); + categoryRepository.save(category); + return String.format( + "redirect:categorymanager/categories/ID-%d", + category.getObjectId() + ); + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifierParam) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } @POST @Path("/{categoryIdentifier}/title/${locale}/remove") @AuthorizationRequired public String removeTitle( - @PathParam("categorySystemIdentifier") - final String categorySystemIdentifier, + @PathParam("categoryIdentifier") + final String categoryIdentifierParam, @PathParam("locale") final String localeParam ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + categoryIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Category category = result.get(); + + final Locale locale = new Locale(localeParam); + category.getTitle().removeValue(locale); + categoryRepository.save(category); + return String.format( + "redirect:categorymanager/categories/ID-%d", + category.getObjectId() + ); + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifierParam) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } @POST @Path("/{categoryIdentifier}description/add") @AuthorizationRequired public String addDescription( - @PathParam("categorySystemIdentifier") - final String categorySystemIdentifier + @PathParam("categoryIdentifier") + final String categoryIdentifierParam, + @FormParam("locale") final String localeParam, + @FormParam("value") final String value ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + categoryIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Category category = result.get(); + + final Locale locale = new Locale(localeParam); + category.getDescription().addValue(locale, value); + categoryRepository.save(category); + return String.format( + "redirect:categorymanager/categories/ID-%d", + category.getObjectId() + ); + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifierParam) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } @POST @Path("/{categoryIdentifier}/description/${locale}/edit") @AuthorizationRequired public String editDescription( - @PathParam("categorySystemIdentifier") - final String categorySystemIdentifier, - @PathParam("locale") final String localeParam + @PathParam("categoryIdentifier") + final String categoryIdentifierParam, + @PathParam("locale") final String localeParam, + @FormParam("value") final String value ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + categoryIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Category category = result.get(); + + final Locale locale = new Locale(localeParam); + category.getDescription().addValue(locale, value); + categoryRepository.save(category); + return String.format( + "redirect:categorymanager/categories/ID-%d", + category.getObjectId() + ); + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifierParam) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } @POST @Path("/{categoryIdentifier}/description/${locale}/remove") @AuthorizationRequired public String removeDescription( - @PathParam("categorySystemIdentifier") - final String categorySystemIdentifier, + @PathParam("categoryIdentifier") + final String categoryIdentifierParam, @PathParam("locale") final String localeParam ) { - throw new UnsupportedOperationException(); + final Identifier identifier = identifierParser.parseIdentifier( + categoryIdentifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Category category = result.get(); + + final Locale locale = new Locale(localeParam); + category.getDescription().removeValue(locale); + categoryRepository.save(category); + return String.format( + "redirect:categorymanager/categories/ID-%d", + category.getObjectId() + ); + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifierParam) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoriesPage.java b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoriesPage.java index 150bb5d73..2297d7d11 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoriesPage.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoriesPage.java @@ -46,7 +46,7 @@ public class CategoriesPage implements AdminPage { @Override public String getUriIdentifier() { return String.format( - "%s#getCategories", CategorySystemsController.class.getSimpleName() + "%s#getCategorySystems", CategorySystemsController.class.getSimpleName() ); } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryDetailsModel.java b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryDetailsModel.java new file mode 100644 index 000000000..429684e0f --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryDetailsModel.java @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2020 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.libreccm.ui.admin.categories; + +import org.libreccm.categorization.Category; +import org.libreccm.ui.Message; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("CategoryDetailsModel") +public class CategoryDetailsModel { + + private long categoryId; + + private String uuid; + + private String uniqueId; + + private String name; + + private Map title; + + private Map description; + + private boolean enabled; + + private boolean visible; + + private boolean abstractCategory; + + private List subCategories; + + private CategoryNodeModel parentCategory; + + private long categoryOrder; + + private final List messages; + + public CategoryDetailsModel() { + this.messages = new ArrayList<>(); + } + + public long getCategoryId() { + return categoryId; + } + + public String getUuid() { + return uuid; + } + + public String getUniqueId() { + return uniqueId; + } + + public String getName() { + return name; + } + + public Map getTitle() { + return Collections.unmodifiableMap(title); + } + + public Map getDescription() { + return Collections.unmodifiableMap(description); + } + + public boolean isEnabled() { + return enabled; + } + + public boolean isVisible() { + return visible; + } + + public boolean isAbstractCategory() { + return abstractCategory; + } + + public List getSubCategories() { + return Collections.unmodifiableList(subCategories); + } + + public CategoryNodeModel getParentCategory() { + return parentCategory; + } + + public long getCategoryOrder() { + return categoryOrder; + } + + public List getMessages() { + return Collections.unmodifiableList(messages); + } + + public void addMessage(final Message message) { + messages.add(message); + } + + @Transactional(Transactional.TxType.REQUIRED) + protected void setCategory(final Category category) { + Objects.requireNonNull(category); + + categoryId = category.getObjectId(); + uuid = category.getUuid(); + uniqueId = category.getUniqueId(); + name = category.getName(); + title = category + .getTitle() + .getValues() + .entrySet() + .stream() + .collect( + Collectors.toMap( + entry -> entry.getKey().toString(), + entry -> entry.getValue() + ) + ); + description = category + .getDescription() + .getValues() + .entrySet() + .stream() + .collect( + Collectors.toMap( + entry -> entry.getKey().toString(), + entry -> entry.getValue() + ) + ); + enabled = category.isEnabled(); + visible = category.isVisible(); + abstractCategory = category.isAbstractCategory(); + subCategories = category + .getSubCategories() + .stream() + .map(CategoryNodeModel::new) + .sorted() + .collect(Collectors.toList()); + parentCategory = new CategoryNodeModel(category.getParentCategory()); + categoryOrder = category.getCategoryOrder(); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryFormController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryFormController.java index 7bac08a5d..e08d94e18 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryFormController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryFormController.java @@ -18,15 +18,29 @@ */ package org.libreccm.ui.admin.categories; +import org.libreccm.api.Identifier; +import org.libreccm.api.IdentifierParser; +import org.libreccm.categorization.Category; +import org.libreccm.categorization.CategoryManager; +import org.libreccm.categorization.CategoryRepository; import org.libreccm.core.CoreConstants; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; +import org.libreccm.ui.Message; +import org.libreccm.ui.MessageType; +import org.libreccm.ui.admin.AdminMessages; + +import java.util.Arrays; +import java.util.Optional; 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.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; /** * @@ -37,13 +51,95 @@ import javax.ws.rs.Path; @Path("/categorymanager/categories") public class CategoryFormController { + @Inject + private AdminMessages adminMessages; + + @Inject + private CategoryDetailsModel categoryDetailsModel; + + @Inject + private CategoryManager categoryManager; + + @Inject + private CategoryRepository categoryRepository; + + @Inject + private IdentifierParser identifierParser; + + @FormParam("uniqueId") + private String uniqueId; + + @FormParam("name") + private String name; + + @FormParam("enabled") + private boolean enabled; + + @FormParam("visible") + private boolean visisble; + + @FormParam("abstractCategory") + private boolean abstractCategory; + + @FormParam("categoryOrder") + private long categoryOrder; + + @FormParam("parentCategoryIdentifier") + private String parentCategoryIdentifier; + @POST @Path("/new") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) public String createCategory() { - throw new UnsupportedOperationException(); + final Identifier parentIdentifier = identifierParser.parseIdentifier( + parentCategoryIdentifier + ); + final Optional parentResult; + switch (parentIdentifier.getType()) { + case ID: + parentResult = categoryRepository.findById( + Long.parseLong( + parentIdentifier.getIdentifier() + ) + ); + break; + default: + parentResult = categoryRepository.findByUuid( + parentIdentifier.getIdentifier() + ); + break; + } + + if (parentResult.isPresent()) { + final Category parentCategory = parentResult.get(); + final Category category = new Category(); + category.setUniqueId(uniqueId); + category.setName(name); + category.setEnabled(enabled); + category.setVisible(visisble); + category.setAbstractCategory(abstractCategory); + category.setCategoryOrder(categoryOrder); + + categoryRepository.save(category); + categoryManager.addSubCategoryToCategory(category, parentCategory); + + return String.format( + "redirect:categorymanager/categories/ID-%s", + parentCategory.getObjectId() + ); + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(parentCategoryIdentifier) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } @POST @@ -51,8 +147,55 @@ public class CategoryFormController { @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) - public String updateCategory() { - throw new UnsupportedOperationException(); + public String updateCategory( + @PathParam("categoryIdentifierParam") + final String categoryIdentifierParam + ) { + final Identifier identifier = identifierParser.parseIdentifier( + parentCategoryIdentifier + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = categoryRepository.findById( + Long.parseLong( + identifier.getIdentifier() + ) + ); + break; + default: + result = categoryRepository.findByUuid( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Category category = result.get(); + category.setUniqueId(uniqueId); + category.setName(name); + category.setEnabled(enabled); + category.setVisible(visisble); + category.setAbstractCategory(abstractCategory); + category.setCategoryOrder(categoryOrder); + + categoryRepository.save(category); + + return String.format( + "redirect:categorymanager/categories/ID-%s", + category.getObjectId() + ); + } else { + categoryDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categories.not_found.message", + Arrays.asList(categoryIdentifierParam) + ), MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/category-not-found.xhtml"; + } } } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryNodeModel.java b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryNodeModel.java new file mode 100644 index 000000000..d5776222e --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategoryNodeModel.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2020 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.libreccm.ui.admin.categories; + +import org.libreccm.categorization.Category; + +import java.util.Objects; + +/** + * + * @author Jens Pelzetter + */ +public class CategoryNodeModel implements Comparable { + + private final long categoryId; + + private final String uuid; + + private final String uniqueId; + + private final String name; + + private final long categoryOrder; + + public CategoryNodeModel(final Category category) { + Objects.requireNonNull(category); + categoryId = category.getObjectId(); + uuid = category.getUuid(); + uniqueId = category.getUniqueId(); + categoryOrder = category.getCategoryOrder(); + name = category.getName(); + } + + public long getCategoryId() { + return categoryId; + } + + public String getUuid() { + return uuid; + } + + public String getUniqueId() { + return uniqueId; + } + + public String getName() { + return name; + } + + public long getCategoryOrder() { + return categoryOrder; + } + + @Override + public int compareTo(final CategoryNodeModel other) { + int result = Long.compare( + categoryOrder, + Objects.requireNonNull(other).getCategoryOrder() + ); + + if (result == 0) { + result = Objects.compare( + name, + Objects.requireNonNull(other).getName(), + String::compareTo + ); + } + + return result; + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemDetailsModel.java b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemDetailsModel.java index 51b03d8a3..1e7f90bc0 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemDetailsModel.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemDetailsModel.java @@ -29,12 +29,16 @@ import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; import javax.transaction.Transactional; /** * * @author Jens Pelzetter */ +@RequestScoped +@Named("CategoryDetailsModel") public class CategorySystemDetailsModel { private long categorySystemId; @@ -85,6 +89,14 @@ public class CategorySystemDetailsModel { return Collections.unmodifiableList(owners); } + public List getMessages() { + return Collections.unmodifiableList(messages); + } + + public void addMessage(final Message message) { + messages.add(message); + } + @Transactional(Transactional.TxType.REQUIRED) protected void setCategorySystem(final Domain domain) { Objects.requireNonNull(domain); @@ -115,7 +127,7 @@ public class CategorySystemDetailsModel { entry -> entry.getValue() ) ); - + owners = domain .getOwners() .stream() @@ -123,18 +135,7 @@ public class CategorySystemDetailsModel { .sorted() .collect(Collectors.toList()); } - - public List getMessages() { - return Collections.unmodifiableList(messages); - } - - public void addMessage(final Message message) { - messages.add(message); - } - - - private CategorySystemOwnerRow buildOwnerRow( final DomainOwnership ownership ) { @@ -144,7 +145,7 @@ public class CategorySystemDetailsModel { ownerRow.setContext(ownership.getContext()); ownerRow.setOwnerOrder(ownership.getOwnerOrder()); ownerRow.setOwnerAppName(ownership.getOwner().getDisplayName()); - + return ownerRow; } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemFormController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemFormController.java index d45df8c31..bb3acf256 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemFormController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemFormController.java @@ -18,15 +18,29 @@ */ package org.libreccm.ui.admin.categories; +import org.libreccm.api.Identifier; +import org.libreccm.api.IdentifierParser; +import org.libreccm.categorization.Domain; +import org.libreccm.categorization.DomainManager; +import org.libreccm.categorization.DomainRepository; import org.libreccm.core.CoreConstants; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; +import org.libreccm.ui.Message; +import org.libreccm.ui.MessageType; +import org.libreccm.ui.admin.AdminMessages; + +import java.util.Arrays; +import java.util.Optional; 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.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; /** * @@ -36,23 +50,89 @@ import javax.ws.rs.Path; @Path("/categorymanager/categorysystems") @RequestScoped public class CategorySystemFormController { - + + @Inject + private AdminMessages adminMessages; + + @Inject + private CategorySystemDetailsModel categorySystemDetailsModel; + + @Inject + private DomainRepository domainRepository; + + @Inject + private IdentifierParser identifierParser; + + @FormParam("domainKey") + private String domainKey; + + @FormParam("uri") + private String uri; + @POST @Path("/new") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) public String createCategorySystem() { - throw new UnsupportedOperationException(); + final Domain domain = new Domain(); + domain.setDomainKey(domainKey); + domain.setUri(uri); + + domainRepository.save(domain); + + return "redirect:/categorymanager/categorysystems"; } - + @POST @Path("/{categorySystemIdentifier}/edit") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) - public String updateCategorySystem() { - throw new UnsupportedOperationException(); + public String updateCategorySystem( + @PathParam("categorySystemIdentifier") + final String identifierParam + ) { + final Identifier identifier = identifierParser.parseIdentifier( + identifierParam + ); + final Optional result; + switch (identifier.getType()) { + case ID: + result = domainRepository.findById( + Long.parseLong(identifier.getIdentifier()) + ); + break; + case UUID: + result = domainRepository.findByUuid(identifier.getIdentifier()); + break; + default: + result = domainRepository.findByDomainKey( + identifier.getIdentifier() + ); + break; + } + + if (result.isPresent()) { + final Domain domain = result.get(); + domain.setDomainKey(domainKey); + domain.setUri(uri); + domainRepository.save(domain); + + categorySystemDetailsModel.setCategorySystem(domain); + return "org/libreccm/ui/admin/categories/categorysystem-details.xhtml"; + } else { + categorySystemDetailsModel.addMessage( + new Message( + adminMessages.getMessage( + "categorysystems.not_found.message", + Arrays.asList(identifierParam) + ), + MessageType.WARNING + ) + ); + return "org/libreccm/ui/admin/categories/categorysystem-not-found.xhtml"; + } } - + } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemTableRow.java b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemTableRow.java index 6a6839eb9..1ae934808 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemTableRow.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/categories/CategorySystemTableRow.java @@ -19,7 +19,6 @@ package org.libreccm.ui.admin.categories; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -28,7 +27,8 @@ import java.util.Objects; * * @author Jens Pelzetter */ -public class CategorySystemTableRow implements Comparable{ +public class CategorySystemTableRow implements + Comparable { private long domainId; @@ -50,6 +50,10 @@ public class CategorySystemTableRow implements Comparable

#{AdminMessages['categories.label']}

-

Placeholder

+

ToDo

diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/category-details.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/category-details.xhtml new file mode 100644 index 000000000..f828f658d --- /dev/null +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/category-details.xhtml @@ -0,0 +1,25 @@ + + + + + + + + + + + + +
+

#{AdminMessages['categories.label']}

+

ToDo

+
+
+ +
+ diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/category-form.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/category-form.xhtml new file mode 100644 index 000000000..f828f658d --- /dev/null +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/category-form.xhtml @@ -0,0 +1,25 @@ + + + + + + + + + + + + +
+

#{AdminMessages['categories.label']}

+

ToDo

+
+
+ +
+ diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/category-not-found.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/category-not-found.xhtml new file mode 100644 index 000000000..f828f658d --- /dev/null +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/category-not-found.xhtml @@ -0,0 +1,25 @@ + + + + + + + + + + + + +
+

#{AdminMessages['categories.label']}

+

ToDo

+
+
+ +
+ diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-details.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-details.xhtml new file mode 100644 index 000000000..f828f658d --- /dev/null +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-details.xhtml @@ -0,0 +1,25 @@ + + + + + + + + + + + + +
+

#{AdminMessages['categories.label']}

+

ToDo

+
+
+ +
+ diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-form.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-form.xhtml new file mode 100644 index 000000000..f828f658d --- /dev/null +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-form.xhtml @@ -0,0 +1,25 @@ + + + + + + + + + + + + +
+

#{AdminMessages['categories.label']}

+

ToDo

+
+
+ +
+ diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-not-found.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-not-found.xhtml new file mode 100644 index 000000000..f828f658d --- /dev/null +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-not-found.xhtml @@ -0,0 +1,25 @@ + + + + + + + + + + + + +
+

#{AdminMessages['categories.label']}

+

ToDo

+
+
+ +
+ diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystems.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystems.xhtml new file mode 100644 index 000000000..0cc6aae0b --- /dev/null +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystems.xhtml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + +
+

#{AdminMessages['categorysystems.label']}

+ + + + + + + + + + + + + + + + + + + + + +
#{AdminMessages['categorysystems.table.headers.domainKey']}#{AdminMessages['categorysystems.table.headers.uri']}#{AdminMessages['categorysystems.table.headers.version']}#{AdminMessages['categorysystems.table.headers.released']}
+ + #{categorySystem.domainKey} + + #{categorySystem.uri}#{categorySystem.version}#{categorySystem.released}
+ +
+
+ +
+ diff --git a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties index 9e60c46e0..cb8c4676a 100644 --- a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties +++ b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties @@ -3,7 +3,7 @@ systeminformation.label=System Information applications.label=Applications applications.description=Manage application instances imexport.label=Import/Export -categories.label=Categories +categories.label=Categories Manager categories.description=Manage categories configuration.label=Configuration configuration.description=Manage configuration settings @@ -240,3 +240,11 @@ configuration.settings.setting.reset.title=Reset setting {0} configuration.settings.setting.reset.close=Cancel configuration.settings.setting.reset.confirm=Are you sure to set reset setting {1} of configuration {0} to its default value {2}? configuration.settings.setting.reset.submit=Reset to default value +categories.not_found.message=No category identified by {0} available +categorysystems.not_found.message=No category system identified by {0} available +categorysystems.label=Category Systems +categorysystems.add=Add Category System +categorysystems.table.headers.domainKey=Domain Key +categorysystems.table.headers.uri=URI +categorysystems.table.headers.version=Version +categorysystems.table.headers.released=Released diff --git a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties index 7a051b9ef..1385f1a99 100644 --- a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties +++ b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties @@ -3,7 +3,7 @@ systeminformation.label=System Informationen applications.label=Anwendungen applications.description=Verwalten der Anwendungsinstanzen imexport.label=Import/Export -categories.label=Kategorien +categories.label=Kategorienmanager categories.description=Verwaltung der Kategorien configuration.label=Konfiguration configuration.description=Bearbeiten der Konfiguration @@ -240,3 +240,11 @@ configuration.settings.setting.reset.title=Einstellung {0} zur\u00fccksetzen configuration.settings.setting.reset.close=Abbrechen configuration.settings.setting.reset.confirm=Sind Sie sicher, dass die die Einstellung {1} in Konfiguration {0} auf ihren Standardwert {2} zur\u00fccksetzen wollen? configuration.settings.setting.reset.submit=Auf Standardwert zur\u00fccksetzen +categories.not_found.message=Keine Kategorie f\u00fcr den Identifier {0} gefunden +categorysystems.not_found.message=Es wurde keine Kategorien f\u00fcr den Identifier {0} gefunden +categorysystems.label=Kategoriensysteme +categorysystems.add=Neues Kategoriensystem erstellen +categorysystems.table.headers.domainKey=Domain Key +categorysystems.table.headers.uri=URI +categorysystems.table.headers.version=Version +categorysystems.table.headers.released=Freigegeben