/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.github.sdbg.utilities; import java.io.File; import java.net.URI; import java.util.HashMap; import javax.xml.transform.Source; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceProxy; import org.eclipse.core.resources.IResourceProxyVisitor; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import com.github.sdbg.debug.core.SDBGDebugCorePlugin; /** * Utilities for mapping {@link Source} to {@link File} to {@link IFile}. * * @coverage dart.tools.core */ public class ResourceUtil { /** * The root of the workspace, cached for efficiency. */ public static IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); /** * A cached table mapping the URI's of file resources to the resource associated with the URI. */ private static HashMap<URI, IResource> resourceMap = null; /** * The listener used to maintain the resource map when the list of resources has changed. */ private static final IResourceChangeListener listener = new IResourceChangeListener() { @Override public void resourceChanged(IResourceChangeEvent event) { // // This is overkill, but it has the advantage that it is not error prone. We can consider // implementing a more efficient version that would update the state of the map if the // performance still isn't good enough. // synchronized (ResourceUtil.class) { resourceMap = null; } } }; private static URI getCanonicalUri(File file) { return CanonicalizationManager.getManager().getCanonicalUri(file); } private static URI getCanonicalUri(IResource resource) { return getCanonicalUri(resource.getLocationURI()); } public static URI getCanonicalUri(URI uri) { return CanonicalizationManager.getManager().getCanonicalUri(uri); } /** * Return the file resource associated with the given file, or <code>null</code> if the file does * not correspond to an existing file resource. * * @param file the file representing the file resource to be returned * @return the file resource associated with the given file */ public static IFile getFile(File file) { if (file == null) { return null; } return getFile(getCanonicalUri(file)); } /** * Return the file corresponding to the specified Dart source, or <code>null</code> if there is no * such file. * * @param source the source corresponding to the file to be returned * @return the file corresponding to the specified Dart source */ public static File getFile(Source source) { return null; } /** * Return the file associated with the given URI, or <code>null</code> if the URI does not * correspond to an existing file. * * @param uri the URI representing the file to be returned * @return the file associated with the given URI */ public static IFile getFile(URI uri) { IResource[] resources = ResourceUtil.getResources(uri); if (resources != null) { for (IResource resource : resources) { if (resource instanceof IFile && resource.exists()) { return (IFile) resource; } } } return null; } public static IPath getProjectLocation(IProject project) { if (project.getRawLocation() == null) { return project.getLocation(); } else { return project.getRawLocation(); } } /** * Answer the Eclipse resource associated with the specified file or <code>null</code> if none */ public static IResource getResource(File file) { if (file == null) { return null; } return getResource(getCanonicalUri(file)); } /** * Answer the Eclipse resource associated with the specified source or <code>null</code> if none */ public static IResource getResource(Source source) { return getResource(getFile(source)); } /** * Return the resource associated with the given URI, or <code>null</code> if the URI does not * correspond to an existing resource. * * @param uri the URI representing the resource to be returned * @return the resource associated with the given URI */ public static IResource getResource(URI uri) { IResource[] resources = ResourceUtil.getResources(uri); if (resources != null) { for (IResource resource : resources) { if (resource.exists()) { return resource; } } } return null; } /** * Return a table mapping the URI's of file resources to the resource associated with the URI. * * @return a table mapping the URI's of file resources to the resource associated with the URI */ private static HashMap<URI, IResource> getResourceMap() { synchronized (ResourceUtil.class) { //resourceMap = null; if (resourceMap == null) { resourceMap = new HashMap<URI, IResource>(); try { root.accept(new IResourceProxyVisitor() { @Override public boolean visit(IResourceProxy proxy) { int type = proxy.getType(); if (type == IResource.FILE || type == IResource.FOLDER || type == IResource.PROJECT) { IResource resource = proxy.requestResource(); URI resourceUri = getCanonicalUri(resource); if (resourceUri != null) { resourceMap.put(resourceUri, resource); } } return true; } }, 0); } catch (CoreException exception) { //&&&DartCore.logError("Could not visit resources", exception); SDBGDebugCorePlugin.logError("Could not visit resources", exception); } } return resourceMap; } } /** * Answer the Eclipse resources associated with the specified file or <code>null</code> if none */ public static IResource[] getResources(File file) { if (file == null) { return null; } return getResources(getCanonicalUri(file)); } /** * Answer the Eclipse resources associated with the Dart source or <code>null</code> if none */ public static IResource[] getResources(Source source) { return getResources(getFile(source)); } /** * Return the Eclipse resources associated with the given URI, or <code>null</code> if there is no * associated resource. The URI must be a canonical URI (a file: URI built from a canonical path). * * @return the Eclipse resources associated with the given URI */ public static IResource[] getResources(URI uri) { if (uri == null) { return null; //&&& // } else if (PackageLibraryManager.isDartUri(uri)) { // return null; } else if (!uri.isAbsolute()) { //&&& // DartCore.logError( // "Cannot get resource associated with non-absolute URI: " + uri, // new Exception()); SDBGDebugCorePlugin.logError( "Cannot get resource associated with non-absolute URI: " + uri, new Exception()); return null; } IResource resource = getResourceMap().get(uri); if (resource == null) { resource = getResourceMap().get(getCanonicalUri(uri)); } if (resource != null) { return new IResource[] {resource}; } return root.findFilesForLocationURI(uri); } public static boolean isExistingProject(IProject project) { if (!project.isOpen()) { return false; } IPath location = getProjectLocation(project); if (location == null) { return false; } File file = location.toFile(); if (file == null) { return false; } return file.exists(); } /** * Perform any clean up required when the core plug-in is shutting down. */ public static void shutdown() { ResourcesPlugin.getWorkspace().removeResourceChangeListener(listener); } /** * Perform any initialization required when the core plug-in is starting up. */ public static void startup() { ResourcesPlugin.getWorkspace().addResourceChangeListener(listener); } // No instances private ResourceUtil() { } }