b28161e0e1b35d32947e82e7f9cecd62950e33ab
[idea/community.git] / platform / platform-impl / src / com / intellij / internal / statistic / beans / ConvertUsagesUtil.java
1 /*
2  * Copyright 2000-2011 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.internal.statistic.beans;
17
18
19 import com.intellij.util.containers.hash.HashMap;
20 import org.jetbrains.annotations.NotNull;
21
22 import java.util.*;
23
24 public class ConvertUsagesUtil {
25   private static final char GROUP_SEPARATOR = ':';
26   private static final char GROUPS_SEPARATOR = ';';
27   private static final char GROUP_VALUE_SEPARATOR = ',';
28
29   private ConvertUsagesUtil() {
30   }
31
32
33   // @NotNull
34   public static <T extends UsageDescriptor> String convertUsages(Map<GroupDescriptor, Set<T>> map) {
35     assert map != null;
36     final Map<GroupDescriptor, Set<T>> sortedMap = sortDescriptorsByPriority(map);
37
38     StringBuffer buffer = new StringBuffer();
39     for (Map.Entry<GroupDescriptor, Set<T>> entry : sortedMap.entrySet()) {
40       buffer.append(entry.getKey().getId());
41       buffer.append(GROUP_SEPARATOR);
42       buffer.append(convertValueMap(entry.getValue()));
43       buffer.append(GROUPS_SEPARATOR);
44     }
45
46     return buffer.toString();
47   }
48
49   //@NotNull
50   public static String convertValueMap(Set<? extends UsageDescriptor> descriptors) {
51     assert descriptors != null;
52     final StringBuffer buffer = new StringBuffer();
53     for (UsageDescriptor usageDescriptor : descriptors) {
54       buffer.append(usageDescriptor.getKey());
55       buffer.append("=");
56       buffer.append(usageDescriptor.getValue());
57       buffer.append(GROUP_VALUE_SEPARATOR);
58     }
59     buffer.deleteCharAt(buffer.length() - 1);
60
61     return buffer.toString();
62   }
63
64   //@NotNull
65   public static String cutPatchString(String patchStr, int maxSize) {
66     assert patchStr != null;
67     for (int i = maxSize - 1; i >= 0; i--) {
68       final char c = patchStr.charAt(i);
69       if (c == GROUPS_SEPARATOR || c == GROUP_VALUE_SEPARATOR) {
70         return patchStr.substring(0, i);
71       }
72     }
73     return "";
74   }
75
76   //@NotNull
77   public static Map<GroupDescriptor, Set<UsageDescriptor>> convertString(String usages) {
78     assert usages != null;
79     Map<GroupDescriptor, Set<UsageDescriptor>> descriptors = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
80     for (String groupStr : usages.split(Character.toString(GROUPS_SEPARATOR))) {
81       if (!isEmptyOrSpaces(groupStr)) {
82         final StringPair group = getPair(groupStr, Character.toString(GROUP_SEPARATOR));
83         if (group != null) {
84           final String groupId = group.first;
85           assert groupId != null;
86           if (groupId.length() < GroupDescriptor.MAX_ID_LENGTH) {
87             descriptors.putAll(convertValueString(GroupDescriptor.create(groupId), group.second));
88           }
89         }
90       }
91     }
92     return descriptors;
93   }
94
95   //@NotNull
96   public static Map<GroupDescriptor, Set<UsageDescriptor>> convertValueString(GroupDescriptor groupId, String valueData) {
97     assert groupId != null;
98     final Map<GroupDescriptor, Set<UsageDescriptor>> descriptors = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
99     for (String value : valueData.split(Character.toString(GROUP_VALUE_SEPARATOR))) {
100       if (!isEmptyOrSpaces(value)) {
101         final StringPair pair = getPair(value, "=");
102         if (pair != null) {
103           final String count = pair.second;
104           if (!isEmptyOrSpaces(count)) {
105             try {
106               final int i = Integer.parseInt(count);
107               if (!descriptors.containsKey(groupId)) {
108                 descriptors.put(groupId, new LinkedHashSet<UsageDescriptor>());
109               }
110               descriptors.get(groupId).add(new UsageDescriptor(pair.first, i));
111             }
112             catch (NumberFormatException ignored) {
113             }
114           }
115         }
116       }
117     }
118
119     return descriptors;
120   }
121
122   //@Nullable
123   public static StringPair getPair(String str, String separator) {
124     assert str != null;
125     assert separator != null;
126     final int i = str.indexOf(separator);
127     if (i > 0 && i < str.length() - 1) {
128       String key = str.substring(0, i).trim();
129       String value = str.substring(i + 1).trim();
130       if (!isEmptyOrSpaces(key) && !isEmptyOrSpaces(value)) {
131         return new StringPair(key, value);
132       }
133     }
134     return null;
135   }
136
137   //@NotNull
138   public static <T extends UsageDescriptor> Map<GroupDescriptor, Set<T>> sortDescriptorsByPriority(Map<GroupDescriptor, Set<T>> descriptors) {
139     assert descriptors != null;
140     final SortedMap<GroupDescriptor, Set<T>> map = new TreeMap<GroupDescriptor, Set<T>>(new Comparator<GroupDescriptor>() {
141       public int compare(GroupDescriptor g1, GroupDescriptor g2) {
142         final int priority = (int)(g2.getPriority() - g1.getPriority());
143         return priority == 0 ? g1.getId().compareTo(g2.getId()) : priority;
144       }
145     });
146
147     map.putAll(descriptors);
148
149     return map;
150   }
151
152   private static class StringPair {
153     public final String first;
154     public final String second;
155
156     public StringPair(String first, String second) {
157       this.first = first;
158       this.second = second;
159     }
160   }
161
162   public static boolean isEmptyOrSpaces(final String s) {
163     return s == null || s.trim().length() == 0;
164   }
165
166   public static void assertDescriptorName(String key) {
167     assert key != null;
168     assert key.indexOf(GROUP_SEPARATOR) == -1 : key + " contains invalid chars";
169     assert key.indexOf(GROUPS_SEPARATOR) == -1 : key + " contains invalid chars";
170     assert key.indexOf(GROUP_VALUE_SEPARATOR) == -1 : key + " contains invalid chars";
171     assert !key.contains("=") : key + " contains invalid chars";
172     assert !key.contains("'") : key + " contains invalid chars";
173     assert !key.contains("\"") : key + " contains invalid chars";
174   }
175
176   @NotNull
177   public static String ensureProperKey(@NotNull String input) {
178     final StringBuilder escaped = new StringBuilder();
179     for (int i = 0; i < input.length(); i++) {
180       final char ch = input.charAt(i);
181       switch (ch) {
182         case GROUP_SEPARATOR:
183         case GROUPS_SEPARATOR:
184         case GROUP_VALUE_SEPARATOR:
185         case '\'':
186         case '\"':
187         case '=':
188           escaped.append(' ');
189           break;
190         default:
191           escaped.append(ch);
192           break;
193       }
194     }
195     return escaped.toString();
196   }
197 }