blob: 235de87567b2ee8df4aca50f0096eb14b02db6af [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2016 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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eugen Neufeld - initial API and implementation
******************************************************************************/
package org.eclipse.emf.ecp.view.spi.custom.model.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecp.common.spi.UniqueSetting;
import org.eclipse.emf.ecp.view.spi.custom.model.ECPHardcodedReferences;
import org.eclipse.emf.ecp.view.spi.custom.model.VCustomDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
import org.eclipse.emfforms.spi.common.report.ReportService;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport;
import org.eclipse.emfforms.spi.core.services.mappingprovider.EMFFormsMappingProvider;
import org.eclipse.emfforms.spi.core.services.mappingprovider.EMFFormsMappingProviderManager;
import org.eclipse.emfforms.spi.localization.LocalizationServiceHelper;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
/**
* An EMFFormsMappingProvider for {@link VCustomDomainModelReference}.
*
* @author Eugen Neufeld
* @since 1.9
*
*/
@Component
public class CustomDMRMappingProvider implements EMFFormsMappingProvider {
private BundleContext bundleContext;
private ServiceReference<EMFFormsMappingProviderManager> eMFFormsMappingProviderManagerServiceReference;
private EMFFormsMappingProviderManager mappingProviderManager;
private ReportService reportService;
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.core.services.mappingprovider.EMFFormsMappingProvider#getMappingFor(org.eclipse.emf.ecp.view.spi.model.VDomainModelReference,
* org.eclipse.emf.ecore.EObject)
*/
@Override
public Set<UniqueSetting> getMappingFor(VDomainModelReference domainModelReference, EObject domainObject) {
if (domainModelReference == null) {
throw new IllegalArgumentException("The given VDomainModelReference must not be null."); //$NON-NLS-1$
}
if (!VCustomDomainModelReference.class.isInstance(domainModelReference)) {
throw new IllegalArgumentException(
"DomainModelReference must be an instance of VTableDomainModelReference."); //$NON-NLS-1$
}
final VCustomDomainModelReference customDomainModelReference = VCustomDomainModelReference.class
.cast(domainModelReference);
if (!customDomainModelReference.getDomainModelReferences().isEmpty()) {
return getMappingFor(customDomainModelReference.getDomainModelReferences(), domainObject);
}
final ECPHardcodedReferences hardcodedReference;
try {
hardcodedReference = loadObject(customDomainModelReference.getBundleName(),
customDomainModelReference.getClassName());
} catch (final DatabindingFailedException ex) {
reportService.report(new DatabindingFailedReport(ex));
return Collections.<UniqueSetting> emptySet();
}
if (hardcodedReference == null) {
reportService.report(new DatabindingFailedReport(new DatabindingFailedException(
String
.format(
"The provided ECPHardcodedReferences from Bundle %1$s Class %2$s cannot be resolved.", //$NON-NLS-1$
customDomainModelReference.getBundleName(), customDomainModelReference.getClassName()))));
return Collections.<UniqueSetting> emptySet();
}
final Set<VDomainModelReference> neededDomainModelReferences = hardcodedReference
.getNeededDomainModelReferences();
if (neededDomainModelReferences.isEmpty()) {
reportService.report(new DatabindingFailedReport(new DatabindingFailedException(
String
.format(
"The provided ECPHardcodedReferences from Bundle %1$s Class %2$s doesn't define any DomainModelReferences.", //$NON-NLS-1$
customDomainModelReference.getBundleName(), customDomainModelReference.getClassName()))));
return Collections.<UniqueSetting> emptySet();
}
return getMappingFor(neededDomainModelReferences, domainObject);
}
private Set<UniqueSetting> getMappingFor(Collection<VDomainModelReference> domainModelReferences,
EObject domainObject) {
final Set<UniqueSetting> result = new LinkedHashSet<UniqueSetting>();
for (final VDomainModelReference domainModelReference : domainModelReferences) {
final Set<UniqueSetting> settingsFor = getEMFFormsMappingProviderManager()
.getAllSettingsFor(domainModelReference, domainObject);
if (settingsFor != null) {
result.addAll(settingsFor);
}
}
return result;
}
private static ECPHardcodedReferences loadObject(String bundleName, String clazz)
throws DatabindingFailedException {
final Bundle bundle = Platform.getBundle(bundleName);
if (bundle == null) {
new ClassNotFoundException(String.format(LocalizationServiceHelper.getString(
VCustomDomainModelReferenceImpl.class, "BundleNotFound_ExceptionMessage"), clazz, bundleName)); //$NON-NLS-1$
return null;
}
try {
final Class<?> loadClass = bundle.loadClass(clazz);
if (!ECPHardcodedReferences.class.isAssignableFrom(loadClass)) {
return null;
}
return ECPHardcodedReferences.class.cast(loadClass.newInstance());
} catch (final ClassNotFoundException ex) {
throw new DatabindingFailedException(ex.getMessage());
} catch (final InstantiationException ex) {
throw new DatabindingFailedException(ex.getMessage());
} catch (final IllegalAccessException ex) {
throw new DatabindingFailedException(ex.getMessage());
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.core.services.mappingprovider.EMFFormsMappingProvider#isApplicable(org.eclipse.emf.ecp.view.spi.model.VDomainModelReference,
* org.eclipse.emf.ecore.EObject)
*/
@Override
public double isApplicable(VDomainModelReference domainModelReference, EObject domainObject) {
if (VCustomDomainModelReference.class.isInstance(domainModelReference)) {
return 10;
}
return NOT_APPLICABLE;
}
/**
* Called by the framework when the component gets activated.
*
* @param bundleContext The {@link BundleContext}
*/
@Activate
protected void activate(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
/**
* Called by the framework when the component gets deactivated.
*
* @param bundleContext The {@link BundleContext}
*/
@Deactivate
protected void deactivate(BundleContext bundleContext) {
if (eMFFormsMappingProviderManagerServiceReference != null) {
bundleContext.ungetService(eMFFormsMappingProviderManagerServiceReference);
mappingProviderManager = null;
}
}
private EMFFormsMappingProviderManager getEMFFormsMappingProviderManager() {
if (mappingProviderManager == null) {
eMFFormsMappingProviderManagerServiceReference = bundleContext
.getServiceReference(EMFFormsMappingProviderManager.class);
if (eMFFormsMappingProviderManagerServiceReference == null) {
throw new IllegalStateException("No EMFFormsDomainExpander available!"); //$NON-NLS-1$
}
setEMFFormsMappingProviderManager(bundleContext.getService(eMFFormsMappingProviderManagerServiceReference));
}
return mappingProviderManager;
}
/**
* Helper method for tests. This is quite ugly!
*
* @param mappingProviderManager The EMFFormsMappingProviderManager to use
*/
void setEMFFormsMappingProviderManager(EMFFormsMappingProviderManager mappingProviderManager) {
this.mappingProviderManager = mappingProviderManager;
}
/**
* Sets the {@link ReportService}.
*
* @param reportService The {@link ReportService}
*/
@Reference(unbind = "-")
protected void setReportService(ReportService reportService) {
this.reportService = reportService;
}
}