/****************************************************************************** * Copyright (c) 2008-2013, Linagora * * 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: * Linagora - initial API and implementation *******************************************************************************/ package com.ebmwebsourcing.petals.common.internal.provisional.utils; import java.io.File; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.navigator.CommonNavigator; import org.eclipse.ui.part.FileEditorInput; import com.ebmwebsourcing.petals.common.internal.PetalsCommonPlugin; /** * Utility methods to manage and look for resources in the workspace. * @author Vincent Zurczak - EBM WebSourcing */ public final class ResourceUtils { /** * Private constructor for utility class. */ private ResourceUtils() { // nothing } /** * Gets all the files whose extension is <b>extension</b> and present in <b>containers</b>. * @param extension the file extension. Use "*" for any extension. Not null. * @param containers the containers to explore * @return all the IFile contained into this container (with no limit in the level). */ public static List<IFile> getFiles( String extension, Collection<? extends IContainer> containers ) { List<IFile> result = new ArrayList<IFile> (); if( containers == null ) return result; for( IContainer container : containers ) { try { IResource[] resources = container.members(); for (IResource resource : resources) { switch (resource.getType()) { case IResource.FILE: if( "*".equals( extension ) || extension.equalsIgnoreCase( resource.getFileExtension())) result.add((IFile) resource); break; case IResource.FOLDER: IFolder subFolder = (IFolder) resource; result.addAll( getFiles( extension, Arrays.asList( subFolder ))); break; case IResource.PROJECT: IProject project = (IProject) resource; if( project.isAccessible()) result.addAll( getFiles( extension, Arrays.asList( project ))); break; default: System.out.println( "unkown type" ); break; } } } catch( CoreException e ) { PetalsCommonPlugin.log( e, IStatus.ERROR ); } } return result; } /** * Gets all the folders present in <b>container</b>. * * @param container * the container to explore * @return all the IFolder contained into this container (with no limit in * the level). */ public static List<IFolder> getFolders(IContainer container) { List<IFolder> result = new ArrayList<IFolder>(); try { IResource[] resources = container.members(); for (IResource resource : resources) { switch (resource.getType()) { case IResource.FOLDER: IFolder subFolder = (IFolder) resource; result.add(subFolder); result.addAll(getFolders(subFolder)); default: break; } } } catch( CoreException e ) { PetalsCommonPlugin.log( e, IStatus.ERROR ); } return result; } /** * Gets sub-containers of container having at least one resource of the * given extensions. * <p> * The algorithm checks in the container children if it contains any valid * element. It searches the entire sub-folders until it finds something or * until it checked all the files in this container. * </p> * * @param container * the container to search into * @param extensions * the file extensions to search for * @param resourcesToSkip * resources to skip. Can't be null. * @return the children that contains at least one composite file */ public static IResource[] getDirectValidChildren( IContainer container, List<String> extensions, List<IResource> resourcesToSkip) { if (container instanceof IProject && !((IProject) container).isOpen()) return new IResource[0]; IResource[] res; try { res = container.members(); } catch (CoreException e) { res = new IResource[0]; } ArrayList<IResource> resources = new ArrayList<IResource>(); for (IResource r : res) { if (resourcesToSkip.contains(r)) continue; if (r instanceof IContainer) { IResource[] subRes = getDirectValidChildren((IContainer) r, extensions, resourcesToSkip); if (subRes.length > 0) resources.add(r); } else if (r instanceof IFile) { String extension = ((IFile) r).getFileExtension(); if (extensions.contains(extension)) resources.add(r); } } res = new IResource[resources.size()]; return resources.toArray(res); } /** * @param container * @param extensions * @param resourcesToSkip * @return */ public static IResource[] getDirectValidChildren( IContainer container, String[] extensions, List<IResource> resourcesToSkip) { return getDirectValidChildren(container, Arrays.asList(extensions), resourcesToSkip); } /** * Gets the plug-in binary path. * <p> * The plug-in can be either in a jar file or as a plug-in project. In case * of a plug-in project, this method assumes the class files are in a "bin" * folder. * </p> * * @param pluginId * the plug-in ID * @param binaryFolderName * the name of the binary folder in the plug-in. * <p> * If null, the name will be set by default to "bin". * </p> * * @return the file containing the binary resources of a plug-in. */ public static File getPluginBinaryPath( final String pluginId, String binaryFolderName ) { if (binaryFolderName == null || binaryFolderName.trim().length() == 0) binaryFolderName = "bin"; //$NON-NLS-1$ File bundleFile; try { bundleFile = FileLocator.getBundleFile( Platform.getBundle( pluginId )); if( bundleFile.isFile()) return bundleFile; else if( bundleFile.isDirectory()) { File binaryFolder = new File( bundleFile, binaryFolderName ); if( binaryFolder.exists() && binaryFolder.isDirectory()) return binaryFolder; } } catch( Exception e ) { PetalsCommonPlugin.log( e, IStatus.ERROR ); } return null; } /** * Returns the IFile corresponding to a File object. * <p> * This is a convenience method for: * </p> * <code> * ResourcesPlugin.getWorkspace().getRoot().getFileForLocation( new Path( file.getAbsolutePath())); * </code> * * @param file * the file * @return the associated IFile, or null if the file is not in the current * workspace * @see IWorkspaceRoot#getFileForLocation(org.eclipse.core.runtime.IPath) */ public static IFile getIFile( File file ) { Path path = new Path( file.getAbsolutePath()); return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path); } /** * Returns an IResources corresponding to the File object. * @param file the file * @return an instance of IFile, or IContainer, or null if the file is not in the workspace */ public static IResource getResource( File file ) { Path path = new Path( file.getAbsolutePath()); if( file.isFile()) return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation( path ); return ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation( path ); } /** * Check if this container or one of its children contains at least one file whose name matches the given regular expression. * <p>Hidden folders and folders whose name starts with a dot are skipped.</p> * * @param container the IContainer (it must exist) * @param regex the pattern the file name must verify * @return true if one file at least match, false otherwise */ public static List<IFile> getFilesByRegexp( IContainer container, String regex ) { List<IFile> result = new ArrayList<IFile> (); try { IResource[] resources = container.members(); for( IResource resource : resources ) { switch( resource.getType()) { case IResource.FILE: String fileName = resource.getName(); if( fileName.matches( regex )) result.add((IFile) resource); break; case IResource.FOLDER: IFolder subFolder = (IFolder) resource; if( subFolder.getName().startsWith( "." ) || subFolder.isHidden()) break; List<IFile> subResult = getFilesByRegexp( subFolder, regex ); result.addAll( subResult ); } } } catch( CoreException e ) { PetalsCommonPlugin.log( e, IStatus.ERROR ); } return result; } /** * Selects and reveals a resource in the Petals explorer. * <p> * This method can be called from a non-UI thread. * </p> * * @param expand true to expand the node in the viewer * @param resources */ public static void selectResourceInPetalsExplorer( final boolean expand, final Collection<?> resources ) { List<Object> elements = new ArrayList<Object> (); for( Object o : resources ) { elements.add( o ); if( o instanceof IResource ) { IJavaElement elt = JavaCore.create((IResource) o); if( elt != null ) elements.add( elt ); } } selectResourceInView( expand, PetalsConstants.PETALS_PROJECT_EXPLORER_VIEW_ID, elements ); } /** * Selects and reveals a resource in the Petals explorer. * <p> * This method can be called from a non-UI thread. * </p> * * @param expand true to expand the node in the viewer * @param resources */ public static void selectResourceInPetalsExplorer( final boolean expand, final IResource... resources ) { if( resources != null ) selectResourceInPetalsExplorer( expand, Arrays.asList( resources )); } /** * Selects and reveals a resource in the Java packages view. * <p> * This method can be called from a non-UI thread. * </p> * * @param expand true to expand the node in the viewer * @param resources */ public static void selectResourceInJavaView( final boolean expand, final List<? extends IResource> resources ) { IResource[] res = new IResource[ resources.size()]; selectResourceInJavaView( expand, resources.toArray( res )); } /** * Selects and reveals a resource in the Java packages view. * <p> * This method can be called from a non-UI thread. * </p> * * @param expand true to expand the node in the viewer * @param resources */ public static void selectResourceInJavaView( final boolean expand, final IResource... resources ) { List<Object> elements = new ArrayList<Object> (); for( IResource res : resources ) { IJavaElement elt = JavaCore.create( res ); if( elt != null ) elements.add( elt ); else elements.add( res ); } selectResourceInView( expand, "org.eclipse.jdt.ui.PackageExplorer", elements ); } /** * Selects a resource in a view. * <p> * This method can be called from a non-UI thread. * </p> * * @param expand true to expand the elements * @param viewId the view ID (not null) * @param resources the resources to select */ public static void selectResourceInView( final boolean expand, final String viewId, final List<?> resources ) { Display display = Display.getCurrent(); if( display == null ) display = Display.getDefault(); if( display != null && resources != null ) { display.syncExec( new Runnable() { @Override public void run() { try { IViewPart viewPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow(). getActivePage().showView( viewId ); if( viewPart instanceof CommonNavigator ) { if( expand ) { for( Object res : resources ) ((CommonNavigator) viewPart).getCommonViewer().reveal( res ); } ((CommonNavigator) viewPart).getCommonViewer().setSelection( new StructuredSelection( resources ), true ); // Alternative, but less options // IStructuredSelection s = new StructuredSelection( resources ); // viewPart.getSite().getSelectionProvider().setSelection( s ); } else { try { Method getTreeViewerMethod = viewPart.getClass().getMethod( "getTreeViewer" ); TreeViewer viewer = (TreeViewer) getTreeViewerMethod.invoke( viewPart ); if( viewer != null ) viewer.setSelection( new StructuredSelection( resources ), expand ); } catch( Exception e ) { viewPart.getViewSite().getSelectionProvider().setSelection( new StructuredSelection( resources )); } } } catch( PartInitException e ) { PetalsCommonPlugin.log( e, IStatus.WARNING ); } catch( Exception e ) { PetalsCommonPlugin.log( e, IStatus.WARNING ); } } }); } } /** * Gets the file edited in the active editor. * @return the file edited in the active editor or null if it could not be retrieved. */ public static IFile getIFileFromEditor() { IFile result = null; IWorkbench workbench = PlatformUI.getWorkbench(); if( workbench != null ) { IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); if( window != null ) { IWorkbenchPage page = window.getActivePage(); if( page != null && page.getActiveEditor() != null ) { IEditorInput editorInput = page.getActiveEditor().getEditorInput(); if( editorInput instanceof FileEditorInput ) result = ((FileEditorInput) editorInput).getFile(); } } } return result; } }