| /* |
| * 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; |
| |
| import com.intellij.openapi.util.TextRange; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.util.containers.ContainerUtil; |
| import com.intellij.util.containers.ContainerUtilRt; |
| |
| import java.util.Map; |
| |
| /** |
| * @author Eugene Zhuravlev |
| * Date: Dec 6, 2004 |
| */ |
| public class ExpandMacroToPathMap extends PathMacroMap { |
| private final Map<String, String> myPlainMap = ContainerUtilRt.newLinkedHashMap(); |
| private final Map<String, String> myMacroExpands = ContainerUtil.newHashMap(); |
| |
| public void addMacroExpand(String macroName, String path) { |
| myMacroExpands.put(macroName, PathMacroMap.quotePath(path)); |
| } |
| |
| public void put(String fromText, String toText) { |
| myPlainMap.put(fromText, toText); |
| } |
| |
| public void putAll(ExpandMacroToPathMap another) { |
| myPlainMap.putAll(another.myPlainMap); |
| myMacroExpands.putAll(another.myMacroExpands); |
| } |
| |
| public String substitute(String text, boolean caseSensitive) { |
| if (text == null) { |
| //noinspection ConstantConditions |
| return null; |
| } |
| |
| if (text.indexOf('$') < 0 && text.indexOf('%') < 0) { |
| return text; |
| } |
| |
| for (Map.Entry<String, String> entry : myPlainMap.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 unnecessary toLowerCase() transforms. |
| text = StringUtil.replace(text, entry.getKey(), entry.getValue(), false); |
| } |
| |
| for (String macroName : myMacroExpands.keySet()) { |
| text = replaceMacro(text, macroName, myMacroExpands.get(macroName)); |
| } |
| |
| return text; |
| } |
| |
| private static String replaceMacro(String text, String macroName, String replacement) { |
| while (true) { |
| int start = findMacroIndex(text, macroName); |
| if (start < 0) { |
| break; |
| } |
| |
| int end = start + macroName.length() + 2; |
| int slashCount = getSlashCount(text, end); |
| String actualReplacement = slashCount > 0 && !replacement.endsWith("/") ? replacement + "/" : replacement; |
| text = StringUtil.replaceSubstring(text, new TextRange(start, end + slashCount), actualReplacement); |
| } |
| return text; |
| } |
| |
| private static int getSlashCount(String text, int pos) { |
| return StringUtil.isChar(text, pos, '/') ? StringUtil.isChar(text, pos + 1, '/') ? 2 : 1 : 0; |
| } |
| |
| private static int findMacroIndex(String text, String macroName) { |
| int i = -1; |
| while (true) { |
| i = text.indexOf('$', i + 1); |
| if (i < 0) { |
| return -1; |
| } |
| if (StringUtil.startsWith(text, i + 1, macroName) && StringUtil.isChar(text, i + macroName.length() + 1, '$')) { |
| return i; |
| } |
| } |
| } |
| |
| @Override |
| public int hashCode() { |
| return myPlainMap.hashCode() + myMacroExpands.hashCode(); |
| } |
| } |