/** * Copyright (C) 2005 - 2015 Eric Van Dewoestine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.eclim.plugin.core.util; import java.io.File; import java.net.URI; import org.eclim.Services; import org.eclim.plugin.core.project.ProjectManagement; import org.eclim.plugin.core.project.ProjectManager; import org.eclim.plugin.core.project.ProjectNatureFactory; import org.eclipse.core.filebuffers.FileBuffers; import org.eclipse.core.filebuffers.ITextFileBuffer; import org.eclipse.core.filebuffers.ITextFileBufferManager; import org.eclipse.core.filebuffers.LocationKind; 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.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jface.text.IDocument; /** * Utility methods for working with eclipse projects. * * @author Eric Van Dewoestine */ public class ProjectUtils { /** * Gets the path on disk to the directory of the supplied project. * * @param project The project name. * @return The path or null if not found. */ public static String getPath(String project) throws Exception { return getPath(getProject(project)); } /** * Gets the path on disk to the directory of the supplied project. * * @param project The project. * @return The path or null if not found. */ public static String getPath(IProject project) throws Exception { IPath path = getIPath(project); return path != null ? path.toOSString().replace('\\', '/') : null; } /** * Gets the project relative path of the supplied absolute file path. * * @param path The absolute path to a file in a project. * @return The path or null if not found. */ public static String getProjectRelativePath(String path) throws Exception { // can't use URLEncoder on the full file since the colon in 'C:' gets // encoded as well. //URI uri = new URI("file://" + URLEncoder.encode(file, "UTF-8")); URI uri = new URI("file://" + path.replaceAll(" ", "%20")); IFile[] files = ResourcesPlugin .getWorkspace().getRoot().findFilesForLocationURI(uri); if (files.length > 0){ return files[0].getProjectRelativePath().toString(); } return null; } /** * Gets the path on disk to the directory of the supplied project. * * @param project The project. * @return The path or null if not found. */ public static IPath getIPath(IProject project) throws Exception { IPath path = project.getRawLocation(); // eclipse returns null for raw location if project is under the workspace. if(path == null){ String name = project.getName(); path = ResourcesPlugin.getWorkspace().getRoot().getRawLocation(); path = path.append(name); } return path; } /** * Gets a project by name. * * @param name The name of the project. * @return The project which may or may not exist. */ public static IProject getProject(String name) throws Exception { return getProject(name, false); } /** * Gets a project by name. * * @param name The name of the project. * @param open true to open the project if not already open, or false to do * nothing. * @return The project which may or may not exist. */ public static IProject getProject(String name, boolean open) throws Exception { IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name); if(open && project.exists() && !project.isOpen()){ project.open(null); } return project; } /** * Gets the absolute file path. * * @param project The file's project. * @param file The file. * @return The absolute file path. */ public static String getFilePath(String project, String file) throws Exception { return getFilePath(getProject(project), file); } /** * Gets the absolute file path. * * @param project The file's project. * @param file The file. * @return The absolute file path. */ public static String getFilePath(IProject project, String file) throws Exception { file = file.replace('\\', '/'); if(file.startsWith("/" + project.getName())){ if(file.startsWith("/" + project.getName() + "/")){ file = file.substring(2 + project.getName().length()); }else if(file.endsWith("/" + project.getName())){ file = file.substring(1 + project.getName().length()); } // path is the project root if (file.length() == 0){ return getPath(project); } }else if(file.startsWith("/") || file.toLowerCase().startsWith("jar:") || file.toLowerCase().startsWith("zip:")) { return file; } String projectPath = getPath(project); if(file.toLowerCase().startsWith(projectPath.toLowerCase())){ return file; } IFile ifile = project.getFile(file); return ifile.getLocation().toOSString().replace('\\', '/'); } /** * Gets the IFile instance for the specified file located in the supplied * project. * * @param project The file's project. * @param file The file. * @return The IFile. */ public static IFile getFile(String project, String file) throws Exception { return getFile(getProject(project), file); } /** * Gets the IFile instance for the specified file located in the supplied * project. * * @param project The file's project. * @param file The file. * @return The IFile. */ public static IFile getFile(IProject project, String file) throws Exception { if (!project.isOpen()){ project.open(null); } String path = getPath(project); path = path.replace('\\', '/'); /*if(!file.startsWith(path)){ throw new RuntimeException( Services.getMessage("project.file.mismatch", file, path)); }*/ //String file = file.substring(path.length()); IFile ifile = project.getFile(file); ifile.refreshLocal(IResource.DEPTH_INFINITE, null); // invoke any nature specific file refreshing String[] natures = ProjectNatureFactory.getProjectNatures(project); for (String nature : natures){ ProjectManager manager = ProjectManagement.getProjectManager(nature); if (manager != null){ manager.refresh(project, ifile); } } return ifile; } /** * Gets the IDocument instance for the given file. * <p/> * Borrowed from org.eclipse.ant.internal.ui.AntUtil * * @param project The project name. * @param file The file. * @return The IDocument. */ public static IDocument getDocument(String project, String file) throws Exception { return getDocument(getProject(project), file); } /** * Gets the IDocument instance for the given file. * <p/> * Borrowed from org.eclipse.ant.internal.ui.AntUtil * * @param project The project. * @param file The file. * @return The IDocument. */ public static IDocument getDocument(IProject project, String file) throws Exception { // using IFile would ensure that ifile.getProject() (used by at least pdt // internally) would result in the proper project reference, but seems to // break ant code completion and validation. //IFile thefile = getFile(project, file); File thefile = new File(getFilePath(project, file)); if(!thefile.exists()){ return null; } ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager(); //IPath location = thefile.getFullPath(); IPath location = new Path(thefile.getAbsolutePath()); boolean connected = false; try { ITextFileBuffer buffer = manager.getTextFileBuffer(location, LocationKind.LOCATION); if (buffer == null) { //no existing file buffer..create one manager.connect(location, LocationKind.LOCATION, new NullProgressMonitor()); connected = true; buffer = manager.getTextFileBuffer(location, LocationKind.LOCATION); if (buffer == null) { return null; } } return buffer.getDocument(); } finally { if (connected) { try { manager.disconnect( location, LocationKind.LOCATION, new NullProgressMonitor()); }catch(Exception e){ } } } } /** * Closes the supplied project and suppresses any exceptions thrown. * * @param project The project. */ public static void closeQuietly(IProject project) { try{ if(project != null){ project.close(null); } }catch(Exception ignore){ } } /** * Assertion that the supplied project exists. * * @param project The project. */ public static void assertExists(IProject project) throws Exception { if(project == null || !project.exists()){ throw new IllegalArgumentException( Services.getMessage("project.not.found", project != null ? project.getName() : null)); } } }