blob: 3036248a429134841a1188dbba9d6c6e6d5a30d8 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2009-2010 Thales Corporate Services S.A.S.
* 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:
* Thales Corporate Services S.A.S - initial API and implementation
*
* </copyright>
*/
package org.eclipse.egf.portfolio.genchain.tools.ui.actions;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.egf.core.domain.EgfResourceSet;
import org.eclipse.egf.core.pde.tools.ConvertProjectOperation;
import org.eclipse.egf.core.producer.InvocationException;
import org.eclipse.egf.domain.IDomainHelper;
import org.eclipse.egf.domain.emf.EMFDomainHelper;
import org.eclipse.egf.model.domain.DomainFactory;
import org.eclipse.egf.model.domain.EMFDomain;
import org.eclipse.egf.model.domain.TypeDomain;
import org.eclipse.egf.model.domain.util.DomainSwitch;
import org.eclipse.egf.model.fcore.Activity;
import org.eclipse.egf.model.fcore.FactoryComponent;
import org.eclipse.egf.model.pattern.Substitution;
import org.eclipse.egf.model.pattern.TypePatternSubstitution;
import org.eclipse.egf.model.types.TypeString;
import org.eclipse.egf.portfolio.genchain.extension.ExtensionHelper;
import org.eclipse.egf.portfolio.genchain.generationChain.FeatureAddition;
import org.eclipse.egf.portfolio.genchain.generationChain.GenerationChain;
import org.eclipse.egf.portfolio.genchain.generationChain.PluginProvider;
import org.eclipse.egf.portfolio.genchain.generationChain.util.GenerationChainSwitch;
import org.eclipse.egf.portfolio.genchain.tools.Activator;
import org.eclipse.egf.portfolio.genchain.tools.ui.Messages;
import org.eclipse.egf.portfolio.genchain.tools.utils.RunActivityHelper;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.ui.internal.editors.text.WorkspaceOperationRunner;
/**
* @author Thomas Guiu
*
*/
public class CreateFcoreHelper {
private static final String ORG_ECLIPSE_PDE_PLUGIN_NATURE = "org.eclipse.pde.PluginNature";
public static final CreateFcoreHelper INSTANCE = new CreateFcoreHelper();
private static final URI GENERATOR_URI = URI.createURI("platform:/plugin/org.eclipse.egf.portfolio.genchain.tools/egf/Generation_Chain_Producer.fcore#_6qO2EYhGEd-Ii9WHGzCGHg");
public WorkspaceJob createJob(final GenerationChain generationChain, final boolean run) {
final String fcoreOutputPath = computeFcoreOutputPath(generationChain);
final WorkspaceJob beforeJob = createBeforeJob();
final WorkspaceJob afterJob = createAfterJob();
final WorkspaceJob runJob = new WorkspaceJob(Messages.genchain_run_action_label) {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
try {
ResourceSet set = new EgfResourceSet();
runFcore(set, generationChain, fcoreOutputPath, monitor);
generateFeaturePlugin(set, generationChain, monitor);
if (afterJob != null) {
afterJob.schedule(1000);
// afterJob.join();
}
} catch (CoreException e) {
throw e;
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getDefault().getPluginID(), e.getMessage(), e));
}
return Status.OK_STATUS;
}
};
final WorkspaceJob buildJob = new WorkspaceJob(Messages.genchain_generate_action_label) {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
try {
createFcore(generationChain, fcoreOutputPath, monitor);
if (run) {
runJob.schedule(1000);
// runJob.join();
}
} catch (CoreException e) {
throw e;
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getDefault().getPluginID(), e.getMessage(), e));
}
return Status.OK_STATUS;
}
};
final WorkspaceJob setupJob = new WorkspaceJob(Messages.genchain_generate_action_label) {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
try {
if (beforeJob != null) {
beforeJob.schedule();
beforeJob.join();
}
setupProject(generationChain.getFactoryComponentName(), computeFcoreRelativePath(generationChain));
buildJob.schedule(1000);
} catch (CoreException e) {
throw e;
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getDefault().getPluginID(), e.getMessage(), e));
}
return Status.OK_STATUS;
}
};
return setupJob;
}
public WorkspaceJob createBeforeJob() {
return null;
}
public WorkspaceJob createAfterJob() {
return null;
}
public WorkspaceJob createJob(URI fcoreURI, boolean run) {
final ResourceSet resourceSet = new EgfResourceSet();
final GenerationChain generationChain = (GenerationChain) resourceSet.getResource(fcoreURI, true).getContents().get(0);
return createJob(generationChain, run);
}
protected String computeFcoreOutputPath(GenerationChain generationChain) {
return generationChain.getFactoryComponentName() + computeFcoreRelativePath(generationChain);
}
protected String computeFcoreRelativePath(GenerationChain generationChain) {
return "/model/" + generationChain.getName() + ".fcore";
}
public void setupProject(String projectName, String fcorePath) throws CoreException {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
if (!project.exists())
project.create(null);
project.open(null);
WorkspaceOperationRunner runner = new WorkspaceOperationRunner();
runner.setProgressMonitor(null);
try {
runner.run(true, false, new ConvertProjectOperation(project, false, false));
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getDefault().getPluginID(), e.getMessage(), e));
}
}
protected void createFcore(final GenerationChain generationChain, final String fcoreOutputPath, IProgressMonitor monitor) throws CoreException {
FactoryComponent fc = (FactoryComponent) new EgfResourceSet().getEObject(getGeneratorURI(), true);
EMFDomain domain = DomainFactory.eINSTANCE.createEMFDomain();
final URI uri = generationChain.eResource().getURI();
domain.setUri(uri);
((TypePatternSubstitution) (fc.getContract("pattern substitutions").getType())).getSubstitutions().addAll(computeSubstitutions());
((TypeDomain) (fc.getContract("genChain model").getType())).setDomain(domain);
((TypeString) (fc.getContract("generation plugin name").getType())).setValue(generationChain.getFactoryComponentName());
((TypeString) (fc.getContract("model name").getType())).setValue(generationChain.getName());
((TypeString) (fc.getContract("fcore output path").getType())).setValue(fcoreOutputPath);
IDomainHelper helper = new EMFDomainHelper();
try {
try {
if (helper.loadDomain(domain))
RunActivityHelper.run(fc, monitor);
} finally {
helper.unLoadDomain(domain);
}
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getDefault().getPluginID(), e.getMessage(), e));
}
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(generationChain.getFactoryComponentName());
if (project != null && project.exists()) {
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
}
}
protected void runFcore(ResourceSet resourceSet, GenerationChain generationChain, String fcoreOutputPath, IProgressMonitor monitor) throws CoreException {
URI uri = URI.createPlatformPluginURI(fcoreOutputPath, false);
EObject eObject = resourceSet.getResource(uri, true).getContents().get(0);
try {
RunActivityHelper.run((Activity) eObject, monitor);
} catch (InvocationException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getDefault().getPluginID(), e.getMessage(), e));
}
}
protected void generateFeaturePlugin(ResourceSet resourceSet, final GenerationChain generationChain, IProgressMonitor monitor) throws CoreException {
final Set<String> pluginList = new HashSet<String>();
final Set<String> includedFeatureList = new HashSet<String>();
String fcPath = computeFcoreOutputPath(generationChain);
// final Map<String, GenModel> genModels = collectGenModels(generationChain.eResource().getResourceSet(), fcPath);
final EList<EObject> collectDomains = collectDomains(resourceSet, fcPath);
String pluginName = generationChain.getFactoryComponentName();
// We don't include anymore the fcore file
// pluginList.add(pluginName);
// add plugin who contains the chain model
URI uri = generationChain.eResource().getURI();
pluginList.add(uri.segment(1));
new GenerationChainSwitch<Object>() {
// we want to walk throught all parents EClass
@Override
protected Object doSwitch(EClass theEClass, EObject theEObject) {
if (theEClass.eContainer() == modelPackage) {
return doSwitch(theEClass.getClassifierID(), theEObject);
} else {
List<EClass> eSuperTypes = theEClass.getESuperTypes();
if (eSuperTypes.isEmpty())
return defaultCase(theEObject);
for (EClass superType : eSuperTypes) {
Object doSwitch = doSwitch(superType, theEObject);
if (doSwitch != null)
return doSwitch;
}
return null;
}
}
@Override
public Object caseGenerationChain(GenerationChain object) {
for (EObject obj : object.getElements())
doSwitch(obj);
return this;
}
@Override
public Object casePluginProvider(PluginProvider object) {
pluginList.addAll(object.getPluginNames(collectDomains));
return this;
}
public Object caseFeatureAddition(FeatureAddition addition) {
for (String projectName : addition.getAdditions()) {
includedFeatureList.add(projectName);
}
return this;
}
}.doSwitch(generationChain);
for (String pluginNameString : pluginList) {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(pluginNameString);
if (project.exists() && !project.hasNature(ORG_ECLIPSE_PDE_PLUGIN_NATURE)) {
WorkspaceOperationRunner runner = new WorkspaceOperationRunner();
runner.setProgressMonitor(null);
try {
runner.run(true, false, new ConvertProjectOperation(project, false, false));
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getDefault().getPluginID(), e.getMessage(), e));
}
}
}
IProject projectF = FeatureHelper.createFeatureProject(includedFeatureList, pluginList, pluginName, generationChain.getName(), monitor);
if (projectF != null && projectF.exists()) {
projectF.refreshLocal(IResource.DEPTH_INFINITE, monitor);
}
}
private EList<EObject> collectDomains(final ResourceSet resourceSet, String fcPath) {
final EList<EObject> result = new BasicEList<EObject>();
DomainSwitch<Object> _switch = new DomainSwitch<Object>() {
@Override
public Object caseEMFDomain(EMFDomain object) {
result.add(resourceSet.getResource(object.getUri(), true).getContents().get(0));
return this;
}
@Override
public Object defaultCase(EObject object) {
for (EObject obj : object.eContents())
doSwitch(obj);
return null;
}
};
for (EObject obj : resourceSet.getResource(URI.createPlatformPluginURI(fcPath, false), true).getContents()) {
_switch.doSwitch(obj);
}
return result;
}
protected List<Substitution> computeSubstitutions() {
return ExtensionHelper.getAllSubstitutions();
}
protected URI getGeneratorURI() {
return GENERATOR_URI;
}
}