| /** |
| * |
| * Copyright (c) 2011, 2019 - 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 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| */ |
| package org.eclipse.osbp.vaaclipse.addons.softwarefactory.perspective; |
| |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| import java.util.UUID; |
| import java.util.function.Consumer; |
| |
| import javax.annotation.PostConstruct; |
| import javax.annotation.PreDestroy; |
| import javax.inject.Inject; |
| import javax.inject.Named; |
| import javax.swing.Timer; |
| |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.e4.core.di.annotations.Optional; |
| import org.eclipse.e4.core.services.events.IEventBroker; |
| import org.eclipse.e4.ui.di.Focus; |
| import org.eclipse.e4.ui.model.application.MApplication; |
| import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; |
| import org.eclipse.e4.ui.workbench.IPresentationEngine; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.osbp.blob.component.BlobConverter; |
| import org.eclipse.osbp.core.api.persistence.IPersistenceService; |
| import org.eclipse.osbp.dsl.common.datatypes.IDto; |
| import org.eclipse.osbp.dsl.dto.lib.impl.DtoServiceAccess; |
| import org.eclipse.osbp.dsl.semantic.entity.LEntity; |
| import org.eclipse.osbp.ecview.core.common.beans.ISlot; |
| import org.eclipse.osbp.ecview.core.common.context.IConfiguration; |
| import org.eclipse.osbp.ecview.core.common.context.IContext; |
| import org.eclipse.osbp.ecview.core.common.context.IViewContext; |
| import org.eclipse.osbp.ecview.core.common.editpart.IFieldEditpart; |
| import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable; |
| import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableEvent; |
| import org.eclipse.osbp.ecview.core.common.model.core.YField; |
| import org.eclipse.osbp.ecview.core.common.model.core.YView; |
| import org.eclipse.osbp.ecview.core.common.model.core.util.BindingIdUtil; |
| 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.services.IWidgetAssocationsService; |
| import org.eclipse.osbp.ecview.core.common.store.IViewStore; |
| import org.eclipse.osbp.ecview.core.common.validation.IFieldValidationManager; |
| import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage; |
| import org.eclipse.osbp.ecview.core.extension.model.extension.YButton; |
| import org.eclipse.osbp.ecview.core.extension.model.extension.listener.YButtonClickListener; |
| import org.eclipse.osbp.ecview.core.util.emf.ModelUtil; |
| import org.eclipse.osbp.ecview.extension.api.IFocusingStrategy; |
| import org.eclipse.osbp.ecview.extension.api.ILayoutingStrategy; |
| import org.eclipse.osbp.ecview.extension.presentation.vaadin.components.common.ECViewComponent; |
| import org.eclipse.osbp.ecview.semantic.uimodel.UiBeanSlot; |
| import org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView; |
| import org.eclipse.osbp.runtime.common.annotations.DirtyStateAdapter; |
| import org.eclipse.osbp.runtime.common.annotations.DtoUtils; |
| import org.eclipse.osbp.runtime.common.annotations.IsDirty; |
| import org.eclipse.osbp.runtime.common.annotations.IsNew; |
| import org.eclipse.osbp.runtime.common.annotations.IsPositioned; |
| import org.eclipse.osbp.runtime.common.annotations.IsValid; |
| import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent; |
| import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherDataTag; |
| import org.eclipse.osbp.runtime.common.event.IEventDispatcher; |
| import org.eclipse.osbp.runtime.common.event.SelectionStore; |
| import org.eclipse.osbp.runtime.common.filter.IDTOHistorizedService; |
| import org.eclipse.osbp.runtime.common.filter.IDTOService; |
| import org.eclipse.osbp.runtime.common.filter.IDTOService; |
| import org.eclipse.osbp.runtime.common.validation.IStatus; |
| import org.eclipse.osbp.runtime.common.validation.ValidationKind; |
| import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptDeleteDialog; |
| import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptLoosingDataDialog; |
| import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.AcceptSaveDialog; |
| import org.eclipse.osbp.runtime.web.vaadin.components.dialogs.QueryDeleteDialog; |
| import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables; |
| import org.eclipse.osbp.ui.api.contextfunction.IViewEmbeddedProvider; |
| import org.eclipse.osbp.ui.api.customfields.IBlobConverter; |
| import org.eclipse.osbp.ui.api.customfields.IBlobService; |
| import org.eclipse.osbp.ui.api.e4.IE4Dialog; |
| import org.eclipse.osbp.ui.api.functionlibrary.IFunctionLibraryService; |
| import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService; |
| import org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider; |
| import org.eclipse.osbp.ui.api.report.IReportProvider; |
| import org.eclipse.osbp.ui.api.statemachine.IDataProvider; |
| import org.eclipse.osbp.ui.api.statemachine.IPeripheral; |
| import org.eclipse.osbp.ui.api.statemachine.IStateMachine; |
| import org.eclipse.osbp.ui.api.statemachine.IStateMachineParticipant; |
| import org.eclipse.osbp.ui.api.themes.EnumCssClass; |
| import org.eclipse.osbp.ui.api.themes.IThemeResourceService; |
| import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType; |
| import org.eclipse.osbp.ui.api.user.IUser; |
| import org.eclipse.osbp.utils.common.EntityUtils; |
| import org.eclipse.osbp.utils.vaadin.DTOInfoDialog; |
| import org.eclipse.osbp.utils.vaadin.SelectDialog; |
| import org.eclipse.osbp.utils.vaadin.ViewLayoutManager; |
| import org.eclipse.osbp.vaaclipse.addons.common.api.IE4Topics; |
| import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusManager; |
| import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusScope; |
| import org.eclipse.osbp.vaaclipse.common.ecview.E4EventBrokerAdapter; |
| import org.eclipse.osbp.vaaclipse.common.ecview.ECViewToE4ServiceBridge; |
| import org.eclipse.osbp.vaaclipse.common.ecview.api.IECViewContainer; |
| import org.eclipse.osbp.xtext.action.ActionDSLPackage; |
| import org.eclipse.osbp.xtext.action.ActionToolbar; |
| import org.eclipse.osbp.xtext.action.DialogActionEnum; |
| import org.eclipse.osbp.xtext.action.UIActionEnum; |
| import org.eclipse.osbp.xtext.action.common.IToolbarAction; |
| import org.eclipse.osbp.xtext.dialogdsl.Dialog; |
| import org.eclipse.osbp.xtext.dialogdsl.DialogFieldHook; |
| import org.eclipse.xtext.xbase.lib.Pair; |
| import org.osgi.service.event.Event; |
| import org.osgi.service.event.EventHandler; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.vaadin.event.LayoutEvents.LayoutClickEvent; |
| import com.vaadin.ui.Button; |
| import com.vaadin.ui.Button.ClickEvent; |
| import com.vaadin.ui.Component; |
| import com.vaadin.ui.HorizontalLayout; |
| 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 ECViewDialog. |
| * |
| * @param <DTO> |
| * the generic type |
| */ |
| @SuppressWarnings("all") |
| public class DialogProvider<DTO> extends AbstractHybridVaaclipseView implements |
| IUser.UserLocaleListener, IEventDispatcher.Receiver, IFieldValidationManager.Listener , IE4Dialog, |
| IViewEmbeddedProvider, YButtonClickListener{ |
| |
| /** The Constant log. */ |
| protected final static Logger log = LoggerFactory.getLogger("vaaclipseDialog"); |
| |
| /** The Constant BEAN_SLOT__VALIDATION_ERROR. */ |
| protected static final String BEAN_SLOT__VALIDATION_ERROR = "validationError"; |
| |
| /** The dialog label. */ |
| protected String dialogLabel; |
| |
| /** The event broker. */ |
| @Inject |
| protected IECViewContainer ecviewContainer; |
| |
| /** The event broker. */ |
| @Inject |
| protected IEventBroker eventBroker; |
| |
| /** The theme resource service. */ |
| @Inject |
| protected IThemeResourceService themeResourceService; |
| |
| /** The translator class service. */ |
| @Inject |
| protected IDSLMetadataService dslMetadataService; |
| |
| /** The report provider. */ |
| @Inject IReportProvider reportProvider; |
| |
| /** The blob service. */ |
| @Inject IBlobService blobService; |
| |
| /** The view store. */ |
| @Inject |
| protected IViewStore viewStore; |
| |
| /** The currently active part. */ |
| @Inject |
| @Optional |
| protected MPart mPart; |
| |
| /** The persistence service. */ |
| @Inject |
| protected IPersistenceService persistenceService; |
| |
| /** The event dispatcher. */ |
| @Inject |
| protected IEventDispatcher eventDispatcher; |
| |
| /** The status manager. */ |
| @Inject |
| protected IStatusManager statusManager; |
| |
| /** The eclipse context. */ |
| @Inject |
| protected IEclipseContext eclipseContext; |
| |
| /** The rendering engine. */ |
| @Inject |
| protected IPresentationEngine renderingEngine; |
| |
| /** The function library service. */ |
| @Inject |
| protected IFunctionLibraryService functionLibraryService; |
| |
| /** The user. */ |
| @Inject |
| protected IUser user; |
| |
| /** The view context. */ |
| protected IViewContext viewContext; |
| |
| /** The ecview component. */ |
| protected ECViewComponent ecviewComponent; |
| |
| /** The rendering params. */ |
| protected Map<String, Object> renderingParams; |
| |
| /** The uuid. */ |
| protected String uuid = UUID.randomUUID().toString(); |
| |
| /** The layout manager. */ |
| protected ViewLayoutManager layoutManager; |
| |
| /** The dto service. */ |
| private IDTOService<DTO> dtoService; |
| |
| /** The toolbar helper. */ |
| private IToolbarAction toolbar; |
| |
| /** Flag whether the dto is newly created */ |
| private boolean newCreatedDto = false; |
| |
| /** The select dialog to get the desired base- or sub-class. */ |
| private SelectDialog selectDialog; |
| |
| /** The select window for the dialog. */ |
| private Window selectWindow; |
| |
| /** The dirty state adapter. */ |
| private DirtyStateAdapter dirtyStateAdapter; |
| |
| /** The ecview field validation manager. */ |
| private IFieldValidationManager ecviewFieldValidationManager; |
| |
| /** The validation result. */ |
| private Set<IStatus> validationResult; |
| |
| /** The info window for last update etc. */ |
| private DTOInfoDialog infoWindow; |
| |
| /** The last used base dto. */ |
| private Class<?> lastBaseDto; |
| |
| /** The field that gets focus. */ |
| private EventHandler onFocusField; |
| |
| /** The underlying xtext dialog model. */ |
| private Dialog dialogModel = null; |
| |
| @Inject |
| @Named("Focusing") |
| private IFocusingStrategy focusingStrategy; |
| |
| /** The reload request service for suggesttext fields. */ |
| private IReloadRequestService reloadRequestService = new AbstractReloadRequestService() { |
| @Override |
| public void requestReload(YEmbeddable component, Object newDto) { |
| updateBindings(newDto); |
| setNewCreatedDto(newDto == null); |
| } |
| }; |
| |
| /** The widget association service. */ |
| private IWidgetAssocationsService<Component, EObject> associationService; |
| |
| private ArrayList<Button> taskButtons; |
| |
| private List<Consumer<DTO>> saveListeners; |
| |
| private boolean manualInput = false; |
| |
| private Timer timer; |
| |
| private boolean oldDirty = false; |
| |
| private String dtoName; |
| |
| private Map<String, Object> subTypes; |
| |
| private String viewId; |
| |
| private String entityName; |
| |
| private String primaryKey; |
| |
| private Class<?> dto; |
| |
| private Object numColumns; |
| |
| private Class<?> dialogFunctionGroup; |
| |
| private Method initializationMethod; |
| private Method preSaveMethod; |
| private Method postSaveMethod; |
| private Map<YField, Pair<Method, Method>> fieldHooks = new HashMap<>(); |
| |
| private VerticalLayout parent; |
| |
| private YView yView; |
| |
| /** |
| * Instantiates a new abstract ec view dialog. |
| * |
| * @param parent |
| * the parent |
| * @param context |
| * the context |
| * @param app |
| * the app |
| */ |
| @Inject |
| public DialogProvider(final VerticalLayout parent, final IEclipseContext context, final MApplication app) { |
| super(parent, context, app); |
| uuid = UUID.randomUUID().toString(); |
| } |
| |
| public DialogProvider() { |
| uuid = UUID.randomUUID().toString(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView#createView |
| * (com.vaadin.ui.VerticalLayout) |
| */ |
| @Override |
| public void createView(final VerticalLayout externalParent) { |
| if(externalParent != null) { |
| parent = externalParent; |
| } else { |
| parent = new VerticalLayout(); |
| } |
| parent.addStyleName(EnumCssClass.DIALOG_VIEW.toString()); |
| layoutManager = new ViewLayoutManager(); |
| if(dialogModel.isHasBackgroundImage()) { |
| layoutManager.init(parent, viewId.replaceAll("\\.","-") + "-"+dialogModel.getBackgroundImage(), themeResourceService.getThemeResourceRelativePath(dialogModel.getBackgroundImage(), ThemeResourceType.IMAGE)); |
| } else { |
| layoutManager.init(parent); |
| } |
| |
| ecviewComponent.setSizeFull(); |
| layoutManager.getDataArea().addComponent(ecviewComponent); |
| layoutManager.setLabelValue(dslMetadataService.translate(user.getLocale().toLanguageTag(), dialogLabel)); |
| selectDialog = new SelectDialog(); |
| // create toolbar |
| if(dialogModel.getToolbar() != null) { |
| String toolBarId = dslMetadataService.getFullyQualifiedName(dialogModel.getToolbar()); |
| ActionToolbar toolBarModel = (ActionToolbar) dslMetadataService.getMetadata(toolBarId, ActionDSLPackage.Literals.ACTION_TOOLBAR); |
| toolbar = (IToolbarAction) dslMetadataService.getClassInstance(toolBarModel, "action"); |
| toolbar.createToolbar(eclipseContext, renderingEngine, themeResourceService, uuid); |
| } |
| if(dialogModel.isEmbedded()) { |
| createEmbeddedToolbar(); |
| } |
| } |
| |
| private void initDialog() { |
| if(mPart != null) { |
| dialogModel = (Dialog) mPart.getTransientData().get(IPerspectiveProvider.TRANSIENT_DIALOG_MODEL); |
| } else { |
| dialogModel = (Dialog) eclipseContext.get(IPerspectiveProvider.TRANSIENT_EMBEDDED_DIALOG_MODEL); |
| } |
| viewId = dslMetadataService.getECViewId(dialogModel); |
| dtoName = dslMetadataService.getFullyQualifiedName(dialogModel.getDto()); |
| if(dtoName != null) { |
| LEntity entity = EntityUtils.getEntityFromDto(dialogModel.getDto()); |
| entityName = entity!=null?EntityUtils.getFQNForLEntity(entity):""; |
| primaryKey = entity!=null?dslMetadataService.getFullyQualifiedName(entity)+"."+entity.getIdAttributeName():""; |
| dto = dslMetadataService.getClass(dialogModel.getDto(), "dto"); |
| dtoService = (IDTOService<DTO>) DtoServiceAccess.getService(dto); |
| subTypes = dslMetadataService.getAllSubtypes(user.getLocale().toLanguageTag(), dto); |
| } |
| dialogLabel = dialogModel.getName(); |
| numColumns = dialogModel.getNumColumns(); |
| |
| dirtyStateAdapter = new DirtyStateAdapter(); |
| eclipseContext.set(IE4Dialog.class, this); |
| 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(user.getUserName(), viewId); |
| } |
| }); |
| } else { |
| ecviewComponent = new ECViewComponent(); |
| } |
| renderingParams = createRenderingParams(); |
| viewContext = ecviewComponent.setValue(viewId, null, renderingParams); |
| if (viewContext == null) { |
| String message = "ViewContext could not be set for '" + viewId + "'"; |
| log.error("{}", message); |
| Notification.show(message, Type.ERROR_MESSAGE); |
| } else { |
| viewContext.setLocale(user.getLocale()); |
| viewContext.createBeanSlot(BEAN_SLOT__VALIDATION_ERROR, Boolean.class); |
| viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.FALSE); |
| if(mPart != null) { |
| mPart.getContext().set(IViewContext.class, viewContext); |
| } |
| associationService = viewContext.getService(IWidgetAssocationsService.ID); |
| // bridges the validation from ECView core to Vaaclipse |
| setupValidationBridge(); |
| yView = (YView) viewContext.getViewEditpart().getModel(); |
| if (yView == null) { |
| Notification.show("Dialog could not be found!", Type.ERROR_MESSAGE); |
| return; |
| } |
| } |
| addSaveAndNewListener(); |
| |
| if(dialogModel.getGroup() != null) { |
| dialogFunctionGroup = functionLibraryService.getFunctionLibraryClass(dslMetadataService.getFullyQualifiedName(dialogModel.getGroup())); |
| if(dialogModel.getInitialization() != null) { |
| initializationMethod = functionLibraryService.getMethod(dialogFunctionGroup, dialogModel.getInitialization().getName()); |
| } |
| if(dialogModel.getPreSave() != null) { |
| preSaveMethod = functionLibraryService.getMethod(dialogFunctionGroup, dialogModel.getPreSave().getName()); |
| } |
| if(dialogModel.getPostSave() != null) { |
| postSaveMethod = functionLibraryService.getMethod(dialogFunctionGroup, dialogModel.getPostSave().getName()); |
| } |
| for(DialogFieldHook fieldHook:dialogModel.getFieldHooks()) { |
| Method preFocus = null; |
| Method postFocus = null; |
| if(fieldHook.getPreFocus() != null) { |
| preFocus = functionLibraryService.getMethod(dialogFunctionGroup, fieldHook.getPreFocus().getName()); |
| } |
| if(fieldHook.getPostFocus() != null) { |
| postFocus = functionLibraryService.getMethod(dialogFunctionGroup, fieldHook.getPostFocus().getName()); |
| } |
| Pair functions = new Pair(preFocus, postFocus); |
| YField fld = (YField)associationService.getModelElement(viewId+"."+dialogModel.getDto().getName()+"."+fieldHook.getAttribute().getName()); |
| if(fld != null) { |
| fieldHooks.put(fld, functions); |
| fld.eAdapters().add(new AdapterImpl() { |
| @Override |
| public void notifyChanged(org.eclipse.emf.common.notify.Notification notification) { |
| if (notification.getEventType() == org.eclipse.emf.common.notify.Notification.SET) { |
| if(notification.getFeatureID(ExtensionModelPackage.class) == ExtensionModelPackage.YTEXT_FIELD__LAST_FOCUS_EVENT) { |
| YField fld = (YField)((YEmbeddableEvent)notification.getNewValue()).getEmbeddable(); |
| if(fieldHooks.containsKey(fld) && fieldHooks.get(fld) != null) { |
| executeDialogFunction("pre field "+fld.getName(), fieldHooks.get(fld).getKey(), fld); |
| } |
| } |
| if(notification.getFeatureID(ExtensionModelPackage.class) == ExtensionModelPackage.YTEXT_FIELD__LAST_BLUR_EVENT) { |
| YField fld = (YField)((YEmbeddableEvent)notification.getNewValue()).getEmbeddable(); |
| if(fieldHooks.containsKey(fld) && fieldHooks.get(fld) != null) { |
| executeDialogFunction("post field "+fld.getName(), fieldHooks.get(fld).getValue(), fld); |
| } |
| } |
| } |
| } |
| }); |
| } |
| } |
| } |
| } |
| |
| private void addSaveAndNewListener() { |
| List<EObject> elements = associationService.getModelElements(); |
| for(EObject element:elements) { |
| if(element instanceof YButton && ((YButton)element).getTags().contains(ILayoutingStrategy.TAG__SAVEANDNEW)) { |
| ((YButton)element).addClickListener(this); |
| ((YButton)element).getTags().add(uuid); |
| } |
| } |
| } |
| |
| public Component getContent() { |
| return parent; |
| } |
| |
| @Override |
| public void validationChanged(IFieldValidationManager.Event event) { |
| // add them to the Vaaclipse status manager |
| IStatusScope scope = statusManager.getScopeFor(mPart); |
| scope.modifyStatus(event.getOldStatus(), event.getNewStatus()); |
| applyValidationResult(); |
| } |
| |
| /** |
| * Apply the validation result to the view. |
| */ |
| protected void applyValidationResult() { |
| // set the validation result |
| viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.FALSE); |
| log.debug("applyValidationResult {}", ((Boolean)viewContext.getBean(BEAN_SLOT__VALIDATION_ERROR)).booleanValue()); |
| } |
| |
| @IsValid |
| public boolean isDataValid() { |
| if(viewContext == null) { |
| return true; |
| } |
| Boolean result = (Boolean) viewContext.getBean(BEAN_SLOT__VALIDATION_ERROR); |
| if(result == null || !result) { |
| eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.VALIDITY, IE4Topics.ToolBarEvents.States.VALID, getStateLabelUUID())); |
| } else { |
| eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.VALIDITY, IE4Topics.ToolBarEvents.States.INVALID, getStateLabelUUID())); |
| } |
| if(result == null) { |
| return true; |
| } |
| return !result; |
| } |
| |
| @Focus |
| public void setFocus() { |
| if(viewContext != null && mPart != null) { |
| String fieldId = null; |
| LayoutClickEvent event = mPart.getContext().get(LayoutClickEvent.class); |
| if(event != null && event.getClickedComponent() instanceof UI) { |
| fieldId = event.getClickedComponent().getId(); |
| } |
| focusingStrategy.focusField(yView, fieldId); |
| } |
| } |
| |
| @IsDirty |
| public boolean isDirty() { |
| Object currentDto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| return isDirtyDto(currentDto); |
| } |
| |
| private boolean isDirtyDto(Object dto) { |
| boolean dirty = false; |
| if (dto != null) { |
| // check if any dto in the dto tree is dirty |
| DirtyStateAdapter adapter = DtoUtils.getAdapter(DirtyStateAdapter.class, dto); |
| if (adapter != null) { |
| dirty = adapter.isDirty(); |
| if(dirty != oldDirty ) { |
| log.debug("dirty state adapter returned {} for dto {}", dirty, dto.getClass().getName()); |
| oldDirty = dirty; |
| } |
| } |
| } |
| if(dirty) { |
| eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.STATE, IE4Topics.ToolBarEvents.States.DIRTY, getStateLabelUUID())); |
| } else { |
| eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.STATE, IE4Topics.ToolBarEvents.States.CLEAN, getStateLabelUUID())); |
| } |
| return dirty; |
| } |
| |
| @IsPositioned |
| public boolean isDtoPositioned() { |
| boolean isPositioned = false; |
| DTO currentDto = (DTO)viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| if (currentDto != null) { |
| if(DtoUtils.getIdValue(currentDto) != null) { |
| isPositioned = true; |
| } |
| } |
| return isPositioned; |
| } |
| |
| @IsNew |
| public boolean isNewDto() { |
| return newCreatedDto; |
| } |
| |
| /** |
| * Deletes the current dto entry. |
| */ |
| protected void doDelete() { |
| DTO deletedDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| dtoService.delete(deletedDto); |
| Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "deleted"),Notification.Type.HUMANIZED_MESSAGE); |
| // initial state of the dialog has to be NEW. This |
| // fills |
| // the view context with a initial blank bean. |
| createNew(dto); |
| } |
| |
| /** |
| * Check other dialogs whether we could use their selection to prefill owners. |
| * Check eclipse context for information to prefill owners |
| * |
| * @param newDto the new dto |
| */ |
| private void prefillOwners(Object newDto) { |
| if(mPart != null) { |
| MPerspective mPersp = mPart.getContext().get(MPerspective.class); |
| if (mPersp != null) { |
| for (Field field : DtoUtils.getOwnerDomainReferences(newDto.getClass())) { |
| // look in dialog's contexts |
| List<IViewContext> contexts = ecviewContainer.getECViews(mPersp); |
| for (IViewContext context : contexts) { |
| if (this.viewContext == context) { |
| continue; |
| } |
| Object bean = context.getBean(IViewContext.MAIN_BEAN_SLOT); |
| if (bean instanceof IDto) { |
| // must reload owner cause else will set owner to dirty on perspective |
| IDTOService<? extends Object> ownerService = DtoServiceAccess.getService(bean.getClass()); |
| Object idVal=DtoUtils.getIdValue(bean); |
| if(idVal != null) { |
| Object beanCopy = ownerService.get(idVal); |
| if(beanCopy != null) { |
| DtoUtils.setValue(newDto, field.getName(), beanCopy); |
| } |
| } |
| } |
| } |
| // look in context for selection |
| String key = EntityUtils.getQualifiedEntityNameForQualifiedDtoName(field.getType().getName())+"."+DtoUtils.getIdField(field.getType()).getName(); |
| Object idObj = SelectionStore.getSelectionFromPerspectiveContext(mPart, key); |
| if(!(idObj instanceof List<?>) && idObj != null) { |
| IDTOService<? extends Object> ownerService = DtoServiceAccess.getService(field.getType()); |
| Object beanCopy = ownerService.get(idObj); |
| if(beanCopy != null) { |
| DtoUtils.setValue(newDto, field.getName(), beanCopy); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * If there comes a selections event with a potential owner we use it to prefill owners. |
| * |
| * @param event the event |
| */ |
| private void reflectOwners(final EventDispatcherEvent event) { |
| List<Field> owners = DtoUtils.getOwnerDomainReferences(dto); |
| for(Field field:owners) { |
| String key = EntityUtils.getQualifiedEntityNameForQualifiedDtoName(field.getType().getName())+"."+DtoUtils.getIdField(field.getType()).getName(); |
| if(key.equals(event.getTopic())) { |
| Object currentDto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| if(currentDto != null) { |
| Object bean = getDtoFromEvent(event, field.getType().getName()); |
| if(bean != null) { |
| DtoUtils.setValue(currentDto, field.getName(), bean); |
| DtoUtils.getAdapter(DirtyStateAdapter.class, currentDto).resetDirty(); |
| } |
| } |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.osbp.osgi.hybrid.api.AbstractHybridVaaclipseView# |
| * createComponents () |
| */ |
| @Override |
| public void createComponents() { |
| if(!dialogModel.isStateful()) { |
| // initial state of the dialog has to be NEW. This fills the view |
| // context with a initial blank bean. |
| createNew(dto); |
| } |
| if(dialogModel.isEmbedded()) { |
| // OSBP UI Code |
| viewContext = ecviewComponent.setValue(viewId, null, renderingParams); |
| viewContext.setLocale(user.getLocale()); |
| YView yView = (YView) viewContext.getViewEditpart().getModel(); |
| |
| if (yView == null) { |
| Notification.show("Dialog could not be found!", Type.ERROR_MESSAGE); |
| return; |
| } |
| } |
| } |
| |
| /** |
| * Setup validation bridge. |
| */ |
| protected void setupValidationBridge() { |
| // create a validation enhancer. If an error message is added to the |
| // field validation manager. The enhancer will set the id of the mpart |
| // to the status. |
| ecviewFieldValidationManager = viewContext.getService(IFieldValidationManager.class.getName()); |
| ecviewFieldValidationManager.setEnhancer(new IFieldValidationManager.Enhancer() { |
| @Override |
| public void enhance(IStatus status) { |
| if(mPart != null) { |
| status.putProperty(IStatus.PROP_UI_APPLICATION_ID, mPart.getElementId()); |
| } else { |
| status.putProperty(IStatus.PROP_UI_APPLICATION_ID, dialogModel.getName()); |
| } |
| } |
| }); |
| |
| ecviewFieldValidationManager.addListener(this); |
| } |
| |
| protected boolean validate(DTO mainDto) { |
| if(mainDto == null) { |
| return true; |
| } |
| log.debug("{}", "validation start"); |
| Set<IStatus> oldValidationResult = validationResult != null ? new HashSet<>(validationResult) |
| : new HashSet<>(); |
| |
| validationResult = dtoService.validate(mainDto, ValidationKind.OTHER, renderingParams); |
| |
| for (IStatus status : validationResult) { |
| // set the application id to the status |
| if(mPart != null) { |
| status.putProperty(IStatus.PROP_UI_APPLICATION_ID, mPart.getElementId()); |
| } else { |
| status.putProperty(IStatus.PROP_UI_APPLICATION_ID, dialogModel.getName()); |
| } |
| |
| if (status.containsProperty(IStatus.PROP_FIELD_ID) |
| && status.containsProperty(IStatus.PROP_FIELD_I18N_KEY)) { |
| continue; |
| } |
| |
| // fix the field id. Therefore we try to find the yField that is |
| // bound to the property path of javax.validation result. |
| if (!status.containsProperty(IStatus.PROP_FIELD_ID)) { |
| if (status.containsProperty(IStatus.PROP_JAVAX_PROPERTY_PATH)) { |
| String path = (String) status.getProperty(IStatus.PROP_JAVAX_PROPERTY_PATH); |
| |
| // if path points to a collection, then remove all the |
| // collection stuff, since Vaadin can not focus rows |
| if (path.matches(".*\\[\\d*\\].*")) { |
| path = path.substring(0, path.indexOf("[")); |
| } |
| |
| // using a regex to find the yElement: |
| // "beanslot/.*/{propertyPath}" |
| YEmbeddable yElement = (YEmbeddable) viewContext |
| .findBoundField(String.format("%s.*/%s", BindingIdUtil.BEANSLOT, path)); |
| if (yElement != null) { |
| status.putProperty(IStatus.PROP_FIELD_ID, yElement.getId()); |
| status.putProperty(IStatus.PROP_FIELD_I18N_KEY, yElement.getLabelI18nKey()); |
| } |
| } |
| } |
| } |
| |
| // now update the field with the new Status instances |
| // |
| for (IStatus status : oldValidationResult) { |
| String fieldId = (String) status.getProperty(IStatus.PROP_FIELD_ID); |
| if (fieldId != null && !fieldId.trim().equals("")) { |
| YEmbeddable yElement = (YEmbeddable) viewContext.findYEmbeddableElement(fieldId); |
| IFieldEditpart editpart = ModelUtil.findEditpart(yElement); |
| if (editpart != null) { |
| editpart.removeExternalStatus(status); |
| } |
| } |
| log.debug("remove old status {}", status.getMessage()); |
| } |
| |
| for (IStatus status : validationResult) { |
| String fieldId = (String) status.getProperty(IStatus.PROP_FIELD_ID); |
| if (fieldId != null && !fieldId.trim().equals("")) { |
| YEmbeddable yElement = (YEmbeddable) viewContext.findYEmbeddableElement(fieldId); |
| IFieldEditpart editpart = ModelUtil.findEditpart(yElement); |
| if (editpart != null) { |
| editpart.addExternalStatus(status); |
| } |
| } |
| log.debug("add new status {}", status.getMessage()); |
| } |
| if(!validationResult.isEmpty()) { |
| log.debug("{}", "get scope for statusManager"); |
| statusManager.getScopeFor(mPart).modifyStatus(oldValidationResult, validationResult); |
| } |
| return validationResult.isEmpty(); |
| } |
| |
| /** |
| * 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<>(); |
| Map<String, Object> services = new HashMap<>(); |
| params.put(IViewContext.PARAM_SERVICES, services); |
| params.put(IViewContext.PROP_SLOT, IViewContext.MAIN_BEAN_SLOT); |
| 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(IUser.class.getName(), user); |
| // this service will handle reload requests from YSuggestTextField |
| services.put(IReloadRequestService.class.getName(), reloadRequestService); |
| |
| if(dialogModel.isStateful()) { |
| IConfiguration config = new IConfiguration() { |
| @Override |
| public void beforeUiRendering(IContext viewContext) { |
| for(UiBeanSlot slot : dialogModel.getUiView().getBeanSlots()) { |
| if(dslMetadataService.hasSupertype(slot.getJvmType(), IDto.class)) { |
| Class<?> dtoClass = dslMetadataService.getClass(slot.getJvmType().getQualifiedName(), "dto"); |
| viewContext.createBeanSlot(slot.getName(), dtoClass).setValue(dslMetadataService.getClassInstance(dtoClass, "dto")); |
| } else if(dslMetadataService.hasSupertype(slot.getJvmType(), IStateMachineParticipant.class) || dslMetadataService.hasSupertype(slot.getJvmType(), IPeripheral.class)) { |
| Class<?> participantClass = dslMetadataService.getClass(slot.getJvmType().getQualifiedName(), "statemachine"); |
| IStateMachineParticipant participantInstance = (IStateMachineParticipant)dslMetadataService.getClassInstance(participantClass, "statemachine"); |
| participantInstance.setLocale(user.getLocale()); |
| viewContext.createBeanSlot(slot.getName(), participantClass).setValue(participantInstance); |
| } else if(dslMetadataService.hasSupertype(slot.getJvmType(), IStateMachine.class)) { |
| Class<?> statemachineClass = dslMetadataService.getClass(slot.getJvmType().getQualifiedName(), "statemachine"); |
| IStateMachine statemachineInstance = (IStateMachine)dslMetadataService.getClassInstance(statemachineClass, "statemachine"); |
| statemachineInstance.setLocale(user.getLocale()); |
| statemachineInstance.setUser(user); |
| statemachineInstance.setEclipseContext(eclipseContext); |
| viewContext.createBeanSlot(slot.getName(), statemachineClass).setValue(statemachineInstance); |
| } else if(dslMetadataService.hasSupertype(slot.getJvmType(), IBlobConverter.class)) { |
| viewContext.createBeanSlot(slot.getName(), BlobConverter.class).setValue(new BlobConverter(blobService)); |
| } |
| } |
| viewContext.setLocale(user.getLocale()); |
| } |
| @Override |
| public void afterUiRendering(IContext context) { |
| } |
| @Override |
| public void beforeBind(IContext context) { |
| } |
| @Override |
| public void afterBind(IContext context) { |
| for(UiBeanSlot slot : dialogModel.getUiView().getBeanSlots()) { |
| if(dslMetadataService.hasSupertype(slot.getJvmType(), IStateMachineParticipant.class)) { |
| ((IStateMachineParticipant)context.getBeanSlot(slot.getName()).getValue()).init(); |
| } |
| if(dslMetadataService.hasSupertype(slot.getJvmType(), IDataProvider.class)) { |
| for(UiBeanSlot innerslot : dialogModel.getUiView().getBeanSlots()) { |
| if(dslMetadataService.hasSupertype(innerslot.getJvmType(), IDto.class)) { |
| if (context.getBeanSlot(innerslot.getName()) != null) { |
| ((IDataProvider)context.getBeanSlot(slot.getName()).getValue()).addDatasource(innerslot.getName(), context.getBeanSlot(innerslot.getName()).getValueType()); |
| } |
| } |
| } |
| } |
| } |
| // at the very end - start the statemachines |
| for(UiBeanSlot slot : dialogModel.getUiView().getBeanSlots()) { |
| if(dslMetadataService.hasSupertype(slot.getJvmType(), IStateMachine.class)) { |
| ((IStateMachine)context.getBeanSlot(slot.getName()).getValue()).start(); |
| } |
| } |
| } |
| }; |
| params.put(IViewContext.PARAM_CONFIGURATION, config); |
| } |
| 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(Object newDto, Object currentDto) { |
| if (isDirtyDto(currentDto)) { |
| AcceptLoosingDataDialog.showDialog(dslMetadataService, themeResourceService, new Runnable() { |
| @Override |
| public void run() { |
| viewContext = ecviewComponent.setValue(viewId, newDto, renderingParams); |
| setNewCreatedDto(false); |
| updateBindings(newDto); |
| } |
| }, null); |
| } else if(newDto == null) { |
| createNew(dto); |
| } else { |
| setNewCreatedDto(false); |
| updateBindings(newDto); |
| } |
| } |
| |
| // protected void showSaveDialog(Object newDto) { |
| // final Object dto = newDto; |
| // AcceptSaveDialog.showDialog(dslMetadataService, themeResourceService, new Runnable() { |
| // @Override |
| // public void run() { |
| // viewContext = ecviewComponent.setValue(viewId, dto, renderingParams); |
| // } |
| // }, null); |
| // } |
| |
| protected void showDeleteDialog(Object currentDto) { |
| if(isDirtyDto(currentDto)) { |
| AcceptDeleteDialog.showDialog(dslMetadataService, themeResourceService, new Runnable() { |
| @Override |
| public void run() { |
| createNew(dto); |
| } |
| }, null); |
| } else { |
| createNew(dto); |
| } |
| } |
| |
| protected void showQueryDeleteDialog() { |
| QueryDeleteDialog.showDialog(dslMetadataService, themeResourceService, new Runnable() { |
| @Override |
| public void run() { |
| doDelete(); |
| } |
| }, null); |
| } |
| |
| @Override |
| public void localeChanged(final Locale locale) { |
| if(viewContext != null) { |
| viewContext.setLocale(locale); |
| } |
| if (layoutManager != null && dialogLabel != null) { |
| layoutManager.setLabelValue( |
| dslMetadataService.translate(user.getLocale().toLanguageTag(), dialogLabel)); |
| } |
| if(infoWindow != null) { |
| infoWindow.setLocale(locale); |
| } |
| // set locale to all statemachine beans |
| if(getViewContext() != null && getViewContext().getValueBeans() != null) { |
| for(Entry<String, ISlot> slotEntry:getViewContext().getValueBeans().entrySet()) { |
| if(slotEntry.getValue() instanceof IStateMachineParticipant) { |
| ((IStateMachineParticipant)slotEntry.getValue().getValue()).setLocale(locale); |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void receiveEvent(final EventDispatcherEvent event) { |
| switch (event.getCommand()) { |
| case OK: // comes from SelectionDialog of subtypes |
| if (viewContext != null && event.getSender().equals(viewId) |
| && event.getData().containsKey(EventDispatcherDataTag.OBJECT)) { |
| if (selectWindow != null) { |
| selectWindow.close(); |
| UI.getCurrent().removeWindow(selectWindow); |
| selectWindow = null; |
| createNew((Class<?>)event.getData().get(EventDispatcherDataTag.OBJECT)); |
| } |
| } |
| break; |
| case CLOSE: |
| if(viewContext != null && event.getSender().equals(viewId) && event.getTopic().equals("DTOInfoDialog")) { |
| if(infoWindow != null) { |
| infoWindow.close(); |
| UI.getCurrent().removeWindow(infoWindow); |
| infoWindow = null; |
| } |
| } |
| break; |
| case SELECT: |
| if (manualInput) { |
| return; |
| } |
| MPerspective perspective = null; |
| ArrayList<String> allowedSenderParts = null; |
| if(mPart != null) { |
| perspective = eclipseContext.get(MPerspective.class); |
| allowedSenderParts = (ArrayList<String>) eclipseContext.getActive(MPart.class).getTransientData().get(IPerspectiveProvider.EventDispatcherConstants.ACCEPTED_SENDERS); |
| } |
| if((event.getPerspective() == null || (perspective != null && event.getPerspective().equals(perspective))) && ((allowedSenderParts != null && allowedSenderParts.contains(event.getSender())) || allowedSenderParts == null)){ |
| if (dtoService != null && viewContext != null && !event.getSender().equals(viewId)) { |
| if(event.getTopic().equals(dtoName) || event.getTopic().equals(primaryKey)) { |
| handleSelectEvent(event); |
| } else if(newCreatedDto){ // while in mode "new" then reflect all external selections to the owner fields |
| reflectOwners(event); |
| } |
| } |
| } |
| break; |
| case REFRESH: |
| if (!event.getSender().equals(viewId) && event.getTopic().equals(entityName)) { |
| if (!newCreatedDto) { |
| final UI currentUi = eclipseContext.get(UI.class); |
| DTO currentDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| IDto newDto = (IDto) dtoService.get(DtoUtils.getIdValue(currentDto)); |
| currentUi.accessSynchronously(new Runnable() { |
| @Override |
| public void run() { |
| VaadinObservables.activateRealm(currentUi); |
| showLoosingDataDialog(newDto, currentDto); |
| } |
| }); |
| } |
| } |
| break; |
| case SAVE: |
| if (!event.getSender().equals(viewId) && event.getTopic().equals(entityName)) { |
| if (event.getData().containsKey(EventDispatcherDataTag.ID)) { |
| final UI currentUi = eclipseContext.get(UI.class); |
| Object eventDataId = event.getData().get(EventDispatcherDataTag.ID); |
| DTO currentDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| Object currentDtoId = DtoUtils.getIdValue(currentDto); |
| IDto newDto = (IDto) dtoService.get(eventDataId); |
| if (eventDataId != null && idEquals(eventDataId, currentDtoId)) { |
| currentUi.accessSynchronously(new Runnable() { |
| @Override |
| public void run() { |
| VaadinObservables.activateRealm(currentUi); |
| showLoosingDataDialog(newDto, currentDto); |
| } |
| }); |
| } |
| } |
| } |
| break; |
| case DELETE: |
| if (!event.getSender().equals(viewId) && event.getTopic().equals(entityName)) { |
| if (event.getData().containsKey(EventDispatcherDataTag.ID)) { |
| final UI currentUi = eclipseContext.get(UI.class); |
| Object eventDataId = event.getData().get(EventDispatcherDataTag.ID); |
| DTO currentDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| Object currentDtoId = DtoUtils.getIdValue(currentDto); |
| if (eventDataId != null && idEquals(eventDataId, currentDtoId)) { |
| currentUi.accessSynchronously(new Runnable() { |
| @Override |
| public void run() { |
| VaadinObservables.activateRealm(currentUi); |
| showDeleteDialog(currentDto); |
| } |
| }); |
| } |
| } |
| } |
| break; |
| case ACTION: |
| if (uuid.equals(event.getTopic()) && event.getData().containsKey(EventDispatcherDataTag.BUTTON_ID)) { |
| Object id = event.getData().get(EventDispatcherDataTag.BUTTON_ID); |
| if (id instanceof DialogActionEnum) { |
| DialogActionEnum enumId = (DialogActionEnum) id; |
| switch (enumId) { |
| case DIALOG_ACTION_NEW: |
| makeNew(); |
| break; |
| case DIALOG_ACTION_SAVE_AS_NEW: |
| actionSaveAsNew(); |
| break; |
| case DIALOG_ACTION_SAVE_AND_NEW: |
| actionSaveAndNew(); |
| break; |
| case DIALOG_ACTION_SAVE: |
| actionSave(); |
| break; |
| case DIALOG_ACTION_DELETE: |
| showQueryDeleteDialog(); |
| break; |
| case DIALOG_ACTION_CANCEL: |
| actionCancel(); |
| break; |
| } |
| } else if (id instanceof UIActionEnum) { |
| UIActionEnum uiEnumId = (UIActionEnum) id; |
| switch (uiEnumId) { |
| case DATABASE_INFO: |
| if(infoWindow == null) { |
| infoWindow = new DTOInfoDialog(eclipseContext, user.getLocale(), viewId, "DTOInfoDialog"); |
| infoWindow.setDto(viewContext.getBean(IViewContext.MAIN_BEAN_SLOT)); |
| UI.getCurrent().addWindow(infoWindow); |
| } |
| break; |
| } |
| } |
| // force focus on me for validation report |
| eclipseContext.activate(); |
| } |
| break; |
| } |
| } |
| |
| private void actionCancel() { |
| DTO reloadedDto = dtoService.reload((DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT)); |
| setNewCreatedDto(reloadedDto == null); |
| updateBindings(reloadedDto); |
| } |
| |
| private void actionSave() { |
| DTO savedDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| if(validate(savedDto)) { |
| if( executeDialogFunction("pre save", preSaveMethod, savedDto) ) |
| dtoService.update(savedDto); |
| DTO newDto = dtoService.reload(savedDto); |
| executeDialogFunction("post save", postSaveMethod, newDto); |
| updateBindings(newDto); |
| setNewCreatedDto(false); |
| Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "saved"),Notification.Type.HUMANIZED_MESSAGE); |
| } |
| } |
| |
| private void actionSaveAndNew() { |
| DTO savedDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| if(validate(savedDto)) { |
| if( executeDialogFunction("pre save", preSaveMethod, savedDto) ) |
| dtoService.update(savedDto); |
| DTO newDto = dtoService.reload(savedDto); |
| executeDialogFunction("post save", postSaveMethod, newDto); |
| if(lastBaseDto != null) { |
| createNew(lastBaseDto); |
| } else { |
| makeNew(); |
| } |
| Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "savedandnew"),Notification.Type.HUMANIZED_MESSAGE); |
| } |
| } |
| |
| private void actionSaveAsNew() { |
| DTO newDto = (DTO) DtoUtils.copyDto(viewContext.getBean(IViewContext.MAIN_BEAN_SLOT)); |
| if(validate(newDto)) { |
| if( executeDialogFunction("pre save", preSaveMethod, newDto) ) |
| dtoService.update(newDto); |
| newDto = dtoService.reload(newDto); |
| executeDialogFunction("post save", postSaveMethod, newDto); |
| updateBindings(newDto); |
| setNewCreatedDto(false); |
| Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "savedas"),Notification.Type.HUMANIZED_MESSAGE); |
| } |
| } |
| |
| private boolean executeDialogFunction(String what, Method method, Object obj) { |
| if(method != null) { |
| Boolean retVal = false; |
| Exception ex = null; |
| try { |
| retVal = (Boolean) method.invoke(dialogFunctionGroup, obj, eclipseContext); |
| } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { |
| ex = e; |
| } |
| if(!retVal) { |
| String message = what+" "+method.getName()+" failed"; |
| if(ex != null) { |
| message += " due to exception " + ex.getCause(); |
| } |
| Notification.show(message, Type.ERROR_MESSAGE); |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| private void handleSelectEvent(EventDispatcherEvent event) { |
| log.debug("buffer select. Class:{} ObjectID:{}", getClass().getName(), System.identityHashCode(this)); |
| if(timer != null && timer.isRunning()) { |
| log.debug("{}", "buffered select restarted."); |
| timer.restart(); |
| } else { |
| timer = new Timer(50, new ActionListener(){ |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| final UI currentUi = eclipseContext.get(UI.class); |
| Object newDto = getDtoFromEvent(event); |
| Object currentDto = viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| currentUi.accessSynchronously(new Runnable() { |
| @Override |
| public void run() { |
| VaadinObservables.activateRealm(currentUi); |
| showLoosingDataDialog(newDto, currentDto); |
| } |
| }); |
| } |
| }); |
| timer.setRepeats(false); |
| timer.start(); |
| } |
| } |
| |
| private Object getDtoFromEvent(EventDispatcherEvent event) { |
| return getDtoFromEvent(event, null); |
| } |
| |
| private Object getDtoFromEvent(EventDispatcherEvent event, String refDtoName) { |
| Object dto = null; |
| if (event.getData().containsKey(EventDispatcherDataTag.ID)) { |
| Object id = event.getData().get(EventDispatcherDataTag.ID); |
| if (id != null) { |
| if(refDtoName == null) { |
| if(dtoService instanceof IDTOHistorizedService) { |
| dto = ((IDTOHistorizedService<DTO>)dtoService).get(id, true); |
| } else { |
| dto = dtoService.get(id); |
| } |
| } else { |
| dto = DtoServiceAccess.getService(refDtoName).get(id); |
| } |
| } |
| } else if (event.getData().containsKey(EventDispatcherDataTag.DTO)) { |
| dto = event.getData().get(EventDispatcherDataTag.DTO); |
| } |
| return dto; |
| } |
| |
| private void makeNew() { |
| if (subTypes.size() > 1) { |
| selectWindow = selectDialog.init(eventDispatcher, viewId, uuid, subTypes, dto, dslMetadataService.translate(user.getLocale().toLanguageTag(), "Select SubType"), dslMetadataService.translate(user.getLocale().toLanguageTag(), "Ok")); |
| UI.getCurrent().addWindow(selectWindow); |
| } else { |
| createNew(dto); |
| lastBaseDto = dto; |
| } |
| } |
| |
| /** |
| * Creates a new dto. |
| * |
| * @param type |
| * the type for the dto, could be a sub-type |
| */ |
| protected Object createNew(Class<?> type) { |
| log.debug("create new"); |
| Object newDto = null; |
| try { |
| if(type != null){ |
| newDto = type.newInstance(); |
| setNewCreatedDto(true); |
| prefillOwners(newDto); |
| initializeDto(newDto); |
| if(DtoUtils.getAdapter(DirtyStateAdapter.class, newDto) == null) { |
| log.debug("register dirty adapter {}", newDto.getClass().getName()); |
| DtoUtils.registerAdapter(dirtyStateAdapter, newDto); |
| } |
| DtoUtils.getAdapter(DirtyStateAdapter.class, newDto).resetDirty(); |
| DtoUtils.getAdapter(DirtyStateAdapter.class, newDto).setActive(true); |
| updateBindings(newDto); |
| viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.FALSE); |
| } |
| } catch (InstantiationException | IllegalAccessException e) { |
| log.error("{}", e); |
| } |
| return newDto; |
| } |
| |
| private void initializeDto(Object newDto) { |
| if(initializationMethod != null) { |
| executeDialogFunction("initializing", initializationMethod, newDto); |
| } |
| } |
| |
| @PostConstruct |
| public void activate() { |
| initDialog(); |
| user.addUserLocaleListener(this); |
| eventDispatcher.addEventReceiver(this); |
| if(!dialogModel.isEmbedded()) { |
| super.initView(); |
| onFocusField = new EventHandler() { |
| @Override |
| public void handleEvent(Event event) { |
| String[] names = event.getPropertyNames(); |
| String partId = (String) event.getProperty(IE4Topics.PartEvents.PROP_MPART_ID); |
| String fieldId = (String) event.getProperty(IE4Topics.PartEvents.PROP_FIELD_ID); |
| if(mPart.getElementId().equals(partId)) { |
| focusingStrategy.focusField(yView, fieldId); |
| } |
| } |
| }; |
| eventBroker.subscribe(IE4Topics.PartEvents.FOCUS_FIELD_TOPIC, onFocusField); |
| if(dialogModel.isStateful()) { |
| if(getViewContext() != null && getViewContext().getValueBeans() != null) { |
| for(String selector:getViewContext().getValueBeans().keySet()) { |
| ISlot slot = getViewContext().getBeanSlot(selector); |
| if(IPeripheral.class.isAssignableFrom(slot.getValueType())) { |
| ((IPeripheral)slot.getValue()).initDevices(getBeeper(), getAudio(), getVideo()); |
| } else if(IStateMachine.class.isAssignableFrom(slot.getValueType())) { |
| ((IStateMachine)slot.getValue()).installKeyEventConsumer(getParent()); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| @PreDestroy |
| public void deactivate() { |
| if(dialogModel.isStateful()) { |
| if(getViewContext() != null && getViewContext().getValueBeans() != null) { |
| for(String selector:getViewContext().getValueBeans().keySet()) { |
| ISlot slot = getViewContext().getBeanSlot(selector); |
| if(IPeripheral.class.isAssignableFrom(slot.getValueType())) { |
| ((IPeripheral)slot.getValue()).releaseDevices(); |
| } else if(IStateMachine.class.isAssignableFrom(slot.getValueType())) { |
| ((IStateMachine)slot.getValue()).uninstallKeyEventConsumer(); |
| } |
| } |
| } |
| } |
| user.removeUserLocaleListener(this); |
| eventDispatcher.removeEventReceiver(this); |
| if(!dialogModel.isEmbedded()) { |
| eventBroker.unsubscribe(onFocusField); |
| if(infoWindow != null) { |
| infoWindow.close(); |
| UI.getCurrent().removeWindow(infoWindow); |
| infoWindow = null; |
| } |
| super.destroyView(); |
| } |
| } |
| |
| protected Map<String, Object> createStateLabelEvent(IE4Topics.ToolBarEvents.Labels labelType, IE4Topics.ToolBarEvents.States state, String uuid) { |
| Map<String, Object> properties = new HashMap<>(); |
| properties.put(IE4Topics.ToolBarEvents.STATE_LABEL, labelType.name()); |
| properties.put(IE4Topics.ToolBarEvents.STATE_STATE, state.name()); |
| properties.put(IE4Topics.ToolBarEvents.STATE_UUID, uuid); |
| return properties; |
| } |
| |
| private boolean idEquals(Object id, Object id2) { |
| if (id2.getClass().isAssignableFrom(id.getClass())) { |
| if (id instanceof String) { |
| return ((String) id).equals(id2); |
| } else if (id instanceof Integer) { |
| return ((Integer) id).intValue() == ((Integer) id2).intValue(); |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Update data with a new dto |
| * |
| * @param newDto |
| * the new dto |
| */ |
| private void updateBindings(Object newDto) { |
| viewContext = ecviewComponent.setValue(viewId, newDto, renderingParams); |
| if(newDto != null) { |
| log.debug("update bindings for dto:{}", newDto.getClass().getName()); |
| if(infoWindow != null) { |
| infoWindow.setDto(newDto); |
| } |
| DtoUtils.getAdapter(DirtyStateAdapter.class, newDto).setActive(true); |
| } |
| } |
| |
| protected void setNewCreatedDto(boolean state) { |
| newCreatedDto = state; |
| reloadRequestService.setMode(!state); |
| if(newCreatedDto) { |
| eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.MODE, IE4Topics.ToolBarEvents.States.ADD_ENTRY, getStateLabelUUID())); |
| } else { |
| eventBroker.send(IE4Topics.ToolBarEvents.NOTIFY_TOOLBAR_DIALOG_STATE, createStateLabelEvent(IE4Topics.ToolBarEvents.Labels.MODE, IE4Topics.ToolBarEvents.States.MODIFY_ENTRY, getStateLabelUUID())); |
| } |
| } |
| |
| @Override |
| public String getStateLabelUUID() { |
| if(toolbar != null) { |
| return toolbar.getStateLabelUUID(); |
| } |
| return null; |
| } |
| |
| /** |
| * Sets the input to the dialog. |
| * |
| * @param dto |
| */ |
| @Override |
| public void setInput(Object dto) { |
| this.dto = (Class<?>) dto; |
| if (dto != null && viewContext != null) { |
| dtoService = (IDTOService<DTO>) DtoServiceAccess.getService(this.dto); |
| DTO persistentDto = dtoService.get(DtoUtils.getIdValue(dto)); |
| viewContext.setBean(IViewContext.MAIN_BEAN_SLOT, persistentDto); |
| } |
| } |
| |
| /** |
| * If true, then EventDispatcherEvents are being ignored. |
| * |
| * @param manualInput |
| */ |
| @Override |
| public void setEnableManualInput(boolean manualInput) { |
| this.manualInput = manualInput; |
| } |
| |
| /** |
| * Creates the embedded toolbar for embedded dialogs. |
| */ |
| private void createEmbeddedToolbar() { |
| taskButtons = new ArrayList<Button>(); |
| HorizontalLayout tools = new HorizontalLayout(); |
| tools.addStyleName("os-embedded-toolbar"); |
| tools.setSpacing(false); |
| |
| Button b = new Button(null, new Button.ClickListener() { |
| public void buttonClick(ClickEvent event) { |
| DTO savedDto = (DTO) viewContext.getBean(IViewContext.MAIN_BEAN_SLOT); |
| if(validate(savedDto)) { |
| dtoService.update(savedDto); |
| DTO newDto = dtoService.reload(savedDto); |
| updateBindings(newDto); |
| setNewCreatedDto(false); |
| Notification.show(dslMetadataService.translate(user.getLocale().toLanguageTag(), "saved"),Notification.Type.HUMANIZED_MESSAGE); |
| notifySaveListeners(newDto); |
| } |
| } |
| }); |
| b.setIcon(themeResourceService.getThemeResource("dssave", ThemeResourceType.ICON)); |
| b.setDescription(null); |
| b.setEnabled(true); |
| b.addStyleName("v-button-small"); |
| tools.addComponent(b); |
| taskButtons.add(b); |
| layoutManager.getDataArea().addComponentAsFirst(tools); |
| } |
| |
| /** |
| * Adds a new save listener. |
| * |
| * @param listener |
| */ |
| public void addSaveListener(Consumer<DTO> listener) { |
| if (saveListeners == null) { |
| saveListeners = new ArrayList<>(); |
| } |
| saveListeners.add(listener); |
| } |
| |
| /** |
| * Removes the given save listener. |
| * |
| * @param listener |
| */ |
| public void removeSaveListener(Consumer<DTO> listener) { |
| if (saveListeners == null) { |
| return; |
| } |
| saveListeners.remove(listener); |
| } |
| |
| protected void notifySaveListeners(DTO dto) { |
| if (saveListeners == null) { |
| return; |
| } |
| |
| for (Consumer<DTO> listener : saveListeners.toArray(new Consumer[saveListeners.size()])) { |
| listener.accept(dto); |
| } |
| } |
| |
| /** |
| * Gets the uuid. |
| * |
| * @return the uuid |
| */ |
| protected String getUUID() { |
| return uuid; |
| } |
| |
| public IEclipseContext getEclipseContext() { |
| return eclipseContext; |
| } |
| |
| public IViewContext getViewContext() { |
| return viewContext; |
| } |
| |
| public IUser getUser() { |
| return user; |
| } |
| |
| public IDSLMetadataService getDslMetadataService() { |
| return dslMetadataService; |
| } |
| |
| public IThemeResourceService getThemeResourceService() { |
| return themeResourceService; |
| } |
| |
| public IReportProvider getReportProvider() { |
| return reportProvider; |
| } |
| |
| public IBlobService getBlobService() { |
| return blobService; |
| } |
| |
| @Override |
| public void clicked(YButton yButton) { |
| // only if the click is for this instance |
| for(String tag:yButton.getTags()) { |
| if(uuid.equals(tag)) { |
| actionSaveAndNew(); |
| } |
| } |
| } |
| } |