/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.zaproxy.zap.view.widgets; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import org.parosproxy.paros.control.Control; import org.zaproxy.zap.extension.users.ExtensionUserManagement; import org.zaproxy.zap.users.User; /** * A {@link JTable} based widget that displays the list of {@link User Users} for a given context * and allows selection of multiple users. * <p> * <strong>NOTE:</strong> Does not automatically refresh when the Users have changed. For this, make sure you * manually call {@link #reloadUsers(int)}. * */ public class UsersMultiSelectTable extends JTable { private static final long serialVersionUID = 7473652413044348214L; private static ExtensionUserManagement usersExtension; private UsersSelectTableModel tableModel; /** * Instantiates a new multi user select table. * * @param contextId the context id */ public UsersMultiSelectTable(int contextId) { super(); // Force loading the UserManagement extension to make sure it's enabled. loadUsersManagementExtension(); // Setup the table this.setTableHeader(null); reloadUsers(contextId); // Note: Adjust the column size after loading the initial model so the table has the // columnModel generated this.getColumnModel().getColumn(0).setMaxWidth(40); } private static void loadUsersManagementExtension() { if (usersExtension == null) { usersExtension = Control.getSingleton().getExtensionLoader() .getExtension(ExtensionUserManagement.class); if (usersExtension == null) throw new IllegalStateException( "Trying to create MultiUserSelectBox without the ExtensionUsersManagement" + " being enabled."); } } /** * Reloads/refreshes the list of {@link User users} associated to the context. * @param contextId the ID of the context */ public void reloadUsers(int contextId) { List<User> users = new ArrayList<User>(usersExtension.getContextUserAuthManager(contextId).getUsers()); tableModel = new UsersSelectTableModel(users); this.setModel(tableModel); } /** * Gets the selected users. This method will generates and returns a new {@link List} of users * for each call, so method callers should cache the returned value when possible. * * @return the selected users */ public List<User> getSelectedUsers() { return tableModel.generateSelectedUsers(); } /** * Gets the number of selected users. * * @return the selected users count */ public int getSelectedUsersCount() { return tableModel.getSelectedUsersCount(); } /** * Allows adding a 'custom' users besides the ones already loaded from the context. Can be used, * for example, to add a 'Any User' entry. * @param user the custom user to add */ public void addCustomUser(User user) { tableModel.addUser(user); } /** * Table model used for selecting a set of users. */ private static class UsersSelectTableModel extends AbstractTableModel { private static final long serialVersionUID = -2187948264137599317L; private Set<Integer> selectedUsersIds; private List<User> users; public UsersSelectTableModel(List<User> users) { super(); this.users = users; this.selectedUsersIds = new HashSet<Integer>(this.users.size()); } public List<User> generateSelectedUsers() { List<User> selectedUsers = new ArrayList<User>(selectedUsersIds.size()); for (User u : users) if (selectedUsersIds.contains(u.getId())) selectedUsers.add(u); return selectedUsers; } public int getSelectedUsersCount() { return selectedUsersIds.size(); } public void addUser(User u) { this.users.add(u); fireTableRowsInserted(this.users.size() - 1, this.users.size() - 1); } @Override public int getRowCount() { return users.size(); } @Override public int getColumnCount() { return 2; } @Override public Object getValueAt(int rowIndex, int columnIndex) { switch (columnIndex) { case 0: return selectedUsersIds.contains(users.get(rowIndex).getId()); case 1: return users.get(rowIndex).getName(); default: return null; } } @Override public Class<?> getColumnClass(int columnIndex) { switch (columnIndex) { case 0: return Boolean.class; case 1: return String.class; default: return super.getColumnClass(columnIndex); } } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { // Just the enable/disable return (columnIndex == 0); } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (columnIndex == 0) { if (aValue instanceof Boolean) { if ((Boolean) aValue) selectedUsersIds.add(users.get(rowIndex).getId()); else selectedUsersIds.remove(users.get(rowIndex).getId()); fireTableCellUpdated(rowIndex, columnIndex); } } } } }