/* 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.activiti.explorer.ui.management.identity;
import java.io.InputStream;
import java.util.Set;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.identity.Picture;
import org.activiti.engine.identity.User;
import org.activiti.explorer.Constants;
import org.activiti.explorer.ExplorerApp;
import org.activiti.explorer.I18nManager;
import org.activiti.explorer.Messages;
import org.activiti.explorer.data.LazyLoadingContainer;
import org.activiti.explorer.ui.Images;
import org.activiti.explorer.ui.custom.ConfirmationDialogPopupWindow;
import org.activiti.explorer.ui.custom.DetailPanel;
import org.activiti.explorer.ui.event.ConfirmationEvent;
import org.activiti.explorer.ui.event.ConfirmationEventListener;
import org.activiti.explorer.ui.event.SubmitEvent;
import org.activiti.explorer.ui.event.SubmitEventListener;
import org.activiti.explorer.ui.mainlayout.ExplorerLayout;
import com.vaadin.terminal.StreamResource;
import com.vaadin.terminal.StreamResource.StreamSource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.Reindeer;
/**
* @author Joram Barrez
*/
public class UserDetailPanel extends DetailPanel implements MemberShipChangeListener {
private static final long serialVersionUID = 1L;
protected I18nManager i18nManager;
protected IdentityService identityService;
protected UserPage userPage;
protected User user;
protected boolean editingDetails;
protected HorizontalLayout userDetailsLayout;
protected TextField firstNameField;
protected TextField lastNameField;
protected TextField emailField;
protected PasswordField passwordField;
protected HorizontalLayout groupLayout;
protected Table groupTable;
protected LazyLoadingContainer groupContainer;
protected GroupsForUserQuery groupsForUserQuery;
protected Label noGroupsLabel;
public UserDetailPanel(UserPage userPage, String userId) {
this.userPage = userPage;
this.i18nManager = ExplorerApp.get().getI18nManager();
this.identityService = ProcessEngines.getDefaultProcessEngine().getIdentityService();
this.user = identityService.createUserQuery().userId(userId).singleResult();
init();
}
protected void init() {
setSizeFull();
addStyleName(Reindeer.PANEL_LIGHT);
initPageTitle();
initUserDetails();
initGroups();
initActions();
}
protected void initActions() {
Button createUserButton = new Button(i18nManager.getMessage(Messages.USER_CREATE));
createUserButton.setIcon(Images.USER_16);
createUserButton.addListener(new ClickListener() {
private static final long serialVersionUID = 1L;
public void buttonClick(ClickEvent event) {
NewUserPopupWindow newUserPopupWindow = new NewUserPopupWindow();
ExplorerApp.get().getViewManager().showPopupWindow(newUserPopupWindow);
}
});
userPage.getToolBar().removeAllButtons();
userPage.getToolBar().addButton(createUserButton);
}
protected void initPageTitle() {
HorizontalLayout layout = new HorizontalLayout();
layout.setWidth(100, UNITS_PERCENTAGE);
layout.setSpacing(true);
layout.setMargin(false, false, true, false);
layout.addStyleName(ExplorerLayout.STYLE_TITLE_BLOCK);
addDetailComponent(layout);
Embedded userImage = new Embedded(null, Images.USER_50);
layout.addComponent(userImage);
Label userName = new Label(user.getFirstName() + " " + user.getLastName());
userName.setSizeUndefined();
userName.addStyleName(Reindeer.LABEL_H2);
layout.addComponent(userName);
layout.setComponentAlignment(userName, Alignment.MIDDLE_LEFT);
layout.setExpandRatio(userName, 1.0f);
}
protected void initUserDetails() {
Label userDetailsHeader = new Label(i18nManager.getMessage(Messages.USER_HEADER_DETAILS));
userDetailsHeader.addStyleName(ExplorerLayout.STYLE_H3);
userDetailsHeader.addStyleName(ExplorerLayout.STYLE_DETAIL_BLOCK);
addDetailComponent(userDetailsHeader);
// Details: picture and basic info
userDetailsLayout = new HorizontalLayout();
userDetailsLayout.setSpacing(true);
userDetailsLayout.setMargin(false, false, true, false);
addDetailComponent(userDetailsLayout);
populateUserDetails();
}
protected void populateUserDetails() {
loadPicture();
loadUserDetails();
initDetailsActions();
}
protected void loadPicture() {
Component pictureComponent = null;
final Picture userPicture = identityService.getUserPicture(user.getId());
if (userPicture != null) {
StreamResource imageresource = new StreamResource(new StreamSource() {
private static final long serialVersionUID = 1L;
public InputStream getStream() {
return userPicture.getInputStream();
}
}, user.getId() + "." + Constants.MIMETYPE_EXTENSION_MAPPING.get(userPicture.getMimeType()), ExplorerApp.get());
pictureComponent = new Embedded(null, imageresource);
} else {
pictureComponent = new Label("");
}
pictureComponent.setHeight("200px");
pictureComponent.setWidth("200px");
pictureComponent.addStyleName(ExplorerLayout.STYLE_PROFILE_PICTURE);
userDetailsLayout.addComponent(pictureComponent);
userDetailsLayout.setComponentAlignment(pictureComponent, Alignment.MIDDLE_CENTER);
}
protected void loadUserDetails() {
// Grid of details
GridLayout detailGrid = new GridLayout();
detailGrid.setColumns(2);
detailGrid.setSpacing(true);
detailGrid.setMargin(true, true, false, true);
userDetailsLayout.addComponent(detailGrid);
// Details
addUserDetail(detailGrid, i18nManager.getMessage(Messages.USER_ID), new Label(user.getId())); // details are non-editable
if (!editingDetails) {
addUserDetail(detailGrid, i18nManager.getMessage(Messages.USER_FIRSTNAME), new Label(user.getFirstName()));
addUserDetail(detailGrid, i18nManager.getMessage(Messages.USER_LASTNAME), new Label(user.getLastName()));
addUserDetail(detailGrid, i18nManager.getMessage(Messages.USER_EMAIL), new Label(user.getEmail()));
} else {
firstNameField = new TextField(null, user.getFirstName() != null ? user.getFirstName() : "");
addUserDetail(detailGrid, i18nManager.getMessage(Messages.USER_FIRSTNAME), firstNameField);
firstNameField.focus();
lastNameField = new TextField(null, user.getLastName() != null ? user.getLastName() : "");
addUserDetail(detailGrid, i18nManager.getMessage(Messages.USER_LASTNAME), lastNameField);
emailField = new TextField(null, user.getEmail() != null ? user.getEmail() : "");
addUserDetail(detailGrid, i18nManager.getMessage(Messages.USER_EMAIL), emailField);
passwordField = new PasswordField();
Label cautionLabel = new Label(i18nManager.getMessage(Messages.USER_RESET_PASSWORD));
cautionLabel.addStyleName(Reindeer.LABEL_SMALL);
HorizontalLayout passwordLayout = new HorizontalLayout();
passwordLayout.setSpacing(true);
passwordLayout.addComponent(passwordField);
passwordLayout.addComponent(cautionLabel);
passwordLayout.setComponentAlignment(cautionLabel, Alignment.MIDDLE_LEFT);
addUserDetail(detailGrid, i18nManager.getMessage(Messages.USER_PASSWORD), passwordLayout);
}
}
protected void addUserDetail(GridLayout detailLayout, String detail, Component value) {
Label label = new Label(detail + ": ");
label.addStyleName(ExplorerLayout.STYLE_LABEL_BOLD);
detailLayout.addComponent(label);
detailLayout.addComponent(value);
}
protected void initDetailsActions() {
VerticalLayout actionLayout = new VerticalLayout();
actionLayout.setSpacing(true);
actionLayout.setMargin(false, false, false, true);
userDetailsLayout.addComponent(actionLayout);
if (!editingDetails) {
initEditButton(actionLayout);
initDeleteButton(actionLayout);
} else {
initSaveButton(actionLayout);
}
}
protected void initEditButton(VerticalLayout actionLayout) {
Button editButton = new Button(i18nManager.getMessage(Messages.USER_EDIT));
editButton.addStyleName(Reindeer.BUTTON_SMALL);
actionLayout.addComponent(editButton);
editButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
editingDetails = true;
userDetailsLayout.removeAllComponents();
populateUserDetails(); // the layout will be populated differently since the 'editingDetails' boolean is set
}
});
}
protected void initSaveButton(VerticalLayout actionLayout) {
Button saveButton = new Button(i18nManager.getMessage(Messages.USER_SAVE));
saveButton.addStyleName(Reindeer.BUTTON_SMALL);
actionLayout.addComponent(saveButton);
saveButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
String originalFirstName = user.getFirstName();
String originalLastName = user.getLastName();
// Change data
user.setFirstName(firstNameField.getValue().toString());
user.setLastName(lastNameField.getValue().toString());
user.setEmail(emailField.getValue().toString());
if (passwordField.getValue() != null && !"".equals(passwordField.getValue().toString())) {
user.setPassword(passwordField.getValue().toString());
}
identityService.saveUser(user);
// Refresh detail panel
editingDetails = false;
userDetailsLayout.removeAllComponents();
populateUserDetails();
// Refresh task list (only if name was changed)
if (nameChanged(originalFirstName, originalLastName)) {
userPage.notifyUserChanged(user.getId());
}
// Update user cache
ExplorerApp.get().getUserCache().notifyUserDataChanged(user.getId());
}
});
}
protected boolean nameChanged(String originalFirstName, String originalLastName) {
boolean nameChanged = false;
if (originalFirstName != null) {
nameChanged = !originalFirstName.equals(user.getFirstName());
} else {
nameChanged = user.getFirstName() != null;
}
if (!nameChanged) {
if (originalLastName != null) {
nameChanged = !originalLastName.equals(user.getLastName());
} else {
nameChanged = user.getLastName() != null;
}
}
return nameChanged;
}
protected void initDeleteButton(VerticalLayout actionLayout) {
Button deleteButton = new Button(i18nManager.getMessage(Messages.USER_DELETE));
deleteButton.addStyleName(Reindeer.BUTTON_SMALL);
actionLayout.addComponent(deleteButton);
deleteButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
ConfirmationDialogPopupWindow confirmPopup =
new ConfirmationDialogPopupWindow(i18nManager.getMessage(Messages.USER_CONFIRM_DELETE, user.getId()));
confirmPopup.addListener(new ConfirmationEventListener() {
protected void rejected(ConfirmationEvent event) {
}
protected void confirmed(ConfirmationEvent event) {
// Delete user from database
identityService.deleteUser(user.getId());
// Update ui
userPage.refreshSelectNext();
// Update user cache
ExplorerApp.get().getUserCache().notifyUserDataChanged(user.getId());
}
});
ExplorerApp.get().getViewManager().showPopupWindow(confirmPopup);
}
});
}
protected void initGroups() {
HorizontalLayout groupHeader = new HorizontalLayout();
groupHeader.setWidth(100, UNITS_PERCENTAGE);
groupHeader.setSpacing(true);
groupHeader.setMargin(false, false, true, false);
groupHeader.addStyleName(ExplorerLayout.STYLE_DETAIL_BLOCK);
addDetailComponent(groupHeader);
initGroupTitle(groupHeader);
initAddGroupsButton(groupHeader);
groupLayout = new HorizontalLayout(); // we wrap the table in a simple layout so we can remove the table easy later on
groupLayout.setWidth(100, UNITS_PERCENTAGE);
addDetailComponent(groupLayout);
initGroupsTable();
}
protected void initGroupTitle(HorizontalLayout groupHeader) {
Label groupsTitle = new Label(i18nManager.getMessage(Messages.USER_HEADER_GROUPS));
groupsTitle.addStyleName(ExplorerLayout.STYLE_H3);
groupHeader.addComponent(groupsTitle);
}
protected void initAddGroupsButton(HorizontalLayout groupHeader) {
Button addRelatedContentButton = new Button();
addRelatedContentButton.addStyleName(ExplorerLayout.STYLE_ADD);
groupHeader.addComponent(addRelatedContentButton);
groupHeader.setComponentAlignment(addRelatedContentButton, Alignment.MIDDLE_RIGHT);
addRelatedContentButton.addListener(new ClickListener() {
private static final long serialVersionUID = 1L;
public void buttonClick(ClickEvent event) {
final GroupSelectionPopupWindow selectionPopup = new GroupSelectionPopupWindow(identityService, user.getId());
selectionPopup.addListener(new SubmitEventListener() {
private static final long serialVersionUID = 1L;
protected void submitted(SubmitEvent event) {
Set<String> selectedGroups = selectionPopup.getSelectedGroupIds();
if (selectedGroups.size() > 0) {
for (String groupId : selectedGroups) {
identityService.createMembership(user.getId(), groupId);
}
notifyMembershipChanged();
}
}
protected void cancelled(SubmitEvent event) {
}
});
ExplorerApp.get().getViewManager().showPopupWindow(selectionPopup);
}
});
}
protected void initGroupsTable() {
groupsForUserQuery = new GroupsForUserQuery(identityService, this, user.getId());
if (groupsForUserQuery.size() > 0) {
groupTable = new Table();
groupTable.setSortDisabled(true);
groupTable.setHeight(150, UNITS_PIXELS);
groupTable.setWidth(100, UNITS_PERCENTAGE);
groupLayout.addComponent(groupTable);
groupContainer = new LazyLoadingContainer(groupsForUserQuery, 10);
groupTable.setContainerDataSource(groupContainer);
groupTable.addContainerProperty("id", Button.class, null);
groupTable.setColumnExpandRatio("id", 22);
groupTable.addContainerProperty("name", String.class, null);
groupTable.setColumnExpandRatio("name", 45);
groupTable.addContainerProperty("type", String.class, null);
groupTable.setColumnExpandRatio("type", 22);
groupTable.addContainerProperty("actions", Component.class, null);
groupTable.setColumnExpandRatio("actions", 11);
groupTable.setColumnAlignment("actions", Table.ALIGN_CENTER);
} else {
noGroupsLabel = new Label(i18nManager.getMessage(Messages.USER_NO_GROUPS));
groupLayout.addComponent(noGroupsLabel);
}
}
public void notifyMembershipChanged() {
groupLayout.removeAllComponents();
initGroupsTable();
}
}