Category Management Admin UI

ccm-docs
Jens Pelzetter 2020-11-10 19:37:56 +01:00
parent 1b7bcfea49
commit cbeb1063ee
19 changed files with 1235 additions and 61 deletions

View File

@ -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<Category> 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<Category> 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<Category> 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<Category> 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<Category> 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<Category> 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<Category> 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<Category> 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<Category> 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<Category> 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<Category> 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";
}
}
}

View File

@ -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()
);
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("CategoryDetailsModel")
public class CategoryDetailsModel {
private long categoryId;
private String uuid;
private String uniqueId;
private String name;
private Map<String, String> title;
private Map<String, String> description;
private boolean enabled;
private boolean visible;
private boolean abstractCategory;
private List<CategoryNodeModel> subCategories;
private CategoryNodeModel parentCategory;
private long categoryOrder;
private final List<Message> 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<String, String> getTitle() {
return Collections.unmodifiableMap(title);
}
public Map<String, String> getDescription() {
return Collections.unmodifiableMap(description);
}
public boolean isEnabled() {
return enabled;
}
public boolean isVisible() {
return visible;
}
public boolean isAbstractCategory() {
return abstractCategory;
}
public List<CategoryNodeModel> getSubCategories() {
return Collections.unmodifiableList(subCategories);
}
public CategoryNodeModel getParentCategory() {
return parentCategory;
}
public long getCategoryOrder() {
return categoryOrder;
}
public List<Message> 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();
}
}

View File

@ -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<Category> 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<Category> 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";
}
}
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategoryNodeModel implements Comparable<CategoryNodeModel> {
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;
}
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("CategoryDetailsModel")
public class CategorySystemDetailsModel {
private long categorySystemId;
@ -85,6 +89,14 @@ public class CategorySystemDetailsModel {
return Collections.unmodifiableList(owners);
}
public List<Message> 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<Message> 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;
}

View File

