blob: f0d4ecf630829a243d5f2b1ae3a83837b225fe11 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2014-2015 itemis 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:
* itemis - Initial API and implementation
* itemis - [458921] Newly introduced registries for metamodel serives, check validators and workflow contributors are not standalone-safe
*
* </copyright>
*/
package org.eclipse.sphinx.emf.mwe.dynamic;
import static org.eclipse.sphinx.jdt.util.JavaExtensions.isDevModePluginClasspathLocationOf;
import static org.eclipse.sphinx.jdt.util.JavaExtensions.isInstalledPluginClasspathRootLocationOf;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.mwe2.runtime.workflow.Workflow;
import org.eclipse.jdt.core.IType;
import org.eclipse.sphinx.emf.mwe.dynamic.internal.Activator;
import org.eclipse.sphinx.platform.util.PlatformLogUtil;
import org.eclipse.sphinx.platform.util.StatusUtil;
public class WorkflowContributorRegistry {
private static final String EXTP_WORKFLOW_CONTRIBUTORS = Activator.INSTANCE.getSymbolicName() + ".workflowContributors"; //$NON-NLS-1$
private static final String ELEM_CONTRIBUTOR = "contributor"; //$NON-NLS-1$
private static final String ATTR_PLUGIN_ID = "pluginId"; //$NON-NLS-1$
public static final WorkflowContributorRegistry INSTANCE = new WorkflowContributorRegistry(Platform.getExtensionRegistry(),
PlatformLogUtil.getLog(Activator.getPlugin()));
private Set<String> contributorPluginIds = null;
private IExtensionRegistry extensionRegistry;
private ILog log;
protected WorkflowContributorRegistry(IExtensionRegistry extensionRegistry, ILog log) {
this.extensionRegistry = extensionRegistry;
this.log = log;
}
public Set<String> getContributorPluginIds() {
initialize();
return contributorPluginIds != null ? contributorPluginIds : Collections.<String> emptySet();
}
/**
* Initialize internal data by reading from platform registry
*/
private void initialize() {
if (extensionRegistry == null) {
return;
}
if (contributorPluginIds == null) {
synchronized (this) {
contributorPluginIds = new HashSet<String>();
IConfigurationElement[] elements = extensionRegistry.getConfigurationElementsFor(EXTP_WORKFLOW_CONTRIBUTORS);
for (IConfigurationElement element : elements) {
if (!element.getName().equals(ELEM_CONTRIBUTOR)) {
continue;
}
// Retrieve contributor bundle id
String id = element.getAttribute(ATTR_PLUGIN_ID);
if (id == null || id.isEmpty()) {
String msg = "Missing contributor id in " + EXTP_WORKFLOW_CONTRIBUTORS + " extension from " //$NON-NLS-1$ //$NON-NLS-2$
+ element.getContributor().getName();
IStatus status = StatusUtil.createErrorStatus(Activator.getPlugin(), new RuntimeException(msg));
log.log(status);
continue;
}
contributorPluginIds.add(id);
}
}
}
}
/**
* Checks if the provided classpath location is a contributed via an installed plug-in or in a development mode
* plug-in. Examples:
* <p>pluginId = org.eclipse.sphinx.examples.workflows</p>
* <p>Expected to match:</p>
* <ul>
* <li>W:/eclipse-sphinx/org.eclipse.sphinx/plugins/org.eclipse.sphinx.examples.workflows/bin/</li>
* <li>W:/eclipse-sphinx/org.eclipse.sphinx/examples/org.eclipse.sphinx.examples.workflows/bin/org/eclipse/sphinx/examples/workflows/model/PrintModelContentWorkflow.class</li>
* <li>W:/eclipse-sphinx/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool/plugins/org.eclipse.sphinx.examples.workflows_0.9.0.v20141209-1519.jar</li>
* <ul>
* <p>Expected to ignore:</p>
* <ul>
* <li>/External Plug-in Libraries</li>
* <li>/MyProject</li>
* <li>C:/Program%20Files/Java/jdk1.7.0_55/jre/lib/resources.jar</li>
* <li>W:/eclipse-sphinx/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool/plugins/org.eclipse.sphinx.examples.workflows.lib_0.9.0.v20141209-1519.jar</li>
* </ul>
*/
public boolean isContributorClasspathLocation(IPath classpathLocation) {
return getContributorPluginId(classpathLocation) != null;
}
private String getContributorPluginId(IPath classpathLocation) {
if (classpathLocation != null && classpathLocation.segmentCount() > 1) {
for (String id : getContributorPluginIds()) {
if (isInstalledPluginClasspathRootLocationOf(id, classpathLocation) || isDevModePluginClasspathLocationOf(id, classpathLocation)) {
return id;
}
}
}
return null;
}
public boolean matchesContributedWorkflowClass(IType workflowType) {
try {
return loadContributedWorkflowClass(workflowType) != null;
} catch (Exception ex) {
// Ignore exception, just return false
return false;
}
}
public Class<Workflow> loadContributedWorkflowClass(IType workflowType) throws CoreException {
Assert.isNotNull(workflowType);
try {
String contributorPluginId = getContributorPluginId(workflowType.getPath());
if (contributorPluginId == null) {
throw new IllegalStateException(
"Workflow '" + workflowType.getFullyQualifiedName() + "' is not contained in any registered workflow contributor plug-in"); //$NON-NLS-1$ //$NON-NLS-2$
}
Class<?> clazz = CommonPlugin.loadClass(contributorPluginId, workflowType.getFullyQualifiedName());
if (!Workflow.class.isAssignableFrom(clazz)) {
throw new IllegalStateException("Workflow class '" + clazz.getName() + "' is not a subclass of " + Workflow.class.getName()); //$NON-NLS-1$ //$NON-NLS-2$
}
@SuppressWarnings("unchecked")
Class<Workflow> workflowClass = (Class<Workflow>) clazz;
return workflowClass;
} catch (Exception ex) {
IStatus status = StatusUtil.createErrorStatus(Activator.getPlugin(), ex);
throw new CoreException(status);
}
}
}