2 * Copyright 2000-2011 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.internal.statistic.beans;
19 import com.intellij.util.containers.hash.HashMap;
24 * ATTENTION! DO NOT IMPORT @NotNull AND @Nullable ANNOTATIONS
25 * This class is also used on jetbrains web site
28 public class ConvertUsagesUtil {
29 private static final char GROUP_SEPARATOR = ':';
30 private static final char GROUPS_SEPARATOR = ';';
31 private static final char GROUP_VALUE_SEPARATOR = ',';
33 private ConvertUsagesUtil() {
38 public static <T extends UsageDescriptor> String convertUsages(Map<GroupDescriptor, Set<T>> map) {
40 final Map<GroupDescriptor, Set<T>> sortedMap = sortDescriptorsByPriority(map);
42 StringBuffer buffer = new StringBuffer();
43 for (Map.Entry<GroupDescriptor, Set<T>> entry : sortedMap.entrySet()) {
44 buffer.append(entry.getKey().getId());
45 buffer.append(GROUP_SEPARATOR);
46 buffer.append(convertValueMap(entry.getValue()));
47 buffer.append(GROUPS_SEPARATOR);
50 return buffer.toString();
54 public static String convertValueMap(Set<? extends UsageDescriptor> descriptors) {
55 assert descriptors != null;
56 final StringBuffer buffer = new StringBuffer();
57 for (UsageDescriptor usageDescriptor : descriptors) {
58 buffer.append(usageDescriptor.getKey());
60 buffer.append(usageDescriptor.getValue());
61 buffer.append(GROUP_VALUE_SEPARATOR);
63 buffer.deleteCharAt(buffer.length() - 1);
65 return buffer.toString();
69 public static String cutPatchString(String patchStr, int maxSize) {
70 assert patchStr != null;
71 for (int i = maxSize - 1; i >= 0; i--) {
72 final char c = patchStr.charAt(i);
73 if (c == GROUPS_SEPARATOR || c == GROUP_VALUE_SEPARATOR) {
74 return patchStr.substring(0, i);
81 public static Map<GroupDescriptor, Set<UsageDescriptor>> convertString(String usages) {
82 assert usages != null;
83 Map<GroupDescriptor, Set<UsageDescriptor>> descriptors = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
84 for (String groupStr : usages.split(Character.toString(GROUPS_SEPARATOR))) {
85 if (!isEmptyOrSpaces(groupStr)) {
86 final StringPair group = getPair(groupStr, Character.toString(GROUP_SEPARATOR));
88 final String groupId = group.first;
89 assert groupId != null;
90 if (groupId.length() < GroupDescriptor.MAX_ID_LENGTH) {
91 descriptors.putAll(convertValueString(GroupDescriptor.create(groupId), group.second));
100 public static Map<GroupDescriptor, Set<UsageDescriptor>> convertValueString(GroupDescriptor groupId, String valueData) {
101 assert groupId != null;
102 final Map<GroupDescriptor, Set<UsageDescriptor>> descriptors = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
103 for (String value : valueData.split(Character.toString(GROUP_VALUE_SEPARATOR))) {
104 if (!isEmptyOrSpaces(value)) {
105 final StringPair pair = getPair(value, "=");
107 final String count = pair.second;
108 if (!isEmptyOrSpaces(count)) {
110 final int i = Integer.parseInt(count);
111 if (!descriptors.containsKey(groupId)) {
112 descriptors.put(groupId, new LinkedHashSet<UsageDescriptor>());
114 descriptors.get(groupId).add(new UsageDescriptor(pair.first, i));
116 catch (NumberFormatException ignored) {
127 public static StringPair getPair(String str, String separator) {
129 assert separator != null;
130 final int i = str.indexOf(separator);
131 if (i > 0 && i < str.length() - 1) {
132 String key = str.substring(0, i).trim();
133 String value = str.substring(i + 1).trim();
134 if (!isEmptyOrSpaces(key) && !isEmptyOrSpaces(value)) {
135 return new StringPair(key, value);
142 public static <T extends UsageDescriptor> Map<GroupDescriptor, Set<T>> sortDescriptorsByPriority(Map<GroupDescriptor, Set<T>> descriptors) {
143 assert descriptors != null;
144 final SortedMap<GroupDescriptor, Set<T>> map = new TreeMap<GroupDescriptor, Set<T>>(new Comparator<GroupDescriptor>() {
145 public int compare(GroupDescriptor g1, GroupDescriptor g2) {
146 final int priority = (int)(g2.getPriority() - g1.getPriority());
147 return priority == 0 ? g1.getId().compareTo(g2.getId()) : priority;
151 map.putAll(descriptors);
156 private static class StringPair {
157 public final String first;
158 public final String second;
160 public StringPair(String first, String second) {
162 this.second = second;
166 public static boolean isEmptyOrSpaces(final String s) {
167 return s == null || s.trim().length() == 0;
170 public static void assertDescriptorName(String key) {
172 assert key.indexOf(GROUP_SEPARATOR) == -1 : key + " contains invalid chars";
173 assert key.indexOf(GROUPS_SEPARATOR) == -1 : key + " contains invalid chars";
174 assert key.indexOf(GROUP_VALUE_SEPARATOR) == -1 : key + " contains invalid chars";
175 assert !key.contains("=") : key + " contains invalid chars";
176 assert !key.contains("'") : key + " contains invalid chars";
177 assert !key.contains("\"") : key + " contains invalid chars";
181 public static String ensureProperKey(/*@NotNull*/ String input) {
182 final StringBuilder escaped = new StringBuilder();
183 for (int i = 0; i < input.length(); i++) {
184 final char ch = input.charAt(i);
186 case GROUP_SEPARATOR:
187 case GROUPS_SEPARATOR:
188 case GROUP_VALUE_SEPARATOR:
199 return escaped.toString();