@ -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<Domain> 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";
}
}
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategorySystemTableRow implements Comparable<CategorySystemTableRow>{
public class CategorySystemTableRow implements
Comparable<CategorySystemTableRow> {
private long domainId;
@ -50,6 +50,10 @@ public class CategorySystemTableRow implements Comparable<CategorySystemTableRow
this.domainId = domainId;
}
public String getIdentifier() {
return String.format("ID-%d", domainId);
}
public String getDomainKey() {
return domainKey;
}
@ -89,24 +93,24 @@ public class CategorySystemTableRow implements Comparable<CategorySystemTableRow
void setReleased(final String released) {
this.released = released;
}
@Override
@Override
public int compareTo(final CategorySystemTableRow other) {
int result;
result = Objects.compare(
domainKey, other.getDomainKey(), String::compareTo
);
if (result == 0) {
result = Objects.compare(uri, uri, String::compareTo);
}
if (result == 0) {
result = Objects.compare(
domainId, other.getDomainId(), Long::compare
);
}
return result;
}

View File

@ -290,6 +290,7 @@ public class CategorySystemsController {
final Locale locale = new Locale(localeParam);
domain.getTitle().addValue(locale, value);
domainRepository.save(domain);
categorySystemDetailsModel.setCategorySystem(domain);
return "org/libreccm/ui/admin/categories/categorysystem-form.xhtml";
} else {
@ -343,6 +344,7 @@ public class CategorySystemsController {
final Locale locale = new Locale(localeParam);
domain.getTitle().addValue(locale, value);
domainRepository.save(domain);
categorySystemDetailsModel.setCategorySystem(domain);
return "org/libreccm/ui/admin/categories/categorysystem-form.xhtml";
} else {
@ -395,6 +397,7 @@ public class CategorySystemsController {
final Locale locale = new Locale(localeParam);
domain.getTitle().removeValue(locale);
domainRepository.save(domain);
categorySystemDetailsModel.setCategorySystem(domain);
return "org/libreccm/ui/admin/categories/categorysystem-form.xhtml";
} else {
@ -448,6 +451,7 @@ public class CategorySystemsController {
final Locale locale = new Locale(localeParam);
domain.getDescription().addValue(locale, value);
domainRepository.save(domain);
categorySystemDetailsModel.setCategorySystem(domain);
return "org/libreccm/ui/admin/categories/categorysystem-form.xhtml";
} else {
@ -502,6 +506,7 @@ public class CategorySystemsController {
final Locale locale = new Locale(localeParam);
domain.getDescription().addValue(locale, value);
domainRepository.save(domain);
categorySystemDetailsModel.setCategorySystem(domain);
return "org/libreccm/ui/admin/categories/categorysystem-form.xhtml";
} else {
@ -555,6 +560,7 @@ public class CategorySystemsController {
final Locale locale = new Locale(localeParam);
domain.getDescription().removeValue(locale);
domainRepository.save(domain);
categorySystemDetailsModel.setCategorySystem(domain);
return "org/libreccm/ui/admin/categories/categorysystem-form.xhtml";
} else {
@ -641,8 +647,6 @@ public class CategorySystemsController {
);
return "org/libreccm/ui/admin/categories/categorysystem-not-found.xhtml";
}
// ToDo
}
@POST

View File

@ -17,7 +17,7 @@
<ui:define name="main">
<div class="container">
<h1>#{AdminMessages['categories.label']}</h1>
<p>Placeholder</p>
<p>ToDo</p>
</div>
</ui:define>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/libreccm/ui/admin/ccm-admin.xhtml">
<ui:param name="activePage" value="categories" />
<ui:param name="title" value="#{AdminMessages['categories.label']}" />
<ui:define name="breadcrumb">
<li class="breadcrumb-item active">
#{AdminMessages['categories.label']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<h1>#{AdminMessages['categories.label']}</h1>
<p>ToDo</p>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/libreccm/ui/admin/ccm-admin.xhtml">
<ui:param name="activePage" value="categories" />
<ui:param name="title" value="#{AdminMessages['categories.label']}" />
<ui:define name="breadcrumb">
<li class="breadcrumb-item active">
#{AdminMessages['categories.label']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<h1>#{AdminMessages['categories.label']}</h1>
<p>ToDo</p>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/libreccm/ui/admin/ccm-admin.xhtml">
<ui:param name="activePage" value="categories" />
<ui:param name="title" value="#{AdminMessages['categories.label']}" />
<ui:define name="breadcrumb">
<li class="breadcrumb-item active">
#{AdminMessages['categories.label']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<h1>#{AdminMessages['categories.label']}</h1>
<p>ToDo</p>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/libreccm/ui/admin/ccm-admin.xhtml">
<ui:param name="activePage" value="categories" />
<ui:param name="title" value="#{AdminMessages['categories.label']}" />
<ui:define name="breadcrumb">
<li class="breadcrumb-item active">
#{AdminMessages['categories.label']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<h1>#{AdminMessages['categories.label']}</h1>
<p>ToDo</p>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/libreccm/ui/admin/ccm-admin.xhtml">
<ui:param name="activePage" value="categories" />
<ui:param name="title" value="#{AdminMessages['categories.label']}" />
<ui:define name="breadcrumb">
<li class="breadcrumb-item active">
#{AdminMessages['categories.label']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<h1>#{AdminMessages['categories.label']}</h1>
<p>ToDo</p>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/libreccm/ui/admin/ccm-admin.xhtml">
<ui:param name="activePage" value="categories" />
<ui:param name="title" value="#{AdminMessages['categories.label']}" />
<ui:define name="breadcrumb">
<li class="breadcrumb-item active">
#{AdminMessages['categories.label']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<h1>#{AdminMessages['categories.label']}</h1>
<p>ToDo</p>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:xlink="http://www.w3.org/1999/xlink">
<ui:composition template="/WEB-INF/views/org/libreccm/ui/admin/ccm-admin.xhtml">
<ui:param name="activePage" value="categories" />
<ui:param name="title" value="#{AdminMessages['categories.label']}" />
<ui:define name="breadcrumb">
<li class="breadcrumb-item active">
#{AdminMessages['categories.label']}
</li>
<li class="breadcrumb-item active">
#{AdminMessages['categories.label']}
</li>
<li class="breadcrumb-item active">
#{AdminMessages['categorysystems.label']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<h1>#{AdminMessages['categorysystems.label']}</h1>
<div class="text-right">
<a class="btn btn-secondary"
href="#{mvc.uri('CategorySystemsController#newCategorySystem')}">
<svg class="bi"
width="1em"
height="1em"
fill="currentColor">
<use xlink:href="#{request.contextPath}/assets/bootstrap/bootstrap-icons.svg#circle-plus" />
</svg>
<span>#{AdminMessages['categorysystems.add']}</span>
</a>
</div>
<table class="table table-hover categorysystems-table">
<thead class="thead-light">
<tr>
<th>#{AdminMessages['categorysystems.table.headers.domainKey']}</th>
<th>#{AdminMessages['categorysystems.table.headers.uri']}</th>
<th>#{AdminMessages['categorysystems.table.headers.version']}</th>
<th>#{AdminMessages['categorysystems.table.headers.released']}</th>
</tr>
</thead>
<tbody>
<c:forEach items="#{CategorySystemsTableModel.categorySystems}"
var="categorySystem">
<tr>
<td>
<a href="#{mvc.uri('CategorySystemsController#getCategorySystemDetails', categorySystem.identifier)}">
#{categorySystem.domainKey}
</a>
</td>
<td>#{categorySystem.uri}</td>
<td>#{categorySystem.version}</td>
<td>#{categorySystem.released}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -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

View File

@ -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