| // Copyright (c) 2010 The Chromium Authors. 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 |
| |
| package org.eclipse.wst.jsdt.chromium.debug.ui.actions; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceVisitor; |
| import org.eclipse.core.resources.mapping.ResourceMapping; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| |
| /** |
| * A utility class for creating actions that work with files in selection. |
| * User should extend either {@link Single} or {@link Multiple} nested class. |
| * Custom file filter is supported. |
| */ |
| class FileBasedAction { |
| |
| /** |
| * A base class for actions that are enabled for a single file. User provides |
| * a {@link FileFilter} that may additionally convert low-level {@link IFile} |
| * to a user type RES. |
| * @param <RES> a user-specified type that corresponds to a file |
| */ |
| static abstract class Single<RES> extends SelectionBasedAction.Single<RES> { |
| private final FileFilter<RES> fileFilter; |
| |
| /** |
| * @param allowMutipleSelection see javadoc for {@link SelectionBasedAction.Single} |
| */ |
| protected Single(boolean allowMutipleSelection, FileFilter<RES> fileFilter) { |
| super(allowMutipleSelection); |
| this.fileFilter = fileFilter; |
| } |
| |
| @Override |
| protected RES castElement(Object element) { |
| List<RES> files = readFilesFromSelectionObject(element, fileFilter); |
| if (files.size() != 1) { |
| return null; |
| } |
| return files.get(0); |
| } |
| } |
| |
| /** |
| * A base class for actions that are enabled for several files. User provides |
| * a {@link FileFilter} that may additionally convert low-level {@link IFile} |
| * to a user type RES. |
| * @param <RES> a user-specified type that corresponds to a file |
| */ |
| static abstract class Multiple<RES> extends SelectionBasedAction.Multiple<RES> { |
| private final FileFilter<RES> fileFilter; |
| |
| protected Multiple(FileFilter<RES> fileFilter) { |
| this.fileFilter = fileFilter; |
| } |
| |
| @Override |
| protected List<? extends RES> readSelection( |
| IStructuredSelection selection) { |
| List<RES> files = new ArrayList<RES>(1); |
| for (Iterator<?> it = selection.iterator(); it.hasNext(); ) { |
| Object element = it.next(); |
| files.addAll(readFilesFromSelectionObject(element, fileFilter)); |
| } |
| return files; |
| } |
| } |
| |
| /** |
| * A filter that converts input file into a user type T or null. |
| * @param <T> |
| */ |
| static abstract class FileFilter<T> { |
| /** |
| * @return user data or null if the file should be ignored |
| */ |
| abstract T accept(IFile file); |
| } |
| |
| private static <RES> List<RES> readFilesFromSelectionObject(Object element, |
| FileFilter<RES> fileFilter) { |
| if (element instanceof ResourceMapping == false) { |
| return null; |
| } |
| ResourceMapping resourceMapping = (ResourceMapping) element; |
| return readFiles(resourceMapping, fileFilter); |
| } |
| |
| private static <RES> List<RES> readFiles(ResourceMapping resourceMapping, |
| final FileFilter<RES> fileFilter) { |
| final List<RES> fileList = new ArrayList<RES>(1); |
| IResourceVisitor visitor = new IResourceVisitor() { |
| public boolean visit(IResource resource) throws CoreException { |
| if (resource instanceof IFile == false) { |
| return true; |
| } else { |
| IFile file = (IFile) resource; |
| RES res = fileFilter.accept(file); |
| if (res != null) { |
| fileList.add(res); |
| } |
| return false; |
| } |
| } |
| }; |
| try { |
| // This will always return one project |
| IProject project = resourceMapping.getProjects()[0]; |
| if(project.isOpen()) |
| resourceMapping.accept(null, visitor, null); |
| } catch (CoreException e) { |
| throw new RuntimeException(e); |
| } |
| return fileList; |
| } |
| } |