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 1d82ef46f47b..9bfa674c4614 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EPathUtil.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EPathUtil.java @@ -20,6 +20,7 @@ */ 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; @@ -29,6 +30,7 @@ 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.JarFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -40,6 +42,7 @@ import org.jetbrains.idea.eclipse.importWizard.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()); @@ -244,8 +247,8 @@ public class EPathUtil { } @Nullable - static String collapse2EclipseVariabledPath(final LibraryOrderEntry libraryOrderEntry) { - final VirtualFile[] virtualFiles = libraryOrderEntry.getFiles(OrderRootType.CLASSES); + static String collapse2EclipseVariabledPath(final LibraryOrderEntry libraryOrderEntry, OrderRootType type) { + final VirtualFile[] virtualFiles = libraryOrderEntry.getFiles(type); if (virtualFiles.length > 0) { VirtualFile jarFile = virtualFiles[0]; if (jarFile.getFileSystem() instanceof JarFileSystem) { @@ -256,11 +259,22 @@ public class EPathUtil { } final Project project = libraryOrderEntry.getOwnerModule().getProject(); final VirtualFile baseDir = project.getBaseDir(); + final String filePath = jarFile.getPath(); if (baseDir != null && !VfsUtil.isAncestor(baseDir, jarFile, false)) { - final String ideaCollapsed = PathMacroManager.getInstance(project).collapsePath(jarFile.getPath()); - if (ideaCollapsed.contains("..")) return null; + final String ideaCollapsed = PathMacroManager.getInstance(project).collapsePath(filePath); + if (ideaCollapsed.contains("..")) return null; return ideaCollapsed.substring(ideaCollapsed.indexOf('$')).replace("$", ""); - } + } else { //check if existing eclipse variable points inside project + final PathMacros pathMacros = PathMacros.getInstance(); + final Set 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; } diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathWriter.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathWriter.java index c7e22d068b76..78879defff23 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathWriter.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/EclipseClasspathWriter.java @@ -20,6 +20,7 @@ */ package org.jetbrains.idea.eclipse.conversion; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.projectRoots.JavaSdkType; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; @@ -37,6 +38,7 @@ import java.util.HashMap; import java.util.Map; public class EclipseClasspathWriter { + private static final Logger LOG = Logger.getInstance("#" + EclipseClasspathWriter.class.getName()); private final ModuleRootModel myModel; private final Map myOldEntries = new HashMap(); @@ -113,11 +115,13 @@ public class EclipseClasspathWriter { setExported(orderEntry, libraryOrderEntry); } else { + boolean newVarLibrary = false; String eclipseVariablePath = eclipseModuleManager.getEclipseVariablePath(files[0]); if (eclipseVariablePath == null && !eclipseModuleManager.isEclipseLibUrl(files[0])) { //new library was added - eclipseVariablePath = EPathUtil.collapse2EclipseVariabledPath(libraryOrderEntry); + newVarLibrary = true; + eclipseVariablePath = EPathUtil.collapse2EclipseVariabledPath(libraryOrderEntry, OrderRootType.CLASSES); } - final Element orderEntry; + Element orderEntry; if (eclipseVariablePath != null) { orderEntry = addOrderEntry(EclipseXml.VAR_KIND, eclipseVariablePath, classpathRoot); } @@ -128,6 +132,7 @@ public class EclipseClasspathWriter { final String srcRelativePath; String eclipseSrcVariablePath = null; + boolean addSrcRoots = true; final String[] srcFiles = libraryOrderEntry.getUrls(OrderRootType.SOURCES); if (srcFiles.length == 0) { srcRelativePath = null; @@ -138,11 +143,23 @@ public class EclipseClasspathWriter { if (eclipseVariablePath != null) { eclipseSrcVariablePath = eclipseModuleManager.getEclipseSrcVariablePath(srcFile); if (eclipseSrcVariablePath == null) { - eclipseSrcVariablePath = "/" + EPathUtil.collapse2EclipseVariabledPath(libraryOrderEntry); + eclipseSrcVariablePath = EPathUtil.collapse2EclipseVariabledPath(libraryOrderEntry, OrderRootType.SOURCES); + if (eclipseSrcVariablePath != null) { + eclipseSrcVariablePath = "/" + eclipseSrcVariablePath; + } else { + if (newVarLibrary) { //new library which cannot be replaced with vars + orderEntry.detach(); + orderEntry = addOrderEntry(EclipseXml.LIB_KIND, EPathUtil.collapse2EclipsePath(files[0], myModel), classpathRoot); + } + else { + LOG.info("Added root " + srcRelativePath + " (in existing var library) can't be replaced with any variable; src roots placed in .eml only"); + addSrcRoots = false; + } + } } } } - setOrRemoveAttribute(orderEntry, EclipseXml.SOURCEPATH_ATTR, eclipseSrcVariablePath != null ? eclipseSrcVariablePath : srcRelativePath); + if (addSrcRoots) setOrRemoveAttribute(orderEntry, EclipseXml.SOURCEPATH_ATTR, eclipseSrcVariablePath != null ? eclipseSrcVariablePath : srcRelativePath); EJavadocUtil.setupJavadocAttributes(orderEntry, libraryOrderEntry, myModel); setExported(orderEntry, libraryOrderEntry); diff --git a/plugins/eclipse/testData/modification/cantReplaceWithVariables/expected/.classpath b/plugins/eclipse/testData/modification/cantReplaceWithVariables/expected/.classpath new file mode 100644 index 000000000000..af4e20310f7e --- /dev/null +++ b/plugins/eclipse/testData/modification/cantReplaceWithVariables/expected/.classpath @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/cantReplaceWithVariables/srcvariableidea/test.jar b/plugins/eclipse/testData/modification/cantReplaceWithVariables/srcvariableidea/test.jar new file mode 100644 index 000000000000..69d35ecffe38 Binary files /dev/null and b/plugins/eclipse/testData/modification/cantReplaceWithVariables/srcvariableidea/test.jar differ diff --git a/plugins/eclipse/testData/modification/cantReplaceWithVariables/test/.classpath b/plugins/eclipse/testData/modification/cantReplaceWithVariables/test/.classpath new file mode 100644 index 000000000000..bbef4220ff82 --- /dev/null +++ b/plugins/eclipse/testData/modification/cantReplaceWithVariables/test/.classpath @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/cantReplaceWithVariables/test/.project b/plugins/eclipse/testData/modification/cantReplaceWithVariables/test/.project new file mode 100644 index 000000000000..3c7030a86519 --- /dev/null +++ b/plugins/eclipse/testData/modification/cantReplaceWithVariables/test/.project @@ -0,0 +1,17 @@ + + + ws-internals + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/plugins/eclipse/testData/modification/cantReplaceWithVariables/variableidea1/test.jar b/plugins/eclipse/testData/modification/cantReplaceWithVariables/variableidea1/test.jar new file mode 100644 index 000000000000..69d35ecffe38 Binary files /dev/null and b/plugins/eclipse/testData/modification/cantReplaceWithVariables/variableidea1/test.jar differ diff --git a/plugins/eclipse/testData/modification/replacedWithVariables/expected/.classpath b/plugins/eclipse/testData/modification/replacedWithVariables/expected/.classpath new file mode 100644 index 000000000000..e6552e05aca7 --- /dev/null +++ b/plugins/eclipse/testData/modification/replacedWithVariables/expected/.classpath @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/replacedWithVariables/srcvariableidea/test.jar b/plugins/eclipse/testData/modification/replacedWithVariables/srcvariableidea/test.jar new file mode 100644 index 000000000000..69d35ecffe38 Binary files /dev/null and b/plugins/eclipse/testData/modification/replacedWithVariables/srcvariableidea/test.jar differ diff --git a/plugins/eclipse/testData/modification/replacedWithVariables/test/.classpath b/plugins/eclipse/testData/modification/replacedWithVariables/test/.classpath new file mode 100644 index 000000000000..bbef4220ff82 --- /dev/null +++ b/plugins/eclipse/testData/modification/replacedWithVariables/test/.classpath @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/replacedWithVariables/test/.project b/plugins/eclipse/testData/modification/replacedWithVariables/test/.project new file mode 100644 index 000000000000..3c7030a86519 --- /dev/null +++ b/plugins/eclipse/testData/modification/replacedWithVariables/test/.project @@ -0,0 +1,17 @@ + + + ws-internals + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/plugins/eclipse/testData/modification/replacedWithVariables/variableidea/test.jar b/plugins/eclipse/testData/modification/replacedWithVariables/variableidea/test.jar new file mode 100644 index 000000000000..69d35ecffe38 Binary files /dev/null and b/plugins/eclipse/testData/modification/replacedWithVariables/variableidea/test.jar differ diff --git a/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/expected/.classpath b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/expected/.classpath new file mode 100644 index 000000000000..69df082536f6 --- /dev/null +++ b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/expected/.classpath @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/srcvariableidea1/test.jar b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/srcvariableidea1/test.jar new file mode 100644 index 000000000000..69d35ecffe38 Binary files /dev/null and b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/srcvariableidea1/test.jar differ diff --git a/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/test/.classpath b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/test/.classpath new file mode 100644 index 000000000000..bbef4220ff82 --- /dev/null +++ b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/test/.classpath @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/test/.project b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/test/.project new file mode 100644 index 000000000000..3c7030a86519 --- /dev/null +++ b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/test/.project @@ -0,0 +1,17 @@ + + + ws-internals + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/variableidea/test.jar b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/variableidea/test.jar new file mode 100644 index 000000000000..69d35ecffe38 Binary files /dev/null and b/plugins/eclipse/testData/modification/replacedWithVariablesCantReplaceSrc/variableidea/test.jar differ diff --git a/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/expected/.classpath b/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/expected/.classpath new file mode 100644 index 000000000000..8fb44aaed0aa --- /dev/null +++ b/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/expected/.classpath @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/test/.classpath b/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/test/.classpath new file mode 100644 index 000000000000..bbef4220ff82 --- /dev/null +++ b/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/test/.classpath @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/test/.project b/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/test/.project new file mode 100644 index 000000000000..3c7030a86519 --- /dev/null +++ b/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/test/.project @@ -0,0 +1,17 @@ + + + ws-internals + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/variableidea/test.jar b/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/variableidea/test.jar new file mode 100644 index 000000000000..69d35ecffe38 Binary files /dev/null and b/plugins/eclipse/testData/modification/replacedWithVariablesNoSources/variableidea/test.jar differ diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java index 929d437c450f..9f437018a908 100644 --- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java @@ -72,7 +72,7 @@ public class EclipseClasspathTest extends IdeaTestCase { checkModule(path, setUpModule(path, project)); } - private static Module setUpModule(final String path, final Project project) throws IOException, JDOMException, ConversionException { + static Module setUpModule(final String path, final Project project) throws IOException, JDOMException, ConversionException { final File classpathFile = new File(path, EclipseXml.DOT_CLASSPATH_EXT); String fileText = new String(FileUtil.loadFileText(classpathFile)).replaceAll("\\$ROOT\\$", project.getBaseDir().getPath()); if (!SystemInfo.isWindows) { @@ -95,7 +95,7 @@ public class EclipseClasspathTest extends IdeaTestCase { return module; } - private static void checkModule(String path, Module module) throws IOException, JDOMException, ConversionException { + static void checkModule(String path, Module module) throws IOException, JDOMException, ConversionException { final File classpathFile1 = new File(path, EclipseXml.DOT_CLASSPATH_EXT); if (!classpathFile1.exists()) return; String fileText1 = new String(FileUtil.loadFileText(classpathFile1)).replaceAll("\\$ROOT\\$", module.getProject().getBaseDir().getPath()); diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseLibrariesModificationsTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseLibrariesModificationsTest.java new file mode 100644 index 000000000000..50bd2d3530bd --- /dev/null +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseLibrariesModificationsTest.java @@ -0,0 +1,87 @@ +/* + * 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: 28-Nov-2008 + */ +package org.jetbrains.idea.eclipse; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VirtualFileManager; + +import java.util.HashMap; +import java.util.Map; + +public class EclipseLibrariesModificationsTest extends EclipseVarsTest { + + private void doTest(String[] classRoots, String[] sourceRoots) throws Exception { + final Project project = getProject(); + final String path = project.getBaseDir().getPath() + "/test"; + final Module module = EclipseClasspathTest.setUpModule(path, project); + final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); + final String parentUrl = VirtualFileManager.constructUrl(JarFileSystem.PROTOCOL, model.getContentRoots()[0].getParent().getPath()); + final Library library = model.getModuleLibraryTable().createLibrary("created"); + final Library.ModifiableModel libModifiableModel = library.getModifiableModel(); + for (String classRoot : classRoots) { + libModifiableModel.addRoot(parentUrl + classRoot, OrderRootType.CLASSES); + } + for (String sourceRoot : sourceRoots) { + libModifiableModel.addRoot(parentUrl + sourceRoot, OrderRootType.SOURCES); + } + libModifiableModel.commit(); + model.commit(); + EclipseClasspathTest.checkModule(project.getBaseDir().getPath() + "/expected", module); + } + + public void testReplacedWithVariables() throws Exception { + doTest(new String[]{"/variableidea/test.jar!/"}, new String[]{"/srcvariableidea/test.jar!/"}); + } + + public void testCantReplaceWithVariables() throws Exception { + doTest(new String[]{"/variableidea1/test.jar!/"}, new String[]{"/srcvariableidea/test.jar!/"}); + } + + public void testReplacedWithVariablesCantReplaceSrc() throws Exception { + doTest(new String[]{"/variableidea/test.jar!/"}, new String[]{"/srcvariableidea1/test.jar!/"}); + } + + public void testReplacedWithVariablesNoSources() throws Exception { + doTest(new String[]{"/variableidea/test.jar!/"}, new String[]{}); + } + + @Override + protected String getRelativeTestPath() { + return "modification"; + } + + enum Bar{ + ONE; + } + class Foo { + void foo(String each) { + Map map = new HashMap(); + map.put(new Foo(), Bar.ONE); + } + } + +} \ No newline at end of file