/******************************************************************************* * Copyright (c) 2005, 2016 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation * David Black - bug 198091 * Mickael Istria (Red Hat Inc.) - Bug 486901 *******************************************************************************/ package org.eclipse.ui.internal.ide.dialogs; import java.net.URI; import java.util.ArrayList; import java.util.Date; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.URIUtil; 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.Path; import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.osgi.util.NLS; import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; import org.eclipse.ui.statushandlers.StatusManager; import com.ibm.icu.text.DateFormat; import com.ibm.icu.text.MessageFormat; import com.ibm.icu.text.NumberFormat; /** * Utility class supporting common information required from resources. * * @since 3.2 * */ public class IDEResourceInfoUtils { private static String BYTES_LABEL = IDEWorkbenchMessages.ResourceInfo_bytes; /** * An empty string to reuse. */ public static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static String FILE_LABEL = IDEWorkbenchMessages.ResourceInfo_file; private static String FILE_NOT_EXIST_TEXT = IDEWorkbenchMessages.ResourceInfo_fileNotExist; private static String FILE_TYPE_FORMAT = IDEWorkbenchMessages.ResourceInfo_fileTypeFormat; private static String FOLDER_LABEL = IDEWorkbenchMessages.ResourceInfo_folder; private static String LINKED_FILE_LABEL = IDEWorkbenchMessages.ResourceInfo_linkedFile; private static String LINKED_FOLDER_LABEL = IDEWorkbenchMessages.ResourceInfo_linkedFolder; private static String VIRTUAL_FOLDER_LABEL = IDEWorkbenchMessages.ResourceInfo_virtualFolder; private static String VIRTUAL_FOLDER_TEXT = IDEWorkbenchMessages.ResourceInfo_isVirtualFolder; private static String MISSING_PATH_VARIABLE_TEXT = IDEWorkbenchMessages.ResourceInfo_undefinedPathVariable; private static String NOT_EXIST_TEXT = IDEWorkbenchMessages.ResourceInfo_notExist; private static String NOT_LOCAL_TEXT = IDEWorkbenchMessages.ResourceInfo_notLocal; private static String PROJECT_LABEL = IDEWorkbenchMessages.ResourceInfo_project; private static String UNKNOWN_LABEL = IDEWorkbenchMessages.ResourceInfo_unknown; /** * Return whether or not the file called pathName exists. * * @param pathName * @return boolean <code>true</code> if the file exists. * @see IFileInfo#exists() */ public static boolean exists(String pathName) { IFileInfo info = getFileInfo(pathName); if (info == null) { return false; } return info.exists(); } private static String getContentTypeString(IContentDescription description) { if (description != null) { IContentType contentType = description.getContentType(); if (contentType != null) { return contentType.getName(); } } return null; } /** * Return the value for the date String for the timestamp of the supplied * resource. * * @param resource * The resource to query * @return String */ public static String getDateStringValue(IResource resource) { if (!resource.isLocal(IResource.DEPTH_ZERO)) { return NOT_LOCAL_TEXT; } // don't access the file system for closed projects (bug 151089) if (!isProjectAccessible(resource)) { return UNKNOWN_LABEL; } URI location = resource.getLocationURI(); if (location == null) { if (resource.isLinked()) { return MISSING_PATH_VARIABLE_TEXT; } return NOT_EXIST_TEXT; } IFileInfo info = getFileInfo(location); if (info == null) { return UNKNOWN_LABEL; } if (info.exists()) { DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM); return format.format(new Date(info.getLastModified())); } return NOT_EXIST_TEXT; } /** * Return the fileInfo at pathName or <code>null</code> if the format is * invalid or if the file info cannot be determined. * * @param pathName * @return IFileInfo or <code>null</code> */ public static IFileInfo getFileInfo(IPath pathName) { IFileStore store = getFileStore(pathName.toFile().toURI()); if (store == null) { return null; } return store.fetchInfo(); } /** * Return the fileInfo at pathName or <code>null</code> if the format is * invalid or if the file info cannot be determined. * * @param pathName * @return IFileInfo or <code>null</code> */ public static IFileInfo getFileInfo(String pathName) { IFileStore store = getFileStore(pathName); if (store == null) { return null; } return store.fetchInfo(); } /** * Return the fileInfo for location. Return <code>null</code> if there is * a CoreException looking it up * * @param location * @return String or <code>null</code> */ public static IFileInfo getFileInfo(URI location) { if (location.getScheme() == null) return null; IFileStore store = getFileStore(location); if (store == null) { return null; } return store.fetchInfo(); } /** * Get the file store for the local file system path. * * @param string * @return IFileStore or <code>null</code> if there is a * {@link CoreException}. */ public static IFileStore getFileStore(String string) { Path location = new Path(string); //see if there is an existing resource at that location that might have a different file store IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(location); if (file != null) { return getFileStore(file.getLocationURI()); } return getFileStore(location.toFile().toURI()); } /** * Get the file store for the URI. * * @param uri * @return IFileStore or <code>null</code> if there is a * {@link CoreException}. */ public static IFileStore getFileStore(URI uri) { try { return EFS.getStore(uri); } catch (CoreException e) { log(e); return null; } } /** * Get the location of a resource * * @param resource * @return String the text to display the location */ public static String getLocationText(IResource resource) { if (resource.isVirtual()) return VIRTUAL_FOLDER_TEXT; if (!resource.isLocal(IResource.DEPTH_ZERO)) { return NOT_LOCAL_TEXT; } URI resolvedLocation = resource.getLocationURI(); URI location = resolvedLocation; boolean isLinked = resource.isLinked(); if (isLinked) { location = resource.getRawLocationURI(); } if (location == null) { return NOT_EXIST_TEXT; } if (resolvedLocation.getScheme() == null) return location.toString(); IFileStore store = getFileStore(resolvedLocation); // don't access the file system for closed projects (bug 151089) boolean isPathVariable = isPathVariable(resource); if (isProjectAccessible(resource) && resolvedLocation != null && !isPathVariable) { // No path variable used. Display the file not exist message // in the location. Fixes bug 33318. if (store == null) { return UNKNOWN_LABEL; } if (!store.fetchInfo().exists()) { return NLS.bind(FILE_NOT_EXIST_TEXT, store.toString()); } } if (isLinked && isPathVariable) { String tmp = URIUtil.toPath(resource.getRawLocationURI()).toOSString(); return resource.getPathVariableManager().convertToUserEditableFormat(tmp, true); } if (store != null) { return store.toString(); } return location.toString(); } /** * Get the resolved location of a resource. This resolves path variables if * present in the resource path. * * @param resource * @return String */ public static String getResolvedLocationText(IResource resource) { if (!resource.isLocal(IResource.DEPTH_ZERO)) { return NOT_LOCAL_TEXT; } URI location = resource.getLocationURI(); if (location == null) { if (resource.isLinked()) { return MISSING_PATH_VARIABLE_TEXT; } return NOT_EXIST_TEXT; } if (location.getScheme() == null) return UNKNOWN_LABEL; IFileStore store = getFileStore(location); if (store == null) { return UNKNOWN_LABEL; } // don't access the file system for closed projects (bug 151089) if (isProjectAccessible(resource) && !store.fetchInfo().exists()) { return NLS.bind(FILE_NOT_EXIST_TEXT, store.toString()); } return store.toString(); } /** * Return a String that indicates the size of the supplied file. * * @param resource * @return String */ public static String getSizeString(IResource resource) { if (resource.getType() != IResource.FILE) { return ""; //$NON-NLS-1$ } IFile file = (IFile) resource; if (!file.isLocal(IResource.DEPTH_ZERO)) { return NOT_LOCAL_TEXT; } URI location = file.getLocationURI(); if (location == null) { if (file.isLinked()) { return MISSING_PATH_VARIABLE_TEXT; } return NOT_EXIST_TEXT; } IFileInfo info = getFileInfo(location); if (info == null) { return UNKNOWN_LABEL; } if (info.exists()) { return NLS.bind(BYTES_LABEL, NumberFormat.getInstance().format(info.getLength())); } return NOT_EXIST_TEXT; } /** * Get the string that identifies the type of this resource. * * @param resource * @param description * @return String */ public static String getTypeString(IResource resource, IContentDescription description) { if (resource.getType() == IResource.FILE) { if (resource.isLinked()) { return LINKED_FILE_LABEL; } if (resource instanceof IFile) { String contentType = getContentTypeString(description); if (contentType != null) { return MessageFormat.format(FILE_TYPE_FORMAT, contentType ); } } return FILE_LABEL; } if (resource.getType() == IResource.FOLDER) { if (resource.isVirtual()) { return VIRTUAL_FOLDER_LABEL; } if (resource.isLinked()) { return LINKED_FOLDER_LABEL; } return FOLDER_LABEL; } if (resource.getType() == IResource.PROJECT) { return PROJECT_LABEL; } // Should not be possible return UNKNOWN_LABEL; } /** * Returns whether the given resource is a linked resource bound to a path * variable. * * @param resource * resource to test * @return boolean <code>true</code> the given resource is a linked * resource bound to a path variable. <code>false</code> the given * resource is either not a linked resource or it is not using a * path variable. */ private static boolean isPathVariable(IResource resource) { if (!resource.isLinked()) { return false; } URI resolvedLocation = resource.getLocationURI(); if (resolvedLocation == null) { // missing path variable return true; } URI rawLocation = resource.getRawLocationURI(); if (resolvedLocation.equals(rawLocation)) { return false; } return true; } /** * Returns whether the resource's project is available */ private static boolean isProjectAccessible(IResource resource) { IProject project = resource.getProject(); return project != null && project.isAccessible(); } /** * Return the file stores that are a child of store that the filter accepts. * * @param store * @param fileFilter * @param monitor * @return IFileStore[] */ public static IFileStore[] listFileStores(IFileStore store, IFileStoreFilter fileFilter, IProgressMonitor monitor) { ArrayList result = new ArrayList(); IFileStore[] children; try { children = store.childStores(EFS.NONE, monitor); } catch (CoreException e) { log(e); return new IFileStore[0]; } for (IFileStore fileStore : children) { if (fileFilter.accept(fileStore)) { result.add(fileStore); } } IFileStore[] stores = new IFileStore[result.size()]; result.toArray(stores); return stores; } /** * Log the CoreException * @param e */ private static void log(CoreException e) { StatusManager.getManager().handle(e, IDEWorkbenchPlugin.IDE_WORKBENCH); } }