blob: 735806e8f22e792b5f71b926a46b6d713c6317b4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2015 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:
* Eugen Neufeld - initial API and implementation
******************************************************************************/
package org.eclipse.emfforms.internal.swt.core.plugin;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.model.VElement;
import org.eclipse.emf.ecp.view.spi.swt.ECPAdditionalRendererTester;
import org.eclipse.emf.ecp.view.spi.swt.reporting.ECPRendererDescriptionInitFailedReport;
import org.eclipse.emf.ecp.view.spi.swt.reporting.RendererInitFailedReport;
import org.eclipse.emfforms.spi.common.report.ReportService;
import org.eclipse.emfforms.spi.swt.core.AbstractAdditionalSWTRenderer;
import org.eclipse.emfforms.spi.swt.core.EMFFormsAdditionalRendererService;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* Renderer service which uses the extension point derivates.
*
* @author Eugen Neufeld
*
*/
@Component
public class LegacyAdditionalRendererService implements EMFFormsAdditionalRendererService<VElement> {
private static final String ADDITIONAL_RENDER_EXTENSION = "org.eclipse.emf.ecp.ui.view.swt.additionalRenderers"; //$NON-NLS-1$
private ReportService reportService;
private final Map<ECPAdditionalRendererTester, Class<AbstractAdditionalSWTRenderer<VElement>>> legacyRenderer = new LinkedHashMap<ECPAdditionalRendererTester, Class<AbstractAdditionalSWTRenderer<VElement>>>();
/**
* Called by the initializer to set the {@link ReportService}.
*
* @param reportService The ReportService to set
*/
@Reference(unbind = "-")
protected void setReportService(ReportService reportService) {
this.reportService = reportService;
}
/**
* Activate method of OSGI Component.
*
* @param bundleContext The {@link BundleContext} to use
*/
@Activate
protected void activate(BundleContext bundleContext) {
readAdditionalRenderer(bundleContext);
}
private void readAdditionalRenderer(BundleContext bundleContext) {
final IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
.getExtensionPoint(ADDITIONAL_RENDER_EXTENSION);
if (extensionPoint == null) {
return;
}
for (final IExtension extension : extensionPoint.getExtensions()) {
for (final IConfigurationElement configurationElement : extension
.getConfigurationElements()) {
try {
final Class<AbstractAdditionalSWTRenderer<VElement>> renderer = loadClass(configurationElement
.getContributor().getName(),
configurationElement
.getAttribute("renderer")); //$NON-NLS-1$
final ECPAdditionalRendererTester tester = (ECPAdditionalRendererTester) configurationElement
.createExecutableExtension("tester"); //$NON-NLS-1$
legacyRenderer.put(tester, renderer);
} catch (final CoreException ex) {
reportService.report(new ECPRendererDescriptionInitFailedReport(ex));
} catch (final ClassNotFoundException e) {
reportService.report(new ECPRendererDescriptionInitFailedReport(e));
} catch (final InvalidRegistryObjectException e) {
reportService.report(new ECPRendererDescriptionInitFailedReport(e));
}
}
}
}
@SuppressWarnings("unchecked")
private static <T> Class<T> loadClass(String bundleName, String clazz)
throws ClassNotFoundException {
final Bundle bundle = Platform.getBundle(bundleName);
if (bundle == null) {
throw new ClassNotFoundException(clazz + bundleName);
}
return (Class<T>) bundle.loadClass(clazz);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.swt.core.EMFFormsAdditionalRendererService#isApplicable(org.eclipse.emf.ecp.view.spi.model.VElement,
* org.eclipse.emf.ecp.view.spi.context.ViewModelContext)
*/
@Override
public boolean isApplicable(VElement vElement, ViewModelContext viewModelContext) {
boolean result = false;
for (final ECPAdditionalRendererTester tester : legacyRenderer.keySet()) {
result |= tester.isApplicable(vElement, null);
}
return result;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emfforms.spi.swt.core.EMFFormsAdditionalRendererService#getRendererInstances(org.eclipse.emf.ecp.view.spi.model.VElement,
* org.eclipse.emf.ecp.view.spi.context.ViewModelContext)
*/
@Override
public Collection<AbstractAdditionalSWTRenderer<VElement>> getRendererInstances(VElement vElement,
ViewModelContext viewModelContext) {
final Collection<AbstractAdditionalSWTRenderer<VElement>> result = new ArrayList<AbstractAdditionalSWTRenderer<VElement>>();
for (final Class<AbstractAdditionalSWTRenderer<VElement>> renderer : getFittingRenderer(vElement,
viewModelContext)) {
final AbstractAdditionalSWTRenderer<VElement> additionalRenderer = createRenderer(vElement,
viewModelContext,
reportService, renderer);
additionalRenderer.init();
result.add(additionalRenderer);
}
return result;
}
private Collection<Class<AbstractAdditionalSWTRenderer<VElement>>> getFittingRenderer(VElement vElement,
ViewModelContext viewModelContext) {
final Collection<Class<AbstractAdditionalSWTRenderer<VElement>>> fitting = new ArrayList<Class<AbstractAdditionalSWTRenderer<VElement>>>();
for (final Entry<ECPAdditionalRendererTester, Class<AbstractAdditionalSWTRenderer<VElement>>> entry : legacyRenderer
.entrySet()) {
if (entry.getKey().isApplicable(vElement, viewModelContext)) {
fitting.add(entry.getValue());
}
}
return fitting;
}
private AbstractAdditionalSWTRenderer<VElement> createRenderer(VElement vElement, ViewModelContext viewContext,
final ReportService reportService,
final Class<? extends AbstractAdditionalSWTRenderer<VElement>> rendererClass) {
try {
return rendererClass
.getConstructor(vElement.getClass().getInterfaces()[0], ViewModelContext.class)
.newInstance(vElement, viewContext);
} catch (final InstantiationException ex) {
reportService.report(new RendererInitFailedReport(ex));
throw new IllegalStateException(ex);
} catch (final IllegalAccessException ex) {
reportService.report(new RendererInitFailedReport(ex));
throw new IllegalStateException(ex);
} catch (final IllegalArgumentException ex) {
reportService.report(new RendererInitFailedReport(ex));
throw new IllegalStateException(ex);
} catch (final InvocationTargetException ex) {
reportService.report(new RendererInitFailedReport(ex));
throw new IllegalStateException(ex);
} catch (final NoSuchMethodException ex) {
reportService.report(new RendererInitFailedReport(ex));
throw new IllegalStateException(ex);
} catch (final SecurityException ex) {
reportService.report(new RendererInitFailedReport(ex));
throw new IllegalStateException(ex);
}
}
}