empty macros check
[fedora-idea.git] / source / com / intellij / application / options / ReplacePathToMacroMap.java
blob82ad44d9eb0030eddb41ece39c84a9d4e9a5a327
1 /*
2 * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
3 * Use is subject to license terms.
4 */
5 package com.intellij.application.options;
7 import com.intellij.openapi.components.PathMacroMap;
8 import com.intellij.openapi.util.text.StringUtil;
9 import com.intellij.util.StringBuilderSpinAllocator;
11 import java.util.*;
13 /**
14 * @author Eugene Zhuravlev
15 * Date: Dec 6, 2004
17 public class ReplacePathToMacroMap extends PathMacroMap {
18 final Set<String> myUsedMacros = new HashSet<String>();
19 List<String> myPathsIndex = null;
20 private static final Comparator<String> PATHS_COMPARATOR = new Comparator<String>() {
21 public int compare(final String o1, final String o2) {
22 return o2.length() - o1.length();
26 public void addMacroReplacement(String path, String macroName) {
27 put(quotePath(path), "$" + macroName + "$");
30 public String substitute(String text, boolean caseSensitive) {
31 for (final String path : getPathIndex()) {
32 final String macro = get(path);
33 text = replacePathMacro(text, path, macro, caseSensitive);
35 return text;
38 private String replacePathMacro(String text, String path, final String macro, boolean caseSensitive) {
39 if (text.length() < path.length()) {
40 return text;
43 if (path.length() == 0) return text;
45 final StringBuilder newText = StringBuilderSpinAllocator.alloc();
46 try {
47 final boolean isWindowsRoot = path.endsWith(":/");
48 int i = 0;
49 while (i < text.length()) {
50 int occurrenceOfPath = caseSensitive ? text.indexOf(path, i) : StringUtil.indexOfIgnoreCase(text, path, i);
51 if (occurrenceOfPath >= 0) {
52 int endOfOccurence = occurrenceOfPath + path.length();
53 if (!isWindowsRoot && endOfOccurence < text.length() && text.charAt(endOfOccurence) != '/') {
54 i = endOfOccurence;
55 continue;
58 if (occurrenceOfPath < 0) {
59 if (newText.length() == 0) {
60 return text;
62 newText.append(text.substring(i));
63 break;
65 else {
66 newText.append(text.substring(i, occurrenceOfPath));
67 newText.append(macro);
68 logUsage(macro);
69 i = occurrenceOfPath + path.length();
72 return newText.toString();
74 finally {
75 StringBuilderSpinAllocator.dispose(newText);
79 private void logUsage(String macroReplacement) {
80 if (macroReplacement.length() >= 2 && macroReplacement.startsWith("$") && macroReplacement.endsWith("$")) {
81 macroReplacement = macroReplacement.substring(1, macroReplacement.length() - 1);
83 myUsedMacros.add(macroReplacement);
86 public Set<String> getUsedMacroNames() {
87 final Set<String> userMacroNames = PathMacrosImpl.getInstanceEx().getUserMacroNames();
88 final Set<String> used = new HashSet<String>(myUsedMacros);
89 used.retainAll(userMacroNames);
90 return used;
93 private List<String> getPathIndex() {
94 if (myPathsIndex == null || myPathsIndex.size() != size()) {
95 myPathsIndex = new ArrayList<String>(keySet());
96 // sort so that lenthy paths are traversed first
97 // so from the 2 strings such that one is a substring of another the one that dominates is substituted first
98 Collections.sort(myPathsIndex, PATHS_COMPARATOR);
100 return myPathsIndex;
103 public boolean equals(Object obj) {
104 if (obj == this) return true;
105 if (!(obj instanceof ReplacePathToMacroMap)) return false;
107 return myMacroMap.equals(((ReplacePathToMacroMap)obj).myMacroMap);
110 public int hashCode() {
111 return myMacroMap.hashCode();