| /** |
| * |
| * 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 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.ui.common.helper.impl; |
| |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.inject.Inject; |
| import javax.inject.Named; |
| |
| //import com.vaadin.ui.HasComponents.ComponentAttachListener; |
| |
| |
| |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; |
| import org.eclipse.e4.ui.model.application.ui.menu.MToolItem; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| 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.YExposedAction; |
| 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.validation.IFieldValidationManager; |
| import org.eclipse.osbp.ecview.core.util.emf.ModelUtil; |
| 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.vaaclipse.addons.common.api.di.Validate; |
| import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusManager; |
| import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusScope; |
| import org.eclipse.osbp.ui.common.helper.ICommonUIHelper; |
| |
| import org.eclipse.osbp.ecview.extension.model.YStrategyLayout; |
| |
| public class CommonUIHelper implements IFieldValidationManager.Listener, ICommonUIHelper{ |
| |
| private IFieldValidationManager ecviewFieldValidationManager; |
| private IViewContext viewContext; |
| |
| // ----------- Validation required variables ------------- |
| private static final String BEAN_SLOT__VALIDATION_ERROR = "validationError"; |
| @Inject |
| private IStatusManager statusManager; |
| @Inject |
| private IDTOService<Object> dtoService; |
| @Inject |
| private IEclipseContext fEclipseContext; |
| |
| private Set<IStatus> validationResult; |
| private Map<String, CommandInfo> commandInfo = new HashMap<String, CommandInfo>(); |
| // ------------------------------------------------------- |
| |
| public CommonUIHelper() { |
| // TODO Auto-generated constructor stub |
| } |
| |
| /* (non-Javadoc) |
| * @see org.osbp.ui.common.helper.impl.ICommonUIHelper#findLayout(org.eclipse.osbp.ecview.core.common.model.core.YView) |
| */ |
| @Override |
| public YStrategyLayout findLayout(YView yView) { |
| |
| for (Iterator<EObject> iterator = EcoreUtil |
| .getAllContents(yView, false); iterator.hasNext();) { |
| EObject type = (EObject) iterator.next(); |
| if (type instanceof YStrategyLayout) { |
| return (YStrategyLayout) type; |
| } |
| } |
| return null; |
| } |
| |
| // ************** Validation required code ****************** |
| |
| // +++++++++++++++ Methods +++++++++++++++++ |
| |
| 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) { |
| status.putProperty(IStatus.PROP_UI_APPLICATION_ID, |
| getPart().getElementId()); |
| } |
| }); |
| |
| ecviewFieldValidationManager.addListener(this); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.osbp.ui.common.helper.impl.ICommonUIHelper#validationChanged(org.eclipse.osbp.ecview.core.common.validation.IFieldValidationManager.Event) |
| */ |
| @Override |
| public void validationChanged(IFieldValidationManager.Event event) { |
| // add them to the Vaaclipse status manager |
| IStatusScope scope = statusManager.getScopeFor(getPart()); |
| scope.modifyStatus(event.getOldStatus(), event.getNewStatus()); |
| |
| applyValidationResult(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.osbp.ui.common.helper.impl.ICommonUIHelper#validate(java.lang.String) |
| */ |
| @Override |
| @Validate |
| public void validate(@Named("commandId") String commandId) { |
| if (commandId != null) { |
| |
| Set<IStatus> oldValidationResult = validationResult != null ? new HashSet<IStatus>( |
| validationResult) : new HashSet<IStatus>(); |
| |
| final Object mainDto = viewContext |
| .getBean(IViewContext.MAIN_BEAN_SLOT); |
| validationResult = dtoService.validate(mainDto, |
| ValidationKind.OTHER, null); |
| |
| for (IStatus status : validationResult) { |
| // set the application id to the status |
| status.putProperty(IStatus.PROP_UI_APPLICATION_ID, |
| getPart().getElementId()); |
| |
| 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("")) { |
| YField yField = (YField) viewContext |
| .findModelElement(fieldId); |
| IFieldEditpart editpart = ModelUtil.getEditpart(viewContext, yField); |
| if (editpart != null) { |
| editpart.removeExternalStatus(status); |
| } |
| } |
| } |
| |
| for (IStatus status : validationResult) { |
| String fieldId = (String) status |
| .getProperty(IStatus.PROP_FIELD_ID); |
| if (fieldId != null && !fieldId.trim().equals("")) { |
| YField yField = (YField) viewContext |
| .findModelElement(fieldId); |
| IFieldEditpart editpart = ModelUtil.getEditpart(viewContext, yField); |
| if (editpart != null) { |
| editpart.addExternalStatus(status); |
| } |
| } |
| } |
| |
| statusManager.getScopeFor(getPart()).modifyStatus(oldValidationResult, |
| validationResult); |
| |
| notifyExternalClicked(toExposedAction(commandId)); |
| |
| applyValidationResult(); |
| } |
| } |
| |
| /** |
| * Apply the validation result to the view. |
| */ |
| protected void applyValidationResult() { |
| // set the validation result |
| viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.FALSE); |
| for (IStatus status : statusManager.getScopeFor(getPart()).getAllStatus()) { |
| if (status.isError()) { |
| viewContext.setBean(BEAN_SLOT__VALIDATION_ERROR, Boolean.TRUE); |
| break; |
| } |
| } |
| } |
| |
| private YExposedAction toExposedAction(String commandId) { |
| return commandInfo.get(commandId).action; |
| } |
| |
| /** |
| * Notifies the action about external clicked. |
| * |
| * @param yAction |
| */ |
| protected void notifyExternalClicked(final YExposedAction yAction) { |
| ActionExternalClickedAdapter.notify(yAction); |
| } |
| |
| private MPart getPart() { |
| return (MPart)fEclipseContext.get(MPart.class); |
| } |
| |
| // +++++++++++++++ Inner classes +++++++++++++++++ |
| |
| /** |
| * A pojo to keep related objects together. Will be used by the |
| * GenericECViewPart and also by handlers to determine enabled state. |
| */ |
| private static class CommandInfo { |
| |
| private YExposedAction action; |
| private MToolItem toolItem; |
| // is used to return the enabled state for a request from handler |
| private boolean enabled; |
| private String commandId; |
| |
| public CommandInfo(YExposedAction action, MToolItem toolItem, |
| boolean enabled, String commandId) { |
| super(); |
| this.action = action; |
| this.toolItem = toolItem; |
| this.enabled = enabled; |
| this.commandId = commandId; |
| } |
| |
| } |
| |
| /** |
| * Notifies the action about the external click. |
| */ |
| private static class ActionExternalClickedAdapter implements Runnable { |
| private final YExposedAction action; |
| |
| public static void notify(YExposedAction action) { |
| action.setExternalClickTime(new Date().getTime()); |
| } |
| |
| @SuppressWarnings("unused") |
| public ActionExternalClickedAdapter(YExposedAction action) { |
| super(); |
| this.action = action; |
| } |
| |
| @Override |
| public void run() { |
| notify(action); |
| } |
| } |
| |
| |
| } |