package org.ovirt.engine.ui.uicommonweb.models.users;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.ovirt.engine.core.common.VdcActionUtils;
import org.ovirt.engine.core.common.action.AddGroupParameters;
import org.ovirt.engine.core.common.action.AddUserParameters;
import org.ovirt.engine.core.common.action.AttachEntityToTagParameters;
import org.ovirt.engine.core.common.action.IdParameters;
import org.ovirt.engine.core.common.action.VdcActionParametersBase;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.businessentities.Cluster;
import org.ovirt.engine.core.common.businessentities.Tags;
import org.ovirt.engine.core.common.businessentities.aaa.DbGroup;
import org.ovirt.engine.core.common.businessentities.aaa.DbUser;
import org.ovirt.engine.core.common.interfaces.SearchType;
import org.ovirt.engine.core.common.queries.SearchParameters;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.searchbackend.SearchObjects;
import org.ovirt.engine.core.searchbackend.VdcUserConditionFieldAutoCompleter.UserOrGroup;
import org.ovirt.engine.ui.frontend.Frontend;
import org.ovirt.engine.ui.uicommonweb.TagAssigningModel;
import org.ovirt.engine.ui.uicommonweb.UICommand;
import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
import org.ovirt.engine.ui.uicommonweb.help.HelpTag;
import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel;
import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
import org.ovirt.engine.ui.uicommonweb.models.HasEntity;
import org.ovirt.engine.ui.uicommonweb.models.ListWithSimpleDetailsModel;
import org.ovirt.engine.ui.uicommonweb.models.tags.TagListModel;
import org.ovirt.engine.ui.uicommonweb.models.tags.TagModel;
import org.ovirt.engine.ui.uicommonweb.models.users.AdElementListModel.AdSearchType;
import org.ovirt.engine.ui.uicommonweb.place.WebAdminApplicationPlaces;
import org.ovirt.engine.ui.uicompat.ConstantsManager;
import org.ovirt.engine.ui.uicompat.IFrontendActionAsyncCallback;
import org.ovirt.engine.ui.uicompat.IFrontendMultipleActionAsyncCallback;
import com.google.gwt.core.client.Scheduler;
import com.google.inject.Inject;
public class UserListModel extends ListWithSimpleDetailsModel<Void, DbUser> implements TagAssigningModel<DbUser> {
private UICommand privateAddCommand;
public UICommand getAddCommand() {
return privateAddCommand;
}
private void setAddCommand(UICommand value) {
privateAddCommand = value;
}
private UICommand privateRemoveCommand;
public UICommand getRemoveCommand() {
return privateRemoveCommand;
}
private void setRemoveCommand(UICommand value) {
privateRemoveCommand = value;
}
private UICommand privateAssignTagsCommand;
@Override
public UICommand getAssignTagsCommand() {
return privateAssignTagsCommand;
}
private void setAssignTagsCommand(UICommand value) {
privateAssignTagsCommand = value;
}
protected Object[] getSelectedKeys() {
if (getSelectedItems() == null) {
return new Object[0];
}
else {
ArrayList<Object> items = new ArrayList<>();
for (Object i : getSelectedItems()) {
items.add(((Cluster) i).getId());
}
return items.toArray(new Object[] {});
}
}
@Inject
public UserListModel(final UserGroupListModel userGroupListModel,
final UserEventNotifierListModel userEventNotifierListModel, final UserGeneralModel userGeneralModel,
final UserQuotaListModel userQuotaListModel, final UserPermissionListModel userPermissionListModel,
final UserEventListModel userEventListModel) {
setIsTimerDisabled(true);
this.userGroupListModel = userGroupListModel;
this.userEventNotifierListModel = userEventNotifierListModel;
setDetailList(userGeneralModel, userQuotaListModel, userPermissionListModel, userEventListModel);
setTitle(ConstantsManager.getInstance().getConstants().usersTitle());
setApplicationPlace(WebAdminApplicationPlaces.userMainTabPlace);
setDefaultSearchString("Users:"); //$NON-NLS-1$
setSearchString(getDefaultSearchString());
setSearchObjects(new String[] { SearchObjects.VDC_USER_OBJ_NAME, SearchObjects.VDC_USER_PLU_OBJ_NAME });
setAddCommand(new UICommand("Add", this)); //$NON-NLS-1$
setRemoveCommand(new UICommand("Remove", this)); //$NON-NLS-1$
setAssignTagsCommand(new UICommand("AssignTags", this)); //$NON-NLS-1$
updateActionAvailability();
getSearchNextPageCommand().setIsAvailable(true);
getSearchPreviousPageCommand().setIsAvailable(true);
}
private void setDetailList(final UserGeneralModel userGeneralModel, final UserQuotaListModel userQuotaListModel,
final UserPermissionListModel userPermissionListModel, final UserEventListModel userEventListModel) {
List<HasEntity<DbUser>> list = new ArrayList<>();
list.add(userGeneralModel);
list.add(userQuotaListModel);
list.add(userPermissionListModel);
list.add(userEventListModel);
userGroupListModel.setIsAvailable(false);
list.add(userGroupListModel);
list.add(userEventNotifierListModel);
setDetailModels(list);
}
public void assignTags() {
if (getWindow() != null) {
return;
}
TagListModel model = new TagListModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().assignTagsTitle());
model.setHelpTag(HelpTag.assign_tags_users);
model.setHashName("assign_tags_users"); //$NON-NLS-1$
getAttachedTagsToSelectedUsers(model);
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnAssignTags", this); //$NON-NLS-1$
model.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("Cancel", this); //$NON-NLS-1$
model.getCommands().add(tempVar2);
}
public Map<Guid, Boolean> attachedTagsToEntities;
@Override
public Map<Guid, Boolean> getAttachedTagsToEntities() {
return attachedTagsToEntities;
}
public ArrayList<Tags> allAttachedTags;
@Override
public List<Tags> getAllAttachedTags() {
return allAttachedTags;
}
public int selectedItemsCounter;
private UserOrGroup userOrGroup;
private void getAttachedTagsToSelectedUsers(final TagListModel model) {
ArrayList<Guid> userIds = new ArrayList<>();
ArrayList<Guid> grpIds = new ArrayList<>();
attachedTagsToEntities = new HashMap<>();
allAttachedTags = new ArrayList<>();
selectedItemsCounter = 0;
for (Object item : getSelectedItems()) {
DbUser user = (DbUser) item;
if (!user.isGroup()) {
userIds.add(user.getId());
}
else {
grpIds.add(user.getId());
}
}
for (Guid userId : userIds) {
AsyncDataProvider.getInstance().getAttachedTagsToUser(new AsyncQuery<>(returnValue -> {
allAttachedTags.addAll(returnValue);
selectedItemsCounter++;
if (selectedItemsCounter == getSelectedItems().size()) {
postGetAttachedTags(model);
}
}),
userId);
}
for (Guid grpId : grpIds) {
AsyncDataProvider.getInstance().getAttachedTagsToUserGroup(new AsyncQuery<>(
returnValue -> {
allAttachedTags.addAll(returnValue);
selectedItemsCounter++;
if (selectedItemsCounter == getSelectedItems().size()) {
postGetAttachedTags(model);
}
}),
grpId);
}
}
private void onAssignTags() {
TagListModel model = (TagListModel) getWindow();
getAttachedTagsToSelectedUsers(model);
}
@Override
public void postOnAssignTags(Map<Guid, Boolean> attachedTags) {
TagListModel model = (TagListModel) getWindow();
ArrayList<Guid> userIds = new ArrayList<>();
ArrayList<Guid> grpIds = new ArrayList<>();
for (Object item : getSelectedItems()) {
DbUser user = (DbUser) item;
if (user.isGroup()) {
grpIds.add(user.getId());
}
else {
userIds.add(user.getId());
}
}
// prepare attach/detach lists
ArrayList<Guid> tagsToAttach = new ArrayList<>();
ArrayList<Guid> tagsToDetach = new ArrayList<>();
if (model.getItems() != null && model.getItems().size() > 0) {
ArrayList<TagModel> tags = (ArrayList<TagModel>) model.getItems();
TagModel rootTag = tags.get(0);
TagModel.recursiveEditAttachDetachLists(rootTag, attachedTags, tagsToAttach, tagsToDetach);
}
ArrayList<VdcActionParametersBase> usersToAttach = new ArrayList<>();
ArrayList<VdcActionParametersBase> grpsToAttach = new ArrayList<>();
for (Guid tag_id : tagsToAttach) {
if (userIds.size() > 0) {
usersToAttach.add(new AttachEntityToTagParameters(tag_id, userIds));
}
if (grpIds.size() > 0) {
grpsToAttach.add(new AttachEntityToTagParameters(tag_id, grpIds));
}
}
if (usersToAttach.size() > 0) {
Frontend.getInstance().runMultipleAction(VdcActionType.AttachUserToTag, usersToAttach);
}
if (grpsToAttach.size() > 0) {
Frontend.getInstance().runMultipleAction(VdcActionType.AttachUserGroupToTag, grpsToAttach);
}
ArrayList<VdcActionParametersBase> usersToDetach = new ArrayList<>();
ArrayList<VdcActionParametersBase> grpsToDetach = new ArrayList<>();
for (Guid tag_id : tagsToDetach) {
if (userIds.size() > 0) {
usersToDetach.add(new AttachEntityToTagParameters(tag_id, userIds));
}
if (grpIds.size() > 0) {
grpsToDetach.add(new AttachEntityToTagParameters(tag_id, grpIds));
}
}
if (usersToDetach.size() > 0) {
Frontend.getInstance().runMultipleAction(VdcActionType.DetachUserFromTag, usersToDetach);
}
if (grpsToDetach.size() > 0) {
Frontend.getInstance().runMultipleAction(VdcActionType.DetachUserGroupFromTag, grpsToDetach);
}
cancel();
}
public void add() {
if (getWindow() != null) {
return;
}
AdElementListModel model = new AdElementListModel();
if (getUserOrGroup() == UserOrGroup.Group) {
model.setSearchType(AdSearchType.GROUP);
} else {
model.setSearchType(AdSearchType.USER);
}
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().addUsersAndGroupsTitle());
model.setHelpTag(HelpTag.add_users_and_groups);
model.setHashName("add_users_and_groups"); //$NON-NLS-1$
model.setIsRoleListHidden(true);
model.getIsEveryoneSelectionHidden().setEntity(true);
UICommand addCommand = new UICommand("OnAdd", this); //$NON-NLS-1$
addCommand.setTitle(ConstantsManager.getInstance().getConstants().add());
model.getCommands().add(addCommand);
UICommand addAndCloseCommand = new UICommand("OnAddAndClose", this); //$NON-NLS-1$
addAndCloseCommand.setTitle(ConstantsManager.getInstance().getConstants().addAndClose());
addAndCloseCommand.setIsDefault(true);
model.getCommands().add(addAndCloseCommand);
UICommand closeCommand = new UICommand("Cancel", this); //$NON-NLS-1$
closeCommand.setTitle(ConstantsManager.getInstance().getConstants().close());
closeCommand.setIsCancel(true);
model.getCommands().add(closeCommand);
}
public UserOrGroup getUserOrGroup() {
return this.userOrGroup;
}
public void setUserOrGroup(UserOrGroup value) {
this.userOrGroup = value;
}
public void remove() {
if (getWindow() != null) {
return;
}
ConfirmationModel model = new ConfirmationModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().removeUsersTitle());
model.setHelpTag(HelpTag.remove_user);
model.setHashName("remove_user"); //$NON-NLS-1$
ArrayList<String> list = new ArrayList<>();
for (DbUser item : getSelectedItems()) {
list.add(item.getFirstName());
}
model.setItems(list);
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnRemove", this); //$NON-NLS-1$
model.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("Cancel", this); //$NON-NLS-1$
model.getCommands().add(tempVar2);
}
@Override
public boolean isSearchStringMatch(String searchString) {
return searchString.trim().toLowerCase().startsWith("user"); //$NON-NLS-1$
}
@Override
protected void syncSearch() {
SearchParameters tempVar = new SearchParameters(applySortOptions(getSearchString()), SearchType.DBUser,
isCaseSensitiveSearch());
tempVar.setMaxCount(getSearchPageSize());
super.syncSearch(VdcQueryType.Search, tempVar);
}
@Override
public boolean supportsServerSideSorting() {
return true;
}
private final UserGroupListModel userGroupListModel;
private final UserEventNotifierListModel userEventNotifierListModel;
private IFrontendActionAsyncCallback nopCallback = result -> {
// Nothing.
};
@Override
protected void updateDetailsAvailability() {
if (getSelectedItem() != null) {
DbUser adUser = getSelectedItem();
userGroupListModel.setIsAvailable(!adUser.isGroup());
userEventNotifierListModel.setIsAvailable(!adUser.isGroup());
}
}
public void cancel() {
setWindow(null);
}
public void onAdd(final boolean closeWindow) {
AdElementListModel model = (AdElementListModel) getWindow();
if (model.getProgress() != null) {
return;
}
if (model.getSelectedItems() == null) {
cancel();
return;
}
List<EntityModel<DbUser>> selectedItems = new ArrayList<>();
for (EntityModel<DbUser> dbUserEntity : model.getItems()) {
if (dbUserEntity.getIsSelected()) {
selectedItems.add(dbUserEntity);
}
}
List<VdcActionType> actionsList = new ArrayList<>(selectedItems.size());
List<VdcActionParametersBase> parametersList = new ArrayList<>(selectedItems.size());
VdcActionParametersBase parameters = null;
for (EntityModel<DbUser> item : selectedItems) {
if (item.getEntity().isGroup()) {
actionsList.add(VdcActionType.AddGroup);
DbGroup grp = new DbGroup();
grp.setExternalId(item.getEntity().getExternalId());
grp.setName(item.getEntity().getFirstName());
grp.setNamespace(item.getEntity().getNamespace());
grp.setId(item.getEntity().getId());
grp.setDomain(item.getEntity().getDomain());
parameters = new AddGroupParameters(grp);
}
else {
actionsList.add(VdcActionType.AddUser);
parameters = new AddUserParameters(item.getEntity());
}
parametersList.add(parameters);
}
model.startProgress();
IFrontendActionAsyncCallback lastCallback = result -> {
AdElementListModel localModel = (AdElementListModel) result.getState();
localModel.stopProgress();
//Refresh user list.
syncSearch();
if (closeWindow) {
cancel();
}
};
Collection<EntityModel<DbUser>> currentItems = model.getItems();
List<IFrontendActionAsyncCallback> callbacksList = new ArrayList<>(selectedItems.size());
for (EntityModel<DbUser> user: selectedItems) {
callbacksList.add(nopCallback);
currentItems.remove(user);
}
callbacksList.remove(callbacksList.size() - 1);
callbacksList.add(lastCallback);
//Refresh display
model.setItems(null);
model.setItems(currentItems);
Frontend.getInstance().runMultipleActions(actionsList, parametersList, callbacksList, lastCallback, model);
}
public void onRemove() {
List<DbUser> selectedItems = getSelectedItems();
ArrayList<VdcActionParametersBase> userPrms = new ArrayList<>();
ArrayList<VdcActionParametersBase> groupPrms = new ArrayList<>();
for (DbUser item : selectedItems) {
if (!item.isGroup()) {
userPrms.add(new IdParameters(item.getId()));
}
else {
groupPrms.add(new IdParameters(item.getId()));
}
}
IFrontendMultipleActionAsyncCallback lastCallback = result -> Scheduler.get().scheduleDeferred(() -> {
//Refresh user list.
syncSearch();
cancel();
});
if (getUserOrGroup() == UserOrGroup.User) {
if (userPrms.size() > 0) {
Frontend.getInstance().runMultipleAction(VdcActionType.RemoveUser, userPrms, lastCallback);
}
} else if (getUserOrGroup() == UserOrGroup.Group) {
if (groupPrms.size() > 0) {
Frontend.getInstance().runMultipleAction(VdcActionType.RemoveGroup, groupPrms, lastCallback);
}
}
}
@Override
protected void onSelectedItemChanged() {
super.onSelectedItemChanged();
updateActionAvailability();
}
@Override
protected void selectedItemsChanged() {
super.selectedItemsChanged();
updateActionAvailability();
}
private void updateActionAvailability() {
ArrayList items =
((ArrayList) getSelectedItems() != null) ? (ArrayList) getSelectedItems()
: new ArrayList();
getRemoveCommand().setIsExecutionAllowed(items.size() > 0
&& VdcActionUtils.canExecute(items, DbUser.class, VdcActionType.RemoveUser));
getAssignTagsCommand().setIsExecutionAllowed(items.size() > 0);
}
@Override
public void executeCommand(UICommand command) {
super.executeCommand(command);
if (command == getAddCommand()) {
add();
}
if (command == getRemoveCommand()) {
remove();
}
if (command == getAssignTagsCommand()) {
assignTags();
}
if ("Cancel".equals(command.getName())) { //$NON-NLS-1$
cancel();
}
if ("OnAssignTags".equals(command.getName())) { //$NON-NLS-1$
onAssignTags();
}
if ("OnAdd".equals(command.getName())) { //$NON-NLS-1$
onAdd(false);
}
if ("OnAddAndClose".equals(command.getName())) { //$NON-NLS-1$
onAdd(true);
}
if ("OnRemove".equals(command.getName())) { //$NON-NLS-1$
onRemove();
}
}
@Override
protected String getListName() {
return "UserListModel"; //$NON-NLS-1$
}
}