blob: e9ebafd5bfe05f02fa99b183d101f44ad3ef0661 [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*/
package org.eclipse.osbp.xtext.dialogdsl.common;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.di.extensions.EventUtils;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.dto.lib.services.IDTOServiceWithMutablePersistence;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.notification.AbstractReloadRequestService;
import org.eclipse.osbp.ecview.core.common.notification.IReloadRequestService;
import org.eclipse.osbp.ecview.core.common.store.IViewStore;
import org.eclipse.osbp.ecview.extension.model.YStrategyLayout;
import org.eclipse.osbp.ecview.extension.presentation.vaadin.components.common.ECViewComponent;
import org.eclipse.osbp.eventbroker.EventBrokerMsg;
import org.eclipse.osbp.i18n.common.OSI18nService;
import org.eclipse.osbp.persistence.IPersistenceService;
import org.eclipse.osbp.runtime.common.annotations.DirtyStateAdapter;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.i18n.II18nService;
import org.eclipse.osbp.runtime.web.vaadin.common.resource.IResourceProvider;
import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptLoosingDataDialog;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.report.IReportProvider;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.ui.common.helper.ICommonUIHelper;
import org.eclipse.osbp.utils.vaadin.SelectDialog;
import org.eclipse.osbp.utils.vaadin.ViewLayoutManager;
import org.eclipse.osbp.vaaclipse.common.ecview.E4EventBrokerAdapter;
import org.eclipse.osbp.vaaclipse.common.ecview.ECViewToE4ServiceBridge;
import org.eclipse.osbp.xtext.action.common.IToolbarAction;
import org.osgi.dto.DTO;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
/**
* The Class AbstractEmbeddedDialog.
*
* @param <DTO> the generic type
*/
@SuppressWarnings("all")
public abstract class AbstractEmbeddedDialog<DTO> implements IUser.UserLocaleListener {
/** The Constant EVENT__CANCEL. */
public static final String EVENT__CANCEL = "Cancel";
/** The Constant EVENT__DELETE. */
public static final String EVENT__DELETE = "Delete";
/** The Constant EVENT__SAVE. */
public static final String EVENT__SAVE = "Save";
/** The Constant EVENT__NEW. */
public static final String EVENT__NEW = "New";
/** The Constant log. */
private final static Logger log = LoggerFactory.getLogger("vaaclipseDialog");
/** The user id. */
@Inject
@Named("userId")
@Optional
String userId;
/** The event broker. */
@Inject
private IEventBroker eventBroker;
/** The rendering engine. */
@Inject
private IPresentationEngine renderingEngine;
/** The persistence service. */
@Inject
private IPersistenceService persistenceService;
/** The theme resource service. */
@Inject
private IThemeResourceService themeResourceService;
/** The common ui helper. */
@Inject
private ICommonUIHelper commonUIHelper;
/** The translator class service. */
@Inject
private IDSLMetadataService dslMetadataService;
/** The report provider. */
@Inject IReportProvider reportProvider;
/** The i18n service. */
@Inject
private II18nService i18nService;
/** The view store. */
@Inject
private IViewStore viewStore;
/** The eclipse context. */
@Inject
private IEclipseContext eclipseContext;
@Inject
private IUser user;
/** The strategy event handler. */
private StrategyEventHandler strategyEventHandler;
/** The table selection handler. */
private EventHandler tableSelectionHandler;
/** The dispatch action handler. */
private EventHandler dispatchActionHandler;
/** The dispatch new ok handler. */
private EventHandler dispatchNewOkHandler;
/** The view context. */
// ecview stuff
private IViewContext viewContext;
/** The ecview component. */
private ECViewComponent ecviewComponent;
/** The rendering params. */
private Map<String, Object> renderingParams;
/** The dto service. */
private IDTOServiceWithMutablePersistence<DTO> dtoService;
/** The layout manager. */
private ViewLayoutManager layoutManager;
/** The toolbar helper. */
private IToolbarAction toolbarHelper;
/** The uuid. */
protected String uuid = UUID.randomUUID().toString();
private Label dialogLabel;
private boolean newCreatedDto = false;
private SelectDialog selectDialog;
private Window selectWindow;
private IReloadRequestService reloadRequestService = new AbstractReloadRequestService() {
@Override
public void requestReload(YEmbeddable component, Object newDto) {
if (viewContext == null) {
return;
}
Object currentDto = viewContext.getBean(getMainBeanSlot());
if (currentDto != null) {
boolean dirty = false;
// check if any dto in the dto tree is dirty
DirtyStateAdapter adapter = DtoUtils.getAdapter(DirtyStateAdapter.class, currentDto);
if (adapter != null) {
dirty = adapter.isDirty();
}
if (!dirty) {
try {
// in case no adapter available, check if
// the current dto is dirty
dirty = DtoUtils.isDirty(currentDto);
} catch (IllegalAccessException e) {
}
}
if (dirty) {
showLoosingDataDialog(viewContext, currentDto, newDto);
} else {
viewContext.setBean(getMainBeanSlot(), newDto);
}
} else {
viewContext.setBean(getMainBeanSlot(), newDto);
}
}
};
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView#createView(com.vaadin.ui.VerticalLayout)
*/
public void createView(final VerticalLayout parent) {
layoutManager = new ViewLayoutManager();
layoutManager.init(parent);
// create the toolbar
//
toolbarHelper = createToobarHelper();
if (toolbarHelper != null) {
toolbarHelper.createToolbar(eclipseContext, renderingEngine, themeResourceService);
}
if (viewStore != null) {
ecviewComponent = new ECViewComponent(new ECViewComponent.ViewProviderCallback() {
@Override
public YView getView(String viewId, Map<String, Object> properties) {
// use the view store to find a user saved view
return viewStore.getMostRecentView(userId, viewId);
}
});
} else {
ecviewComponent = new ECViewComponent();
}
ecviewComponent.setSizeFull();
layoutManager.getDataArea().addComponent(ecviewComponent);
// create the rendering params used for ECView
renderingParams = createRenderingParams();
// create the event handlers
strategyEventHandler = new StrategyEventHandler();
selectDialog = new SelectDialog();
tableSelectionHandler = new EventHandler() {
@Override
public void handleEvent(Event event) {
Object dto = null;
Object data = event.getProperty(org.eclipse.e4.core.di.extensions.EventUtils.DATA);
if (data instanceof IDto) {
dto = data;
} else if (data instanceof EventBrokerMsg) {
EventBrokerMsg msg = (EventBrokerMsg) data;
String id = msg.getId();
log.debug("load bean with id:" + id);
if (id != null) {
try {
dto = dtoService.get((int) Double.parseDouble(id));
} catch (NumberFormatException e) {
dto = dtoService.get(id);
} catch (NullPointerException e) {
dto = dtoService.get(id);
}
}
}
ecviewComponent.setValue(getViewId(), dto, renderingParams);
newCreatedDto = false;
reloadRequestService.setMode(true);
}
};
dispatchActionHandler = new EventHandler() {
@Override
public void handleEvent(Event event) {
EventBrokerMsg msg = (EventBrokerMsg) event.getProperty(org.eclipse.e4.core.di.extensions.EventUtils.DATA);
log.debug("dispatch action received in Company for " + msg.getName());
switch (msg.getName()) {
case EVENT__NEW:
String dtoFQN = getBaseDtoName();
Map<String, String> subTypes = dslMetadataService.getAllTypeNames(user.getLocale().toLanguageTag(), dtoFQN);
if (subTypes.size() > 1) {
selectWindow = selectDialog.init(eventBroker, subTypes, dtoFQN, "Select SubType", "Ok", getUUID());
UI.getCurrent().addWindow(selectWindow);
} else {
createNew(dtoFQN);
}
break;
case EVENT__SAVE:
try {
DTO savedDto = (DTO) viewContext.getBean(getMainBeanSlot());
dtoService.update(savedDto);
DTO newInstance = dtoService.get(getIdForDto(savedDto));
ecviewComponent.setValue(getViewId(), newInstance, renderingParams);
int insertUpdateFlag = newCreatedDto ? 1 : 0;
eventBroker.send(EventBrokerMsg.REFRESH_VIEW + getEventTopicSuffix(), new EventBrokerMsg(getIdForDtoString(savedDto), getDataName(), 0L, insertUpdateFlag));
newCreatedDto = false;
reloadRequestService.setMode(true);
} catch (Exception ex) {
showSaveErrorMessage(ex);
}
break;
case EVENT__DELETE:
try {
DTO deletedDto = (DTO) viewContext.getBean(getMainBeanSlot());
dtoService.delete(deletedDto);
ecviewComponent.setValue(getViewId(), null, renderingParams);
eventBroker.send(EventBrokerMsg.REFRESH_VIEW + getEventTopicSuffix(), new EventBrokerMsg(getIdForDtoString(deletedDto), getDataName()));
newCreatedDto = false;
reloadRequestService.setMode(false);
// initial state of the dialog has to be NEW. This fills the view context with a initial blank bean.
createNew(getBaseDtoName());
} catch (org.eclipse.osbp.dsl.dto.lib.services.DtoServiceException dtoEx) {
showDeleteErrorMessage(dtoEx);
}
break;
case EVENT__CANCEL:
DTO canceledDto = (DTO) viewContext.getBean(getMainBeanSlot());
DTO oldInstanceCompanyDto = dtoService.get(getIdForDto(canceledDto));
ecviewComponent.setValue(getViewId(), oldInstanceCompanyDto, renderingParams);
reloadRequestService.setMode(false);
break;
}
}
};
dispatchNewOkHandler = new EventHandler() {
@Override
public void handleEvent(Event event) {
if (selectWindow != null) {
selectWindow.close();
UI.getCurrent().removeWindow(selectWindow);
selectWindow = null;
}
EventBrokerMsg msg = (EventBrokerMsg) event.getProperty(EventUtils.DATA);
createNew(msg.getName());
}
};
user.addUserLocaleListener(this);
subscribe();
}
/**
* Creates a new dto.
*
* @param typeName
* the type name for the dto
*/
protected void createNew(String typeName) {
Object newDto = null;
Class<?> clazz = null;
try {
clazz = dslMetadataService.createType(typeName);
} catch (ClassNotFoundException e) {
log.error("{}", e);
return;
}
try {
newDto = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
log.error("{}", e);
return;
}
newCreatedDto = true;
viewContext.setBean(getMainBeanSlot(), newDto);
reloadRequestService.setMode(false);
}
public void createComponents() {
registerPersistenceUnit(persistenceService);
// DTO Services (via DS)
dtoService = getDtoService();
// OSBP UI Code
viewContext = ecviewComponent.setValue(getViewId(), null, renderingParams);
viewContext.setLocale(user.getLocale());
// enable the suggest mode of suggest textfields
reloadRequestService.setMode(true);
YView yView = (YView) viewContext.getViewEditpart().getModel();
if (yView == null) {
Notification.show("Dialog could not be found!", Type.ERROR_MESSAGE);
return;
}
// render the Vaadin UI
YStrategyLayout yStrategyLayoutT = commonUIHelper.findLayout(yView);
if (yStrategyLayoutT != null) {
yStrategyLayoutT.setDefaultFocusingEnhancerId("DefaultFocusingEnhancer");
}
// Creating event handler for receiving events from StrategyCombo
strategyEventHandler.setViewContext(viewContext);
strategyEventHandler.setUi(UI.getCurrent());
strategyEventHandler.setLayout(commonUIHelper.findLayout(yView));
// initial state of the dialog has to be NEW. This fills the view context with a initial blank bean.
createNew(getBaseDtoName());
}
/**
* Removes the old view.
*/
private void removeOldView() {
if (viewContext != null) {
viewContext.dispose();
}
if (layoutManager.getDataArea().getComponentCount() > 0) {
layoutManager.getDataArea().removeAllComponents();
}
}
/**
* Creates the rendering parameters.
*
* @return the map
*/
protected Map<String, Object> createRenderingParams() {
Map<String, Object> params = new HashMap<String, Object>();
Map<String, Object> services = new HashMap<String, Object>();
params.put(IViewContext.PARAM_SERVICES, services);
params.put(ECViewComponent.PROP_SLOT, getMainBeanSlot());
params.put(IViewContext.PARAM_THIRDPARTY_SERVICE_PROVIDER, new ECViewToE4ServiceBridge(eclipseContext));
services.put(org.eclipse.osbp.runtime.common.event.IEventBroker.class.getName(), new E4EventBrokerAdapter(eventBroker));
services.put(II18nService.class.getName(), new OSI18nService(dslMetadataService, i18nService));
services.put(IUser.class.getName(), user);
// this service will handle reload requests from YSuggestTextField
services.put(IReloadRequestService.class.getName(), reloadRequestService);
return params;
}
/**
* Shows a dialog which warns about loosing data.
*
* @param context
* the context
* @param currentDto
* the current dto
* @param newDto
* the new dto
*/
protected void showLoosingDataDialog(IViewContext context, Object currentDto, Object newDto) {
II18nService i18nService = context.getService(II18nService.class.getName());
IResourceProvider resourceProvider = eclipseContext.get(IResourceProvider.class);
AcceptLoosingDataDialog.showDialog(i18nService, resourceProvider, new Runnable() {
@Override
public void run() {
viewContext.setBean(getMainBeanSlot(), newDto);
}
}, null);
}
/**
* Gets the uuid.
*
* @return the uuid
*/
protected String getUUID() {
return uuid;
}
/**
* Subscribe.
*/
protected void subscribe() {
eventBroker.subscribe(EventBrokerMsg.AUTOWIRED_ENTITY_PREFIX + getDataName(), tableSelectionHandler);
if (toolbarHelper != null) {
eventBroker.subscribe(EventBrokerMsg.ACTION_BUTTON_EXECUTE_PREFIX + toolbarHelper.getClass().getSimpleName() + getUUID(), dispatchActionHandler);
}
eventBroker.subscribe(EventBrokerMsg.DIALOG_STRATEGY_CHANGED, strategyEventHandler);
eventBroker.subscribe(EventBrokerMsg.QUERY_ANSWER + getUUID(), dispatchNewOkHandler);
}
/**
* Unsubscribe.
*/
@PreDestroy
protected void unsubscribe() {
eventBroker.unsubscribe(dispatchActionHandler);
eventBroker.unsubscribe(tableSelectionHandler);
eventBroker.unsubscribe(strategyEventHandler);
eventBroker.unsubscribe(dispatchNewOkHandler);
}
/**
* Gets the view id.
*
* @return the view id
*/
protected abstract String getViewId();
/**
* Gets the main bean slot.
*
* @return the main bean slot
*/
protected abstract String getMainBeanSlot();
/**
* Gets the full qualified dto name.
*
* @return the base class dto name
*/
protected abstract String getBaseDtoName();
/**
* Gets the id for dto string.
*
* @param savedDto
* the saved dto
* @return the id for dto string
*/
protected abstract String getIdForDtoString(DTO savedDto);
/**
* Gets the id for dto.
*
* @param savedDto
* the saved dto
* @return the id for dto
*/
protected abstract Object getIdForDto(DTO savedDto);
/**
* Gets the event topic suffix.
*
* @return the event topic suffix
*/
protected abstract String getEventTopicSuffix();
/**
* Gets the data name.
*
* @return the data name
*/
protected abstract String getDataName();
/**
* Gets the binding property name.
*
* @return the binding property name
*/
protected abstract String getBindingPropertyName();
/**
* Gets the dto service.
*
* @return the dto service
*/
protected abstract IDTOServiceWithMutablePersistence<DTO> getDtoService();
protected abstract void registerPersistenceUnit(IPersistenceService persistenceService);
/**
* Creates the toobar helper.
*
* @return the i dialog toolbar action
*/
protected abstract IToolbarAction createToobarHelper();
/**
* Show save error message.
*
* @param ex
* the ex
*/
protected abstract void showSaveErrorMessage(Exception ex);
/**
* Show delete error message.
*
* @param ex
* the ex
*/
protected abstract void showDeleteErrorMessage(Exception ex);
@Override
public void localeChanged(final Locale locale) {
if (layoutManager != null) {
layoutManager.setLabelValue(dslMetadataService.translate(user.getLocale().toLanguageTag(), getBindingPropertyName()));
}
}
}