blob: 76ad6e1fc9223e060747edf44d79256de03ad62f [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 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);
}
}
}