From fcea2c3fa10734bedd7003cc48a14b631162fc3b Mon Sep 17 00:00:00 2001 From: jensp Date: Wed, 5 Jul 2017 18:03:24 +0000 Subject: [PATCH] CCM NG/ccm-core: Some things for the Vaadin prototype git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4844 8810af33-2d31-482b-a856-94f89814c4df --- .../ui/usersgroupsroles/GroupDetails.java | 5 +- .../GroupRolesController.java | 8 +- .../ui/usersgroupsroles/UserDetails.java | 73 ++++++++++- .../UserGroupsDataProvider.java | 118 +++++++++++++++++ .../usersgroupsroles/UserRolesController.java | 92 ++++++++++++++ .../UserRolesTableDataProvider.java | 119 ++++++++++++++++++ 6 files changed, 404 insertions(+), 11 deletions(-) create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserGroupsDataProvider.java create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserRolesController.java create mode 100644 ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserRolesTableDataProvider.java diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupDetails.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupDetails.java index 6e2d3c1ab..41051cc4b 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupDetails.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupDetails.java @@ -239,8 +239,7 @@ public class GroupDetails extends Window { rolesGrid.setWidth("100%"); - final RoleRepository roleRepository = cdiUtil - .findBean(RoleRepository.class); + final RoleRepository roleRepo = cdiUtil.findBean(RoleRepository.class); final HeaderRow rolesGridHeader = rolesGrid.prependHeaderRow(); final Button addRoleButton = new Button("Add role"); @@ -251,7 +250,7 @@ public class GroupDetails extends Window { "Select role(s) to add to group", "Add selected role(s) to group", usersGroupsRoles, - roleRepository.findByParty(group), + roleRepo.findByParty(group), (selectedRoles -> { selectedRoles.forEach(role -> { rolesController.assignRoleToGroup(role, group); diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupRolesController.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupRolesController.java index cfcb9d739..5a409e63b 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupRolesController.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/GroupRolesController.java @@ -19,7 +19,6 @@ package org.libreccm.admin.ui.usersgroupsroles; import org.libreccm.security.Group; -import org.libreccm.security.GroupManager; import org.libreccm.security.GroupRepository; import org.libreccm.security.Role; import org.libreccm.security.RoleManager; @@ -47,9 +46,6 @@ class GroupRolesController { @Inject private GroupRepository groupRepo; - @Inject - private GroupManager groupManager; - @Transactional(Transactional.TxType.REQUIRED) protected void assignRolesToGroup(final Set roles, final Group group) { @@ -77,7 +73,7 @@ class GroupRolesController { @Transactional(Transactional.TxType.REQUIRED) protected void removeRoleFromGroup(final Role role, final Group group) { - + final Role theRole = roleRepo .findById(role.getRoleId()) .orElseThrow(() -> new IllegalArgumentException(String @@ -90,7 +86,7 @@ class GroupRolesController { .format("No group with id %d in the database. " + "Where did that ID come from?", group.getPartyId()))); - + roleManager.removeRoleFromParty(theRole, theGroup); } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserDetails.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserDetails.java index 4f69087c6..6abe01407 100644 --- a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserDetails.java +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserDetails.java @@ -20,15 +20,24 @@ package org.libreccm.admin.ui.usersgroupsroles; import com.arsdigita.ui.admin.AdminUiConstants; +import com.vaadin.cdi.CDIUI; import com.vaadin.icons.VaadinIcons; -import com.vaadin.ui.Accordion; import com.vaadin.ui.Button; import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.TabSheet; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; +import com.vaadin.ui.components.grid.HeaderCell; +import com.vaadin.ui.components.grid.HeaderRow; +import com.vaadin.ui.renderers.ButtonRenderer; +import com.vaadin.ui.themes.ValoTheme; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Role; +import org.libreccm.security.RoleRepository; import org.libreccm.security.User; import org.libreccm.security.UserManager; import org.libreccm.security.UserRepository; @@ -43,6 +52,12 @@ public class UserDetails extends Window { private static final long serialVersionUID = 7852981019990845392L; + private static final String COL_GROUP_NAME = "group_name"; + private static final String COL_GROUP_REMOVE = "group_remove"; + + private static final String COL_ROLE_NAME = "role_name"; + private static final String COL_ROLE_REMOVE = "role_remove"; + private final UsersGroupsRoles usersGroupsRoles; private final User user; private final UserRepository userRepo; @@ -124,10 +139,64 @@ public class UserDetails extends Window { final VerticalLayout layout = new VerticalLayout(formLayout, editButton); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + + final UserRolesController rolesController = cdiUtil + .findBean(UserRolesController.class); + final Grid rolesGrid = new Grid<>(); + rolesGrid + .addColumn(Role::getName) + .setId(COL_ROLE_NAME) + .setCaption("Role name"); + rolesGrid + .addColumn(role -> bundle + .getString("ui.groups.roles.remove"), + new ButtonRenderer<>(event -> { + rolesController + .removeRoleFromUser(event.getItem(), user); + rolesGrid.getDataProvider().refreshAll(); + })) + .setId(COL_ROLE_REMOVE); + + rolesGrid.setWidth("100%"); + + final RoleRepository roleRepo = cdiUtil.findBean(RoleRepository.class); + + final HeaderRow rolesGridHeader = rolesGrid.prependHeaderRow(); + final Button addRoleButton = new Button("Add role"); + addRoleButton.setIcon(VaadinIcons.PLUS); + addRoleButton.setStyleName(ValoTheme.BUTTON_TINY); + addRoleButton.addClickListener(event -> { + final RoleSelector roleSelector = new RoleSelector( + "Select role(s) to add to group", + "Add selected role(s) to group", + usersGroupsRoles, + roleRepo.findByParty(user), + (selectedRoles -> { + selectedRoles.forEach(role -> { + rolesController.assignRoleToUser(role, user); + rolesGrid.getDataProvider().refreshAll(); + }); + })); + roleSelector.center(); + roleSelector.setWidth("80%"); + UI.getCurrent().addWindow(roleSelector); + }); + final HeaderCell rolesGridHeaderCell = rolesGridHeader + .join(COL_ROLE_NAME, + COL_ROLE_REMOVE); + rolesGridHeaderCell + .setComponent(new HorizontalLayout(addRoleButton)); + + final UserRolesTableDataProvider rolesDataProvider = cdiUtil + .findBean(UserRolesTableDataProvider.class); + rolesDataProvider.setUser(user); + rolesGrid.setDataProvider(rolesDataProvider); + final TabSheet tabs = new TabSheet(); tabs.addTab(layout, "Details"); tabs.addTab(layout, "Groups"); - tabs.addTab(layout, "Roles"); + tabs.addTab(rolesGrid, "Roles"); setContent(tabs); } diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserGroupsDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserGroupsDataProvider.java new file mode 100644 index 000000000..eb1b3ce21 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserGroupsDataProvider.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2017 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.admin.ui.usersgroupsroles; + +import com.vaadin.cdi.ViewScoped; +import com.vaadin.data.provider.AbstractDataProvider; +import com.vaadin.data.provider.Query; +import org.libreccm.security.Group; +import org.libreccm.security.GroupMembership; +import org.libreccm.security.User; + +import java.net.URI; +import java.util.Objects; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.Root; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@ViewScoped +class UserGroupsDataProvider extends AbstractDataProvider { + + private static final long serialVersionUID = 3321330114174366998L; + + @Inject + private EntityManager entityManager; + + private User user; + + @Override + public boolean isInMemory() { + return false; + } + + @Transactional(Transactional.TxType.REQUIRED) + @Override + public int size(final Query query) { + + Objects.requireNonNull(user, + "This data provider needs to be initalized " + + "by calling setUser(User) before calling " + + "the count method."); + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = builder + .createQuery(Long.class); + + final Root from = criteriaQuery + .from(GroupMembership.class); + + criteriaQuery + .select(builder.count(from)) + .where(builder.equal(from.get("member"), user)); + + return entityManager + .createQuery(criteriaQuery) + .getSingleResult() + .intValue(); + } + + @Transactional(Transactional.TxType.REQUIRED) + @Override + public Stream fetch(final Query query) { + + Objects.requireNonNull(user, + "This data provider needs to be initalized " + + "by calling setUser(User) before calling " + + "the fetch method."); + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + + final CriteriaQuery criteriaQuery = builder + .createQuery(GroupMembership.class); + final Root from = criteriaQuery + .from(GroupMembership.class); + final Join join = from.join("group"); + criteriaQuery + .where(builder.equal(from.get("member"), user)) + .orderBy(builder.asc(join.get("name"))); + + return entityManager + .createQuery(criteriaQuery) + .setMaxResults(query.getLimit()) + .setFirstResult(query.getOffset()) + .getResultList() + .stream() + .map(GroupMembership::getGroup); + } + + public void setUser(final User user) { + this.user = user; + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserRolesController.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserRolesController.java new file mode 100644 index 000000000..8548914b2 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserRolesController.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2017 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.admin.ui.usersgroupsroles; + +import org.libreccm.security.Role; +import org.libreccm.security.RoleManager; +import org.libreccm.security.RoleRepository; +import org.libreccm.security.User; +import org.libreccm.security.UserRepository; + +import java.util.Set; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +class UserRolesController { + + @Inject + private RoleRepository roleRepo; + + @Inject + private RoleManager roleManager; + + @Inject + private UserRepository userRepo; + + @Transactional(Transactional.TxType.REQUIRED) + protected void assignRolesToUser(final Set roles, final User user) { + + roles.forEach(role -> assignRoleToUser(role, user)); + } + + @Transactional(Transactional.TxType.REQUIRED) + protected void assignRoleToUser(final Role role, final User user) { + + final Role theRole = roleRepo + .findById(role.getRoleId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No Role with ID %d in the database.", + role.getRoleId()))); + + final User theUser = userRepo + .findById(user.getPartyId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No user with ID %d in the database. ", + user.getPartyId()))); + + roleManager.assignRoleToParty(role, theUser); + } + + @Transactional(Transactional.TxType.REQUIRED) + protected void removeRoleFromUser(final Role role, final User user) { + + final Role theRole = roleRepo + .findById(role.getRoleId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No Role with ID %d in the database.", + role.getRoleId()))); + + final User theUser = userRepo + .findById(user.getPartyId()) + .orElseThrow(() -> new IllegalArgumentException(String + .format("No group with id %d in the database. " + + "Where did that ID come from?", + user.getPartyId()))); + + roleManager.removeRoleFromParty(theRole, theUser); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserRolesTableDataProvider.java b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserRolesTableDataProvider.java new file mode 100644 index 000000000..0449aea41 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/admin/ui/usersgroupsroles/UserRolesTableDataProvider.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2017 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.admin.ui.usersgroupsroles; + +import com.vaadin.cdi.ViewScoped; +import com.vaadin.data.provider.AbstractDataProvider; +import com.vaadin.data.provider.Query; +import org.libreccm.security.Role; +import org.libreccm.security.RoleMembership; +import org.libreccm.security.User; + +import java.util.Objects; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.Root; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@ViewScoped +class UserRolesTableDataProvider + extends AbstractDataProvider { + + private static final long serialVersionUID = -378530060060592701L; + + @Inject + private EntityManager entityManager; + + private User user; + + @Override + public boolean isInMemory() { + return false; + } + + @Transactional(Transactional.TxType.REQUIRED) + @Override + public int size(final Query query) { + + Objects.requireNonNull(user, + "This data provider needs to be initalized " + + "by calling setUser(User) before calling" + + "the count method."); + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + final CriteriaQuery criteriaQuery = builder + .createQuery(Long.class); + + final Root from = criteriaQuery + .from(RoleMembership.class); + + criteriaQuery + .select(builder.count(from)) + .where(builder.equal(from.get("member"), user)); + + return entityManager + .createQuery(criteriaQuery) + .getSingleResult() + .intValue(); + } + + @Transactional(Transactional.TxType.REQUIRED) + @Override + public Stream fetch(final Query query) { + Objects.requireNonNull(user, + "This data provider needs to be initalized " + + "by calling setUser(User) before calling" + + "the fetch method."); + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + + final CriteriaQuery criteriaQuery = builder + .createQuery(RoleMembership.class); + final Root from = criteriaQuery + .from(RoleMembership.class); + final Join join = from.join("role"); + criteriaQuery + .where(builder.equal(from.get("member"), user)) + .orderBy(builder.asc(join.get("name"))); + + return entityManager + .createQuery(criteriaQuery) + .setMaxResults(query.getLimit()) + .setFirstResult(query.getOffset()) + .getResultList() + .stream() + .map(RoleMembership::getRole); + } + + public void setUser(final User user) { + Objects.requireNonNull(user); + + this.user = user; + } + +}