| /* |
| * Copyright 2000-2010 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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. |
| */ |
| |
| /* |
| * User: anna |
| * Date: 25-Mar-2010 |
| */ |
| package org.jetbrains.idea.eclipse.conversion; |
| |
| import com.intellij.openapi.application.PathMacros; |
| import com.intellij.openapi.components.PathMacroManager; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.module.ModuleManager; |
| import com.intellij.openapi.module.ModuleUtilCore; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.roots.*; |
| import com.intellij.openapi.roots.impl.ProjectRootManagerImpl; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.openapi.util.io.FileUtil; |
| import com.intellij.openapi.vfs.*; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.jetbrains.idea.eclipse.EPathCommonUtil; |
| import org.jetbrains.idea.eclipse.EclipseXml; |
| import org.jetbrains.idea.eclipse.EclipseProjectFinder; |
| |
| import java.io.File; |
| import java.util.List; |
| import java.util.Set; |
| |
| public class EPathUtil { |
| static final Logger LOG = Logger.getInstance("#" + EPathUtil.class.getName()); |
| |
| private EPathUtil() { |
| } |
| |
| public static boolean areUrlsPointTheSame(String ideaUrl, String eclipseUrl) { |
| final String path = VfsUtilCore.urlToPath(eclipseUrl); |
| if (ideaUrl.contains(path)) { |
| return true; |
| } |
| else { |
| final String relativeToModulePath = EPathCommonUtil.getRelativeToModulePath(path); |
| final int relativeIdx = ideaUrl.indexOf(relativeToModulePath); |
| if (relativeIdx != -1) { |
| final String pathToProjectFile = VfsUtilCore.urlToPath(ideaUrl.substring(0, relativeIdx)); |
| if (Comparing.strEqual(EPathCommonUtil.getRelativeModuleName(path), |
| EclipseProjectFinder.findProjectName(pathToProjectFile))) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * @param otherModule check file relative to module content root |
| * @param relativeToOtherModule local path (paths inside jars are rejected) |
| * @return url |
| */ |
| @Nullable |
| static String expandEclipseRelative2OtherModule(final @NotNull Module otherModule, final @Nullable String relativeToOtherModule) { |
| final VirtualFile[] contentRoots = ModuleRootManager.getInstance(otherModule).getContentRoots(); |
| for (VirtualFile contentRoot : contentRoots) { |
| if (relativeToOtherModule == null) { |
| return contentRoot.getUrl(); |
| } |
| final VirtualFile fileUnderModuleContentRoot = contentRoot.findFileByRelativePath(relativeToOtherModule); |
| if (fileUnderModuleContentRoot != null) { |
| return fileUnderModuleContentRoot.getUrl(); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * @return url |
| */ |
| static String expandEclipsePath2Url(final String path, |
| final ModifiableRootModel model, |
| final List<String> currentRoots) { |
| final VirtualFile contentRoot = getContentRoot(model); |
| LOG.assertTrue(contentRoot != null); |
| return expandEclipsePath2Url(path, model, currentRoots, contentRoot); |
| } |
| |
| /** |
| * @return url |
| */ |
| static String expandEclipsePath2Url(final String path, |
| final ModifiableRootModel model, |
| final List<String> currentRoots, |
| @NotNull final VirtualFile contentRoot) { |
| final String rootPath = contentRoot.getPath(); |
| String url = null; |
| if (new File(path).exists()) { //absolute path |
| url = EPathCommonUtil.pathToUrl(path); |
| } |
| else { |
| final String relativePath = new File(rootPath, path).getPath(); //inside current project |
| final File file = new File(relativePath); |
| if (file.exists()) { |
| url = EPathCommonUtil.pathToUrl(relativePath); |
| } else if (path.startsWith("/")) { //relative to other project |
| final String moduleName = EPathCommonUtil.getRelativeModuleName(path); |
| final String relativeToRootPath = EPathCommonUtil.getRelativeToModulePath(path); |
| |
| final Module otherModule = ModuleManager.getInstance(model.getModule().getProject()).findModuleByName(moduleName); |
| if (otherModule != null && otherModule != model.getModule()) { |
| url = expandEclipseRelative2OtherModule(otherModule, relativeToRootPath); |
| } |
| else if (currentRoots != null) { |
| url = EPathCommonUtil.expandEclipseRelative2ContentRoots(currentRoots, moduleName, relativeToRootPath); |
| } |
| } |
| } |
| if (url == null) { |
| url = EPathCommonUtil.pathToUrl(path); |
| } |
| |
| final VirtualFile localFile = VirtualFileManager.getInstance().findFileByUrl(url); |
| if (localFile != null) { |
| final VirtualFile jarFile = JarFileSystem.getInstance().getJarRootForLocalFile(localFile); |
| if (jarFile != null) { |
| url = jarFile.getUrl(); |
| } |
| } |
| return url; |
| } |
| |
| @Nullable |
| public static String collapse2eclipseRelative2OtherModule(final @NotNull Project project, final @NotNull VirtualFile file) { |
| final Module module = ModuleUtilCore.findModuleForFile(file, project); |
| if (module != null) { |
| return collapse2eclipsePathRelative2Module(file, module); |
| } else { //should check all modules then |
| final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); |
| if (fileIndex.isExcluded(file) || fileIndex.isInLibraryClasses(file)) { |
| for (Module aModule : ModuleManager.getInstance(project).getModules()) { |
| final String path = collapse2eclipsePathRelative2Module(file, aModule); |
| if (path != null) { |
| return path; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| @Nullable |
| private static String collapse2eclipsePathRelative2Module(VirtualFile file, Module module) { |
| final VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); |
| for (VirtualFile otherRoot : contentRoots) { |
| if (VfsUtilCore.isAncestor(otherRoot, file, false)) { |
| return "/" + module.getName() + "/" + VfsUtilCore.getRelativePath(file, otherRoot, '/'); |
| } |
| } |
| return null; |
| } |
| |
| @Nullable |
| public static VirtualFile getContentRoot(final ModuleRootModel model) { |
| final VirtualFile[] contentRoots = model.getContentRoots(); |
| for (VirtualFile virtualFile : contentRoots) { |
| if (virtualFile.findChild(EclipseXml.PROJECT_FILE) != null) { |
| return virtualFile; |
| } |
| } |
| return null; |
| } |
| |
| static String collapse2EclipsePath(final String url, final ModuleRootModel model) { |
| final Project project = model.getModule().getProject(); |
| final VirtualFile contentRoot = getContentRoot(model); |
| VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); |
| if (file != null) { |
| LOG.assertTrue(file.isValid()); |
| if (file.getFileSystem() instanceof JarFileSystem) { |
| final VirtualFile jarFile = JarFileSystem.getInstance().getVirtualFileForJar(file); |
| if (jarFile == null) { |
| LOG.assertTrue(false, "Url: \'" + url + "\'; file: " + file); |
| return ProjectRootManagerImpl.extractLocalPath(url); |
| } |
| file = jarFile; |
| } |
| if (contentRoot != null && VfsUtilCore.isAncestor(contentRoot, file, false)) { //inside current project |
| return VfsUtilCore.getRelativePath(file, contentRoot, '/'); |
| } else { |
| final String path = collapse2eclipseRelative2OtherModule(project, file); //relative to other project |
| if (path != null) { |
| return path; |
| } |
| } |
| return ProjectRootManagerImpl.extractLocalPath(url); //absolute path |
| } |
| else { //try to avoid absolute path for deleted file |
| if (contentRoot != null) { |
| final String rootUrl = contentRoot.getUrl(); |
| if (url.startsWith(rootUrl) && url.length() > rootUrl.length()) { |
| return url.substring(rootUrl.length() + 1); //without leading / |
| } |
| } |
| final VirtualFile projectBaseDir = contentRoot != null ? contentRoot.getParent() : project.getBaseDir(); |
| assert projectBaseDir != null; |
| final String projectUrl = projectBaseDir.getUrl(); |
| if (url.startsWith(projectUrl)) { |
| return url.substring(projectUrl.length()); //leading / |
| } |
| |
| final String path = VfsUtilCore.urlToPath(url); |
| final String projectPath = projectBaseDir.getPath(); |
| if (path.startsWith(projectPath)) { |
| return ProjectRootManagerImpl.extractLocalPath(path.substring(projectPath.length())); |
| } |
| |
| return ProjectRootManagerImpl.extractLocalPath(url); |
| } |
| } |
| |
| @Nullable |
| static String collapse2EclipseVariabledPath(final LibraryOrderEntry libraryOrderEntry, OrderRootType type) { |
| final VirtualFile[] virtualFiles = libraryOrderEntry.getRootFiles(type); |
| if (virtualFiles.length > 0) { |
| VirtualFile jarFile = virtualFiles[0]; |
| if (jarFile.getFileSystem() instanceof JarFileSystem) { |
| jarFile = JarFileSystem.getInstance().getVirtualFileForJar(jarFile); |
| } |
| if (jarFile == null) { |
| return null; |
| } |
| final Project project = libraryOrderEntry.getOwnerModule().getProject(); |
| final VirtualFile baseDir = project.getBaseDir(); |
| final String filePath = jarFile.getPath(); |
| if (baseDir != null && !VfsUtilCore.isAncestor(baseDir, jarFile, false)) { |
| final String ideaCollapsed = PathMacroManager.getInstance(project).collapsePath(filePath); |
| if (ideaCollapsed.contains("..")) return null; |
| final int index = ideaCollapsed.indexOf('$'); |
| if (index < 0) return null; |
| return ideaCollapsed.substring(index).replace("$", ""); |
| } |
| } |
| for (String url : libraryOrderEntry.getRootUrls(type)) { |
| //check if existing eclipse variable points inside project or doesn't exist |
| String filePath = VirtualFileManager.extractPath(url); |
| final int jarSeparatorIdx = filePath.indexOf(JarFileSystem.JAR_SEPARATOR); |
| if (jarSeparatorIdx > -1) { |
| filePath = filePath.substring(0, jarSeparatorIdx); |
| } |
| final PathMacros pathMacros = PathMacros.getInstance(); |
| final Set<String> names = pathMacros.getUserMacroNames(); |
| for (String name : names) { |
| final String path = FileUtil.toSystemIndependentName(pathMacros.getValue(name)); |
| if (filePath.startsWith(path + "/")) { |
| final String substr = filePath.substring(path.length()); |
| return name + (substr.startsWith("/") || substr.length() == 0 ? substr : "/" + substr); |
| } |
| } |
| } |
| return null; |
| } |
| } |