package org.aperteworkflow.util.vaadin;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import org.aperteworkflow.util.liferay.LiferayBridge;
import org.aperteworkflow.util.liferay.PortalBridge;
import pl.net.bluesoft.rnd.processtool.ProcessToolContext;
import pl.net.bluesoft.rnd.processtool.bpm.ProcessToolBpmSession;
import pl.net.bluesoft.rnd.processtool.model.UserData;
import pl.net.bluesoft.rnd.processtool.ui.widgets.ProcessToolGuiCallback;
import pl.net.bluesoft.rnd.util.i18n.I18NSource;
import pl.net.bluesoft.rnd.util.i18n.I18NSourceFactory;
import pl.net.bluesoft.util.eventbus.EventListener;
import pl.net.bluesoft.util.eventbus.listenables.Listenable;
import pl.net.bluesoft.util.eventbus.listenables.ListenableSupport;
import pl.net.bluesoft.util.lang.Strings;
import com.vaadin.Application;
import com.vaadin.service.ApplicationContext;
import com.vaadin.terminal.gwt.server.PortletApplicationContext2;
import com.vaadin.ui.Label;
import com.vaadin.ui.Window;
/**
* @author tlipski@bluesoft.net.pl
*/
public abstract class GenericVaadinPortlet2BpmApplication extends Application implements
PortletApplicationContext2.PortletListener, TransactionProvider, I18NSource, VaadinExceptionHandler,
Listenable<GenericVaadinPortlet2BpmApplication.RequestParameterListener> {
private static Logger logger = Logger.getLogger(GenericVaadinPortlet2BpmApplication.class.getName());
protected boolean loginRequired = true;
protected UserData user = null;
protected Collection<String> userRoles = null;
protected boolean initialized = false;
protected Locale locale = null;
protected ProcessToolBpmSession bpmSession;
protected I18NSource i18NSource;
private List<UserData> users;
private String showKeysString;
private boolean showExitWarning = false;
private Locale lastLocale;
protected abstract void initializePortlet();
protected abstract void renderPortlet();
protected final ListenableSupport<RequestParameterListener> listenable = ListenableSupport.strongListenable();
@Override
public void init() {
final Window mainWindow = new Window();
setMainWindow(mainWindow);
ApplicationContext applicationContext = getContext();
if (applicationContext instanceof PortletApplicationContext2) {
PortletApplicationContext2 portletCtx = (PortletApplicationContext2) applicationContext;
portletCtx.addPortletListener(this, this);
} else {
mainWindow.addComponent(new Label(getMessage("please.use.from.a.portlet")));
}
}
@Override
public void withTransaction(final ProcessToolGuiCallback r) {
ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext();
r.callback(ctx, bpmSession);
}
public void handleRenderRequest(RenderRequest request, RenderResponse response, Window window) {
showKeysString = PortalBridge.getCurrentRequestParameter("showKeys");
if (request.getLocale() != null) {
setLocale(request.getLocale());
}
else {
setLocale(Locale.getDefault());
}
if (lastLocale!=null && !getLocale().equals(lastLocale)){
VaadinUtility.informationNotification(this, getMessage("please.relog.lang.change"));
}
lastLocale = getLocale();
user = PortalBridge.getLiferayUser(request);
userRoles = user != null ? user.getRoleNames() : Collections.<String>emptyList();
if (user == null) {
if (loginRequired) {
window.removeAllComponents();
window.addComponent(new Label(getMessage("please.log.in")));
return;
}
} else {
PortletSession session = ((PortletApplicationContext2) (getContext())).getPortletSession();
bpmSession = (ProcessToolBpmSession) session.getAttribute("bpmSession", PortletSession.APPLICATION_SCOPE);
if (bpmSession == null) {
ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext();
session.setAttribute("bpmSession",
bpmSession = ctx.getProcessToolSessionFactory().createSession(user, userRoles),
PortletSession.APPLICATION_SCOPE);
}
setUser(user);
}
if (!initialized) {
initializePortlet();
}
initialized = true;
renderPortlet();
handleRequestListeners();
}
public boolean showKeys() {
return showKeysString != null;
}
public boolean isLoginRequired() {
return loginRequired;
}
public void setLoginRequired(boolean loginRequired) {
this.loginRequired = loginRequired;
}
public UserData getUser() {
return user;
}
public UserData getUser(String login) {
return LiferayBridge.getLiferayUser(login, user.getCompanyId());
}
public UserData getUserByEmail(String email) {
return LiferayBridge.getLiferayUserByEmail(email, user.getCompanyId());
}
public List<UserData> getAllUsers() {
return users == null ? (users = LiferayBridge.getAllUsersByCurrentUser(user)) : users;
}
public void setUser(UserData user) {
this.user = user;
}
@Override
public String getMessage(String key) {
return i18NSource.getMessage(key, key);
}
@Override
public String getMessage(String key, String defaultValue) {
return i18NSource.getMessage(key, defaultValue);
}
@Override
public String getMessage(String key, Object... params) {
return i18NSource.getMessage(key, params);
}
@Override
public String getMessage(String key, String defaultValue, Object... params) {
return i18NSource.getMessage(key, defaultValue, params);
}
@Override
public void setLocale(Locale locale) {
super.setLocale(locale);
this.locale = locale;
this.i18NSource = I18NSourceFactory.createI18NSource(locale);
}
public void handleActionRequest(ActionRequest request, ActionResponse response, Window window) {
// nothing
}
public void handleEventRequest(EventRequest request, EventResponse response, Window window) {
// nothing
}
public void handleResourceRequest(ResourceRequest request, ResourceResponse response, Window window) {
if (showExitWarning && Strings.hasText(request.getResourceID()) && request.getResourceID().equals("UIDL")) {
VaadinUtility.registerClosingWarning(getMainWindow(), getMessage("page.reload"));
}
}
public void onThrowable(Throwable e) {
logger.log(Level.SEVERE, e.getMessage(), e);
if (e instanceof TaskAlreadyCompletedException) {
VaadinUtility.errorNotification(this, i18NSource, i18NSource.getMessage("task.already.completed"));
}
else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(baos));
getMainWindow().showNotification(VaadinUtility.validationNotification(i18NSource.getMessage("process-tool.exception.occurred"),
getMessage(e.getMessage())));
}
}
public boolean hasMatchingRole(String roleName) {
for (String role : userRoles) {
if (role != null && role.matches(roleName)) {
return true;
}
}
return false;
}
public void setShowExitWarning(boolean showExitWarning) {
this.showExitWarning = showExitWarning;
}
public static abstract class RequestParameterListener implements EventListener<RequestParameterEvent> {
protected final Set<String> supportedParameters;
public RequestParameterListener(final String... supportedParameters) {
this(new HashSet<String>() {{
for (String param : supportedParameters) {
add(param);
}
}});
}
public RequestParameterListener(Set<String> supportedParameters) {
if (supportedParameters.isEmpty()) {
throw new IllegalArgumentException("Supported parameters set cannot be empty");
}
this.supportedParameters = supportedParameters;
}
@Override
public void onEvent(RequestParameterEvent requestParameterEvent) {
Map<String, String[]> parameterMap = requestParameterEvent.getParameterMap();
Map<String, String[]> mappedParameters = new HashMap<String, String[]>();
for (String param : supportedParameters) {
String[] values = parameterMap.get(param);
if (values != null && values.length > 0) {
mappedParameters.put(param, values);
}
}
if (!mappedParameters.isEmpty()) {
handleRequestParameters(mappedParameters);
}
}
public abstract void handleRequestParameters(Map<String, String[]> parameters);
}
public static class RequestParameterEvent {
private final Map<String, String[]> parameterMap;
public RequestParameterEvent(Map<String, String[]> parameterMap) {
this.parameterMap = parameterMap;
}
public Map getParameterMap() {
return parameterMap;
}
}
@Override
public void addListener(RequestParameterListener listener) {
listenable.addListener(listener);
}
@Override
public void removeListener(RequestParameterListener listener) {
listenable.addListener(listener);
}
private void handleRequestListeners() {
if (listenable.hasListeners()) {
Map<String, String[]> parameterMap = PortalBridge.getCurrentRequestParameterMap();
listenable.fireEvent(new RequestParameterEvent(parameterMap));
}
}
}