blob: 3f692872c41339870cd1625c72edbcacf64289aa [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2017 EclipseSource Muenchen GmbH and others.
*
* 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:
* Edgar Mueller - initial API and implementation
******************************************************************************/
package org.eclipse.emf.ecp.edit.spi.swt.util;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.databinding.EMFUpdateValueStrategy;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecp.view.spi.model.VDiagnostic;
import org.eclipse.emf.ecp.view.spi.model.VElement;
import org.eclipse.emf.ecp.view.spi.model.VViewFactory;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emfforms.spi.common.validation.PreSetValidationService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
/**
* A common {@link EMFUpdateValueStrategy} that implements {@link #validateBeforeSet(Object)}.
*
* @since 1.13
*/
public class PreSetValidationStrategy extends EMFUpdateValueStrategy {
private final EStructuralFeature eStructuralFeature;
private final VElement vElement;
private final UpdateValueStrategy strategy;
/**
* Constructor.
*
* @param vElement the {@link VElement}
* @param eStructuralFeature an {@link EStructuralFeature} that defines any validation constraints
* @param delegate the strategy to delegate to
*/
public PreSetValidationStrategy(VElement vElement, EStructuralFeature eStructuralFeature,
UpdateValueStrategy delegate) {
this.vElement = vElement;
this.eStructuralFeature = eStructuralFeature;
strategy = delegate;
}
@Override
public IStatus validateBeforeSet(Object value) {
final BundleContext bundleContext = FrameworkUtil
.getBundle(getClass())
.getBundleContext();
final ServiceReference<PreSetValidationService> serviceReference = bundleContext
.getServiceReference(PreSetValidationService.class);
if (serviceReference == null) {
return strategy.validateBeforeSet(value);
}
if (eStructuralFeature.isUnsettable() && SetCommand.UNSET_VALUE == value) {
/* we are dealing with an unsettable feature and the unset value */
/* we need to validate the default value instead of the unset value */
value = eStructuralFeature.getDefaultValue();
}
try {
final PreSetValidationService service = bundleContext.getService(serviceReference);
if (service == null) {
return strategy.validateBeforeSet(value);
}
final Diagnostic result = service.validate(eStructuralFeature, value);
if (result.getSeverity() == Diagnostic.OK) {
return Status.OK_STATUS;
}
// TODO: existing diagnostics?
final VDiagnostic vDiagnostic = VViewFactory.eINSTANCE.createDiagnostic();
vDiagnostic.getDiagnostics().add(result);
if (vElement != null) {
vElement.setDiagnostic(vDiagnostic);
}
return BasicDiagnostic.toIStatus(result);
} finally {
bundleContext.ungetService(serviceReference);
}
}
@Override
public Object convert(Object value) {
return strategy.convert(value);
}
@Override
public int getUpdatePolicy() {
return strategy.getUpdatePolicy();
}
@Override
public UpdateValueStrategy setAfterConvertValidator(IValidator validator) {
super.setAfterConvertValidator(validator);
return strategy.setAfterConvertValidator(validator);
}
@Override
public UpdateValueStrategy setBeforeSetValidator(IValidator validator) {
super.setBeforeSetValidator(validator);
return strategy.setBeforeSetValidator(validator);
}
@Override
public UpdateValueStrategy setAfterGetValidator(IValidator validator) {
super.setAfterGetValidator(validator);
return strategy.setAfterGetValidator(validator);
}
@Override
public UpdateValueStrategy setConverter(IConverter converter) {
super.setConverter(converter);
return strategy.setConverter(converter);
}
@Override
public IStatus validateAfterConvert(Object value) {
return strategy.validateAfterConvert(value);
}
@Override
public IStatus validateAfterGet(Object value) {
return strategy.validateAfterGet(value);
}
/**
* Returns the {@link EStructuralFeature} that defines any validation constraints.
*
* @return the structural feature
*/
public EStructuralFeature getStructuralFeature() {
return eStructuralFeature;
}
/**
* Returns the associated {@link VElement}.
*
* @return the {@link VElement}
*/
public VElement getVElement() {
return vElement;
}
}