6912d322fc2df783882dd5ce7f1045dab8b72ec5
[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
21 import java.util.*;
22
23 /**
24  * ATTENTION! DO NOT IMPORT @NotNull AND @Nullable ANNOTATIONS
25  * This class is also used on jetbrains web site
26  */
27
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 = ',';
32
33   private ConvertUsagesUtil() {
34   }
35
36
37   // @NotNull
38   public static <T extends UsageDescriptor> String convertUsages(Map<GroupDescriptor, Set<T>> map) {
39     assert map != null;
40     final Map<GroupDescriptor, Set<T>> sortedMap = sortDescriptorsByPriority(map);
41
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);
48     }
49
50     return buffer.toString();
51   }
52
53   //@NotNull
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());
59       buffer.append("=");
60       buffer.append(usageDescriptor.getValue());
61       buffer.append(GROUP_VALUE_SEPARATOR);
62     }
63     buffer.deleteCharAt(buffer.length() - 1);
64
65     return buffer.toString();
66   }
67
68   //@NotNull
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);
75       }
76     }
77     return "";
78   }
79
80   //@NotNull
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));
87         if (group != null) {
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));
92           }
93         }
94       }
95     }
96     return descriptors;
97   }
98
99   //@NotNull
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, "=");
106         if (pair != null) {
107           final String count = pair.second;
108           if (!isEmptyOrSpaces(count)) {
109             try {
110               final int i = Integer.parseInt(count);
111               if (!descriptors.containsKey(groupId)) {
112                 descriptors.put(groupId, new LinkedHashSet<UsageDescriptor>());
113               }
114               descriptors.get(groupId).add(new UsageDescriptor(pair.first, i));
115             }
116             catch (NumberFormatException ignored) {
117             }
118           }
119         }
120       }
121     }
122
123     return descriptors;
124   }
125
126   //@Nullable
127   public static StringPair getPair(String str, String separator) {
128     assert str != null;
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);
136       }
137     }
138     return null;
139   }
140
141   //@NotNull
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;
148       }
149     });
150
151     map.putAll(descriptors);
152
153     return map;
154   }
155
156   private static class StringPair {
157     public final String first;
158     public final String second;
159
160     public StringPair(String first, String second) {
161       this.first = first;
162       this.second = second;
163     }
164   }
165
166   public static boolean isEmptyOrSpaces(final String s) {
167     return s == null || s.trim().length() == 0;
168   }
169
170   public static void assertDescriptorName(String key) {
171     assert key != null;
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";
178   }
179
180   //@NotNull
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);
185       switch (ch) {
186         case GROUP_SEPARATOR:
187         case GROUPS_SEPARATOR:
188         case GROUP_VALUE_SEPARATOR:
189         case '\'':
190         case '\"':
191         case '=':
192           escaped.append(' ');
193           break;
194         default:
195           escaped.append(ch);
196           break;
197       }
198     }
199     return escaped.toString();
200   }
201 }