mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
faster path macro replacement index building (IDEA-84390)
This commit is contained in:
+271
-273
@@ -1,273 +1,271 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
*/
|
||||
package com.intellij.openapi.components.impl;
|
||||
|
||||
import com.intellij.application.options.PathMacrosImpl;
|
||||
import com.intellij.application.options.ReplacePathToMacroMap;
|
||||
import com.intellij.mock.MockFileSystem;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.PathMacros;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.ex.ProjectEx;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.io.fs.FileSystem;
|
||||
import com.intellij.util.io.fs.IFileSystem;
|
||||
import org.hamcrest.Description;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.api.Action;
|
||||
import org.jmock.api.Invocation;
|
||||
import org.jmock.integration.junit4.JMock;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.jmock.lib.legacy.ClassImposteriser;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
*/
|
||||
@RunWith(JMock.class)
|
||||
public class PathMacroManagerTest {
|
||||
private static final String APP_HOME = FileUtil.toSystemIndependentName(PathManager.getHomePath());
|
||||
private static final String USER_HOME = FileUtil.toSystemIndependentName(StringUtil.trimEnd(SystemProperties.getUserHome(), "/"));
|
||||
|
||||
private Module myModule;
|
||||
private ProjectEx myProject;
|
||||
private PathMacrosImpl myPathMacros;
|
||||
private Mockery context;
|
||||
|
||||
protected ApplicationEx myApplication;
|
||||
private IFileSystem myOldFileSystem;
|
||||
protected MockFileSystem myFileSystem;
|
||||
|
||||
@Before
|
||||
public final void setupApplication() throws Exception {
|
||||
context = new JUnit4Mockery();
|
||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||
myApplication = context.mock(ApplicationEx.class, "application");
|
||||
|
||||
context.checking(new Expectations() {
|
||||
{
|
||||
allowing(myApplication).isUnitTestMode(); will(returnValue(false));
|
||||
allowing(myApplication).getName(); will(returnValue("IDEA"));
|
||||
|
||||
//some tests leave invokeLaters after them...
|
||||
allowing(myApplication).invokeLater(with(any(Runnable.class)), with(any(ModalityState.class)));
|
||||
|
||||
allowing(myApplication).runReadAction(with(any(Runnable.class)));
|
||||
will(new Action() {
|
||||
@Override
|
||||
public void describeTo(final Description description) {
|
||||
description.appendText("runs runnable");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(final Invocation invocation) throws Throwable {
|
||||
((Runnable)invocation.getParameter(0)).run();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Before
|
||||
public final void setupFileSystem() throws Exception {
|
||||
myOldFileSystem = FileSystem.FILE_SYSTEM;
|
||||
myFileSystem = new MockFileSystem();
|
||||
FileSystem.FILE_SYSTEM = myFileSystem;
|
||||
BasePathMacroManager.DEBUG = true;
|
||||
}
|
||||
|
||||
@After
|
||||
public final void restoreFilesystem() throws Exception {
|
||||
BasePathMacroManager.DEBUG = false;
|
||||
FileSystem.FILE_SYSTEM = myOldFileSystem;
|
||||
}
|
||||
|
||||
private void setUpMocks(final String projectPath) {
|
||||
myModule = context.mock(Module.class);
|
||||
myPathMacros = context.mock(PathMacrosImpl.class);
|
||||
myProject = context.mock(ProjectEx.class);
|
||||
|
||||
final VirtualFile projectFile = context.mock(VirtualFile.class, "projectFile");
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
allowing(myModule).isDisposed(); will(returnValue(false));
|
||||
allowing(myProject).isDisposed(); will(returnValue(false));
|
||||
|
||||
allowing(projectFile).getPath(); will(returnValue(projectPath));
|
||||
|
||||
final String moduleFilePath = projectPath + "/module/module.iml";
|
||||
|
||||
allowing(myApplication).getComponent(with(equal(PathMacros.class))); will(returnValue(myPathMacros));
|
||||
allowing(myPathMacros).addMacroReplacements(with(any(ReplacePathToMacroMap.class)));
|
||||
|
||||
allowing(myProject).getBaseDir(); will(returnValue(projectFile));
|
||||
allowing(myModule).getModuleFilePath(); will(returnValue(moduleFilePath));
|
||||
allowing(myModule).getProject(); will(returnValue(myProject));
|
||||
}});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRightMacrosOrder_RelativeValues_NoVariables() throws Exception {
|
||||
setUpMocks("/tmp/foo");
|
||||
|
||||
final ReplacePathToMacroMap replacePathMap = new ModulePathMacroManager(myPathMacros, myModule).getReplacePathMap();
|
||||
final String s = mapToString(replacePathMap);
|
||||
assertEquals("file:/tmp/foo/module -> file:$MODULE_DIR$\n" +
|
||||
"file://tmp/foo/module -> file:/$MODULE_DIR$\n" +
|
||||
"file:///tmp/foo/module -> file://$MODULE_DIR$\n" +
|
||||
"jar:/tmp/foo/module -> jar:$MODULE_DIR$\n" +
|
||||
"jar://tmp/foo/module -> jar:/$MODULE_DIR$\n" +
|
||||
"jar:///tmp/foo/module -> jar://$MODULE_DIR$\n" +
|
||||
"/tmp/foo/module -> $MODULE_DIR$\n" +
|
||||
APP_HOME + " -> $APPLICATION_HOME_DIR$\n" +
|
||||
"file:" + APP_HOME + " -> file:$APPLICATION_HOME_DIR$\n" +
|
||||
"file:/" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"file://" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:" + APP_HOME + " -> jar:$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:/" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar://" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
USER_HOME + " -> $USER_HOME$\n" +
|
||||
"file:" + USER_HOME + " -> file:$USER_HOME$\n" +
|
||||
"file:/" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"file://" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"jar:" + USER_HOME + " -> jar:$USER_HOME$\n" +
|
||||
"jar:/" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"jar://" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"file:/tmp/foo -> file:$MODULE_DIR$/..\n" +
|
||||
"file://tmp/foo -> file:/$MODULE_DIR$/..\n" +
|
||||
"file:///tmp/foo -> file://$MODULE_DIR$/..\n" +
|
||||
"jar:/tmp/foo -> jar:$MODULE_DIR$/..\n" +
|
||||
"jar://tmp/foo -> jar:/$MODULE_DIR$/..\n" +
|
||||
"jar:///tmp/foo -> jar://$MODULE_DIR$/..\n" +
|
||||
"/tmp/foo -> $MODULE_DIR$/..\n" +
|
||||
"file:/tmp -> file:$MODULE_DIR$/../..\n" +
|
||||
"file://tmp -> file:/$MODULE_DIR$/../..\n" +
|
||||
"file:///tmp -> file://$MODULE_DIR$/../..\n" +
|
||||
"jar:/tmp -> jar:$MODULE_DIR$/../..\n" +
|
||||
"jar://tmp -> jar:/$MODULE_DIR$/../..\n" +
|
||||
"jar:///tmp -> jar://$MODULE_DIR$/../..\n" +
|
||||
"/tmp -> $MODULE_DIR$/../..", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPathsOutsideProject() throws Exception {
|
||||
setUpMocks("/tmp/foo");
|
||||
|
||||
final ReplacePathToMacroMap replacePathMap = new ProjectPathMacroManager(myPathMacros, myProject).getReplacePathMap();
|
||||
final String s = mapToString(replacePathMap);
|
||||
assertEquals("file:/tmp/foo -> file:$PROJECT_DIR$\n" +
|
||||
"file://tmp/foo -> file:/$PROJECT_DIR$\n" +
|
||||
"file:///tmp/foo -> file://$PROJECT_DIR$\n" +
|
||||
"jar:/tmp/foo -> jar:$PROJECT_DIR$\n" +
|
||||
"jar://tmp/foo -> jar:/$PROJECT_DIR$\n" +
|
||||
"jar:///tmp/foo -> jar://$PROJECT_DIR$\n" +
|
||||
"/tmp/foo -> $PROJECT_DIR$\n" +
|
||||
APP_HOME + " -> $APPLICATION_HOME_DIR$\n" +
|
||||
"file:" + APP_HOME + " -> file:$APPLICATION_HOME_DIR$\n" +
|
||||
"file:/" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"file://" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:" + APP_HOME + " -> jar:$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:/" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar://" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
USER_HOME + " -> $USER_HOME$\n" +
|
||||
"file:" + USER_HOME + " -> file:$USER_HOME$\n" +
|
||||
"file:/" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"file://" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"jar:" + USER_HOME + " -> jar:$USER_HOME$\n" +
|
||||
"jar:/" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"jar://" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"file:/tmp -> file:$PROJECT_DIR$/..\n" +
|
||||
"file://tmp -> file:/$PROJECT_DIR$/..\n" +
|
||||
"file:///tmp -> file://$PROJECT_DIR$/..\n" +
|
||||
"jar:/tmp -> jar:$PROJECT_DIR$/..\n" +
|
||||
"jar://tmp -> jar:/$PROJECT_DIR$/..\n" +
|
||||
"jar:///tmp -> jar://$PROJECT_DIR$/..\n" +
|
||||
"/tmp -> $PROJECT_DIR$/..", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProjectUnderUserHome() throws Exception {
|
||||
setUpMocks(USER_HOME + "/IdeaProjects/foo");
|
||||
|
||||
final ReplacePathToMacroMap replacePathMap = new ModulePathMacroManager(myPathMacros, myModule).getReplacePathMap();
|
||||
final String s = mapToString(replacePathMap);
|
||||
assertEquals("file:" + USER_HOME + "/IdeaProjects/foo/module -> file:$MODULE_DIR$\n" +
|
||||
"file:/" + USER_HOME + "/IdeaProjects/foo/module -> file:/$MODULE_DIR$\n" +
|
||||
"file://" + USER_HOME + "/IdeaProjects/foo/module -> file://$MODULE_DIR$\n" +
|
||||
"jar:" + USER_HOME + "/IdeaProjects/foo/module -> jar:$MODULE_DIR$\n" +
|
||||
"jar:/" + USER_HOME + "/IdeaProjects/foo/module -> jar:/$MODULE_DIR$\n" +
|
||||
"jar://" + USER_HOME + "/IdeaProjects/foo/module -> jar://$MODULE_DIR$\n" +
|
||||
USER_HOME + "/IdeaProjects/foo/module -> $MODULE_DIR$\n" +
|
||||
APP_HOME + " -> $APPLICATION_HOME_DIR$\n" +
|
||||
"file:" + APP_HOME + " -> file:$APPLICATION_HOME_DIR$\n" +
|
||||
"file:/" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"file://" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:" + APP_HOME + " -> jar:$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:/" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar://" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
"file:" + USER_HOME + "/IdeaProjects/foo -> file:$MODULE_DIR$/..\n" +
|
||||
"file:/" + USER_HOME + "/IdeaProjects/foo -> file:/$MODULE_DIR$/..\n" +
|
||||
"file://" + USER_HOME + "/IdeaProjects/foo -> file://$MODULE_DIR$/..\n" +
|
||||
"jar:" + USER_HOME + "/IdeaProjects/foo -> jar:$MODULE_DIR$/..\n" +
|
||||
"jar:/" + USER_HOME + "/IdeaProjects/foo -> jar:/$MODULE_DIR$/..\n" +
|
||||
"jar://" + USER_HOME + "/IdeaProjects/foo -> jar://$MODULE_DIR$/..\n" +
|
||||
USER_HOME + "/IdeaProjects/foo -> $MODULE_DIR$/..\n" +
|
||||
"file:" + USER_HOME + "/IdeaProjects -> file:$MODULE_DIR$/../..\n" +
|
||||
"file:/" + USER_HOME + "/IdeaProjects -> file:/$MODULE_DIR$/../..\n" +
|
||||
"file://" + USER_HOME + "/IdeaProjects -> file://$MODULE_DIR$/../..\n" +
|
||||
"jar:" + USER_HOME + "/IdeaProjects -> jar:$MODULE_DIR$/../..\n" +
|
||||
"jar:/" + USER_HOME + "/IdeaProjects -> jar:/$MODULE_DIR$/../..\n" +
|
||||
"jar://" + USER_HOME + "/IdeaProjects -> jar://$MODULE_DIR$/../..\n" +
|
||||
USER_HOME + "/IdeaProjects -> $MODULE_DIR$/../..\n" +
|
||||
USER_HOME + " -> $USER_HOME$\n" +
|
||||
"file:" + USER_HOME + " -> file:$USER_HOME$\n" +
|
||||
"file:/" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"file://" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"jar:" + USER_HOME + " -> jar:$USER_HOME$\n" +
|
||||
"jar:/" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"jar://" + USER_HOME + " -> jar://$USER_HOME$", s);
|
||||
}
|
||||
|
||||
private static String mapToString(final ReplacePathToMacroMap replacePathMap) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
|
||||
final List<String> pathIndex = replacePathMap.getPathIndex();
|
||||
for (String s : pathIndex) {
|
||||
if (buf.length() > 0) buf.append("\n");
|
||||
buf.append(s);
|
||||
buf.append(" -> ");
|
||||
buf.append(replacePathMap.get(s));
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
*/
|
||||
package com.intellij.openapi.components.impl;
|
||||
|
||||
import com.intellij.application.options.PathMacrosImpl;
|
||||
import com.intellij.application.options.ReplacePathToMacroMap;
|
||||
import com.intellij.mock.MockFileSystem;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.PathMacros;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.ex.ProjectEx;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.io.fs.FileSystem;
|
||||
import com.intellij.util.io.fs.IFileSystem;
|
||||
import org.hamcrest.Description;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.api.Action;
|
||||
import org.jmock.api.Invocation;
|
||||
import org.jmock.integration.junit4.JMock;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.jmock.lib.legacy.ClassImposteriser;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
*/
|
||||
@RunWith(JMock.class)
|
||||
public class PathMacroManagerTest {
|
||||
private static final String APP_HOME = FileUtil.toSystemIndependentName(PathManager.getHomePath());
|
||||
private static final String USER_HOME = FileUtil.toSystemIndependentName(StringUtil.trimEnd(SystemProperties.getUserHome(), "/"));
|
||||
|
||||
private Module myModule;
|
||||
private ProjectEx myProject;
|
||||
private PathMacrosImpl myPathMacros;
|
||||
private Mockery context;
|
||||
|
||||
protected ApplicationEx myApplication;
|
||||
private IFileSystem myOldFileSystem;
|
||||
protected MockFileSystem myFileSystem;
|
||||
|
||||
@Before
|
||||
public final void setupApplication() throws Exception {
|
||||
context = new JUnit4Mockery();
|
||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||
myApplication = context.mock(ApplicationEx.class, "application");
|
||||
|
||||
context.checking(new Expectations() {
|
||||
{
|
||||
allowing(myApplication).isUnitTestMode(); will(returnValue(false));
|
||||
allowing(myApplication).getName(); will(returnValue("IDEA"));
|
||||
|
||||
//some tests leave invokeLaters after them...
|
||||
allowing(myApplication).invokeLater(with(any(Runnable.class)), with(any(ModalityState.class)));
|
||||
|
||||
allowing(myApplication).runReadAction(with(any(Runnable.class)));
|
||||
will(new Action() {
|
||||
@Override
|
||||
public void describeTo(final Description description) {
|
||||
description.appendText("runs runnable");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(final Invocation invocation) throws Throwable {
|
||||
((Runnable)invocation.getParameter(0)).run();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Before
|
||||
public final void setupFileSystem() throws Exception {
|
||||
myOldFileSystem = FileSystem.FILE_SYSTEM;
|
||||
myFileSystem = new MockFileSystem();
|
||||
FileSystem.FILE_SYSTEM = myFileSystem;
|
||||
}
|
||||
|
||||
@After
|
||||
public final void restoreFilesystem() throws Exception {
|
||||
FileSystem.FILE_SYSTEM = myOldFileSystem;
|
||||
}
|
||||
|
||||
private void setUpMocks(final String projectPath) {
|
||||
myModule = context.mock(Module.class);
|
||||
myPathMacros = context.mock(PathMacrosImpl.class);
|
||||
myProject = context.mock(ProjectEx.class);
|
||||
|
||||
final VirtualFile projectFile = context.mock(VirtualFile.class, "projectFile");
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
allowing(myModule).isDisposed(); will(returnValue(false));
|
||||
allowing(myProject).isDisposed(); will(returnValue(false));
|
||||
|
||||
allowing(projectFile).getPath(); will(returnValue(projectPath));
|
||||
|
||||
final String moduleFilePath = projectPath + "/module/module.iml";
|
||||
|
||||
allowing(myApplication).getComponent(with(equal(PathMacros.class))); will(returnValue(myPathMacros));
|
||||
allowing(myPathMacros).addMacroReplacements(with(any(ReplacePathToMacroMap.class)));
|
||||
|
||||
allowing(myProject).getBaseDir(); will(returnValue(projectFile));
|
||||
allowing(myModule).getModuleFilePath(); will(returnValue(moduleFilePath));
|
||||
allowing(myModule).getProject(); will(returnValue(myProject));
|
||||
}});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRightMacrosOrder_RelativeValues_NoVariables() throws Exception {
|
||||
setUpMocks("/tmp/foo");
|
||||
|
||||
final ReplacePathToMacroMap replacePathMap = new ModulePathMacroManager(myPathMacros, myModule).getReplacePathMap();
|
||||
final String s = mapToString(replacePathMap);
|
||||
assertEquals("file:/tmp/foo/module -> file:$MODULE_DIR$\n" +
|
||||
"file://tmp/foo/module -> file:/$MODULE_DIR$\n" +
|
||||
"file:///tmp/foo/module -> file://$MODULE_DIR$\n" +
|
||||
"jar:/tmp/foo/module -> jar:$MODULE_DIR$\n" +
|
||||
"jar://tmp/foo/module -> jar:/$MODULE_DIR$\n" +
|
||||
"jar:///tmp/foo/module -> jar://$MODULE_DIR$\n" +
|
||||
"/tmp/foo/module -> $MODULE_DIR$\n" +
|
||||
APP_HOME + " -> $APPLICATION_HOME_DIR$\n" +
|
||||
"file:" + APP_HOME + " -> file:$APPLICATION_HOME_DIR$\n" +
|
||||
"file:/" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"file://" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:" + APP_HOME + " -> jar:$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:/" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar://" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
USER_HOME + " -> $USER_HOME$\n" +
|
||||
"file:" + USER_HOME + " -> file:$USER_HOME$\n" +
|
||||
"file:/" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"file://" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"jar:" + USER_HOME + " -> jar:$USER_HOME$\n" +
|
||||
"jar:/" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"jar://" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"file:/tmp/foo -> file:$MODULE_DIR$/..\n" +
|
||||
"file://tmp/foo -> file:/$MODULE_DIR$/..\n" +
|
||||
"file:///tmp/foo -> file://$MODULE_DIR$/..\n" +
|
||||
"jar:/tmp/foo -> jar:$MODULE_DIR$/..\n" +
|
||||
"jar://tmp/foo -> jar:/$MODULE_DIR$/..\n" +
|
||||
"jar:///tmp/foo -> jar://$MODULE_DIR$/..\n" +
|
||||
"/tmp/foo -> $MODULE_DIR$/..\n" +
|
||||
"file:/tmp -> file:$MODULE_DIR$/../..\n" +
|
||||
"file://tmp -> file:/$MODULE_DIR$/../..\n" +
|
||||
"file:///tmp -> file://$MODULE_DIR$/../..\n" +
|
||||
"jar:/tmp -> jar:$MODULE_DIR$/../..\n" +
|
||||
"jar://tmp -> jar:/$MODULE_DIR$/../..\n" +
|
||||
"jar:///tmp -> jar://$MODULE_DIR$/../..\n" +
|
||||
"/tmp -> $MODULE_DIR$/../..", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPathsOutsideProject() throws Exception {
|
||||
setUpMocks("/tmp/foo");
|
||||
|
||||
final ReplacePathToMacroMap replacePathMap = new ProjectPathMacroManager(myPathMacros, myProject).getReplacePathMap();
|
||||
final String s = mapToString(replacePathMap);
|
||||
assertEquals("file:/tmp/foo -> file:$PROJECT_DIR$\n" +
|
||||
"file://tmp/foo -> file:/$PROJECT_DIR$\n" +
|
||||
"file:///tmp/foo -> file://$PROJECT_DIR$\n" +
|
||||
"jar:/tmp/foo -> jar:$PROJECT_DIR$\n" +
|
||||
"jar://tmp/foo -> jar:/$PROJECT_DIR$\n" +
|
||||
"jar:///tmp/foo -> jar://$PROJECT_DIR$\n" +
|
||||
"/tmp/foo -> $PROJECT_DIR$\n" +
|
||||
APP_HOME + " -> $APPLICATION_HOME_DIR$\n" +
|
||||
"file:" + APP_HOME + " -> file:$APPLICATION_HOME_DIR$\n" +
|
||||
"file:/" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"file://" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:" + APP_HOME + " -> jar:$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:/" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar://" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
USER_HOME + " -> $USER_HOME$\n" +
|
||||
"file:" + USER_HOME + " -> file:$USER_HOME$\n" +
|
||||
"file:/" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"file://" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"jar:" + USER_HOME + " -> jar:$USER_HOME$\n" +
|
||||
"jar:/" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"jar://" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"file:/tmp -> file:$PROJECT_DIR$/..\n" +
|
||||
"file://tmp -> file:/$PROJECT_DIR$/..\n" +
|
||||
"file:///tmp -> file://$PROJECT_DIR$/..\n" +
|
||||
"jar:/tmp -> jar:$PROJECT_DIR$/..\n" +
|
||||
"jar://tmp -> jar:/$PROJECT_DIR$/..\n" +
|
||||
"jar:///tmp -> jar://$PROJECT_DIR$/..\n" +
|
||||
"/tmp -> $PROJECT_DIR$/..", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProjectUnderUserHome() throws Exception {
|
||||
setUpMocks(USER_HOME + "/IdeaProjects/foo");
|
||||
|
||||
final ReplacePathToMacroMap replacePathMap = new ModulePathMacroManager(myPathMacros, myModule).getReplacePathMap();
|
||||
final String s = mapToString(replacePathMap);
|
||||
assertEquals("file:" + USER_HOME + "/IdeaProjects/foo/module -> file:$MODULE_DIR$\n" +
|
||||
"file:/" + USER_HOME + "/IdeaProjects/foo/module -> file:/$MODULE_DIR$\n" +
|
||||
"file://" + USER_HOME + "/IdeaProjects/foo/module -> file://$MODULE_DIR$\n" +
|
||||
"jar:" + USER_HOME + "/IdeaProjects/foo/module -> jar:$MODULE_DIR$\n" +
|
||||
"jar:/" + USER_HOME + "/IdeaProjects/foo/module -> jar:/$MODULE_DIR$\n" +
|
||||
"jar://" + USER_HOME + "/IdeaProjects/foo/module -> jar://$MODULE_DIR$\n" +
|
||||
USER_HOME + "/IdeaProjects/foo/module -> $MODULE_DIR$\n" +
|
||||
APP_HOME + " -> $APPLICATION_HOME_DIR$\n" +
|
||||
"file:" + APP_HOME + " -> file:$APPLICATION_HOME_DIR$\n" +
|
||||
"file:/" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"file://" + APP_HOME + " -> file://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:" + APP_HOME + " -> jar:$APPLICATION_HOME_DIR$\n" +
|
||||
"jar:/" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
"jar://" + APP_HOME + " -> jar://$APPLICATION_HOME_DIR$\n" +
|
||||
"file:" + USER_HOME + "/IdeaProjects/foo -> file:$MODULE_DIR$/..\n" +
|
||||
"file:/" + USER_HOME + "/IdeaProjects/foo -> file:/$MODULE_DIR$/..\n" +
|
||||
"file://" + USER_HOME + "/IdeaProjects/foo -> file://$MODULE_DIR$/..\n" +
|
||||
"jar:" + USER_HOME + "/IdeaProjects/foo -> jar:$MODULE_DIR$/..\n" +
|
||||
"jar:/" + USER_HOME + "/IdeaProjects/foo -> jar:/$MODULE_DIR$/..\n" +
|
||||
"jar://" + USER_HOME + "/IdeaProjects/foo -> jar://$MODULE_DIR$/..\n" +
|
||||
USER_HOME + "/IdeaProjects/foo -> $MODULE_DIR$/..\n" +
|
||||
"file:" + USER_HOME + "/IdeaProjects -> file:$MODULE_DIR$/../..\n" +
|
||||
"file:/" + USER_HOME + "/IdeaProjects -> file:/$MODULE_DIR$/../..\n" +
|
||||
"file://" + USER_HOME + "/IdeaProjects -> file://$MODULE_DIR$/../..\n" +
|
||||
"jar:" + USER_HOME + "/IdeaProjects -> jar:$MODULE_DIR$/../..\n" +
|
||||
"jar:/" + USER_HOME + "/IdeaProjects -> jar:/$MODULE_DIR$/../..\n" +
|
||||
"jar://" + USER_HOME + "/IdeaProjects -> jar://$MODULE_DIR$/../..\n" +
|
||||
USER_HOME + "/IdeaProjects -> $MODULE_DIR$/../..\n" +
|
||||
USER_HOME + " -> $USER_HOME$\n" +
|
||||
"file:" + USER_HOME + " -> file:$USER_HOME$\n" +
|
||||
"file:/" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"file://" + USER_HOME + " -> file://$USER_HOME$\n" +
|
||||
"jar:" + USER_HOME + " -> jar:$USER_HOME$\n" +
|
||||
"jar:/" + USER_HOME + " -> jar://$USER_HOME$\n" +
|
||||
"jar://" + USER_HOME + " -> jar://$USER_HOME$", s);
|
||||
}
|
||||
|
||||
private static String mapToString(final ReplacePathToMacroMap replacePathMap) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
|
||||
final List<String> pathIndex = replacePathMap.getPathIndex();
|
||||
for (String s : pathIndex) {
|
||||
if (buf.length() > 0) buf.append("\n");
|
||||
buf.append(s);
|
||||
buf.append(" -> ");
|
||||
buf.append(replacePathMap.get(s));
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
+212
-220
@@ -1,220 +1,212 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
*/
|
||||
package com.intellij.application.options;
|
||||
|
||||
import com.intellij.openapi.components.PathMacroMap;
|
||||
import com.intellij.openapi.components.impl.BasePathMacroManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 6, 2004
|
||||
*/
|
||||
public class ReplacePathToMacroMap extends PathMacroMap {
|
||||
private List<String> myPathsIndex = null;
|
||||
|
||||
private static final Comparator<Map.Entry<String, String>> PATHS_COMPARATOR = new Comparator<Map.Entry<String, String>>() {
|
||||
public int compare(final Map.Entry<String, String> o1, final Map.Entry<String, String> o2) {
|
||||
int idx1 = getIndex(o1);
|
||||
int idx2 = getIndex(o2);
|
||||
|
||||
if (idx1 != idx2) return idx1 - idx2;
|
||||
|
||||
return stripPrefix(o2.getKey()).length() - stripPrefix(o1.getKey()).length();
|
||||
}
|
||||
|
||||
private int getIndex(final Map.Entry<String, String> s) {
|
||||
final String replacement = s.getValue();
|
||||
if (replacement.indexOf("..") >= 0) return 3;
|
||||
if (replacement.indexOf("$" + PathMacrosImpl.USER_HOME_MACRO_NAME + "$") >= 0) return 3;
|
||||
|
||||
if (replacement.indexOf("$" + PathMacrosImpl.MODULE_DIR_MACRO_NAME + "$") >= 0) return 1;
|
||||
if (replacement.indexOf("$" + PathMacrosImpl.PROJECT_DIR_MACRO_NAME + "$") >= 0) return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
private String stripPrefix(String key) {
|
||||
key = StringUtil.trimStart(key, "jar:");
|
||||
key = StringUtil.trimStart(key, "file:");
|
||||
while (key.startsWith("/")) {
|
||||
key = key.substring(1);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@NonNls private static final String[] PROTOCOLS = new String[]{"file", "jar"};
|
||||
|
||||
public void addMacroReplacement(String path, String macroName) {
|
||||
final String p = quotePath(path);
|
||||
final String m = "$" + macroName + "$";
|
||||
|
||||
if (BasePathMacroManager.DEBUG) {
|
||||
System.out.println("BasePathMacroManager.addFileHierarchyReplacements");
|
||||
System.out.println("path = " + p);
|
||||
System.out.println("macro = " + macroName);
|
||||
}
|
||||
|
||||
|
||||
put(p, m);
|
||||
for (String protocol : PROTOCOLS) {
|
||||
put(protocol + ":" + p, protocol + ":" + m);
|
||||
put(protocol + ":/" + p, protocol + "://" + m);
|
||||
put(protocol + "://" + p, protocol + "://" + m);
|
||||
}
|
||||
}
|
||||
|
||||
public String substitute(String text, boolean caseSensitive) {
|
||||
if (text == null) return null;
|
||||
for (final String path : getPathIndex()) {
|
||||
final String macro = get(path);
|
||||
text = replacePathMacro(text, path, macro, caseSensitive);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static String replacePathMacro(String text,
|
||||
String path,
|
||||
final String macro,
|
||||
boolean caseSensitive) {
|
||||
if (text.length() < path.length() || path.length() == 0) {
|
||||
return text;
|
||||
}
|
||||
|
||||
boolean startsWith;
|
||||
|
||||
if (caseSensitive) {
|
||||
startsWith = text.startsWith(path);
|
||||
}
|
||||
else {
|
||||
startsWith = StringUtil.startsWithIgnoreCase(text, path);
|
||||
}
|
||||
|
||||
if (!startsWith) return text;
|
||||
|
||||
final StringBuilder newText = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
//check that this is complete path (ends with "/" or "!/")
|
||||
// do not collapse partial paths, i.e. do not substitute "/a/b/cd" in paths like "/a/b/cdef"
|
||||
int endOfOccurence = path.length();
|
||||
final boolean isWindowsRoot = path.endsWith(":/");
|
||||
if (!isWindowsRoot &&
|
||||
endOfOccurence < text.length() &&
|
||||
text.charAt(endOfOccurence) != '/' &&
|
||||
!text.substring(endOfOccurence).startsWith("!/")) {
|
||||
return text;
|
||||
}
|
||||
|
||||
newText.append(macro);
|
||||
newText.append(text.substring(endOfOccurence));
|
||||
|
||||
return newText.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(newText);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String substituteRecursively(String text, final boolean caseSensitive) {
|
||||
for (final String path : getPathIndex()) {
|
||||
final String macro = get(path);
|
||||
text = replacePathMacroRecursively(text, path, macro, caseSensitive);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static String replacePathMacroRecursively(String text,
|
||||
String path,
|
||||
final String macro,
|
||||
boolean caseSensitive) {
|
||||
if (text.length() < path.length()) {
|
||||
return text;
|
||||
}
|
||||
|
||||
if (path.length() == 0) return text;
|
||||
|
||||
final StringBuilder newText = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
final boolean isWindowsRoot = path.endsWith(":/");
|
||||
int i = 0;
|
||||
while (i < text.length()) {
|
||||
int occurrenceOfPath = caseSensitive ? text.indexOf(path, i) : StringUtil.indexOfIgnoreCase(text, path, i);
|
||||
if (occurrenceOfPath >= 0) {
|
||||
int endOfOccurence = occurrenceOfPath + path.length();
|
||||
if (!isWindowsRoot &&
|
||||
endOfOccurence < text.length() &&
|
||||
text.charAt(endOfOccurence) != '/' &&
|
||||
text.charAt(endOfOccurence) != '\"' &&
|
||||
text.charAt(endOfOccurence) != ' ' &&
|
||||
!text.substring(endOfOccurence).startsWith("!/")) {
|
||||
newText.append(text.substring(i, endOfOccurence));
|
||||
i = endOfOccurence;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (occurrenceOfPath < 0) {
|
||||
if (newText.length() == 0) {
|
||||
return text;
|
||||
}
|
||||
newText.append(text.substring(i));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
newText.append(text.substring(i, occurrenceOfPath));
|
||||
newText.append(macro);
|
||||
i = occurrenceOfPath + path.length();
|
||||
}
|
||||
}
|
||||
return newText.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(newText);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getPathIndex() {
|
||||
if (myPathsIndex == null || myPathsIndex.size() != size()) {
|
||||
|
||||
final Set<Map.Entry<String, String>> entrySet = entries();
|
||||
Map.Entry<String, String>[] entries = entrySet.toArray(new Map.Entry[entrySet.size()]);
|
||||
ContainerUtil.sort(entries, PATHS_COMPARATOR);
|
||||
myPathsIndex = new ArrayList<String>(entries.length);
|
||||
|
||||
for (Map.Entry<String, String> entry : entries) {
|
||||
myPathsIndex.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
return myPathsIndex;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
if (!(obj instanceof ReplacePathToMacroMap)) return false;
|
||||
|
||||
return myMacroMap.equals(((ReplacePathToMacroMap)obj).myMacroMap);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myMacroMap.hashCode();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
*/
|
||||
package com.intellij.application.options;
|
||||
|
||||
import com.intellij.openapi.components.PathMacroMap;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 6, 2004
|
||||
*/
|
||||
public class ReplacePathToMacroMap extends PathMacroMap {
|
||||
private List<String> myPathsIndex = null;
|
||||
|
||||
@NonNls private static final String[] PROTOCOLS = new String[]{"file", "jar"};
|
||||
|
||||
public void addMacroReplacement(String path, String macroName) {
|
||||
final String p = quotePath(path);
|
||||
final String m = "$" + macroName + "$";
|
||||
|
||||
put(p, m);
|
||||
for (String protocol : PROTOCOLS) {
|
||||
put(protocol + ":" + p, protocol + ":" + m);
|
||||
put(protocol + ":/" + p, protocol + "://" + m);
|
||||
put(protocol + "://" + p, protocol + "://" + m);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String substitute(String text, boolean caseSensitive) {
|
||||
if (text == null) return null;
|
||||
for (final String path : getPathIndex()) {
|
||||
final String macro = get(path);
|
||||
text = replacePathMacro(text, path, macro, caseSensitive);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static String replacePathMacro(String text,
|
||||
String path,
|
||||
final String macro,
|
||||
boolean caseSensitive) {
|
||||
if (text.length() < path.length() || path.length() == 0) {
|
||||
return text;
|
||||
}
|
||||
|
||||
boolean startsWith;
|
||||
|
||||
if (caseSensitive) {
|
||||
startsWith = text.startsWith(path);
|
||||
}
|
||||
else {
|
||||
startsWith = StringUtil.startsWithIgnoreCase(text, path);
|
||||
}
|
||||
|
||||
if (!startsWith) return text;
|
||||
|
||||
final StringBuilder newText = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
//check that this is complete path (ends with "/" or "!/")
|
||||
// do not collapse partial paths, i.e. do not substitute "/a/b/cd" in paths like "/a/b/cdef"
|
||||
int endOfOccurence = path.length();
|
||||
final boolean isWindowsRoot = path.endsWith(":/");
|
||||
if (!isWindowsRoot &&
|
||||
endOfOccurence < text.length() &&
|
||||
text.charAt(endOfOccurence) != '/' &&
|
||||
!text.substring(endOfOccurence).startsWith("!/")) {
|
||||
return text;
|
||||
}
|
||||
|
||||
newText.append(macro);
|
||||
newText.append(text.substring(endOfOccurence));
|
||||
|
||||
return newText.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(newText);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String substituteRecursively(String text, final boolean caseSensitive) {
|
||||
for (final String path : getPathIndex()) {
|
||||
final String macro = get(path);
|
||||
text = replacePathMacroRecursively(text, path, macro, caseSensitive);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static String replacePathMacroRecursively(String text,
|
||||
String path,
|
||||
final String macro,
|
||||
boolean caseSensitive) {
|
||||
if (text.length() < path.length()) {
|
||||
return text;
|
||||
}
|
||||
|
||||
if (path.length() == 0) return text;
|
||||
|
||||
final StringBuilder newText = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
final boolean isWindowsRoot = path.endsWith(":/");
|
||||
int i = 0;
|
||||
while (i < text.length()) {
|
||||
int occurrenceOfPath = caseSensitive ? text.indexOf(path, i) : StringUtil.indexOfIgnoreCase(text, path, i);
|
||||
if (occurrenceOfPath >= 0) {
|
||||
int endOfOccurence = occurrenceOfPath + path.length();
|
||||
if (!isWindowsRoot &&
|
||||
endOfOccurence < text.length() &&
|
||||
text.charAt(endOfOccurence) != '/' &&
|
||||
text.charAt(endOfOccurence) != '\"' &&
|
||||
text.charAt(endOfOccurence) != ' ' &&
|
||||
!text.substring(endOfOccurence).startsWith("!/")) {
|
||||
newText.append(text.substring(i, endOfOccurence));
|
||||
i = endOfOccurence;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (occurrenceOfPath < 0) {
|
||||
if (newText.length() == 0) {
|
||||
return text;
|
||||
}
|
||||
newText.append(text.substring(i));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
newText.append(text.substring(i, occurrenceOfPath));
|
||||
newText.append(macro);
|
||||
i = occurrenceOfPath + path.length();
|
||||
}
|
||||
}
|
||||
return newText.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(newText);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getIndex(final Map.Entry<String, String> s) {
|
||||
final String replacement = s.getValue();
|
||||
if (replacement.contains("..")) return 1;
|
||||
if (replacement.contains("$" + PathMacrosImpl.USER_HOME_MACRO_NAME + "$")) return 1;
|
||||
if (replacement.contains("$" + PathMacrosImpl.MODULE_DIR_MACRO_NAME + "$")) return 3;
|
||||
if (replacement.contains("$" + PathMacrosImpl.PROJECT_DIR_MACRO_NAME + "$")) return 3;
|
||||
return 2;
|
||||
}
|
||||
|
||||
private static int stripPrefix(String key) {
|
||||
key = StringUtil.trimStart(key, "jar:");
|
||||
key = StringUtil.trimStart(key, "file:");
|
||||
while (key.startsWith("/")) {
|
||||
key = key.substring(1);
|
||||
}
|
||||
return key.length();
|
||||
}
|
||||
|
||||
public List<String> getPathIndex() {
|
||||
if (myPathsIndex == null || myPathsIndex.size() != size()) {
|
||||
List<Map.Entry<String, String>> entries = new ArrayList<Map.Entry<String, String>>(myMacroMap.entrySet());
|
||||
|
||||
final TObjectIntHashMap<Map.Entry<String, String>> weights = new TObjectIntHashMap<Map.Entry<String, String>>();
|
||||
for (Map.Entry<String, String> entry : entries) {
|
||||
weights.put(entry, getIndex(entry) * 512 + stripPrefix(entry.getKey()));
|
||||
}
|
||||
|
||||
ContainerUtil.sort(entries, new Comparator<Map.Entry<String, String>>() {
|
||||
public int compare(final Map.Entry<String, String> o1, final Map.Entry<String, String> o2) {
|
||||
return weights.get(o2) - weights.get(o1);
|
||||
}
|
||||
});
|
||||
myPathsIndex = ContainerUtil.map2List(entries, new Function<Map.Entry<String, String>, String>() {
|
||||
@Override
|
||||
public String fun(Map.Entry<String, String> entry) {
|
||||
return entry.getKey();
|
||||
}
|
||||
});
|
||||
}
|
||||
return myPathsIndex;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
if (!(obj instanceof ReplacePathToMacroMap)) return false;
|
||||
|
||||
return myMacroMap.equals(((ReplacePathToMacroMap)obj).myMacroMap);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myMacroMap.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class ExpandMacroToPathMap extends PathMacroMap {
|
||||
|
||||
public String substitute(String text, boolean caseSensitive) {
|
||||
if (text == null) return null;
|
||||
for (Map.Entry<String, String> entry : entries()) {
|
||||
for (Map.Entry<String, String> entry : myMacroMap.entrySet()) {
|
||||
// when replacing macros with actual paths the replace utility may be used as always 'case-sensitive'
|
||||
// for case-insensitive file systems there will be no unnecesary toLowerCase() transforms.
|
||||
text = StringUtil.replace(text, entry.getKey(), entry.getValue(), false);
|
||||
|
||||
@@ -105,10 +105,6 @@ public abstract class PathMacroMap {
|
||||
return myMacroMap.size();
|
||||
}
|
||||
|
||||
protected Set<Map.Entry<String, String>> entries() {
|
||||
return myMacroMap.entrySet();
|
||||
}
|
||||
|
||||
protected Set<String> keySet() {
|
||||
return myMacroMap.keySet();
|
||||
}
|
||||
|
||||
+249
-259
@@ -1,259 +1,249 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
*/
|
||||
package com.intellij.openapi.components.impl;
|
||||
|
||||
import com.intellij.application.options.PathMacrosImpl;
|
||||
import com.intellij.application.options.ReplacePathToMacroMap;
|
||||
import com.intellij.openapi.application.PathMacros;
|
||||
import com.intellij.openapi.components.ExpandMacroToPathMap;
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.StandardFileSystems;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BasePathMacroManager extends PathMacroManager {
|
||||
public static boolean DEBUG = false;
|
||||
private PathMacrosImpl myPathMacros;
|
||||
|
||||
public BasePathMacroManager(@Nullable PathMacros pathMacros) {
|
||||
myPathMacros = (PathMacrosImpl)pathMacros;
|
||||
}
|
||||
|
||||
protected static void addFileHierarchyReplacements(ExpandMacroToPathMap result, String macroName, @Nullable String path) {
|
||||
if (path == null) return;
|
||||
addFileHierarchyReplacements(result, getLocalFileSystem().findFileByPath(path), "$" + macroName + "$");
|
||||
}
|
||||
|
||||
private static void addFileHierarchyReplacements(ExpandMacroToPathMap result, @Nullable VirtualFile f, String macro) {
|
||||
if (f == null) return;
|
||||
addFileHierarchyReplacements(result, f.getParent(), macro + "/..");
|
||||
|
||||
final String path = FileUtil.toSystemIndependentName(f.getCanonicalPath());
|
||||
if (StringUtil.endsWithChar(path, '/')) {
|
||||
result.put(macro + "/", path);
|
||||
result.put(macro, path.substring(0, path.length()-1));
|
||||
}
|
||||
else {
|
||||
result.put(macro, path);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void addFileHierarchyReplacements(ReplacePathToMacroMap result, String macroName, @Nullable String path, @Nullable String stopAt) {
|
||||
if (path == null) return;
|
||||
|
||||
String macro = "$" + macroName + "$";
|
||||
if (DEBUG) {
|
||||
System.out.println("BasePathMacroManager.addFileHierarchyReplacements");
|
||||
System.out.println("macroName = " + macroName);
|
||||
}
|
||||
path = StringUtil.trimEnd(FileUtil.toSystemIndependentName(path), "/");
|
||||
boolean check = false;
|
||||
while (StringUtil.isNotEmpty(path) && path.contains("/")) {
|
||||
if (DEBUG) {
|
||||
System.out.println("path = " + path);
|
||||
System.out.println("macro = " + macro);
|
||||
}
|
||||
|
||||
putIfAbsent(result, "file:" + path, "file:" + macro, check);
|
||||
putIfAbsent(result, "file:/" + path, "file:/" + macro, check);
|
||||
putIfAbsent(result, "file://" + path, "file://" + macro, check);
|
||||
putIfAbsent(result, "jar:" + path, "jar:" + macro, check);
|
||||
putIfAbsent(result, "jar:/" + path, "jar:/" + macro, check);
|
||||
putIfAbsent(result, "jar://" + path, "jar://" + macro, check);
|
||||
if (!path.equalsIgnoreCase("e:/") && !path.equalsIgnoreCase("r:/") && !path.equalsIgnoreCase("p:/")) {
|
||||
putIfAbsent(result, path, macro, check);
|
||||
}
|
||||
|
||||
if (path.equals(stopAt)) {
|
||||
break;
|
||||
}
|
||||
|
||||
macro += "/..";
|
||||
check = true;
|
||||
path = StringUtil.getPackageName(path, '/');
|
||||
}
|
||||
}
|
||||
|
||||
private static VirtualFileSystem getLocalFileSystem() {
|
||||
// Use VFM directly because of mocks in tests.
|
||||
return VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL);
|
||||
}
|
||||
|
||||
private static void putIfAbsent(final ReplacePathToMacroMap result,
|
||||
@NonNls final String pathWithPrefix,
|
||||
@NonNls final String substitutionWithPrefix,
|
||||
final boolean check) {
|
||||
if (check && result.get(pathWithPrefix) != null)
|
||||
return;
|
||||
|
||||
if (StringUtil.endsWithChar(pathWithPrefix, '/')) {
|
||||
result.put(pathWithPrefix, substitutionWithPrefix + "/");
|
||||
result.put(pathWithPrefix.substring(0, pathWithPrefix.length()-1), substitutionWithPrefix);
|
||||
}
|
||||
else {
|
||||
result.put(pathWithPrefix, substitutionWithPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
protected ExpandMacroToPathMap getExpandMacroMap() {
|
||||
ExpandMacroToPathMap result = new ExpandMacroToPathMap();
|
||||
for (Map.Entry<String, String> entry : PathMacrosImpl.getGlobalSystemMacros().entrySet()) {
|
||||
result.addMacroExpand(entry.getKey(), entry.getValue());
|
||||
}
|
||||
getPathMacros().addMacroExpands(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected ReplacePathToMacroMap getReplacePathMap() {
|
||||
ReplacePathToMacroMap result = new ReplacePathToMacroMap();
|
||||
for (Map.Entry<String, String> entry : PathMacrosImpl.getGlobalSystemMacros().entrySet()) {
|
||||
result.addMacroReplacement(entry.getValue(), entry.getKey());
|
||||
}
|
||||
getPathMacros().addMacroReplacements(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public TrackingPathMacroSubstitutor createTrackingSubstitutor() {
|
||||
return new MyTrackingPathMacroSubstitutor();
|
||||
}
|
||||
|
||||
public String expandPath(final String path) {
|
||||
return getExpandMacroMap().substitute(path, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public String collapsePath(final String path) {
|
||||
return getReplacePathMap().substitute(path, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public void collapsePathsRecursively(final Element element) {
|
||||
getReplacePathMap().substitute(element, SystemInfo.isFileSystemCaseSensitive, true);
|
||||
}
|
||||
|
||||
public void expandPaths(final Element element) {
|
||||
getExpandMacroMap().substitute(element, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public void collapsePaths(final Element element) {
|
||||
getReplacePathMap().substitute(element, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public PathMacrosImpl getPathMacros() {
|
||||
if (myPathMacros == null) {
|
||||
myPathMacros = PathMacrosImpl.getInstanceEx();
|
||||
}
|
||||
|
||||
return myPathMacros;
|
||||
}
|
||||
|
||||
private class MyTrackingPathMacroSubstitutor implements TrackingPathMacroSubstitutor {
|
||||
private final Map<String, Set<String>> myMacroToComponentNames = new FactoryMap<String, Set<String>>() {
|
||||
@Override
|
||||
protected Set<String> create(String key) {
|
||||
return new HashSet<String>();
|
||||
}
|
||||
};
|
||||
|
||||
private final Map<String, Set<String>> myComponentNameToMacros = new FactoryMap<String, Set<String>>() {
|
||||
@Override
|
||||
protected Set<String> create(String key) {
|
||||
return new HashSet<String>();
|
||||
}
|
||||
};
|
||||
|
||||
public MyTrackingPathMacroSubstitutor() {
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
myMacroToComponentNames.clear();
|
||||
myComponentNameToMacros.clear();
|
||||
}
|
||||
|
||||
public String expandPath(final String path) {
|
||||
return getExpandMacroMap().substitute(path, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public String collapsePath(final String path) {
|
||||
return getReplacePathMap().substitute(path, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public void expandPaths(final Element element) {
|
||||
getExpandMacroMap().substitute(element, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public void collapsePaths(final Element element) {
|
||||
getReplacePathMap().substitute(element, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getExpandMacroMap().hashCode();
|
||||
}
|
||||
|
||||
public void invalidateUnknownMacros(final Set<String> macros) {
|
||||
for (final String macro : macros) {
|
||||
final Set<String> components = myMacroToComponentNames.get(macro);
|
||||
for (final String component : components) {
|
||||
myComponentNameToMacros.remove(component);
|
||||
}
|
||||
|
||||
myMacroToComponentNames.remove(macro);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<String> getComponents(final Collection<String> macros) {
|
||||
final Set<String> result = new HashSet<String>();
|
||||
for (String macro : myMacroToComponentNames.keySet()) {
|
||||
if (macros.contains(macro)) {
|
||||
result.addAll(myMacroToComponentNames.get(macro));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<String> getUnknownMacros(final String componentName) {
|
||||
final Set<String> result = new HashSet<String>();
|
||||
result.addAll(componentName == null ? myMacroToComponentNames.keySet() : myComponentNameToMacros.get(componentName));
|
||||
return Collections.unmodifiableCollection(result);
|
||||
}
|
||||
|
||||
public void addUnknownMacros(final String componentName, final Collection<String> unknownMacros) {
|
||||
if (unknownMacros.isEmpty()) return;
|
||||
|
||||
for (String unknownMacro : unknownMacros) {
|
||||
final Set<String> stringList = myMacroToComponentNames.get(unknownMacro);
|
||||
stringList.add(componentName);
|
||||
}
|
||||
|
||||
myComponentNameToMacros.get(componentName).addAll(unknownMacros);
|
||||
}
|
||||
}
|
||||
|
||||
protected static boolean pathsEqual(@Nullable String path1, @Nullable String path2) {
|
||||
return path1 != null && path2 != null &&
|
||||
FileUtil.pathsEqual(FileUtil.toSystemIndependentName(path1), FileUtil.toSystemIndependentName(path2));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
*/
|
||||
package com.intellij.openapi.components.impl;
|
||||
|
||||
import com.intellij.application.options.PathMacrosImpl;
|
||||
import com.intellij.application.options.ReplacePathToMacroMap;
|
||||
import com.intellij.openapi.application.PathMacros;
|
||||
import com.intellij.openapi.components.ExpandMacroToPathMap;
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.StandardFileSystems;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BasePathMacroManager extends PathMacroManager {
|
||||
private PathMacrosImpl myPathMacros;
|
||||
|
||||
public BasePathMacroManager(@Nullable PathMacros pathMacros) {
|
||||
myPathMacros = (PathMacrosImpl)pathMacros;
|
||||
}
|
||||
|
||||
protected static void addFileHierarchyReplacements(ExpandMacroToPathMap result, String macroName, @Nullable String path) {
|
||||
if (path == null) return;
|
||||
addFileHierarchyReplacements(result, getLocalFileSystem().findFileByPath(path), "$" + macroName + "$");
|
||||
}
|
||||
|
||||
private static void addFileHierarchyReplacements(ExpandMacroToPathMap result, @Nullable VirtualFile f, String macro) {
|
||||
if (f == null) return;
|
||||
addFileHierarchyReplacements(result, f.getParent(), macro + "/..");
|
||||
|
||||
final String path = FileUtil.toSystemIndependentName(f.getCanonicalPath());
|
||||
if (StringUtil.endsWithChar(path, '/')) {
|
||||
result.put(macro + "/", path);
|
||||
result.put(macro, path.substring(0, path.length()-1));
|
||||
}
|
||||
else {
|
||||
result.put(macro, path);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void addFileHierarchyReplacements(ReplacePathToMacroMap result, String macroName, @Nullable String path, @Nullable String stopAt) {
|
||||
if (path == null) return;
|
||||
|
||||
String macro = "$" + macroName + "$";
|
||||
path = StringUtil.trimEnd(FileUtil.toSystemIndependentName(path), "/");
|
||||
boolean check = false;
|
||||
while (StringUtil.isNotEmpty(path) && path.contains("/")) {
|
||||
putIfAbsent(result, "file:" + path, "file:" + macro, check);
|
||||
putIfAbsent(result, "file:/" + path, "file:/" + macro, check);
|
||||
putIfAbsent(result, "file://" + path, "file://" + macro, check);
|
||||
putIfAbsent(result, "jar:" + path, "jar:" + macro, check);
|
||||
putIfAbsent(result, "jar:/" + path, "jar:/" + macro, check);
|
||||
putIfAbsent(result, "jar://" + path, "jar://" + macro, check);
|
||||
if (!path.equalsIgnoreCase("e:/") && !path.equalsIgnoreCase("r:/") && !path.equalsIgnoreCase("p:/")) {
|
||||
putIfAbsent(result, path, macro, check);
|
||||
}
|
||||
|
||||
if (path.equals(stopAt)) {
|
||||
break;
|
||||
}
|
||||
|
||||
macro += "/..";
|
||||
check = true;
|
||||
path = StringUtil.getPackageName(path, '/');
|
||||
}
|
||||
}
|
||||
|
||||
private static VirtualFileSystem getLocalFileSystem() {
|
||||
// Use VFM directly because of mocks in tests.
|
||||
return VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL);
|
||||
}
|
||||
|
||||
private static void putIfAbsent(final ReplacePathToMacroMap result,
|
||||
@NonNls final String pathWithPrefix,
|
||||
@NonNls final String substitutionWithPrefix,
|
||||
final boolean check) {
|
||||
if (check && result.get(pathWithPrefix) != null)
|
||||
return;
|
||||
|
||||
if (StringUtil.endsWithChar(pathWithPrefix, '/')) {
|
||||
result.put(pathWithPrefix, substitutionWithPrefix + "/");
|
||||
result.put(pathWithPrefix.substring(0, pathWithPrefix.length()-1), substitutionWithPrefix);
|
||||
}
|
||||
else {
|
||||
result.put(pathWithPrefix, substitutionWithPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
protected ExpandMacroToPathMap getExpandMacroMap() {
|
||||
ExpandMacroToPathMap result = new ExpandMacroToPathMap();
|
||||
for (Map.Entry<String, String> entry : PathMacrosImpl.getGlobalSystemMacros().entrySet()) {
|
||||
result.addMacroExpand(entry.getKey(), entry.getValue());
|
||||
}
|
||||
getPathMacros().addMacroExpands(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected ReplacePathToMacroMap getReplacePathMap() {
|
||||
ReplacePathToMacroMap result = new ReplacePathToMacroMap();
|
||||
for (Map.Entry<String, String> entry : PathMacrosImpl.getGlobalSystemMacros().entrySet()) {
|
||||
result.addMacroReplacement(entry.getValue(), entry.getKey());
|
||||
}
|
||||
getPathMacros().addMacroReplacements(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public TrackingPathMacroSubstitutor createTrackingSubstitutor() {
|
||||
return new MyTrackingPathMacroSubstitutor();
|
||||
}
|
||||
|
||||
public String expandPath(final String path) {
|
||||
return getExpandMacroMap().substitute(path, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public String collapsePath(final String path) {
|
||||
return getReplacePathMap().substitute(path, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public void collapsePathsRecursively(final Element element) {
|
||||
getReplacePathMap().substitute(element, SystemInfo.isFileSystemCaseSensitive, true);
|
||||
}
|
||||
|
||||
public void expandPaths(final Element element) {
|
||||
getExpandMacroMap().substitute(element, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public void collapsePaths(final Element element) {
|
||||
getReplacePathMap().substitute(element, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public PathMacrosImpl getPathMacros() {
|
||||
if (myPathMacros == null) {
|
||||
myPathMacros = PathMacrosImpl.getInstanceEx();
|
||||
}
|
||||
|
||||
return myPathMacros;
|
||||
}
|
||||
|
||||
private class MyTrackingPathMacroSubstitutor implements TrackingPathMacroSubstitutor {
|
||||
private final Map<String, Set<String>> myMacroToComponentNames = new FactoryMap<String, Set<String>>() {
|
||||
@Override
|
||||
protected Set<String> create(String key) {
|
||||
return new HashSet<String>();
|
||||
}
|
||||
};
|
||||
|
||||
private final Map<String, Set<String>> myComponentNameToMacros = new FactoryMap<String, Set<String>>() {
|
||||
@Override
|
||||
protected Set<String> create(String key) {
|
||||
return new HashSet<String>();
|
||||
}
|
||||
};
|
||||
|
||||
public MyTrackingPathMacroSubstitutor() {
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
myMacroToComponentNames.clear();
|
||||
myComponentNameToMacros.clear();
|
||||
}
|
||||
|
||||
public String expandPath(final String path) {
|
||||
return getExpandMacroMap().substitute(path, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public String collapsePath(final String path) {
|
||||
return getReplacePathMap().substitute(path, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public void expandPaths(final Element element) {
|
||||
getExpandMacroMap().substitute(element, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public void collapsePaths(final Element element) {
|
||||
getReplacePathMap().substitute(element, SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getExpandMacroMap().hashCode();
|
||||
}
|
||||
|
||||
public void invalidateUnknownMacros(final Set<String> macros) {
|
||||
for (final String macro : macros) {
|
||||
final Set<String> components = myMacroToComponentNames.get(macro);
|
||||
for (final String component : components) {
|
||||
myComponentNameToMacros.remove(component);
|
||||
}
|
||||
|
||||
myMacroToComponentNames.remove(macro);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<String> getComponents(final Collection<String> macros) {
|
||||
final Set<String> result = new HashSet<String>();
|
||||
for (String macro : myMacroToComponentNames.keySet()) {
|
||||
if (macros.contains(macro)) {
|
||||
result.addAll(myMacroToComponentNames.get(macro));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<String> getUnknownMacros(final String componentName) {
|
||||
final Set<String> result = new HashSet<String>();
|
||||
result.addAll(componentName == null ? myMacroToComponentNames.keySet() : myComponentNameToMacros.get(componentName));
|
||||
return Collections.unmodifiableCollection(result);
|
||||
}
|
||||
|
||||
public void addUnknownMacros(final String componentName, final Collection<String> unknownMacros) {
|
||||
if (unknownMacros.isEmpty()) return;
|
||||
|
||||
for (String unknownMacro : unknownMacros) {
|
||||
final Set<String> stringList = myMacroToComponentNames.get(unknownMacro);
|
||||
stringList.add(componentName);
|
||||
}
|
||||
|
||||
myComponentNameToMacros.get(componentName).addAll(unknownMacros);
|
||||
}
|
||||
}
|
||||
|
||||
protected static boolean pathsEqual(@Nullable String path1, @Nullable String path2) {
|
||||
return path1 != null && path2 != null &&
|
||||
FileUtil.pathsEqual(FileUtil.toSystemIndependentName(path1), FileUtil.toSystemIndependentName(path2));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user