diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeReference.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeReference.java index 9e2f905473c..881f595c761 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeReference.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeReference.java @@ -26,9 +26,13 @@ import org.eclipse.cdt.core.model.IIncludeEntry; import org.eclipse.cdt.core.model.IIncludeReference; import org.eclipse.cdt.internal.core.util.MementoTokenizer; import org.eclipse.cdt.utils.PathUtil; +import org.eclipse.cdt.utils.UNCPathConverter; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; @@ -93,7 +97,7 @@ public class IncludeReference extends Openable implements IIncludeReference { */ @Override protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException { - return computeChildren(info, underlyingResource); + return computeChildren(info, pm, underlyingResource); } /* (non-Javadoc) @@ -106,35 +110,61 @@ public class IncludeReference extends Openable implements IIncludeReference { /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.model.CContainer#computeChildren(org.eclipse.cdt.internal.core.model.OpenableInfo, org.eclipse.core.resources.IResource) */ - protected boolean computeChildren(OpenableInfo info, IResource res) throws CModelException { + protected boolean computeChildren(OpenableInfo info, IProgressMonitor pm, IResource res) throws CModelException { ArrayList vChildren = new ArrayList(); - File file = null; + IPath filePath = null; if (fPath != null) { - file = fPath.toFile(); + filePath = fPath; } else if (fIncludeEntry != null) { - file = fIncludeEntry.getFullIncludePath().toFile(); + filePath = fIncludeEntry.getFullIncludePath(); } - String[] names = null; - if (file != null && file.isDirectory()) { - names = file.list(); - - if (names != null) { - IPath path = new Path(file.getAbsolutePath()); - for (String name : names) { - File child = new File(file, name); - ICElement celement = null; - if (child.isDirectory()) { - celement = new IncludeReference(this, fIncludeEntry, new Path(child.getAbsolutePath())); - } else if (child.isFile()){ - String id = CoreModel.getRegistedContentTypeId(getCProject().getProject(), name); - if (id != null) { - // TODO: should use URI - celement = new ExternalTranslationUnit(this, URIUtil.toURI(path.append(name)), id); + if (filePath != null) { + if (!filePath.isUNC()) { + File file = filePath.toFile(); + String[] names = null; + if (file != null && file.isDirectory()) { + names = file.list(); + + if (names != null) { + IPath path = new Path(file.getAbsolutePath()); + for (String name : names) { + File child = new File(file, name); + ICElement celement = null; + if (child.isDirectory()) { + celement = new IncludeReference(this, fIncludeEntry, new Path(child.getAbsolutePath())); + } else if (child.isFile()){ + String id = CoreModel.getRegistedContentTypeId(getCProject().getProject(), name); + if (id != null) { + // TODO: should use URI + celement = new ExternalTranslationUnit(this, URIUtil.toURI(path.append(name)), id); + } + } + if (celement != null) { + vChildren.add(celement); + } } } - if (celement != null) { - vChildren.add(celement); + } + } else { + try { + IFileStore store = EFS.getStore(UNCPathConverter.getInstance().toURI(filePath)); + IFileStore children[] = store.childStores(EFS.NONE, pm); + for (IFileStore child : children) { + ICElement celement = null; + if (child.fetchInfo().isDirectory()) { + celement = new IncludeReference(this, fIncludeEntry, filePath.append(child.getName())); + } else { + String id = CoreModel.getRegistedContentTypeId(getCProject().getProject(), child.getName()); + if (id != null) { + // TODO: should use URI + celement = new ExternalTranslationUnit(this, child.toURI(), id); + } + } + if (celement != null) { + vChildren.add(celement); + } } + } catch (CoreException e) { } } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index a3ecf626959..0e8792a5642 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -75,10 +75,10 @@ import org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerIncludeResolutio import org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerInputAdapter; import org.eclipse.cdt.internal.core.util.ICanceler; import org.eclipse.cdt.internal.core.util.MementoTokenizer; +import org.eclipse.cdt.utils.UNCPathConverter; 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; @@ -319,7 +319,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return null; } } - return URIUtil.toPath(location); + return UNCPathConverter.toPath(location); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java index a9622127611..faf7147a02b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2009 Symbian Software Ltd. and others. + * Copyright (c) 2006, 2011 Symbian Software Ltd. 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 @@ -18,7 +18,7 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.index.IndexFileLocation; import org.eclipse.cdt.internal.core.resources.ResourceLookup; -import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.cdt.utils.UNCPathConverter; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -56,12 +56,12 @@ public class IndexLocationFactory { /** * Returns the absolute file path of a location, or {@code null} - * if the location is not a filesystem path. + * if the location is not a file-system path. * @return the absolute file path of a location, or {@code null} - * if the location is not a filesystem path. + * if the location is not a file-system path. */ public static IPath getAbsolutePath(IIndexFileLocation location) { - return URIUtil.toPath(location.getURI()); + return UNCPathConverter.toPath(location.getURI()); } /** @@ -113,7 +113,7 @@ public class IndexLocationFactory { * @return an IIndexFileLocation for the specified absolute path, with no associated full path. */ public static IIndexFileLocation getExternalIFL(IPath absolutePath) { - return new IndexFileLocation(URIUtil.toURI(absolutePath), null); + return new IndexFileLocation(UNCPathConverter.getInstance().toURI(absolutePath), null); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java index 6a632814a96..c0b6a07f269 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2011 Wind River Systems, Inc. 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 @@ -23,6 +23,7 @@ import org.eclipse.cdt.internal.core.index.IndexFileLocation; import org.eclipse.cdt.internal.core.parser.InternalParserUtil; import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter; import org.eclipse.cdt.internal.core.pdom.indexer.FileExistsCache; +import org.eclipse.cdt.utils.UNCPathConverter; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; @@ -102,7 +103,7 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter { // use the original } //Standalone indexing stores the absolute paths of files being indexed - result = new IndexFileLocation(URIUtil.toURI(astPath), null); + result = new IndexFileLocation(UNCPathConverter.getInstance().toURI(astPath), null); fIflCache.put(astPath, result); } return result; @@ -128,7 +129,7 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter { // use the original } //Stand-alone indexing stores the absolute paths of files being indexed - result = new IndexFileLocation(URIUtil.toURI(includePath),null); + result = new IndexFileLocation(UNCPathConverter.getInstance().toURI(includePath),null); fIflCache.put(includePath, result); } return result; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java index 23ef5a39786..76688c442ce 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2010 IBM Corporation and others. + * Copyright (c) 2003, 2011 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 @@ -24,6 +24,9 @@ import org.eclipse.cdt.internal.core.parser.scanner.AbstractCharArray; import org.eclipse.cdt.internal.core.parser.scanner.FileCharArray; import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent; import org.eclipse.cdt.internal.core.resources.PathCanonicalizationStrategy; +import org.eclipse.cdt.utils.UNCPathConverter; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceStatus; @@ -132,6 +135,14 @@ public class InternalParserUtil extends ParserFactory { IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath)); if (res instanceof IFile) return createWorkspaceFileContent((IFile) res); + } + /* + * If URI refers to a remote resource, use the full URI to retrieve the file content + * Otherwise, assume it is in the local filesystem somewhere + */ + String scheme = ifl.getURI().getScheme(); + if (!scheme.equals(EFS.SCHEME_FILE)) { + return createExternalFileContent(UNCPathConverter.toPath(ifl.getURI()).toString(), SYSTEM_DEFAULT_ENCODING); } return createExternalFileContent(ifl.getURI().getPath(), SYSTEM_DEFAULT_ENCODING); } @@ -171,12 +182,23 @@ public class InternalParserUtil extends ParserFactory { * canonical path. */ public static InternalFileContent createExternalFileContent(String externalLocation, String encoding) { - File includeFile = new File(externalLocation); - if (includeFile.isFile()) { + File includeFile = null; + String path = null; + if (!UNCPathConverter.isUNC(externalLocation)) { + includeFile = new File(externalLocation); // Use the canonical path so that in case of non-case-sensitive OSs // the CodeReader always has the same name as the file on disk with // no differences in case. - final String path = PathCanonicalizationStrategy.getCanonicalPath(includeFile); + path = PathCanonicalizationStrategy.getCanonicalPath(includeFile); + } else { + try { + IFileStore store = EFS.getStore(UNCPathConverter.getInstance().toURI(externalLocation)); + includeFile = store.toLocalFile(EFS.CACHE, null); + path = externalLocation; + } catch (CoreException e) { + } + } + if (includeFile != null && includeFile.isFile()) { FileInputStream in; try { in = new FileInputStream(includeFile); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerUtility.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerUtility.java index 80d033e1ee6..28e6eb48ac5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerUtility.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerUtility.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2011 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 @@ -59,9 +59,13 @@ public class ScannerUtility { originalPath.getChars(0, len, ein, 0); // allow double backslash at beginning for windows UNC paths, bug 233511 - if(ein.length >= 2 && ein[0] == BSLASH && ein[1] == BSLASH && - File.separatorChar == BSLASH) { - aus[j++] = BSLASH; + // also allow Unix UNC paths + if (ein.length >= 2) { + if (ein[0] == BSLASH && ein[1] == BSLASH && File.separatorChar == BSLASH) { + aus[j++] = BSLASH; + } else if (ein[0] == SLASH && ein[1] == SLASH && File.separatorChar == SLASH) { + aus[j++] = SLASH; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/FileExistsCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/FileExistsCache.java index d0d7b9f142c..7f557e41b0e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/FileExistsCache.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/FileExistsCache.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2011 Wind River Systems, Inc. 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 @@ -13,11 +13,17 @@ package org.eclipse.cdt.internal.core.pdom.indexer; import java.io.File; import java.lang.ref.Reference; import java.lang.ref.SoftReference; +import java.net.URI; import java.util.Arrays; import java.util.BitSet; import java.util.HashMap; import java.util.Map; +import org.eclipse.cdt.utils.UNCPathConverter; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.runtime.CoreException; + /** * A cache for checking whether a file exists. The cache shall be used for a limited amount of time, only (e.g. one * indexer task). It uses as much memory as it needs. To protect against OutOfMemory situations, a soft reference is @@ -45,22 +51,51 @@ public final class FileExistsCache { } public boolean isFile(String path) { - File file= new File(path); - if (BYPASS_CACHE) { - return file.isFile(); + String parent; + String name; + File file = null; + IFileStore parentStore = null; + IFileStore fileStore = null; + + if (UNCPathConverter.isUNC(path)) { + try { + URI uri = UNCPathConverter.getInstance().toURI(path); + fileStore = EFS.getStore(uri); + if (BYPASS_CACHE) { + return fileStore != null && !fileStore.fetchInfo().isDirectory(); + } + parentStore = fileStore.getParent(); + if (parentStore == null) { + parentStore = fileStore; + } + parent = parentStore.toURI().toString(); + name = fileStore.getName(); + } catch (CoreException e) { + return false; + } + } else { + file= new File(path); + if (BYPASS_CACHE) { + return file.isFile(); + } + + parent= file.getParent(); + if (parent == null) + return false; + + name= file.getName(); } - - String parent= file.getParent(); - if (parent == null) - return false; - - String name= file.getName(); if (fCaseInSensitive) name= name.toUpperCase(); Content avail= getExistsCache().get(parent); if (avail == null) { - String[] files= new File(parent).list(); + String[] files = null; + try { + files = (parentStore == null) ? new File(parent).list() : parentStore.childNames(EFS.NONE, null); + } catch (CoreException e) { + // Ignore + } if (files == null || files.length == 0) { avail= EMPTY_STRING_ARRAY; } @@ -86,7 +121,7 @@ public final class FileExistsCache { if (isFileBitset.get(idx+1)) return false; - if (file.isFile()) { + if ((file != null && file.isFile()) || (fileStore != null && !fileStore.fetchInfo().isDirectory())) { isFileBitset.set(idx); return true; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java index 9b7bca315b2..d77b9d1a611 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2011 Wind River Systems, Inc. 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 @@ -31,6 +31,7 @@ import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.internal.core.parser.InternalParserUtil; import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter; import org.eclipse.cdt.internal.core.resources.PathCanonicalizationStrategy; +import org.eclipse.cdt.utils.UNCPathConverter; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; @@ -114,7 +115,7 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter { IIndexFileLocation result= fIflCache.get(includePath); if (result == null) { result = doResolveASTPath(includePath); - if (result.getFullPath() == null) { + if (result.getFullPath() == null && !UNCPathConverter.isUNC(includePath)) { File location= new File(includePath); String canonicalPath= PathCanonicalizationStrategy.getCanonicalPath(location); if (!includePath.equals(canonicalPath)) { diff --git a/core/org.eclipse.cdt.core/plugin.properties b/core/org.eclipse.cdt.core/plugin.properties index d06c01ddc49..e791b820771 100644 --- a/core/org.eclipse.cdt.core/plugin.properties +++ b/core/org.eclipse.cdt.core/plugin.properties @@ -124,4 +124,7 @@ templateAssociations.name = Template Associations CProjectDescriptionStorage.name = Project Description Storage Extension point CProjectStorageType.singlefile.name = Xml Storage (single file) CProjectStorageType.separatefile.name = Xml Storage (Separate Files) -scannerInfoProvider2.name = Scanner Info Provider \ No newline at end of file +scannerInfoProvider2.name = Scanner Info Provider +efsExtensionProvider.name = EFSExtensionProvider +refreshExclusionFactory.name = Refresh Exclusion Factory +uncPathConverter.name = UNC Path Converter \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml index 6220df80c4c..63cd92ab49a 100644 --- a/core/org.eclipse.cdt.core/plugin.xml +++ b/core/org.eclipse.cdt.core/plugin.xml @@ -638,8 +638,9 @@ - - + + + diff --git a/core/org.eclipse.cdt.core/schema/UNCPathConverter.exsd b/core/org.eclipse.cdt.core/schema/UNCPathConverter.exsd new file mode 100644 index 00000000000..25db7597e8f --- /dev/null +++ b/core/org.eclipse.cdt.core/schema/UNCPathConverter.exsd @@ -0,0 +1,102 @@ + + + + + + + + + [Enter description of this extension point.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + An instance of a UNC Path Converter. UNC Path Converters map UNC paths into a corresponding URI. Since the server name is the only distinguishing element of a UNC, the converter must use this to locate an EFS provider that can manipulate URIs for the server. These extensions are consulted by CDT in order to extract path information from the filesystem and manipulate filesystem resources. + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/UNCPathConverterImpl.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/UNCPathConverterImpl.java new file mode 100644 index 00000000000..be40ed0dbdb --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/UNCPathConverterImpl.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2011 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: + * Greg Watson (IBM Corporation) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.utils.UNCPathConverter; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; + +/** + * UNCPathConverter that combines all registered convertes. + */ +public class UNCPathConverterImpl extends UNCPathConverter { + private static String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$ + private static String EXTENSION_POINT = "org.eclipse.cdt.core.UNCPathConverter"; //$NON-NLS-1$ + + private static UNCPathConverterImpl fInstance = new UNCPathConverterImpl(); + + public static UNCPathConverterImpl getInstance() { + return fInstance; + } + + private volatile List fUNCPathConverters = null; + + private UNCPathConverterImpl() { + } + + private void loadUNCPathConverters() { + if (fUNCPathConverters == null) { + ArrayList list = new ArrayList(); + + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = registry.getExtensionPoint(EXTENSION_POINT); + if (extensionPoint != null) { + for (IExtension ext : extensionPoint.getExtensions()) { + for (IConfigurationElement ce : ext.getConfigurationElements()) { + if (ce.getAttribute(CLASS_ATTRIBUTE) != null) { + try { + UNCPathConverter converter = (UNCPathConverter) ce + .createExecutableExtension(CLASS_ATTRIBUTE); + list.add(converter); + } catch (Exception e) { + CCorePlugin.log(e); + } + } + } + } + } + fUNCPathConverters = list; + } + } + + @Override + public URI toURI(IPath path) { + if (path.isUNC()) { + loadUNCPathConverters(); + for (UNCPathConverter converter : fUNCPathConverters) { + URI uri = converter.toURI(path); + if (uri != null) { + return uri; + } + } + } + return URIUtil.toURI(path); + } + + @Override + public URI toURI(String path) { + if (isUNC(path)) { + loadUNCPathConverters(); + for (UNCPathConverter converter : fUNCPathConverters) { + URI uri = converter.toURI(path); + if (uri != null) { + return uri; + } + } + } + return URIUtil.toURI(path); + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/UNCPathConverter.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/UNCPathConverter.java new file mode 100644 index 00000000000..44e6bdd1c31 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/UNCPathConverter.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2011 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: + * Greg Watson (IBM Corporation) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.utils; + +import java.io.File; +import java.net.URI; + +import org.eclipse.cdt.internal.core.UNCPathConverterImpl; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * Base class for the UNC path conversion extension point. UNC paths are used to represent remote include + * locations, and this class is used to translate between UNC, IPath and URI representations. By default, + * paths are translated into the equivalent local file version to preserve existing behavior, but by providing + * an appropriate extension, these paths can be mapped into locations on a remote system. + * + * May be subclassed by clients. + * @since 5.3 + */ +public abstract class UNCPathConverter { + + /** + * Get the instance of the class that combines the registered converters. + * @return instance of UNCPathConverter + */ + public static UNCPathConverter getInstance() { + return UNCPathConverterImpl.getInstance(); + } + + + /** + * Test if the string path is in UNC format. + * + * @param path + * path to test + * @return true if the path is in UNC format, false otherwise + */ + public static boolean isUNC(String path) { + if (path.length() >= 2) { + char c= path.charAt(0); + if (c == IPath.SEPARATOR || c == File.separatorChar) { + c= path.charAt(1); + return c == IPath.SEPARATOR || c == File.separatorChar; + } + } + return false; + } + + + /** + * Convert a URI to an IPath. If URI has a host section, return a UNC rather than a file based path. + * + * @param uri + * URI to convert to an IPath + * @return IPath representation of the URI + */ + public static IPath toPath(URI uri) { + String host = uri.getHost(); + if (host != null) { + return new Path(host + uri.getPath()).makeUNC(true); + } + return URIUtil.toPath(uri); + } + + /** + * Convert an IPath to a URI. + * + * @param path + * path to convert + * @return URI representation of the IPath + */ + public abstract URI toURI(IPath path); + + /** + * Convert a string path to a URI + * + * @param path + * path to convert + * @return URI representation of the path + */ + public abstract URI toURI(String path); +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java index de179fa2207..19ac337eea3 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java @@ -19,6 +19,8 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -51,6 +53,7 @@ import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoProvider; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.utils.PathUtil; +import org.eclipse.cdt.utils.UNCPathConverter; import org.eclipse.cdt.internal.core.resources.ResourceLookup; @@ -91,9 +94,14 @@ public class OpenIncludeAction extends Action { ArrayList filesFound = new ArrayList(4); String fullFileName= include.getFullFileName(); if (fullFileName != null) { - IPath fullPath= new Path(fullFileName); + IPath fullPath = new Path(fullFileName); if (fullPath.isAbsolute() && fullPath.toFile().exists()) { filesFound.add(fullPath); + } else if (fullPath.isUNC()) { + IFileStore store = EFS.getStore(UNCPathConverter.getInstance().toURI(fullPath)); + if (store.fetchInfo().exists()) { + filesFound.add(fullPath); + } } } if (filesFound.isEmpty() && res != null) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java index a8025fc2e7e..2c1f8c98b2d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 QNX Software Systems and others. + * Copyright (c) 2000, 2011 QNX Software Systems 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 @@ -96,6 +96,7 @@ import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.resources.FileStorage; import org.eclipse.cdt.ui.CDTUITools; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.utils.UNCPathConverter; import org.eclipse.cdt.internal.core.resources.ResourceLookup; @@ -422,6 +423,9 @@ public class EditorUtility { if (resource != null) { return new FileEditorInput(resource); } + if (location.isUNC()) { + return getEditorInputForLocation(UNCPathConverter.getInstance().toURI(location), context); + } if (context == null) { // try to synthesize a context for a location appearing on a project's @@ -780,12 +784,11 @@ public class EditorUtility { List result= new ArrayList(0); IWorkbench workbench= PlatformUI.getWorkbench(); IWorkbenchWindow[] windows= workbench.getWorkbenchWindows(); - for (int i= 0; i < windows.length; i++) { - IWorkbenchPage[] pages= windows[i].getPages(); - for (int x= 0; x < pages.length; x++) { - IEditorPart[] editors= pages[x].getDirtyEditors(); - for (int z= 0; z < editors.length; z++) { - IEditorPart ep= editors[z]; + for (IWorkbenchWindow window : windows) { + IWorkbenchPage[] pages= window.getPages(); + for (IWorkbenchPage page : pages) { + IEditorPart[] editors= page.getDirtyEditors(); + for (IEditorPart ep : editors) { IEditorInput input= ep.getEditorInput(); if (inputs.add(input)) { if (!skipNonResourceEditors || isResourceEditorInput(input)) { @@ -801,8 +804,8 @@ public class EditorUtility { private static boolean isResourceEditorInput(IEditorInput input) { if (input instanceof MultiEditorInput) { IEditorInput[] inputs= ((MultiEditorInput) input).getInput(); - for (int i= 0; i < inputs.length; i++) { - if (inputs[i].getAdapter(IResource.class) != null) { + for (IEditorInput input2 : inputs) { + if (input2.getAdapter(IResource.class) != null) { return true; } } @@ -825,12 +828,12 @@ public class EditorUtility { List result= new ArrayList(0); IWorkbench workbench= PlatformUI.getWorkbench(); IWorkbenchWindow[] windows= workbench.getWorkbenchWindows(); - for (int i= 0; i < windows.length; i++) { - IWorkbenchPage[] pages= windows[i].getPages(); - for (int x= 0; x < pages.length; x++) { - IEditorPart[] editors= pages[x].getDirtyEditors(); - for (int z= 0; z < editors.length; z++) { - IEditorPart ep= editors[z]; + for (IWorkbenchWindow window : windows) { + IWorkbenchPage[] pages= window.getPages(); + for (IWorkbenchPage page : pages) { + IEditorPart[] editors= page.getDirtyEditors(); + for (IEditorPart editor : editors) { + IEditorPart ep= editor; IEditorInput input= ep.getEditorInput(); if (!mustSaveDirtyEditor(ep, input, saveUnknownEditors)) continue;