diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EPathUtil.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EPathUtil.java index acb28cabe047..581bece8181c 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EPathUtil.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EPathUtil.java @@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.impl.ProjectRootManagerImpl; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.JarFileSystem; @@ -154,16 +155,29 @@ public class EPathUtil { public static String collapse2eclipseRelative2OtherModule(final @NotNull Project project, final @NotNull VirtualFile file) { final Module module = ModuleUtil.findModuleForFile(file, project); if (module != null) { - final VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); - for (VirtualFile otherRoot : contentRoots) { - if (VfsUtil.isAncestor(otherRoot, file, false)) { - return "/" + module.getName() + "/" + VfsUtil.getRelativePath(file, otherRoot, '/'); + return collapse2eclipsePathRelative2Module(file, module); + } else if (ProjectRootManager.getInstance(project).getFileIndex().isIgnored(file)) { //should check all modules then + 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 (VfsUtil.isAncestor(otherRoot, file, false)) { + return "/" + module.getName() + "/" + VfsUtil.getRelativePath(file, otherRoot, '/'); + } + } + return null; + } + @Nullable public static VirtualFile getContentRoot(final ModuleRootModel model) { final VirtualFile[] contentRoots = model.getContentRoots(); diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java index feb35a0020a1..f9fbc3c0563c 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java @@ -22,6 +22,10 @@ package org.jetbrains.idea.eclipse.conversion; 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.ModuleUtil; +import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.Comparing; @@ -31,6 +35,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.pom.java.LanguageLevel; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -38,12 +43,20 @@ import org.jetbrains.idea.eclipse.IdeaXml; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; import java.util.List; /** * Read/write .eml */ public class IdeaSpecificSettings { + @NonNls private static final String RELATIVE_MODULE_SRC = "relative-module-src"; + @NonNls private static final String RELATIVE_MODULE_CLS = "relative-module-cls"; + @NonNls private static final String RELATIVE_MODULE_JAVADOC = "relative-module-javadoc"; + @NonNls private static final String PROJECT_RELATED = "project-related"; + @NonNls private static final String SRCROOT_ATTR = "srcroot"; private static final Logger LOG = Logger.getInstance("#" + IdeaSpecificSettings.class.getName()); @@ -88,6 +101,9 @@ public class IdeaSpecificSettings { appendLibraryScope(model, libElement, libraryByName); final Library.ModifiableModel modifiableModel = libraryByName.getModifiableModel(); replaceCollapsedByEclipseSourceRoots(libElement, modifiableModel); + replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, OrderRootType.SOURCES, RELATIVE_MODULE_SRC); + replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, OrderRootType.CLASSES, RELATIVE_MODULE_CLS); + replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, JavadocOrderRootType.getInstance(), RELATIVE_MODULE_JAVADOC); modifiableModel.commit(); } else { @@ -99,6 +115,9 @@ public class IdeaSpecificSettings { for (Library library : libraries) { final Library.ModifiableModel modifiableModel = library.getModifiableModel(); replaceCollapsedByEclipseSourceRoots(libElement, modifiableModel); + replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, OrderRootType.SOURCES, RELATIVE_MODULE_SRC); + replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, OrderRootType.CLASSES, RELATIVE_MODULE_CLS); + replaceModuleRelatedRoots(model.getProject(), modifiableModel, libElement, JavadocOrderRootType.getInstance(), RELATIVE_MODULE_JAVADOC); modifiableModel.commit(); } } @@ -239,6 +258,18 @@ public class IdeaSpecificSettings { } } + for (String srcUrl : entry.getUrls(OrderRootType.SOURCES)) { + appendModuleRelatedRoot(element, srcUrl, RELATIVE_MODULE_SRC, model); + } + + for (String classesUrl : entry.getUrls(OrderRootType.CLASSES)) { + appendModuleRelatedRoot(element, classesUrl, RELATIVE_MODULE_CLS, model); + } + + for (String javadocUrl : entry.getUrls(JavadocOrderRootType.getInstance())) { + appendModuleRelatedRoot(element, javadocUrl, RELATIVE_MODULE_JAVADOC, model); + } + if (!element.getChildren().isEmpty()) { root.addContent(element); isModified = true; @@ -256,4 +287,55 @@ public class IdeaSpecificSettings { return isModified; } + + public static void replaceModuleRelatedRoots(final Project project, + final Library.ModifiableModel modifiableModel, final Element libElement, + final OrderRootType orderRootType, final String relativeModuleName) { + final List urls = new ArrayList(Arrays.asList(modifiableModel.getUrls(orderRootType))); + for (Object r : libElement.getChildren(relativeModuleName)) { + final String root = PathMacroManager.getInstance(project).expandPath(((Element)r).getAttributeValue(PROJECT_RELATED)); + for (Iterator iterator = urls.iterator(); iterator.hasNext();) { + String url = iterator.next(); + if (root.contains(VfsUtil.urlToPath(url))) { + iterator.remove(); + modifiableModel.removeRoot(url, orderRootType); + modifiableModel.addRoot(root, orderRootType); + break; + } + } + } + } + + public static boolean appendModuleRelatedRoot(Element element, String classesUrl, final String rootName, ModuleRootModel model) { + VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(classesUrl); + if (file != null) { + if (file.getFileSystem() instanceof JarFileSystem) { + file = JarFileSystem.getInstance().getVirtualFileForJar(file); + assert file != null; + } + final Project project = model.getModule().getProject(); + final Module module = ModuleUtil.findModuleForFile(file, project); + if (module != null) { + return appendRelatedToModule(element, classesUrl, rootName, file, module); + } else if (ProjectRootManager.getInstance(project).getFileIndex().isIgnored(file)) { + for (Module aModule : ModuleManager.getInstance(project).getModules()) { + if (appendRelatedToModule(element, classesUrl, rootName, file, aModule)) return true; + } + } + } + return false; + } + + private static boolean appendRelatedToModule(Element element, String classesUrl, String rootName, VirtualFile file, Module module) { + final VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); + for (VirtualFile contentRoot : contentRoots) { + if (VfsUtil.isAncestor(contentRoot, file, false)) { + final Element clsElement = new Element(rootName); + clsElement.setAttribute(PROJECT_RELATED, PathMacroManager.getInstance(module.getProject()).collapsePath(classesUrl)); + element.addContent(clsElement); + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/plugins/eclipse/testData/eml/sourceRootPaths/srcPath/sourceRootPaths/sourceRootPaths.eml b/plugins/eclipse/testData/eml/sourceRootPaths/srcPath/sourceRootPaths/sourceRootPaths.eml index 2f2863aeec6e..dca242cc70d6 100644 --- a/plugins/eclipse/testData/eml/sourceRootPaths/srcPath/sourceRootPaths/sourceRootPaths.eml +++ b/plugins/eclipse/testData/eml/sourceRootPaths/srcPath/sourceRootPaths/sourceRootPaths.eml @@ -11,5 +11,11 @@ + + + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/round/IDEA53188/multi/main/.classpath b/plugins/eclipse/testData/round/IDEA53188/multi/main/.classpath new file mode 100644 index 000000000000..4fbfd1bb22fc --- /dev/null +++ b/plugins/eclipse/testData/round/IDEA53188/multi/main/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/plugins/eclipse/testData/round/IDEA53188/multi/main/.project b/plugins/eclipse/testData/round/IDEA53188/multi/main/.project new file mode 100644 index 000000000000..03d8aa35eb8e --- /dev/null +++ b/plugins/eclipse/testData/round/IDEA53188/multi/main/.project @@ -0,0 +1,17 @@ + + + Software-Testing + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/plugins/eclipse/testData/round/IDEA53188/multi/ws-internals/.classpath b/plugins/eclipse/testData/round/IDEA53188/multi/ws-internals/.classpath new file mode 100644 index 000000000000..b795d73a3619 --- /dev/null +++ b/plugins/eclipse/testData/round/IDEA53188/multi/ws-internals/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/plugins/eclipse/testData/round/IDEA53188/multi/ws-internals/.project b/plugins/eclipse/testData/round/IDEA53188/multi/ws-internals/.project new file mode 100644 index 000000000000..3c7030a86519 --- /dev/null +++ b/plugins/eclipse/testData/round/IDEA53188/multi/ws-internals/.project @@ -0,0 +1,17 @@ + + + ws-internals + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/plugins/eclipse/testData/round/IDEA53188/multi/ws-internals/Jar/comms.jar b/plugins/eclipse/testData/round/IDEA53188/multi/ws-internals/Jar/comms.jar new file mode 100644 index 000000000000..0e0dc04dfbaa Binary files /dev/null and b/plugins/eclipse/testData/round/IDEA53188/multi/ws-internals/Jar/comms.jar differ diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspath2ModulesTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspath2ModulesTest.java index a1a5ae940f09..f7f54687ade0 100644 --- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspath2ModulesTest.java +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspath2ModulesTest.java @@ -38,6 +38,10 @@ public class EclipseClasspath2ModulesTest extends Eclipse2ModulesTest { doTest("relPaths", "scnd"); } + public void testIDEA53188() throws Exception { + doTest("multi", "main"); + } + protected void doTest(final String workspaceRoot, final String projectRoot) throws Exception { super.doTest(workspaceRoot, projectRoot); EclipseClasspathTest.doTest("/" + workspaceRoot + "/" + projectRoot, getProject());