| /******************************************************************************* |
| * Copyright (c) 2009, 2010 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.cdt.utils; |
| |
| import java.net.URI; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.cdt.core.CCorePlugin; |
| import org.eclipse.cdt.core.EFSExtensionProvider; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtension; |
| import org.eclipse.core.runtime.IExtensionPoint; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| |
| /** |
| * Manager class that consults contributors to the EFSExtensionProvider extension point |
| * to perform operations corresponding to those filesystems. The default behaviour if no provider is present |
| * is to assumes that URIs for the given filesystem map directly to resources in the physical filesystem, and |
| * that the path component of the URI is a direct representation of the absolute path to the file in the |
| * physical filesystem. Also, operations will by default respect the syntax and semantics of the local EFS |
| * filesystem, if operations are performed with respect to it. |
| * |
| * <strong>EXPERIMENTAL</strong>. This class or interface has been added as part of a work in progress. There |
| * is no guarantee that this API will work or that it will remain the same. Please do not use this API without |
| * consulting with the CDT team. |
| * |
| * @author crecoskie |
| * @noextend This class is not intended to be extended by clients. |
| * @since 5.2 |
| */ |
| public class EFSExtensionManager { |
| |
| private class DefaultProvider extends EFSExtensionProvider { |
| |
| } |
| |
| private DefaultProvider fDefaultProvider = new DefaultProvider(); |
| |
| private static EFSExtensionManager instance; |
| |
| private Map<String, EFSExtensionProvider> fSchemeToExtensionProviderMap; |
| |
| private static String EXTENSION_ID = "EFSExtensionProvider"; //$NON-NLS-1$ |
| |
| private EFSExtensionManager() { |
| fSchemeToExtensionProviderMap = new HashMap<>(); |
| loadExtensions(); |
| } |
| |
| private void loadExtensions() { |
| IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, |
| EXTENSION_ID); |
| if (extension != null) { |
| IExtension[] extensions = extension.getExtensions(); |
| for (IExtension extension2 : extensions) { |
| IConfigurationElement[] configElements = extension2.getConfigurationElements(); |
| for (IConfigurationElement configElement : configElements) { |
| |
| String scheme = configElement.getAttribute("scheme"); //$NON-NLS-1$ |
| String utility = configElement.getAttribute("class"); //$NON-NLS-1$ |
| |
| if (utility != null) { |
| try { |
| Object execExt = configElement.createExecutableExtension("class"); //$NON-NLS-1$ |
| if (execExt instanceof EFSExtensionProvider) { |
| fSchemeToExtensionProviderMap.put(scheme, (EFSExtensionProvider) execExt); |
| } |
| } catch (CoreException e) { |
| CCorePlugin.log(e); |
| } |
| } |
| |
| } |
| } |
| } |
| |
| } |
| |
| public synchronized static EFSExtensionManager getDefault() { |
| if (instance == null) { |
| instance = new EFSExtensionManager(); |
| } |
| return instance; |
| } |
| |
| /** |
| * If the EFS store represented by locationURI is backed by a physical file, gets the path corresponding |
| * to the underlying file. The path returned is suitable for use in constructing a {@link Path} object. This |
| * method will return the corresponding path regardless of whether or not the EFS store actually exists. |
| * |
| * |
| * @param locationURI |
| * @return String representing the path, or <code>null</code> if there is an error or if the store |
| * is not backed by a physical file. |
| */ |
| public String getPathFromURI(URI locationURI) { |
| EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(locationURI.getScheme()); |
| |
| if (provider == null) { |
| provider = fDefaultProvider; |
| } |
| |
| return provider.getPathFromURI(locationURI); |
| |
| } |
| |
| /** |
| * In the case of a virtual filesystem, where URIs in the given filesystem are just soft links in EFS to |
| * URIs in other filesystems, returns the URI that this URI links to. If the filesystem is not virtual, |
| * then this method acts as an identity mapping. |
| * |
| * @param locationURI |
| * @return A URI corresponding to the linked store, or <code>null</code> on error. |
| */ |
| public URI getLinkedURI(URI locationURI) { |
| EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(locationURI.getScheme()); |
| |
| if (provider == null) { |
| provider = fDefaultProvider; |
| } |
| |
| return provider.getLinkedURI(locationURI); |
| |
| } |
| |
| /** |
| * Creates a new URI which clones the contents of the original URI, but with the path replaced by the |
| * given path, such that calling getPathFromURI() on the returned URI will return the given path. Returns |
| * null on error. |
| * |
| * @param locationOnSameFilesystem |
| * @param path |
| * @return the new URI, or <code>null</code> on error |
| */ |
| public URI createNewURIFromPath(URI locationOnSameFilesystem, String path) { |
| URI uri = locationOnSameFilesystem; |
| EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(uri.getScheme()); |
| |
| if (provider == null) { |
| return fDefaultProvider.createNewURIFromPath(uri, path); |
| } else { |
| return provider.createNewURIFromPath(uri, path); |
| } |
| } |
| |
| /** |
| * For filesystems that map the path to a physical file in one filesystem (say on a remote machine) to |
| * another path (say, on the local machine), this method returns the path that the store maps to. I.e., it |
| * returns the path that the path returned by getPathFromURI(URI locationURI) maps to. If there is no such |
| * mapping, then an identity mapping of the paths is assumed. |
| * |
| * Typically if a filesystem maps one filesytem to another, it will place the mapped path in the path |
| * field of its URIs (which the default implementation assumes), but this is not guaranteed to be so for |
| * all filesystem implementations. |
| * |
| * @return String representing the path, or <code>null</code> on error. |
| */ |
| public String getMappedPath(URI locationURI) { |
| URI uri = locationURI; |
| EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(uri.getScheme()); |
| |
| if (provider == null) { |
| provider = fDefaultProvider; |
| } |
| |
| return provider.getMappedPath(uri); |
| } |
| |
| /** |
| * Returns true if the given URI is part of a virtual filesystem and thus points to another underlying |
| * URI. Returns false otherwise. By default, filesystems are assumed to be non-virtual. |
| * |
| * @param locationURI |
| * @return boolean |
| */ |
| public boolean isVirtual(URI locationURI) { |
| EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(locationURI.getScheme()); |
| |
| if (provider == null) { |
| provider = fDefaultProvider; |
| } |
| |
| return provider.isVirtual(locationURI); |
| } |
| |
| /** |
| * Creates a new URI with the same components as the baseURI, except that calling |
| * getPathFromURI() on the new URI will return a path that has the extension appended to |
| * the path returned by baseURI.getPathFromURI() |
| * |
| * @param baseURI |
| * @param extension |
| * @return the new URI, or <code>null</code> on error. |
| */ |
| public URI append(URI baseURI, String extension) { |
| EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(baseURI.getScheme()); |
| |
| if (provider == null) { |
| provider = fDefaultProvider; |
| } |
| |
| return provider.append(baseURI, extension); |
| } |
| |
| } |