/******************************************************************************* * Copyright (c) 2011 Bundlemaker project team. * 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: * Bundlemaker project team - initial API and implementation ******************************************************************************/ package org.bundlemaker.core.ui.handler; import java.lang.reflect.InvocationTargetException; import java.util.List; import org.bundlemaker.core.analysis.IBundleMakerArtifact; import org.bundlemaker.core.parser.IParserAwareBundleMakerProject; import org.bundlemaker.core.project.IProjectDescriptionAwareBundleMakerProject; import org.bundlemaker.core.resource.IModularizedSystem; import org.bundlemaker.core.ui.internal.Activator; import org.bundlemaker.core.ui.internal.BundleMakerUiUtils; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; import org.eclipse.ui.dialogs.ISelectionStatusValidator; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.ui.views.navigator.ResourceComparator; /** * This handler lets the user select a transformation script that is applied on a new IModularizedSystem * * @author Nils Hartmann (nils@nilshartmann.net) * */ public class TransformHandler extends AbstractArtifactBasedHandler { /* * (non-Javadoc) * * @see org.bundlemaker.core.ui.commands.AbstractBundleMakerHandler#execute(org.eclipse.core.commands.ExecutionEvent , * java.util.List) */ @Override protected void execute(ExecutionEvent event, List<IBundleMakerArtifact> selectedArtifacts) throws Exception { for (IBundleMakerArtifact iArtifact : selectedArtifacts) { IBundleMakerArtifact advancedArtifact = iArtifact; IModularizedSystem modularizedSystem = advancedArtifact.getModularizedSystem(); // Ask the user for the script that should be run IFile selectedScript = selectTransformationScript(modularizedSystem.getBundleMakerProject()); if (selectedScript != null) { String moduleName = getModuleName(selectedScript); // Apply the transformation script transform(modularizedSystem.getBundleMakerProject(), moduleName, selectedScript); } } } static String getModuleName(IFile transformationScript) { // TODO ask user for name of module String moduleName = transformationScript.getLocation().removeFileExtension().lastSegment(); return moduleName; } /** * Applies the transformation script that is identified by the given uri * * @param bundleMakerProject * @param moduleName * the name of the new {@link IModularizedSystem} * @param uri * @throws Exception */ static void transform(final IProjectDescriptionAwareBundleMakerProject bundleMakerProject, final String moduleName, final IFile scriptFile) throws Exception { PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException { try { // monitor.beginTask("Running " + scriptFile.getName(), 100); // Parse the transformation script // TransformationModel model = TransformationDslUtils.parse(scriptFile.getLocationURI().toString()); // // Execute the script and apply the contained transformation // final TransformationExecutor executor = new TransformationExecutor(createModularizedSystem( // bundleMakerProject, moduleName), model); // executor.apply(monitor); } catch (Exception ex) { throw new InvocationTargetException(ex); } finally { monitor.done(); } } }); // Refresh the project explorer to make sure new project is visible BundleMakerUiUtils.refreshProjectExplorer(bundleMakerProject); } /** * Asks the user to select a transformation script from the workspace. * * <p> * The dialog that will be opened only displays <tt>.bmt</tt>-transformation scripts * * @param project * @return the selected BMT-file or null if no file has been selected */ private IFile selectTransformationScript(IProjectDescriptionAwareBundleMakerProject project) { ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(new Shell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider()); dialog.setHelpAvailable(false); dialog.setTitle("Choose transformation script"); dialog.setMessage("Choose a transformation script that will be applied on " + project.getProject().getName()); // set the filter that filters bmt-files and their containing directories dialog.addFilter(new DslFileFilter()); // set the validator that checks that only IFile instances can be selected dialog.setValidator(new ISelectionStatusValidator() { private IStatus fgErrorStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, ""); private IStatus fgOKStatus = new Status(IStatus.OK, Activator.PLUGIN_ID, ""); @Override public IStatus validate(Object[] selection) { for (Object object : selection) { if (!(object instanceof IFile)) { return fgErrorStatus; } } return fgOKStatus; } }); dialog.setInput(ResourcesPlugin.getWorkspace().getRoot()); dialog.setComparator(new ResourceComparator(ResourceComparator.NAME)); dialog.setAllowMultiple(false); // open the dialog and return the selected IFile if (dialog.open() == Window.OK) { Object firstResult = dialog.getFirstResult(); if (firstResult == null) { return null; } IFile selectedScript = (IFile) firstResult; return selectedScript; } return null; } /** * (Re-)creates a {@link IModularizedSystem} with the specified name * * @param bundleMakerProject * @param name * @return * @throws Exception */ private static IModularizedSystem createModularizedSystem(IParserAwareBundleMakerProject bundleMakerProject, String name) throws Exception { if (bundleMakerProject.hasModularizedSystemWorkingCopy(name)) { // Remote exisiting system bundleMakerProject.deleteModularizedSystemWorkingCopy(name); } return bundleMakerProject.createModularizedSystemWorkingCopy( new NullProgressMonitor(), name); } class DslFileFilter extends ViewerFilter { @Override public boolean select(Viewer viewer, Object parent, Object element) { if (element instanceof IFile) { IPath fullPath = ((IFile) element).getFullPath(); String ext = fullPath.getFileExtension(); return "bmt".equals(ext); } else if (element instanceof IContainer) { // IProject, IFolder // ignore closed projects if (element instanceof IProject && !((IProject) element).isOpen()) return false; try { IResource[] resources = ((IContainer) element).members(); for (int i = 0; i < resources.length; i++) { // recursive! Only show containers that contain an archive if (select(viewer, parent, resources[i])) { return true; } } } catch (CoreException e) { reportError(Activator.PLUGIN_ID, e.toString(), e); } } return false; } } }