/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.editors.text; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.eclipse.swt.widgets.Shell; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.filebuffers.FileBuffers; import org.eclipse.core.filebuffers.manipulation.FileBufferOperationRunner; import org.eclipse.core.filebuffers.manipulation.IFileBufferOperation; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.text.ITextSelection; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; /** * Operation handler for a file buffer. *

* This class may be instantiated or be subclassed.

* * @since 3.1 */ public class FileBufferOperationHandler extends AbstractHandler { private IFileBufferOperation fFileBufferOperation; private IWorkbenchWindow fWindow; private IResource[] fResources; private IPath fLocation; /** * Creates a new file buffer operation handler. * * @param fileBufferOperation the file buffer operation */ public FileBufferOperationHandler(IFileBufferOperation fileBufferOperation) { fFileBufferOperation= fileBufferOperation; } /** * Initializes this file buffer operation handler with the given resources and the given location. The array of resources * is adopted by this handler and may not be modified by clients after that method has been called. * * @param resources the resources to be adopted * @param location the location */ public void initialize(IResource[] resources, IPath location) { if (resources != null) { fResources= new IResource[resources.length]; System.arraycopy(resources, 0, fResources, 0, resources.length); } else { fResources= null; } fLocation= location; } /** * Computes the selected resources. */ protected final void computeSelectedResources() { if (fResources != null || fLocation != null) return; ISelection selection= getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection= (IStructuredSelection) selection; ArrayList resources= new ArrayList<>(structuredSelection.size()); Iterator e= structuredSelection.iterator(); while (e.hasNext()) { Object element= e.next(); if (element instanceof IResource) resources.add(element); else if (element instanceof IAdaptable) { IAdaptable adaptable= (IAdaptable) element; Object adapter= adaptable.getAdapter(IResource.class); if (adapter instanceof IResource) resources.add(adapter); } } if (!resources.isEmpty()) fResources= resources.toArray(new IResource[resources.size()]); } else if (selection instanceof ITextSelection) { IWorkbenchWindow window= getWorkbenchWindow(); if (window != null) { IWorkbenchPart workbenchPart= window.getPartService().getActivePart(); if (workbenchPart instanceof IEditorPart) { IEditorPart editorPart= (IEditorPart) workbenchPart; IEditorInput input= editorPart.getEditorInput(); Object adapter= input.getAdapter(IResource.class); if (adapter instanceof IResource) fResources= new IResource[] { (IResource) adapter }; else { adapter= input.getAdapter(ILocationProvider.class); if (adapter instanceof ILocationProvider) { ILocationProvider provider= (ILocationProvider) adapter; fLocation= provider.getPath(input); } } } } } } /** * Returns the selection of the active workbench window. * * @return the current selection in the active workbench window or null */ protected final ISelection getSelection() { IWorkbenchWindow window= getWorkbenchWindow(); if (window != null) return window.getSelectionService().getSelection(); return null; } /** * Returns the active workbench window. * * @return the active workbench window or null if not available */ protected final IWorkbenchWindow getWorkbenchWindow() { if (fWindow == null) fWindow= PlatformUI.getWorkbench().getActiveWorkbenchWindow(); return fWindow; } /** * Collects the files out of the given resources. * * @param resources the resources from which to get the files * @return an array of files */ protected IFile[] collectFiles(IResource[] resources) { Set files= new HashSet<>(); for (IResource resource : resources) { if ((IResource.FILE & resource.getType()) > 0) files.add(resource); } return files.toArray(new IFile[files.size()]); } /** * Runs the given operation. * * @param files the file on which to run this operation * @param location the file buffer location * @param fileBufferOperation the operation to run */ protected final void doRun(final IFile[] files, final IPath location, final IFileBufferOperation fileBufferOperation) { Job job= new Job(fileBufferOperation.getOperationName()) { @Override protected IStatus run(IProgressMonitor monitor) { IStatus status; try { int ticks= 100; SubMonitor subMonitor= SubMonitor.convert(monitor, fFileBufferOperation.getOperationName(), ticks); IPath[] locations; if (files != null) { ticks-= 30; locations= generateLocations(files, subMonitor.split(30)); } else locations= new IPath[] { location }; if (locations != null && locations.length > 0) { FileBufferOperationRunner runner= new FileBufferOperationRunner(FileBuffers.getTextFileBufferManager(), getShell()); runner.execute(locations, fileBufferOperation, subMonitor.split(ticks)); } status= Status.OK_STATUS; } catch (OperationCanceledException e) { status= new Status(IStatus.CANCEL, EditorsUI.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$ } catch (CoreException e) { status= new Status(IStatus.ERROR, EditorsUI.PLUGIN_ID, IStatus.OK, "", e); //$NON-NLS-1$ } return status; } }; job.setUser(true); job.schedule(); } /** * Returns the shell of the active workbench window. * * @return the shell */ protected final Shell getShell() { IWorkbenchWindow window= getWorkbenchWindow(); return window == null ? null : window.getShell(); } /** * Generates the file buffer locations out of the given files. * * @param files an array of files * @param progressMonitor the progress monitor * @return an array with the generated locations */ protected final IPath[] generateLocations(IFile[] files, IProgressMonitor progressMonitor) { progressMonitor.beginTask(TextEditorMessages.FileBufferOperationHandler_collectionFiles_label, files.length); try { Set locations= new HashSet<>(); for (IFile file : files) { IPath fullPath = file.getFullPath(); if (isAcceptableLocation(fullPath)) locations.add(fullPath); progressMonitor.worked(1); } return locations.toArray(new IPath[locations.size()]); } finally { progressMonitor.done(); } } /** * Tells whether the given location is accepted by this handler. * * @param location a file buffer location * @return true if the given location is acceptable */ protected boolean isAcceptableLocation(IPath location) { return true; } @Override public Object execute(ExecutionEvent event) throws ExecutionException { computeSelectedResources(); try { if (fResources != null && fResources.length > 0) { IFile[] files= collectFiles(fResources); if (files != null && files.length > 0) doRun(files, null, fFileBufferOperation); } else if (isAcceptableLocation(fLocation)) doRun(null, fLocation, fFileBufferOperation); // Standard return value. DO NOT CHANGE. return null; } finally { fResources= null; fLocation= null; } } }