From 403fa93dfaef22c57a95e1253ad71b9e8c2fb106 Mon Sep 17 00:00:00 2001 From: jensp Date: Thu, 14 Apr 2016 09:18:17 +0000 Subject: [PATCH] CCM NG: Missing file git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3990 8810af33-2d31-482b-a856-94f89814c4df --- .../usersgroupsroles/groups/GroupAdmin.java | 133 ++++++++++++ .../usersgroupsroles/groups/GroupForm.java | 178 ++++++++++++++++ .../usersgroupsroles/groups/GroupsTable.java | 191 ++++++++++++++++++ .../java/org/libreccm/security/Group.java | 2 +- .../ui/admin/AdminResources.properties | 7 + .../ui/admin/AdminResources_de.properties | 7 + .../ui/admin/AdminResources_en.properties | 7 + .../ui/admin/AdminResources_fr.properties | 7 + 8 files changed, 531 insertions(+), 1 deletion(-) create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAdmin.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupForm.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupsTable.java diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAdmin.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAdmin.java new file mode 100644 index 000000000..14fe811ec --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupAdmin.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2016 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 com.arsdigita.ui.admin.usersgroupsroles.groups; + +import com.arsdigita.bebop.ActionLink; +import com.arsdigita.bebop.BoxPanel; +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.Page; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.form.Submit; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.ui.login.UserForm; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class GroupAdmin extends BoxPanel { + + private final static Logger LOGGER = LogManager.getLogger(GroupAdmin.class); + + private final StringParameter groupIdParameter; + private final ParameterSingleSelectionModel selectedGroupId; + private final TextField groupsTableFilter; + private final BoxPanel groupsTablePanel; + private final GroupsTable groupsTable; + private final GroupForm groupForm; + + public GroupAdmin() { + super(); + + setBasicProperties(); + + groupsTablePanel = new BoxPanel(); + groupsTablePanel.setIdAttr("groupsTablePanel"); + + final Form filterForm = new Form("groupsTableFilterForm"); + groupsTableFilter = new TextField("groupsTableFilter"); + groupsTableFilter.setLabel(new GlobalizedMessage( + "ui.admin.groups.table.filter.term", ADMIN_BUNDLE)); + filterForm.add(groupsTableFilter); + filterForm.add(new Submit(new GlobalizedMessage( + "ui.admin.groups.filter.submit", ADMIN_BUNDLE))); + final ActionLink clearLink = new ActionLink(new GlobalizedMessage( + "ui.admin.groups.table.filter.clear", ADMIN_BUNDLE)); + clearLink.addActionListener(e -> { + final PageState state = e.getPageState(); + groupsTableFilter.setValue(state, null); + }); + filterForm.add(clearLink); + groupsTablePanel.add(filterForm); + + groupIdParameter = new StringParameter("selected_group_id"); + selectedGroupId = new ParameterSingleSelectionModel<>( + groupIdParameter); + + groupsTable = new GroupsTable(this, groupsTableFilter, selectedGroupId); + groupsTablePanel.add(groupsTable); + + final ActionLink addNewGroupLink = new ActionLink(new GlobalizedMessage( + "ui.admin.new_group_link", ADMIN_BUNDLE)); + addNewGroupLink.addActionListener(e -> { + showGroupForm(e.getPageState()); + }); + groupsTablePanel.add(addNewGroupLink); + + add(groupsTablePanel); + + groupForm = new GroupForm(this, selectedGroupId); + add(groupForm); + + } + + @Override + public void register(final Page page) { + super.register(page); + + page.addGlobalStateParam(groupIdParameter); + + page.setVisibleDefault(groupsTablePanel, true); + page.setVisibleDefault(groupForm, false); + } + + private void setBasicProperties() { + setIdAttr("groupAdmin"); + + } + + protected void showGroupDetails(final PageState state) { + groupsTablePanel.setVisible(state, false); + groupForm.setVisible(state, false); + } + + protected void hideGroupDetails(final PageState state) { + groupsTablePanel.setVisible(state, true); + groupForm.setVisible(state, false); + } + + protected void showGroupForm(final PageState state) { + groupsTablePanel.setVisible(state, false); + groupForm.setVisible(state, true); + } + + protected void hideGroupForm(final PageState state) { + groupsTablePanel.setVisible(state, true); + groupForm.setVisible(state, false); + } + + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupForm.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupForm.java new file mode 100644 index 000000000..3b3e9f175 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupForm.java @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2016 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 com.arsdigita.ui.admin.usersgroupsroles.groups; + +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.FormData; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.RequestLocal; +import com.arsdigita.bebop.SaveCancelSection; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.parameters.CancellableValidationListener; +import com.arsdigita.bebop.parameters.NotEmptyValidationListener; +import com.arsdigita.bebop.parameters.StringInRangeValidationListener; +import com.arsdigita.globalization.GlobalizedMessage; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Group; +import org.libreccm.security.GroupRepository; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class GroupForm extends Form { + + private static final String GROUP_NAME = "groupname"; + + private final GroupAdmin groupAdmin; + private final ParameterSingleSelectionModel selectedGroupId; + private final TextField groupName; + private final SaveCancelSection saveCancelSection; + + public GroupForm( + final GroupAdmin groupAdmin, + final ParameterSingleSelectionModel selectedGroupId) { + super("groupform"); + + this.groupAdmin = groupAdmin; + this.selectedGroupId = selectedGroupId; + + add(new Label(e -> { + final PageState state = e.getPageState(); + + final Label target = (Label) e.getTarget(); + + final String selectedGroupIdStr = selectedGroupId.getSelectedKey( + state); + if (selectedGroupIdStr == null || selectedGroupIdStr.isEmpty()) { + target.setLabel(new GlobalizedMessage( + "ui.admin.group.create_new", + ADMIN_BUNDLE)); + } else { + target.setLabel(new GlobalizedMessage("ui.admin.group.edit", + ADMIN_BUNDLE)); + } + })); + + final RequestLocal cancelled = new RequestLocal() { + @Override + public Object initialValue(final PageState state) { + return !saveCancelSection.getSaveButton().isSelected(state); + } + }; + + groupName = new TextField(GROUP_NAME); + groupName.setLabel(new GlobalizedMessage("ui.admin.group.name", + ADMIN_BUNDLE)); + groupName.addValidationListener(new CancellableValidationListener( + new NotEmptyValidationListener( + new GlobalizedMessage( + "ui.admin.group.name.error.notempty", + ADMIN_BUNDLE)), + cancelled)); + groupName.addValidationListener( + new CancellableValidationListener( + new StringInRangeValidationListener( + 1, + 256, + new GlobalizedMessage( + "ui.admin.group.name.error.length", + ADMIN_BUNDLE)), + cancelled)); + + add(groupName); + + saveCancelSection = new SaveCancelSection(); + add(saveCancelSection); + + addValidationListener(e -> { + final PageState state = e.getPageState(); + + if (saveCancelSection.getSaveButton().isSelected(state)) { + final FormData data = e.getFormData(); + + final String groupNameData = data.getString(GROUP_NAME); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final GroupRepository groupRepository = cdiUtil.findBean( + GroupRepository.class); + + if (groupRepository.findByName(groupNameData) != null) { + data.addError(new GlobalizedMessage( + "ui.admin.group.error.name_already_in_use", + ADMIN_BUNDLE)); + } + } + }); + + addInitListener(e -> { + final PageState state = e.getPageState(); + + final String selectedGroupIdStr = selectedGroupId.getSelectedKey( + state); + + if (selectedGroupIdStr != null && !selectedGroupIdStr.isEmpty()) { + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final GroupRepository groupRepository = cdiUtil.findBean( + GroupRepository.class); + + final Group group = groupRepository.findById(Long.parseLong( + selectedGroupIdStr)); + groupName.setValue(state, group.getName()); + } + }); + + addProcessListener(e -> { + final PageState state = e.getPageState(); + + if (saveCancelSection.getSaveButton().isSelected(state)) { + final FormData data = e.getFormData(); + final String groupNameData = data.getString(GROUP_NAME); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final GroupRepository groupRepository = cdiUtil.findBean( + GroupRepository.class); + + final String selectedGroupIdStr = selectedGroupId. + getSelectedKey(state); + if (selectedGroupIdStr == null + || selectedGroupIdStr.isEmpty()) { + final Group group = new Group(); + group.setName(groupNameData); + + groupRepository.save(group); + } else { + final Group group = groupRepository.findById(Long.parseLong( + selectedGroupIdStr)); + group.setName(groupNameData); + + groupRepository.save(group); + } + } + + groupAdmin.hideGroupDetails(state); + }); + + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupsTable.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupsTable.java new file mode 100644 index 000000000..d8248934c --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/groups/GroupsTable.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2016 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 com.arsdigita.ui.admin.usersgroupsroles.groups; + +import com.arsdigita.bebop.Component; +import com.arsdigita.bebop.ControlLink; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.ParameterSingleSelectionModel; +import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.event.TableActionEvent; +import com.arsdigita.bebop.event.TableActionListener; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.table.TableCellRenderer; +import com.arsdigita.bebop.table.TableColumn; +import com.arsdigita.bebop.table.TableColumnModel; +import com.arsdigita.bebop.table.TableModel; +import com.arsdigita.bebop.table.TableModelBuilder; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.util.LockableImpl; +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Group; +import org.libreccm.security.GroupRepository; + +import static com.arsdigita.ui.admin.AdminUiConstants.*; + +/** + * + * @author Jens Pelzetter + */ +public class GroupsTable extends Table { + + private static final Logger LOGGER = LogManager.getLogger(GroupsTable.class); + + private static final int COL_GROUP_NAME = 0; + private static final int COL_DELETE = 1; + + private final TextField groupsTableFilter; + private final ParameterSingleSelectionModel selectedGroupId; + + public GroupsTable( + final GroupAdmin parent, + final TextField groupsTableFilter, + final ParameterSingleSelectionModel selectedGroupId) { + super(); + + setIdAttr("groupsTable"); + + this.groupsTableFilter = groupsTableFilter; + this.selectedGroupId = selectedGroupId; + + setEmptyView(new Label(new GlobalizedMessage( + "ui.admin.groups.table.no_groups", ADMIN_BUNDLE))); + + final TableColumnModel columnModel = getColumnModel(); + columnModel.add(new TableColumn( + COL_GROUP_NAME, + new Label(new GlobalizedMessage("ui.admin.groups.table.name", + ADMIN_BUNDLE)))); + columnModel.add(new TableColumn( + COL_DELETE, + new Label(new GlobalizedMessage("ui.admin.groups.table.delete", + ADMIN_BUNDLE)))); + + columnModel.get(COL_GROUP_NAME).setCellRenderer( + new TableCellRenderer() { + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + return new ControlLink((String) value); + } + }); + + addTableActionListener(new TableActionListener() { + @Override + public void cellSelected(final TableActionEvent event) { + final PageState state = event.getPageState(); + final String key = (String) event.getRowKey(); + selectedGroupId.setSelectedKey(state, key); + parent.showGroupDetails(state); + } + + @Override + public void headSelected(final TableActionEvent event) { + //Nothing + } + }); + + setModelBuilder(new GroupsTableModelBuilder()); + } + + private class GroupsTableModelBuilder extends LockableImpl + implements TableModelBuilder { + + @Override + public TableModel makeModel(final Table table, + final PageState state) { + table.getRowSelectionModel().clearSelection(state); + + return new GroupsTableModel(state); + } + } + + private class GroupsTableModel implements TableModel { + + private final List groups; + private int index = -1; + + public GroupsTableModel(final PageState state) { + LOGGER.debug("Creating GroupsTableModel"); + final String filterTerm = (String) groupsTableFilter.getValue(state); + LOGGER.debug("Value of filter is: \"{}\"", filterTerm); + final GroupRepository groupRepository = CdiUtil.createCdiUtil(). + findBean(GroupRepository.class); + if (filterTerm == null || filterTerm.isEmpty()) { + groups = groupRepository.findAllOrderedByGroupName(); + LOGGER.debug("Found {} groups in database.", groups.size()); + } else { + groups = groupRepository.searchGroupByName(filterTerm); + LOGGER.debug("Found {} groups in database which match the " + + "filter \"{}\".", + groups.size(), + filterTerm); + } + } + + @Override + public int getColumnCount() { + return 2; + } + + @Override + public boolean nextRow() { + index++; + LOGGER.debug("Next row called. Index is now {}", index); + return index < groups.size(); + } + + @Override + public Object getElementAt(final int columnIndex) { + LOGGER.debug("Getting element for row {}, column {}...", + index, + columnIndex); + final Group group = groups.get(index); + switch (columnIndex) { + case COL_GROUP_NAME: + return group.getName(); + case COL_DELETE: + return new Label(new GlobalizedMessage( + "ui.admin.groups.table.delete", ADMIN_BUNDLE)); + default: + throw new IllegalArgumentException( + "Not a valid column index"); + } + } + + @Override + public Object getKeyAt(final int columnIndex) { + LOGGER.debug("Getting key for row {}, column {}...", + index, + columnIndex); + return groups.get(index).getPartyId(); + } + + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/security/Group.java b/ccm-core/src/main/java/org/libreccm/security/Group.java index 11105b05d..54e391344 100644 --- a/ccm-core/src/main/java/org/libreccm/security/Group.java +++ b/ccm-core/src/main/java/org/libreccm/security/Group.java @@ -98,7 +98,7 @@ public class Group extends Party implements Serializable { @XmlElement(name = "group-membership", namespace = CORE_XML_NS) private Set memberships = new HashSet<>(); - protected Group() { + public Group() { super(); } diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties index 1ea8cc59e..10f4f2cac 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties @@ -245,3 +245,10 @@ ui.admin.groups.table.filter.clear=Clear filter ui.admin.groups.table.no_groups=No groups available ui.admin.groups.table.name=Name ui.admin.groups.table.delete=Delete +ui.admin.new_group_link=Create a new group +ui.admin.group.name.error.notempty=The name of a group can't be empty. +ui.admin.group.name.error.length=the maximum length of a group name is 256 characters. +ui.admin.group.error.name_already_in_use=The provided group name is already in use. +ui.admin.group.create_new=Create new group +ui.admin.group.edit=Edit group +ui.admin.group.name=Name of group diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties index b581ae5c3..bf20c58e3 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties @@ -245,3 +245,10 @@ ui.admin.groups.table.filter.clear=Filter zur\u00fccksetzen ui.admin.groups.table.no_groups=Keine Gruppen gefunden ui.admin.groups.table.name=Name ui.admin.groups.table.delete=Delete +ui.admin.new_group_link=Neue Gruppe anlegen +ui.admin.group.name.error.notempty=Der Name einer Gruppe kann nicht leer sein. +ui.admin.group.name.error.length=Der Name einer Gruppe darf maximal 256 Zeichen lang sein. +ui.admin.group.error.name_already_in_use=Der angegebene Gruppen-Name wird bereits verwendet. +ui.admin.group.create_new=Neue Gruppe anlegen +ui.admin.group.edit=Gruppe bearbeiten +ui.admin.group.name=Name der Gruppe diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties index 0dac6d456..5fd4509a7 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties @@ -218,3 +218,10 @@ ui.admin.groups.table.filter.clear=Clear filter ui.admin.groups.table.no_groups=No groups available ui.admin.groups.table.name=Name ui.admin.groups.table.delete=Delete +ui.admin.new_group_link=Create a new group +ui.admin.group.name.error.notempty=The name of a group can't be empty. +ui.admin.group.name.error.length=the maximum length of a group name is 256 characters. +ui.admin.group.error.name_already_in_use=The provided group name is already in use. +ui.admin.group.create_new=Create new group +ui.admin.group.edit=Edit group +ui.admin.group.name=Name of group diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties index fa6d3a339..70845f626 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties @@ -209,3 +209,10 @@ ui.admin.groups.table.filter.clear=Clear filter ui.admin.groups.table.no_groups=No groups available ui.admin.groups.table.name=Name ui.admin.groups.table.delete=Delete +ui.admin.new_group_link=Create a new group +ui.admin.group.name.error.notempty=The name of a group can't be empty. +ui.admin.group.name.error.length=the maximum length of a group name is 256 characters. +ui.admin.group.error.name_already_in_use=The provided group name is already in use. +ui.admin.group.create_new=Create new group +ui.admin.group.edit=Edit group +ui.admin.group.name=Name of group