/******************************************************************************* * Copyright (c) 2008, 2012 Obeo. * 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: * Obeo - initial API and implementation *******************************************************************************/ package org.eclipse.emf.eef.codegen.extended.ui.launcher; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.Diagnostician; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; import org.eclipse.emf.eef.EEFGen.EEFGenModel; import org.eclipse.emf.eef.EEFGen.EEFGenModelReference; import org.eclipse.emf.eef.EEFGen.GenEditionContext; import org.eclipse.emf.eef.EEFGen.GenViewsRepository; import org.eclipse.emf.eef.codegen.EEFCodegenPlugin; import org.eclipse.emf.eef.codegen.extended.flow.OverrideEMFEditorCode; import org.eclipse.emf.eef.codegen.flow.Workflow; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IActionDelegate; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IWorkbenchPart; /** * @author <a href="mailto:stephane.bouchet@obeo.fr">Stephane Bouchet</a> */ public class GenerateEEFEditorAction implements IObjectActionDelegate { private static final String GENERATE_EEF_EDITOR = "Generate EEF Editor for "; /** * @deprecated see bug #370409 */ private Shell shell; protected Set<IFile> selectedFiles; /** * the list of eefgenmodels * * @deprecated since a job is used to generates files */ protected List<EEFGenModel> eefGenModels; /** * Constructor. */ public GenerateEEFEditorAction() { selectedFiles = new LinkedHashSet<IFile>(); } /** * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) * @deprecated see bug #370409 */ public void setActivePart(IAction action, IWorkbenchPart targetPart) { } /** * {@inheritDoc} * * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) */ public void run(IAction action) { if (selectedFiles != null) { try { List<EEFGenModel> eefgenmodels = initEEFGenModel(); final Workflow flow = new Workflow("Generate EEF Editors", shell); for (final EEFGenModel eefGenModel : eefgenmodels) { String key = GENERATE_EEF_EDITOR + eefGenModel.eResource().getURI().toString(); OverrideEMFEditorCode eefEditorCode = new OverrideEMFEditorCode(key, eefGenModel); flow.addStep(key, eefEditorCode); } flow.prepare(); Job job = new Job("EEF editors generation") { @Override protected IStatus run(IProgressMonitor monitor) { flow.execute(monitor); monitor.done(); selectedFiles.clear(); return Status.OK_STATUS; } }; job.setUser(true); // lock the workspace to avoid concurrent modification job.setRule(ResourcesPlugin.getWorkspace().getRoot()); job.schedule(); } catch (IOException e) { EEFCodegenPlugin.getDefault().logError(e); } } } /** * @see IActionDelegate#selectionChanged(IAction, ISelection) */ public void selectionChanged(IAction action, ISelection selection) { selectedFiles.clear(); if (selection instanceof StructuredSelection) { StructuredSelection sSelection = (StructuredSelection)selection; for (Object selectedElement : sSelection.toList()) { if (selectedElement instanceof IFile) { this.selectedFiles.add((IFile)selectedElement); } } } } /** * {@inheritDoc} * * @see org.eclipse.emf.eef.codegen.ui.generators.actions.AbstractGenerateEEFAction#inutEEFGenModel() */ protected List<EEFGenModel> initEEFGenModel() throws IOException { List<EEFGenModel> eefgenmodels = new ArrayList<EEFGenModel>(selectedFiles.size()); if (!selectedFiles.isEmpty()) { ResourceSet resourceSet = new ResourceSetImpl(); for (IFile selectedFile : selectedFiles) { URI modelURI = URI.createPlatformResourceURI(selectedFile.getFullPath().toString(), true); String fileExtension = modelURI.fileExtension(); if (fileExtension == null || fileExtension.length() == 0) { fileExtension = Resource.Factory.Registry.DEFAULT_EXTENSION; } final Resource.Factory.Registry registry = Resource.Factory.Registry.INSTANCE; final Object resourceFactory = registry.getExtensionToFactoryMap().get(fileExtension); if (resourceFactory != null) { resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap() .put(fileExtension, resourceFactory); } else { resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap() .put(fileExtension, new XMIResourceFactoryImpl()); } Resource res = resourceSet.createResource(modelURI); res.load(Collections.EMPTY_MAP); EcoreUtil.resolveAll(resourceSet); if (res.getContents().size() > 0) { EObject object = res.getContents().get(0); if (object instanceof EEFGenModel) { eefgenmodels.add((EEFGenModel)object); } } } } // validate eefgenmodels and components recursively return validateEEFGenmodels(eefgenmodels); } /** * @param eefgenmodels * @return * @since 2.0 */ private List<EEFGenModel> validateEEFGenmodels(List<EEFGenModel> eefgenmodels) { List<EEFGenModel> eefModels = new ArrayList<EEFGenModel>(eefgenmodels.size()); eefModels.addAll(eefgenmodels); for (EEFGenModel eefGenModel : eefgenmodels) { if (!validateOneEEFGenModel(eefGenModel)) eefModels.remove(eefGenModel); // validate also referenced EEFGenModels if (!validateReferencedEEFGenModels(eefGenModel)) eefModels.remove(eefGenModel); } return eefModels; } /** * @param eefGenModel */ private boolean validateReferencedEEFGenModels(EEFGenModel eefGenModel) { for (EEFGenModelReference eefGenModelReference : eefGenModel.getReferences()) { EEFGenModel referencedEEFGenModel = eefGenModelReference.getReferencedContext(); if (!validateOneEEFGenModel(referencedEEFGenModel)) return false; return validateReferencedEEFGenModels(referencedEEFGenModel); } return true; } /** * @param eefGenModel * @return * @since 2.0 */ private boolean validateOneEEFGenModel(EEFGenModel eefGenModel) { // validate eefgenmodels final Diagnostic diag = Diagnostician.INSTANCE.validate(eefGenModel); if (diag.getSeverity() != Diagnostic.OK) { Status status = new Status(diag.getSeverity(), EEFCodegenPlugin.PLUGIN_ID, "EEFGenmodel '" + eefGenModel.eResource().getURI() + "' contains errors."); EEFCodegenPlugin.getDefault().getLog().log(status); return false; } // validate PropertiesEditionContext for (GenEditionContext genEditionContext : eefGenModel.getEditionContexts()) { final Diagnostic diag2 = Diagnostician.INSTANCE.validate(genEditionContext .getPropertiesEditionContext()); if (diag2.getSeverity() != Diagnostic.OK) { Status status = new Status(diag2.getSeverity(), EEFCodegenPlugin.PLUGIN_ID, "PropertiesEditionContext '" + genEditionContext.getPropertiesEditionContext().eResource().getURI() + "' contains errors."); EEFCodegenPlugin.getDefault().getLog().log(status); return false; } } // validate ViewsRepository for (GenViewsRepository genViewsRepository : eefGenModel.getViewsRepositories()) { final Diagnostic diag2 = Diagnostician.INSTANCE.validate(genViewsRepository.getViewsRepository()); if (diag2.getSeverity() != Diagnostic.OK) { Status status = new Status(diag2.getSeverity(), EEFCodegenPlugin.PLUGIN_ID, "ViewsRepository '" + genViewsRepository.getViewsRepository().eResource().getURI() + "' contains errors."); EEFCodegenPlugin.getDefault().getLog().log(status); return false; } } return true; } }