/* 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.profile;
import java.io.InputStream;
import java.text.SimpleDateFormat;
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.ViewManager;
import org.activiti.explorer.ui.Images;
import org.activiti.explorer.ui.custom.InMemoryUploadReceiver;
import org.activiti.explorer.ui.mainlayout.ExplorerLayout;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.StreamResource;
import com.vaadin.terminal.StreamResource.StreamSource;
import com.vaadin.ui.AbstractField;
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.DateField;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Link;
import com.vaadin.ui.Panel;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Upload;
import com.vaadin.ui.Upload.FinishedEvent;
import com.vaadin.ui.Upload.FinishedListener;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.Reindeer;
/**
* @author Joram Barrez
*/
public class ProfilePanel extends Panel {
private static final long serialVersionUID = -4274649964206760400L;
// services
protected transient IdentityService identityService;
protected I18nManager i18nManager;
protected ViewManager viewManager;
// user information
protected String userId;
protected User user;
protected Picture picture;
protected String birthDate;
protected String jobTitle;
protected String location;
protected String phone;
protected String twitterName;
protected String skypeId;
// ui
protected boolean isCurrentLoggedInUser;
protected boolean editable = false;
protected HorizontalLayout profilePanelLayout;
protected VerticalLayout imageLayout;
protected VerticalLayout infoPanelLayout;
protected TextField firstNameField;
protected TextField lastNameField;
protected PasswordField passwordField;
protected TextField jobTitleField;
protected DateField birthDateField;
protected TextField locationField;
protected TextField emailField;
protected TextField phoneField;
protected TextField twitterField;
protected TextField skypeField;
public ProfilePanel(String userId) {
this.userId = userId;
this.isCurrentLoggedInUser = userId.equals(ExplorerApp.get().getLoggedInUser().getId());
this.identityService = ProcessEngines.getDefaultProcessEngine().getIdentityService();
this.i18nManager = ExplorerApp.get().getI18nManager();
this.viewManager = ExplorerApp.get().getViewManager();
loadProfileData();
initUi();
}
protected void loadProfileData() {
this.user = identityService.createUserQuery().userId(userId).singleResult();
this.picture = identityService.getUserPicture(user.getId());
this.birthDate = identityService.getUserInfo(user.getId(), Constants.USER_INFO_BIRTH_DATE);
this.jobTitle = identityService.getUserInfo(user.getId(), Constants.USER_INFO_JOB_TITLE);
this.location = identityService.getUserInfo(user.getId(), Constants.USER_INFO_LOCATION);
this.phone = identityService.getUserInfo(user.getId(), Constants.USER_INFO_PHONE);
this.twitterName = identityService.getUserInfo(user.getId(), Constants.USER_INFO_TWITTER);
this.skypeId = identityService.getUserInfo(user.getId(), Constants.USER_INFO_SKYPE);
}
protected void initUi() {
removeAllComponents();
addStyleName(Reindeer.PANEL_LIGHT);
addStyleName(ExplorerLayout.STYLE_PROFILE_LAYOUT);
setSizeFull();
// Profile page is a horizontal layout: left we have a panel with the picture,
// and one the right there is another panel the about, contact, etc information
this.profilePanelLayout = new HorizontalLayout();
profilePanelLayout.setSizeFull();
setContent(profilePanelLayout);
// init both panels
initImagePanel();
Label emptySpace = new Label(" ", Label.CONTENT_XHTML);
emptySpace.setWidth(50, UNITS_PIXELS);
profilePanelLayout.addComponent(emptySpace);
initInformationPanel();
}
protected void initImagePanel() {
imageLayout = new VerticalLayout();
imageLayout.setSpacing(true);
imageLayout.setHeight("100%");
profilePanelLayout.addComponent(imageLayout);
initPicture();
}
protected void initPicture() {
StreamResource imageresource = new StreamResource(new StreamSource() {
private static final long serialVersionUID = 1L;
public InputStream getStream() {
return picture.getInputStream();
}
}, user.getId(), ExplorerApp.get());
imageresource.setCacheTime(0);
Embedded picture = new Embedded(null, imageresource);
picture.setType(Embedded.TYPE_IMAGE);
picture.setHeight(200, UNITS_PIXELS);
picture.setWidth(200, UNITS_PIXELS);
picture.addStyleName(ExplorerLayout.STYLE_PROFILE_PICTURE);
imageLayout.addComponent(picture);
imageLayout.setWidth(picture.getWidth() + 5, picture.getWidthUnits());
// Change picture button
if (isCurrentLoggedInUser) {
Upload changePictureButton = initChangePictureButton();
imageLayout.addComponent(changePictureButton);
imageLayout.setComponentAlignment(changePictureButton, Alignment.MIDDLE_CENTER);
}
}
protected Upload initChangePictureButton() {
final Upload changePictureUpload = new Upload();
changePictureUpload.setImmediate(true);
changePictureUpload.setButtonCaption(i18nManager.getMessage(Messages.PROFILE_CHANGE_PICTURE));
final InMemoryUploadReceiver receiver = initPictureReceiver(changePictureUpload);
changePictureUpload.addListener(new FinishedListener() {
private static final long serialVersionUID = 1L;
public void uploadFinished(FinishedEvent event) {
if (!receiver.isInterruped()) {
picture = new Picture(receiver.getBytes(), receiver.getMimeType());
identityService.setUserPicture(userId, picture);
// reset picture
imageLayout.removeAllComponents();
initPicture();
} else {
receiver.reset();
}
}
});
return changePictureUpload;
}
protected InMemoryUploadReceiver initPictureReceiver(Upload upload) {
InMemoryUploadReceiver receiver = new InMemoryUploadReceiver(upload, 102400L); // 100 kb limit
upload.setReceiver(receiver);
receiver.setAcceptedMimeTypes(Constants.DEFAULT_IMAGE_MIMETYPES);
return receiver;
}
protected void initInformationPanel() {
Panel infoPanel = new Panel();
infoPanel.addStyleName(Reindeer.PANEL_LIGHT);
infoPanel.setSizeFull();
profilePanelLayout.addComponent(infoPanel);
profilePanelLayout.setExpandRatio(infoPanel, 1.0f); // info panel should take all the remaining width available
// All the information sections are put under each other in a vertical layout
this.infoPanelLayout = new VerticalLayout();
infoPanel.setContent(infoPanelLayout);
initAboutSection();
initContactSection();
}
protected void initAboutSection() {
// Header
HorizontalLayout header = new HorizontalLayout();
header.setWidth(100, UNITS_PERCENTAGE);
header.addStyleName(ExplorerLayout.STYLE_DETAIL_BLOCK);
infoPanelLayout.addComponent(header);
Label aboutLabel = createProfileHeader(infoPanelLayout, i18nManager.getMessage(Messages.PROFILE_ABOUT));
header.addComponent(aboutLabel);
header.setExpandRatio(aboutLabel, 1.0f);
// only show edit/save buttons if current user matches
if (isCurrentLoggedInUser) {
Button actionButton = null;
if (!editable) {
actionButton = initEditProfileButton();
} else {
actionButton = initSaveProfileButton();
}
header.addComponent(actionButton);
header.setComponentAlignment(actionButton, Alignment.MIDDLE_RIGHT);
}
// 'About' fields
GridLayout aboutLayout = createInfoSectionLayout(2, 4);
// Name
if (!editable && (isDefined(user.getFirstName()) || isDefined(user.getLastName()) )) {
addProfileEntry(aboutLayout, i18nManager.getMessage(Messages.PROFILE_NAME), user.getFirstName() + " " + user.getLastName());
} else if (editable) {
firstNameField = new TextField();
firstNameField.focus();
addProfileInputField(aboutLayout, i18nManager.getMessage(Messages.PROFILE_FIRST_NAME), firstNameField, user.getFirstName());
lastNameField = new TextField();
addProfileInputField(aboutLayout, i18nManager.getMessage(Messages.PROFILE_LAST_NAME), lastNameField, user.getLastName());
}
// Job title
if (!editable && isDefined(jobTitle)) {
addProfileEntry(aboutLayout, i18nManager.getMessage(Messages.PROFILE_JOBTITLE), jobTitle);
} else if (editable) {
jobTitleField = new TextField();
addProfileInputField(aboutLayout, i18nManager.getMessage(Messages.PROFILE_JOBTITLE), jobTitleField, jobTitle);
}
// Birthdate
if (!editable && isDefined(birthDate)) {
addProfileEntry(aboutLayout, i18nManager.getMessage(Messages.PROFILE_BIRTHDATE), birthDate);
} else if (editable) {
birthDateField = new DateField();
birthDateField.setDateFormat(Constants.DEFAULT_DATE_FORMAT);
birthDateField.setResolution(DateField.RESOLUTION_DAY);
try {
birthDateField.setValue(new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT).parse(birthDate));
} catch (Exception e) {} // do nothing
addProfileInputField(aboutLayout, i18nManager.getMessage(Messages.PROFILE_BIRTHDATE), birthDateField, null);
}
// Location
if (!editable && isDefined(location)) {
addProfileEntry(aboutLayout, i18nManager.getMessage(Messages.PROFILE_LOCATION), location);
} else if (editable) {
locationField = new TextField();
addProfileInputField(aboutLayout, i18nManager.getMessage(Messages.PROFILE_LOCATION), locationField, location);
}
}
protected Button initEditProfileButton() {
Button editProfileButton = new Button(i18nManager.getMessage(Messages.PROFILE_EDIT));
editProfileButton.setIcon(Images.EDIT);
editProfileButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
editable = true;
initUi();
}
});
return editProfileButton;
}
protected Button initSaveProfileButton() {
Button saveProfileButton = new Button(i18nManager.getMessage(Messages.PROFILE_SAVE));
saveProfileButton.setIcon(Images.SAVE);
saveProfileButton.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
user.setFirstName((String) firstNameField.getValue());
user.setLastName((String) lastNameField.getValue());
user.setEmail((String) emailField.getValue());
identityService.saveUser(user);
identityService.setUserInfo(user.getId(), Constants.USER_INFO_JOB_TITLE, jobTitleField.getValue().toString());
if (birthDateField.getValue() != null && !"".equals(birthDateField.getValue().toString())) {
identityService.setUserInfo(user.getId(), Constants.USER_INFO_BIRTH_DATE, new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT).format(birthDateField.getValue()));
}
identityService.setUserInfo(user.getId(), Constants.USER_INFO_LOCATION, locationField.getValue().toString());
identityService.setUserInfo(user.getId(), Constants.USER_INFO_PHONE, phoneField.getValue().toString());
identityService.setUserInfo(user.getId(), Constants.USER_INFO_TWITTER, twitterField.getValue().toString());
identityService.setUserInfo(user.getId(), Constants.USER_INFO_SKYPE, skypeField.getValue().toString());
// UI
editable = false;
loadProfileData();
initUi();
}
});
return saveProfileButton;
}
protected void initContactSection() {
Label header = createProfileHeader(infoPanelLayout, i18nManager.getMessage(Messages.PROFILE_CONTACT));
header.addStyleName(ExplorerLayout.STYLE_H3);
header.addStyleName(ExplorerLayout.STYLE_DETAIL_BLOCK);
infoPanelLayout.addComponent(header);
GridLayout contactLayout = createInfoSectionLayout(2, 4);
// Email
if (!editable && isDefined(user.getEmail())) {
addProfileEntry(contactLayout, i18nManager.getMessage(Messages.PROFILE_EMAIL), user.getEmail());
} else if (editable) {
emailField = new TextField();
addProfileInputField(contactLayout, i18nManager.getMessage(Messages.PROFILE_EMAIL), emailField, user.getEmail());
}
// Phone
if (!editable && isDefined(phone)) {
addProfileEntry(contactLayout, i18nManager.getMessage(Messages.PROFILE_PHONE), phone);
} else if (editable) {
phoneField = new TextField();
addProfileInputField(contactLayout, i18nManager.getMessage(Messages.PROFILE_PHONE), phoneField, phone);
}
// Twitter
if (!editable && isDefined(twitterName)) {
Link twitterLink = new Link(twitterName, new ExternalResource("http://www.twitter.com/"+twitterName));
addProfileEntry(contactLayout, i18nManager.getMessage(Messages.PROFILE_TWITTER), twitterLink);
} else if (editable) {
twitterField = new TextField();
addProfileInputField(contactLayout, i18nManager.getMessage(Messages.PROFILE_TWITTER), twitterField, twitterName);
}
// Skype
if (!editable && isDefined(skypeId)) {
// The skype entry shows the name + skype icon, laid out in a small grid
GridLayout skypeLayout = new GridLayout(2,1);
skypeLayout.setSpacing(true);
skypeLayout.setSizeUndefined();
Label skypeIdLabel = new Label(skypeId);
skypeIdLabel.setSizeUndefined();
skypeLayout.addComponent(skypeIdLabel);
addProfileEntry(contactLayout, i18nManager.getMessage(Messages.PROFILE_SKYPE), skypeLayout);
} else if (editable) {
skypeField = new TextField();
addProfileInputField(contactLayout, i18nManager.getMessage(Messages.PROFILE_SKYPE), skypeField, skypeId);
}
}
protected boolean isDefined(String information) {
return information != null && !"".equals(information);
}
protected Label createProfileHeader(VerticalLayout infoLayout, String headerName) {
Label label = new Label(headerName);
label.setWidth(100, UNITS_PERCENTAGE);
label.addStyleName(ExplorerLayout.STYLE_H3);
return label;
}
protected GridLayout createInfoSectionLayout(int columns, int rows) {
GridLayout layout = new GridLayout(columns, rows);
layout.setSpacing(true);
layout.setWidth(100, UNITS_PERCENTAGE);
layout.setMargin(true, false, true, false);
infoPanelLayout.addComponent(layout);
return layout;
}
protected void addProfileEntry(GridLayout layout, String name, String value) {
addProfileEntry(layout, name, new Label(value));
}
protected void addProfileEntry(GridLayout layout, String name, Component value) {
addProfileEntry(layout, new Label(name + ": "), value);
}
protected void addProfileEntry(GridLayout layout, Component name, Component value) {
name.addStyleName(ExplorerLayout.STYLE_PROFILE_FIELD);
name.setSizeUndefined();
layout.addComponent(name);
value.setSizeUndefined();
layout.addComponent(value);
}
protected void addProfileInputField(GridLayout layout, String name, AbstractField inputField, String inputFieldValue) {
Label label = new Label(name + ": ");
label.addStyleName(ExplorerLayout.STYLE_PROFILE_FIELD);
label.setSizeUndefined();
layout.addComponent(label);
layout.setComponentAlignment(label, Alignment.MIDDLE_LEFT);
if (inputFieldValue != null) {
inputField.setValue(inputFieldValue);
}
layout.addComponent(inputField);
layout.setComponentAlignment(inputField, Alignment.MIDDLE_LEFT);
}
}