use hashmap implementation from java.util
[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 import java.util.*;
19
20 /**
21  * ATTENTION! DO NOT IMPORT @NotNull AND @Nullable ANNOTATIONS
22  * This class is also used on jetbrains web site
23  */
24
25 public class ConvertUsagesUtil {
26   private static final char GROUP_SEPARATOR = ':';
27   private static final char GROUPS_SEPARATOR = ';';
28   private static final char GROUP_VALUE_SEPARATOR = ',';
29
30   private ConvertUsagesUtil() {
31   }
32
33
34   // @NotNull
35   public static <T extends UsageDescriptor> String convertUsages(Map<GroupDescriptor, Set<T>> map) {
36     assert map != null;
37     final Map<GroupDescriptor, Set<T>> sortedMap = sortDescriptorsByPriority(map);
38
39     StringBuffer buffer = new StringBuffer();
40     for (Map.Entry<GroupDescriptor, Set<T>> entry : sortedMap.entrySet()) {
41       buffer.append(entry.getKey().getId());
42       buffer.append(GROUP_SEPARATOR);
43       buffer.append(convertValueMap(entry.getValue()));
44       buffer.append(GROUPS_SEPARATOR);
45     }
46
47     return buffer.toString();
48   }
49
50   //@NotNull
51   public static String convertValueMap(Set<? extends UsageDescriptor> descriptors) {
52     assert descriptors != null;
53     final StringBuffer buffer = new StringBuffer();
54     for (UsageDescriptor usageDescriptor : descriptors) {
55       buffer.append(usageDescriptor.getKey());
56       buffer.append("=");
57       buffer.append(usageDescriptor.getValue());
58       buffer.append(GROUP_VALUE_SEPARATOR);
59     }
60     buffer.deleteCharAt(buffer.length() - 1);
61
62     return buffer.toString();
63   }
64
65   //@NotNull
66   public static String cutPatchString(String patchStr, int maxSize) {
67     assert patchStr != null;
68     for (int i = maxSize - 1; i >= 0; i--) {
69       final char c = patchStr.charAt(i);
70       if (c == GROUPS_SEPARATOR || c == GROUP_VALUE_SEPARATOR) {
71         return patchStr.substring(0, i);
72       }
73     }
74     return "";
75   }
76
77   //@NotNull
78   public static Map<GroupDescriptor, Set<UsageDescriptor>> convertString(String usages) {
79     assert usages != null;
80     Map<GroupDescriptor, Set<UsageDescriptor>> descriptors = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
81     for (String groupStr : usages.split(Character.toString(GROUPS_SEPARATOR))) {
82       if (!isEmptyOrSpaces(groupStr)) {
83         final StringPair group = getPair(groupStr, Character.toString(GROUP_SEPARATOR));
84         if (group != null) {
85           final String groupId = group.first;
86           assert groupId != null;
87           if (groupId.length() < GroupDescriptor.MAX_ID_LENGTH) {
88             descriptors.putAll(convertValueString(GroupDescriptor.create(groupId), group.second));
89           }
90         }
91       }
92     }
93     return descriptors;
94   }
95
96   //@NotNull
97   public static Map<GroupDescriptor, Set<UsageDescriptor>> convertValueString(GroupDescriptor groupId, String valueData) {
98     assert groupId != null;
99     final Map<GroupDescriptor, Set<UsageDescriptor>> descriptors = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
100     for (String value : valueData.split(Character.toString(GROUP_VALUE_SEPARATOR))) {
101       if (!isEmptyOrSpaces(value)) {
102         final StringPair pair = getPair(value, "=");
103         if (pair != null) {
104           final String count = pair.second;
105           if (!isEmptyOrSpaces(count)) {
106             try {
107               final int i = Integer.parseInt(count);
108               if (!descriptors.containsKey(groupId)) {
109                 descriptors.put(groupId, new LinkedHashSet<UsageDescriptor>());
110               }
111               descriptors.get(groupId).add(new UsageDescriptor(pair.first, i));
112             }
113             catch (NumberFormatException ignored) {
114             }
115           }
116         }
117       }
118     }
119
120     return descriptors;
121   }
122
123   //@Nullable
124   public static StringPair getPair(String str, String separator) {
125     assert str != null;
126     assert separator != null;
127     final int i = str.indexOf(separator);
128     if (i > 0 && i < str.length() - 1) {
129       String key = str.substring(0, i).trim();
130       String value = str.substring(i + 1).trim();
131       if (!isEmptyOrSpaces(key) && !isEmptyOrSpaces(value)) {
132         return new StringPair(key, value);
133       }
134     }
135     return null;
136   }
137
138   //@NotNull
139   public static <T extends UsageDescriptor> Map<GroupDescriptor, Set<T>> sortDescriptorsByPriority(Map<GroupDescriptor, Set<T>> descriptors) {
140     assert descriptors != null;
141     final SortedMap<GroupDescriptor, Set<T>> map = new TreeMap<GroupDescriptor, Set<T>>(new Comparator<GroupDescriptor>() {
142       public int compare(GroupDescriptor g1, GroupDescriptor g2) {
143         final int priority = (int)(g2.getPriority() - g1.getPriority());
144         return priority == 0 ? g1.getId().compareTo(g2.getId()) : priority;
145       }
146     });
147
148     map.putAll(descriptors);
149
150     return map;
151   }
152
153   private static class StringPair {
154     public final String first;
155     public final String second;
156
157     public StringPair(String first, String second) {
158       this.first = first;
159       this.second = second;
160     }
161   }
162
163   public static boolean isEmptyOrSpaces(final String s) {
164     return s == null || s.trim().length() == 0;
165   }
166
167   public static void assertDescriptorName(String key) {
168     assert key != null;
169     assert key.indexOf(GROUP_SEPARATOR) == -1 : key + " contains invalid chars";
170     assert key.indexOf(GROUPS_SEPARATOR) == -1 : key + " contains invalid chars";
171     assert key.indexOf(GROUP_VALUE_SEPARATOR) == -1 : key + " contains invalid chars";
172     assert !key.contains("=") : key + " contains invalid chars";
173     assert !key.contains("'") : key + " contains invalid chars";
174     assert !key.contains("\"") : key + " contains invalid chars";
175   }
176
177   //@NotNull
178   public static String ensureProperKey(/*@NotNull*/ String input) {
179     final StringBuilder escaped = new StringBuilder();
180     for (int i = 0; i < input.length(); i++) {
181       final char ch = input.charAt(i);
182       switch (ch) {
183         case GROUP_SEPARATOR:
184         case GROUPS_SEPARATOR:
185         case GROUP_VALUE_SEPARATOR:
186         case '\'':
187         case '\"':
188         case '=':
189           escaped.append(' ');
190           break;
191         default:
192           escaped.append(ch);
193           break;
194       }
195     }
196     return escaped.toString();
197   }
198 }