/******************************************************************************* * 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * John Camelon (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.parser; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.parser.FileContent; import org.eclipse.cdt.core.parser.ParserFactory; 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; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; /** * Utility for creating code readers */ public class InternalParserUtil extends ParserFactory { public static final String SYSTEM_DEFAULT_ENCODING = System.getProperty("file.encoding"); //$NON-NLS-1$ /** * Normalizes the path by using the location of the file, if possible. */ public static String normalizePath(String path, IFile file) { IPath loc= file.getLocation(); if (loc != null) { path= loc.toOSString(); } return path; } /** * Creates a code reader for an external location, normalizing path to * canonical path. The cache is consulted after the path has been normalized. * @deprecated, use {@link FileContent}, instead. */ @Deprecated public static org.eclipse.cdt.core.parser.CodeReader createExternalFileReader(String externalLocation, CodeReaderLRUCache cache) throws IOException { File includeFile = new File(externalLocation); if (includeFile.isFile()) { // 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); if (cache != null) { org.eclipse.cdt.core.parser.CodeReader result= cache.get(path); if (result != null) return result; } return new org.eclipse.cdt.core.parser.CodeReader(path); } return null; } /** * Creates a code reader for an external location, normalizing path to * canonical path. * @deprecated, use {@link FileContent}, instead. */ @Deprecated public static org.eclipse.cdt.core.parser.CodeReader createWorkspaceFileReader(String path, IFile file, CodeReaderLRUCache cache) throws CoreException, IOException{ path = normalizePath(path, file); if (cache != null) { org.eclipse.cdt.core.parser.CodeReader result= cache.get(path); if (result != null) return result; } InputStream in; try { in= file.getContents(true); } catch (CoreException e) { switch (e.getStatus().getCode()) { case IResourceStatus.NOT_FOUND_LOCAL: case IResourceStatus.NO_LOCATION_LOCAL: case IResourceStatus.FAILED_READ_LOCAL: case IResourceStatus.RESOURCE_NOT_LOCAL: return null; } throw e; } try { return new org.eclipse.cdt.core.parser.CodeReader(path, file.getCharset(), in); } finally { try { in.close(); } catch (IOException e) { } } } /** * @deprecated, use {@link FileContent}, instead. */ @Deprecated public static org.eclipse.cdt.core.parser.CodeReader createCodeReader(IIndexFileLocation ifl, CodeReaderLRUCache cache) throws CoreException, IOException { String fullPath= ifl.getFullPath(); if (fullPath != null) { IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath)); if (res instanceof IFile) return createWorkspaceFileReader(ifl.getURI().getPath(), (IFile) res, cache); } return createExternalFileReader(ifl.getURI().getPath(), cache); } public static InternalFileContent createFileContent(IIndexFileLocation ifl) { String fullPath= ifl.getFullPath(); if (fullPath != null) { 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); } public static InternalFileContent createWorkspaceFileContent(IFile file) { String path= file.getLocationURI().getPath(); path= normalizePath(path, file); InputStream in; try { in= file.getContents(true); if (!(in instanceof FileInputStream)) { /* * In general, non-local file-systems will not use FileInputStream. Instead make a * cached copy of the file and open an input stream to that. */ IFileStore store = EFS.getStore(file.getLocationURI()); File fileCache = store.toLocalFile(EFS.CACHE, null); try { in = new FileInputStream(fileCache); } catch (FileNotFoundException e) { CCorePlugin.log(e); return null; } } try { return createFileContent(path, file.getCharset(), in); } finally { try { in.close(); } catch (IOException e) { } } } catch (CoreException e) { switch (e.getStatus().getCode()) { case IResourceStatus.NOT_FOUND_LOCAL: case IResourceStatus.NO_LOCATION_LOCAL: case IResourceStatus.FAILED_READ_LOCAL: case IResourceStatus.RESOURCE_NOT_LOCAL: case IResourceStatus.RESOURCE_NOT_FOUND: break; default: CCorePlugin.log(e); break; } return null; } } /** * Creates a code reader for an external location, normalizing path to * canonical path. */ public static InternalFileContent createExternalFileContent(String externalLocation, String encoding) { 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. 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); } catch (IOException e) { CCorePlugin.log(e); return null; } try { return createFileContent(path, encoding, in); } finally { try { in.close(); } catch (IOException e) { } } } return null; } private static InternalFileContent createFileContent(String path, String charset, InputStream in) { try { AbstractCharArray chars= FileCharArray.create(path, charset, in); if (chars == null) return null; return new InternalFileContent(path, chars); } catch (IOException e) { CCorePlugin.log(e); } return null; } }