From d31a8dc10e8818fbbed7edfd12f68efd2f825a51 Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Wed, 16 Feb 2011 17:56:24 +0300 Subject: [PATCH] usages statistics refactored + fixed tests --- .../libraries/impl/LibraryUsageCollector.java | 14 +- .../FrameworkStatisticsPersistence.java | 42 --- ...ameworkStatisticsPersistenceComponent.java | 146 -------- .../statistics/FrameworkUsagesCollector.java | 65 +--- .../FeaturesUsageCollector.java | 7 +- .../ide/plugins/PluginsUsagesCollector.java | 6 +- .../AbstractApplicationUsagesCollector.java | 82 +++++ .../statistic/StatisticsUploadAssistant.java | 325 ++++++++++-------- .../internal/statistic/UsagesCollector.java | 3 +- .../statistic/beans/ConvertUsagesUtil.java | 51 ++- .../statistic/beans/PatchedUsage.java | 6 +- .../statistic/beans/UsageDescriptor.java | 35 +- .../configurable/StatisticsConfigurable.java | 16 +- .../ApplicationStatisticsPersistence.java | 37 ++ ...icationStatisticsPersistenceComponent.java | 184 ++++++++++ .../BasicSentUsagesPersistenceComponent.java | 79 +++-- .../persistence/SentUsagesPersistence.java | 6 +- .../UsageStatisticsPersistenceComponent.java | 4 +- .../StatisticsNotificationManager.java | 2 +- .../src/componentSets/Platform.xml | 14 +- .../statistics/VcsStatisticsPersistence.java | 42 --- .../VcsStatisticsPersistenceComponent.java | 146 -------- .../vcs/statistics/VcsUsagesCollector.java | 80 +---- 23 files changed, 620 insertions(+), 772 deletions(-) delete mode 100644 platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java delete mode 100644 platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/AbstractApplicationUsagesCollector.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java delete mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java delete mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/impl/LibraryUsageCollector.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/impl/LibraryUsageCollector.java index fdff8b12dd91..dad76bc77c8b 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/impl/LibraryUsageCollector.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/impl/LibraryUsageCollector.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.roots.ui.configuration.libraries.impl; +import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -34,12 +35,13 @@ import java.util.*; /** * @author nik */ -public class LibraryUsageCollector extends UsagesCollector { +public class LibraryUsageCollector extends AbstractApplicationUsagesCollector { + @NonNls private static final String GROUP_ID = "libraries"; @NotNull @Override - public Set getUsages(@Nullable Project project) { + public Set getProjectUsages(@Nullable Project project) { if (project == null) return Collections.emptySet(); final Set> usedKinds = new HashSet>(); @@ -56,15 +58,13 @@ public class LibraryUsageCollector extends UsagesCollector { final HashSet usageDescriptors = new HashSet(); for (LibraryKind kind : usedKinds) { - final GroupDescriptor group = GroupDescriptor.create(GROUP_ID); - usageDescriptors.add(new UsageDescriptor(group, kind.getKindId(), 1)); + usageDescriptors.add(new UsageDescriptor(kind.getKindId(), 1)); } return usageDescriptors; } @NotNull @Override - public String getGroupId() { - return GROUP_ID; - } + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID); } } diff --git a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java deleted file mode 100644 index b1d9a0894c75..000000000000 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.facet.impl.statistics; - -import com.intellij.openapi.project.Project; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.util.containers.HashMap; -import org.jetbrains.annotations.NotNull; - -import java.util.Map; -import java.util.Set; - -public abstract class FrameworkStatisticsPersistence { - private Map> myFrameworks = new HashMap>(); - - public FrameworkStatisticsPersistence() { - } - - public void persistFrameworks(@NotNull Project project, @NotNull Set frameworks) { - myFrameworks.put(project.getName(), frameworks); - } - - @NotNull - public Map> getFrameworks() { - return myFrameworks; - } - -} diff --git a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java deleted file mode 100644 index 717dabff6e15..000000000000 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.facet.impl.statistics; - -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.components.ApplicationComponent; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.project.ProjectManagerListener; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.Function; -import com.intellij.util.containers.HashSet; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.List; -import java.util.Map; -import java.util.Set; - -@State( - name = "FrameworkUsages", - storages = { - @Storage( - id = "frameworks", - file = "$APP_CONFIG$/framework.usages.xml" - )} -) -public class FrameworkStatisticsPersistenceComponent extends FrameworkStatisticsPersistence - implements ApplicationComponent, PersistentStateComponent { - private static final String TOKENIZER = ","; - - @NonNls private static final String PROJECT_TAG = "project"; - @NonNls private static final String PROJECT_ID_ATTR = "id"; - @NonNls private static final String FRAMEWORKS_ATTR = "frameworks"; - - public FrameworkStatisticsPersistenceComponent() { - } - - public static FrameworkStatisticsPersistenceComponent getInstance() { - return ApplicationManager.getApplication().getComponent(FrameworkStatisticsPersistenceComponent.class); - } - - public void loadState(final Element element) { - List projectsList = element.getChildren(PROJECT_TAG); - for (Object project : projectsList) { - Element projectElement = (Element)project; - String projectId = projectElement.getAttributeValue(PROJECT_ID_ATTR); - String frameworks = projectElement.getAttributeValue(FRAMEWORKS_ATTR); - if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(frameworks)) { - Set frameworkDescriptors = new HashSet(); - for (String key : StringUtil.split(frameworks, TOKENIZER)) { - frameworkDescriptors.add(new UsageDescriptor(FrameworkUsagesCollector.getGroupDescriptor(), key, 1)); - } - getFrameworks().put(projectId, frameworkDescriptors); - } - } - } - - public Element getState() { - Element element = new Element("state"); - - for (Map.Entry> frameworks : getFrameworks().entrySet()) { - Element projectElement = new Element(PROJECT_TAG); - projectElement.setAttribute(PROJECT_ID_ATTR, frameworks.getKey()); - projectElement.setAttribute(FRAMEWORKS_ATTR, joinUsages(frameworks.getValue())); - - element.addContent(projectElement); - } - - return element; - } - - private static String joinUsages(@NotNull Set usages) { - return StringUtil.join(usages, new Function() { - @Override - public String fun(UsageDescriptor usageDescriptor) { - return usageDescriptor.getKey(); - } - }, TOKENIZER); - } - - @NotNull - @NonNls - public File[] getExportFiles() { - return new File[]{PathManager.getOptionsFile("framework.usages")}; - } - - @NotNull - public String getPresentableName() { - return "Framework Usages"; - } - - @NonNls - @NotNull - public String getComponentName() { - return "FrameworkStatisticsPersistenceComponent"; - } - - public void initComponent() { - ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerListener() { - @Override - public void projectOpened(Project project) { - } - - @Override - public boolean canCloseProject(Project project) { - return true; - } - - @Override - public void projectClosed(Project project) { - } - - @Override - public void projectClosing(Project project) { - if (project != null) { - FrameworkUsagesCollector.persistProjectUsages(project); - } - } - }); - } - - public void disposeComponent() { - } -} diff --git a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java index abad35157269..30e78582fb7d 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java @@ -17,84 +17,31 @@ package com.intellij.facet.impl.statistics; import com.intellij.facet.Facet; import com.intellij.facet.FacetManager; +import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; -import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; -import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Map; import java.util.Set; -public class FrameworkUsagesCollector extends UsagesCollector { +public class FrameworkUsagesCollector extends AbstractApplicationUsagesCollector { public static final String GROUP_ID = "frameworks"; - public static void persistProjectUsages(@NotNull Project project) { - persistProjectUsages(project, getProjectUsages(project)); - } - - public static void persistProjectUsages(@NotNull Project project, @NotNull Set usages) { - persistProjectUsages(project, usages, FrameworkStatisticsPersistenceComponent.getInstance()); - } - - public static void persistProjectUsages(@NotNull Project project, - @NotNull Set usages, - @NotNull FrameworkStatisticsPersistence persistence) { - persistence.persistFrameworks(project, usages); - } - - @NotNull - public Set getApplicationUsages() { - return getApplicationUsages(FrameworkStatisticsPersistenceComponent.getInstance()); - } - - @NotNull - public Set getApplicationUsages(@NotNull final FrameworkStatisticsPersistence persistence) { - final Map facets = new HashMap(); - - for (Set frameworks : persistence.getFrameworks().values()) { - for (UsageDescriptor framework : frameworks) { - final String key = framework.getKey(); - final Integer count = facets.get(key); - facets.put(key, count == null ? 1 : count.intValue() + 1); - } - } - - return ContainerUtil.map2Set(facets.entrySet(), new Function, UsageDescriptor>() { - @Override - public UsageDescriptor fun(Map.Entry facet) { - return new UsageDescriptor(getGroupDescriptor(), facet.getKey(), facet.getValue()); - } - }); - } - @NotNull @Override - public String getGroupId() { - return GROUP_ID; - } - - public static GroupDescriptor getGroupDescriptor() { + public GroupDescriptor getGroupId() { return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); } + @NotNull - public Set getUsages(@Nullable Project project) { - if (project != null) { - persistProjectUsages(project, getProjectUsages(project)); - } - - return getApplicationUsages(); - } - - public static Set getProjectUsages(@NotNull Project project) { + public Set getProjectUsages(@NotNull Project project) { final Set facets = new HashSet(); for (Module module : ModuleManager.getInstance(project).getModules()) { for (Facet facet : FacetManager.getInstance(module).getAllFacets()) { @@ -105,7 +52,7 @@ public class FrameworkUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(facets, new Function() { @Override public UsageDescriptor fun(String facet) { - return new UsageDescriptor(getGroupDescriptor(), facet, 1); + return new UsageDescriptor(facet, 1); } }); } diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java b/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java index b983a6d9adc1..44bec87c2dd1 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java +++ b/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java @@ -29,8 +29,8 @@ public class FeaturesUsageCollector extends UsagesCollector { @NotNull @Override - public String getGroupId() { - return "productivity"; + public GroupDescriptor getGroupId() { + return GroupDescriptor.create("productivity", GroupDescriptor.LOWER_PRIORITY); } @NotNull @@ -44,8 +44,7 @@ public class FeaturesUsageCollector extends UsagesCollector { for (String featureId : registry.getFeatureIds()) { final FeatureDescriptor featureDescriptor = registry.getFeatureDescriptor(featureId); if (featureDescriptor != null) { - usages.add(new UsageDescriptor( - GroupDescriptor.create(getGroupId(), GroupDescriptor.LOWER_PRIORITY), featureId, featureDescriptor.getUsageCount())); + usages.add(new UsageDescriptor(featureId, featureDescriptor.getUsageCount())); } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java index 006b58967ada..c4fc51be1450 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java @@ -30,8 +30,8 @@ public class PluginsUsagesCollector extends UsagesCollector { private static final String GROUP_ID = "disabled-plugins"; @NotNull - public String getGroupId() { - return GROUP_ID; + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); } @NotNull @@ -39,7 +39,7 @@ public class PluginsUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(PluginManager.getDisabledPlugins(), new Function() { @Override public UsageDescriptor fun(String descriptor) { - return new UsageDescriptor(GroupDescriptor.create(getGroupId(), GroupDescriptor.HIGHER_PRIORITY), descriptor, 1); + return new UsageDescriptor(descriptor, 1); } }); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/AbstractApplicationUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/AbstractApplicationUsagesCollector.java new file mode 100644 index 000000000000..f7173bc60d65 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/AbstractApplicationUsagesCollector.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.persistence.ApplicationStatisticsPersistence; +import com.intellij.internal.statistic.persistence.ApplicationStatisticsPersistenceComponent; +import com.intellij.openapi.project.Project; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.hash.HashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.Set; + +public abstract class AbstractApplicationUsagesCollector extends UsagesCollector { + public void persistProjectUsages(@NotNull Project project) { + persistProjectUsages(project, getProjectUsages(project)); + } + + public void persistProjectUsages(@NotNull Project project, @NotNull Set usages) { + persistProjectUsages(project, usages, ApplicationStatisticsPersistenceComponent.getInstance()); + } + + public void persistProjectUsages(@NotNull Project project, + @NotNull Set usages, + @NotNull ApplicationStatisticsPersistence persistence) { + persistence.persistFrameworks(getGroupId(), project, usages); + } + + @NotNull + public Set getApplicationUsages() { + return getApplicationUsages(ApplicationStatisticsPersistenceComponent.getInstance()); + } + + @NotNull + public Set getApplicationUsages(@NotNull final ApplicationStatisticsPersistence persistence) { + final Map facets = new HashMap(); + + for (Set frameworks : persistence.getApplicationData(getGroupId()).values()) { + for (UsageDescriptor framework : frameworks) { + final String key = framework.getKey(); + final Integer count = facets.get(key); + facets.put(key, count == null ? 1 : count.intValue() + 1); + } + } + + return ContainerUtil.map2Set(facets.entrySet(), new Function, UsageDescriptor>() { + @Override + public UsageDescriptor fun(Map.Entry facet) { + return new UsageDescriptor(facet.getKey(), facet.getValue()); + } + }); + } + + @NotNull + public Set getUsages(@Nullable Project project) { + if (project != null) { + persistProjectUsages(project, getProjectUsages(project)); + } + + return getApplicationUsages(); + } + + @NotNull + public abstract Set getProjectUsages(@NotNull Project project); +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java index b6a2105b5064..ac676de86be8 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java @@ -30,7 +30,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; -import com.intellij.util.text.DateFormatUtil; +import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,173 +38,204 @@ import java.util.*; public class StatisticsUploadAssistant { - public String getData() { - return getData(Collections.emptySet()); - } + public String getData() { + return getData(Collections.emptySet()); + } - public static boolean showNotification() { - return UsageStatisticsPersistenceComponent.getInstance().isShowNotification(); - } + public static boolean showNotification() { + return UsageStatisticsPersistenceComponent.getInstance().isShowNotification(); + } - public static boolean isTimeToSend() { - if (ApplicationManagerEx.getApplicationEx().isInternal()) return true; // todo remove + public static boolean isTimeToSend() { + if (ApplicationManagerEx.getApplicationEx().isInternal()) return true; // todo remove - return isTimeToSend(UsageStatisticsPersistenceComponent.getInstance()); - } + return isTimeToSend(UsageStatisticsPersistenceComponent.getInstance()); + } - public static boolean isTimeToSend(UsageStatisticsPersistenceComponent settings) { - final long timeDelta = System.currentTimeMillis() - settings.getLastTimeSent(); + public static boolean isTimeToSend(UsageStatisticsPersistenceComponent settings) { + final long timeDelta = System.currentTimeMillis() - settings.getLastTimeSent(); - return Math.abs(timeDelta) > settings.getPeriod().getMillis(); - } + return Math.abs(timeDelta) > settings.getPeriod().getMillis(); + } - public static boolean isSendAllowed() { - if (ApplicationManagerEx.getApplicationEx().isInternal()) return true; // todo remove + public static boolean isSendAllowed() { + if (ApplicationManagerEx.getApplicationEx().isInternal()) return true; // todo remove - return isSendAllowed(UsageStatisticsPersistenceComponent.getInstance()); - } + return isSendAllowed(UsageStatisticsPersistenceComponent.getInstance()); + } - public static boolean isSendAllowed(final SentUsagesPersistence settings) { - return settings != null && settings.isAllowed(); - } + public static boolean isSendAllowed(final SentUsagesPersistence settings) { + return settings != null && settings.isAllowed(); + } - public static String getData(@NotNull Set disabledGroups) { - return getStringPatch(disabledGroups, ProjectManager.getInstance().getOpenProjects()); - } + public static String getData(@NotNull Set disabledGroups) { + return getStringPatch(disabledGroups, ProjectManager.getInstance().getOpenProjects()); + } - public static void persistSentPatch(@NotNull String patchStr) { - persistSentPatch(patchStr, UsageStatisticsPersistenceComponent.getInstance()); - } + public static void persistSentPatch(@NotNull String patchStr) { + persistSentPatch(patchStr, UsageStatisticsPersistenceComponent.getInstance()); + } - public static void persistSentPatch(@NotNull String patchStr, @NotNull SentUsagesPersistence persistenceComponent) { - Set patchedUsages = - ContainerUtil.map2Set(ConvertUsagesUtil.convertString(patchStr), new Function() { - @Override - public PatchedUsage fun(UsageDescriptor usageDescriptor) { - return new PatchedUsage(usageDescriptor); + public static void persistSentPatch(@NotNull String patchStr, @NotNull SentUsagesPersistence persistenceComponent) { + Map> patchedUsages = mapToPatchedUsagesMap(ConvertUsagesUtil.convertString(patchStr)); + + if (patchedUsages.size() > 0) persistenceComponent.persistPatch(patchedUsages); + } + + @NotNull + public static String getStringPatch(@NotNull Set disabledGroups, Project... project) { + return getStringPatch(disabledGroups, project, UsageStatisticsPersistenceComponent.getInstance(), 0); + } + + @NotNull + public static String getStringPatch(@NotNull Set disabledGroups, + @NotNull Project[] projects, + @NotNull SentUsagesPersistence usagesPersistence, + int maxSize) { + final Map> patchedUsages = getPatchedUsages(disabledGroups, projects, usagesPersistence); + + return getStringPatch(patchedUsages, maxSize); + } + + public static String getStringPatch(@NotNull Map> patchedUsages, int maxSize) { + if (patchedUsages.size() == 0) return ""; + + String patchStr = ConvertUsagesUtil.convertUsages(patchedUsages); + if (maxSize > 0 && patchStr.getBytes().length > maxSize) { + patchStr = ConvertUsagesUtil.cutPatchString(patchStr, maxSize); } - }); - if (patchedUsages.size() > 0) persistenceComponent.persistPatch(patchedUsages); - } - - @NotNull - public static String getStringPatch(@NotNull Set disabledGroups, Project... project) { - return getStringPatch(disabledGroups, project, UsageStatisticsPersistenceComponent.getInstance(), 0); - } - - @NotNull - public static String getStringPatch(@NotNull Set disabledGroups, - @NotNull Project[] projects, - @NotNull SentUsagesPersistence usagesPersistence, - int maxSize) { - final Set patchedUsages = getPatchedUsages(disabledGroups, projects, usagesPersistence); - - return getStringPatch(patchedUsages, maxSize); - } - - public static String getStringPatch(@NotNull Set patchedUsages, int maxSize) { - if (patchedUsages.size() == 0) return ""; - - String patchStr = ConvertUsagesUtil.convertUsages(patchedUsages); - if (maxSize > 0 && patchStr.getBytes().length > maxSize) { - patchStr = ConvertUsagesUtil.cutPatchString(patchStr, maxSize); + return patchStr; } - return patchStr; - } + @NotNull + public static Map> getPatchedUsages(@NotNull Set disabledGroups, + @NotNull Project[] projects, + @NotNull SentUsagesPersistence usagesPersistence) { + Map> usages = new HashMap>(); - @NotNull - public static Set getPatchedUsages(@NotNull Set disabledGroups, - @NotNull Project[] projects, - @NotNull SentUsagesPersistence usagesPersistence) { - Set usages = new HashSet(); + for (Project project : projects) { + final Map> allUsages = getAllUsages(project, disabledGroups); + final Map> sentUsages = filterDisabled(disabledGroups, usagesPersistence.getSentUsages()); - for (Project project : projects) { - final Set allUsages = getAllUsages(project, disabledGroups); - final Set sentUsages = filterDisabled(disabledGroups, usagesPersistence.getSentUsages()); - - usages.addAll(getPatchedUsages(allUsages, sentUsages)); - } - return usages; - } - - private static Set filterDisabled(@NotNull Set disabledGroups, @NotNull Set usages) { - Set filtered = new HashSet(); - - for (UsageDescriptor usage : usages) { - if (!disabledGroups.contains(usage.getGroup().getId())) { - filtered.add(usage); - } - } - return filtered; - } - - @NotNull - public static Set getPatchedUsages(@NotNull final Set allUsages, - @NotNull SentUsagesPersistence usagesPersistence) { - return getPatchedUsages(allUsages, usagesPersistence.getSentUsages()); - } - - @NotNull - public static Set getPatchedUsages(@NotNull final Set allUsages, final Set sentUsages) { - final Set patchedUsages = ContainerUtil.map2Set(allUsages, new Function() { - @Override - public PatchedUsage fun(UsageDescriptor usageDescriptor) { - return new PatchedUsage(usageDescriptor); - } - }); - - for (UsageDescriptor sentUsage : sentUsages) { - final PatchedUsage descriptor = findDescriptor(patchedUsages, Pair.create(sentUsage.getGroup(), sentUsage.getKey())); - if (descriptor == null) { - patchedUsages.add(new PatchedUsage(sentUsage.getGroup(), sentUsage.getKey(), -sentUsage.getValue())); - } - else { - descriptor.subValue(sentUsage.getValue()); - } + usages.putAll(getPatchedUsages(allUsages, sentUsages)); + } + return usages; } - return packCollection(patchedUsages, new Condition() { - @Override - public boolean value(PatchedUsage patchedUsage) { - return patchedUsage.getDelta() != 0; - } - }); - } + @NotNull + private static Map> filterDisabled(@NotNull Set disabledGroups, @NotNull Map> usages) { + Map> filtered = new HashMap>(); - @NotNull - private static Set packCollection(@NotNull Collection set, @NotNull Condition condition) { - final Set result = new LinkedHashSet(); - for (T t : set) { - if (condition.value(t)) { - result.add(t); - } + for (Map.Entry> usage : usages.entrySet()) { + if (!disabledGroups.contains(usage.getKey().getId())) { + filtered.put(usage.getKey(), usage.getValue()); + } + } + return filtered; } - return result; - } - - @Nullable - public static T findDescriptor(@NotNull Set descriptors, - @NotNull final Pair id) { - return ContainerUtil.find(descriptors, new Condition() { - @Override - public boolean value(T t) { - return id.getFirst().equals(t.getGroup()) && id.getSecond().equals(t.getKey()); - } - }); - } - - @NotNull - public static Set getAllUsages(@Nullable Project project, @NotNull Set disabledGroups) { - final Set usageDescriptors = new TreeSet(); - - for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { - if (!disabledGroups.contains(usagesCollector.getGroupId())) { - usageDescriptors.addAll(usagesCollector.getUsages(project)); - } + + @NotNull + public static Map> getPatchedUsages(@NotNull final Map> allUsages, + @NotNull SentUsagesPersistence usagesPersistence) { + return getPatchedUsages(allUsages, usagesPersistence.getSentUsages()); + } + + @NotNull + public static Map> getPatchedUsages(@NotNull final Map> allUsages, final Map> sentUsageMap) { + Map> patchedUsages = mapToPatchedUsagesMap(allUsages); + + for (Map.Entry> sentUsageEntry : sentUsageMap.entrySet()) { + final GroupDescriptor sentUsageGroupDescriptor = sentUsageEntry.getKey(); + + final Set sentUsages = sentUsageEntry.getValue(); + + for (UsageDescriptor sentUsage : sentUsages) { + final PatchedUsage descriptor = findDescriptor(patchedUsages, Pair.create(sentUsageGroupDescriptor, sentUsage.getKey())); + if (descriptor == null) { + if (!patchedUsages.containsKey(sentUsageGroupDescriptor)) { + patchedUsages.put(sentUsageGroupDescriptor, new HashSet()); + } + patchedUsages.get(sentUsageGroupDescriptor).add(new PatchedUsage(sentUsage.getKey(), -sentUsage.getValue())); + } else { + descriptor.subValue(sentUsage.getValue()); + } + } + + } + + return packCollection(patchedUsages, new Condition() { + @Override + public boolean value(PatchedUsage patchedUsage) { + return patchedUsage.getDelta() != 0; + } + }); + } + + private static Map> mapToPatchedUsagesMap(Map> allUsages) { + Map> patchedUsages = new HashMap>(); + for (Map.Entry> entry : allUsages.entrySet()) { + patchedUsages.put(entry.getKey(), ContainerUtil.map2Set(entry.getValue(), new Function() { + @Override + public PatchedUsage fun(UsageDescriptor usageDescriptor) { + return new PatchedUsage(usageDescriptor); + } + })); + } + return patchedUsages; + } + + @NotNull + private static Map> packCollection(@NotNull Map> patchedUsages, Condition condition) { + Map> result = new HashMap>(); + for (GroupDescriptor descriptor : patchedUsages.keySet()) { + final Set usages = packCollection(patchedUsages.get(descriptor), condition); + if (usages.size() > 0) { + result.put(descriptor, usages); + } + } + + return result; + } + + @NotNull + private static Set packCollection(@NotNull Collection set, @NotNull Condition condition) { + final Set result = new LinkedHashSet(); + for (T t : set) { + if (condition.value(t)) { + result.add(t); + } + } + return result; + } + + @Nullable + public static T findDescriptor(@NotNull Map> descriptors, + @NotNull final Pair id) { + final Set usages = descriptors.get(id.getFirst()); + if (usages == null) return null; + + return ContainerUtil.find(usages, new Condition() { + @Override + public boolean value(T t) { + return id.getSecond().equals(t.getKey()); + } + }); + } + + @NotNull + public static Map> getAllUsages(@Nullable Project project, @NotNull Set disabledGroups) { + Map> usageDescriptors = new HashMap>(); + + for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { + final GroupDescriptor groupDescriptor = usagesCollector.getGroupId(); + + if (!disabledGroups.contains(groupDescriptor.getId())) { + usageDescriptors.put(groupDescriptor, usagesCollector.getUsages(project)); + } + } + + return usageDescriptors; } - return usageDescriptors; - } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java index e07246e0556a..46e03564bf5d 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java @@ -15,6 +15,7 @@ */ package com.intellij.internal.statistic; +import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -28,5 +29,5 @@ public abstract class UsagesCollector { public abstract @NotNull Set getUsages(@Nullable Project project); - public abstract @NotNull String getGroupId(); + public abstract @NotNull GroupDescriptor getGroupId(); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java index 8fd58411e437..e8f2c6e8acd8 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java @@ -16,6 +16,8 @@ package com.intellij.internal.statistic.beans; +import com.intellij.util.containers.hash.HashMap; + import java.util.*; public class ConvertUsagesUtil { @@ -26,19 +28,14 @@ public class ConvertUsagesUtil { private ConvertUsagesUtil() { } - // @NotNull - public static String convertUsages(Set descriptors) { - assert descriptors != null; - final Map> descriptorGroups = groupDescriptors(descriptors); - - return convertUsages(descriptorGroups); - } // @NotNull - public static String convertUsages(Map> map) { + public static String convertUsages(Map> map) { assert map != null; + final Map> sortedMap = sortDescriptorsByPriority(map); + StringBuffer buffer = new StringBuffer(); - for (Map.Entry> entry : map.entrySet()) { + for (Map.Entry> entry : sortedMap.entrySet()) { buffer.append(entry.getKey().getId()); buffer.append(GROUP_SEPARATOR); buffer.append(convertValueMap(entry.getValue())); @@ -49,7 +46,7 @@ public class ConvertUsagesUtil { } //@NotNull - public static String convertValueMap(Set descriptors) { + public static String convertValueMap(Set descriptors) { assert descriptors != null; final StringBuffer buffer = new StringBuffer(); for (UsageDescriptor usageDescriptor : descriptors) { @@ -76,14 +73,14 @@ public class ConvertUsagesUtil { } //@NotNull - public static Set convertString(String usages) { + public static Map> convertString(String usages) { assert usages != null; - Set descriptors = new LinkedHashSet(); + Map> descriptors = new HashMap>(); for (String groupStr : usages.split(GROUPS_SEPARATOR.toString())) { if (!isEmptyOrSpaces(groupStr)) { final StringPair group = getPair(groupStr, GROUP_SEPARATOR.toString()); if (group != null) { - descriptors.addAll(convertValueString(GroupDescriptor.create(group.first), group.second)); + descriptors.putAll(convertValueString(GroupDescriptor.create(group.first), group.second)); } } } @@ -91,9 +88,9 @@ public class ConvertUsagesUtil { } //@NotNull - public static Set convertValueString(GroupDescriptor groupId, String valueData) { + public static Map> convertValueString(GroupDescriptor groupId, String valueData) { assert groupId != null; - final Set descriptors = new LinkedHashSet(); + final Map> descriptors = new HashMap>(); for (String value : valueData.split(GROUP_VALUE_SEPARATOR.toString())) { if (!isEmptyOrSpaces(value)) { final StringPair pair = getPair(value, "="); @@ -102,7 +99,10 @@ public class ConvertUsagesUtil { if (!isEmptyOrSpaces(count)) { try { final int i = Integer.parseInt(count); - descriptors.add(new UsageDescriptor(groupId, pair.first, i)); + if (!descriptors.containsKey(groupId)) { + descriptors.put(groupId, new LinkedHashSet()); + } + descriptors.get(groupId).add(new UsageDescriptor(pair.first, i)); } catch (NumberFormatException ignored) { } } @@ -129,22 +129,17 @@ public class ConvertUsagesUtil { } //@NotNull - public static Map> groupDescriptors(Set descriptors) { + public static Map> sortDescriptorsByPriority(Map> descriptors) { assert descriptors != null; - final SortedMap> map = new TreeMap>(new Comparator() { + final SortedMap> map = new TreeMap>(new Comparator() { public int compare(GroupDescriptor g1, GroupDescriptor g2) { final int priority = (int) (g2.getPriority() - g1.getPriority()); return priority == 0 ? g1.getId().compareTo(g2.getId()) : priority; } }); - for (UsageDescriptor descriptor : descriptors) { - final GroupDescriptor group = descriptor.getGroup(); - if (!map.containsKey(group)) { - map.put(group, new HashSet()); - } - map.get(group).add(descriptor); - } + map.putAll(descriptors); + return map; } @@ -158,7 +153,7 @@ public class ConvertUsagesUtil { } } - public static boolean isEmptyOrSpaces(final String s) { - return s == null || s.trim().length() == 0; - } + public static boolean isEmptyOrSpaces(final String s) { + return s == null || s.trim().length() == 0; + } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java index f91433e4b6bb..f300bd74362f 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java @@ -18,11 +18,11 @@ package com.intellij.internal.statistic.beans; public class PatchedUsage extends UsageDescriptor { public PatchedUsage(UsageDescriptor descriptor) { - super(descriptor.getGroup(), descriptor.getKey(), descriptor.getValue()); + super(descriptor.getKey(), descriptor.getValue()); } - public PatchedUsage(GroupDescriptor group, String key, int value) { - super(group, key, value); + public PatchedUsage(String key, int value) { + super(key, value); } public int getDelta() { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java index 2ec188afa17d..4b5a4c9c66d6 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java @@ -16,15 +16,12 @@ package com.intellij.internal.statistic.beans; public class UsageDescriptor implements Comparable { - private final GroupDescriptor myGroup; private final String myKey; private int myValue; - public UsageDescriptor(GroupDescriptor group, String key, int value) { - assert group != null; - assert key != null; + public UsageDescriptor(String key, int value) { + assert key != null; - myGroup = group; myKey = key; myValue = value; } @@ -33,10 +30,6 @@ public class UsageDescriptor implements Comparable { return myKey; } - public GroupDescriptor getGroup() { - return myGroup; - } - public int getValue() { return myValue; } @@ -45,29 +38,15 @@ public class UsageDescriptor implements Comparable { myValue = i; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof UsageDescriptor)) return false; - - UsageDescriptor that = (UsageDescriptor) o; - - if (!myGroup.equals(that.myGroup)) return false; - if (!myKey.equals(that.myKey)) return false; - - return true; + public int getMyValue() { + return myValue; } - @Override - public int hashCode() { - int result = myGroup.hashCode(); - result = 31 * result + myKey.hashCode(); - return result; + public void setMyValue(int myValue) { + this.myValue = myValue; } public int compareTo(UsageDescriptor ud) { - final int byGroup = this.getGroup().compareTo(ud.getGroup()); - - return byGroup == 0 ? this.getKey().compareTo(ud.myKey) : byGroup; + return this.getKey().compareTo(ud.myKey); } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java index 9af6117dbd03..c7ff27d0a279 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java @@ -29,7 +29,18 @@ import javax.swing.*; public class StatisticsConfigurable implements SearchableConfigurable { - private StatisticsConfigurationComponent myConfig; + private boolean modifiedByDefault; + + public StatisticsConfigurable() { + this(false); + } + + public StatisticsConfigurable(boolean isModifiedByDefault) { + modifiedByDefault = isModifiedByDefault; + } + + + private StatisticsConfigurationComponent myConfig; @Nls public String getDisplayName() { @@ -56,7 +67,7 @@ public class StatisticsConfigurable implements SearchableConfigurable { final UsageStatisticsPersistenceComponent persistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); return myConfig.isAllowed() != persistenceComponent.isAllowed() || myConfig.getPeriod() != persistenceComponent.getPeriod() || - persistenceComponent.isShowNotification(); + modifiedByDefault; } public void apply() throws ConfigurationException { @@ -65,6 +76,7 @@ public class StatisticsConfigurable implements SearchableConfigurable { persistenceComponent.setPeriod(myConfig.getPeriod()); persistenceComponent.setAllowed(myConfig.isAllowed()); persistenceComponent.setShowNotification(false); + modifiedByDefault = false; } public void reset() { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java new file mode 100644 index 000000000000..b5021df47287 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java @@ -0,0 +1,37 @@ +package com.intellij.internal.statistic.persistence; + +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; +import java.util.Set; + +public abstract class ApplicationStatisticsPersistence { + private Map>> myApplicationData = new HashMap>>(); + + public ApplicationStatisticsPersistence() { + } + + public void persistFrameworks(@NotNull GroupDescriptor groupDescriptor, @NotNull Project project, @NotNull Set frameworks) { + if (!myApplicationData.containsKey(groupDescriptor)) { + myApplicationData.put(groupDescriptor, new HashMap>()); + } + myApplicationData.get(groupDescriptor).put(project.getName(), frameworks); + } + + @NotNull + public Map> getApplicationData(@NotNull GroupDescriptor groupDescriptor) { + final Map> map = myApplicationData.get(groupDescriptor); + + return map == null ? new HashMap>(): map; + } + + @NotNull + public Map>> getApplicationData() { + return myApplicationData; + } + +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java new file mode 100644 index 000000000000..fb8d0fd6bffe --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java @@ -0,0 +1,184 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.internal.statistic.persistence; + +import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.HashSet; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@State( + name = "StatisticsApplicationUsages", + storages = { + @Storage( + id = "statistics.application.usages", + file = "$APP_CONFIG$/statistics.application.usages.xml" + )} +) +public class ApplicationStatisticsPersistenceComponent extends ApplicationStatisticsPersistence + implements ApplicationComponent, PersistentStateComponent { + private static final String TOKENIZER = ","; + + @NonNls + private static final String GROUP_TAG = "group"; + @NonNls + private static final String GROUP_NAME_ATTR = "name"; + + @NonNls + private static final String PROJECT_TAG = "project"; + @NonNls + private static final String PROJECT_ID_ATTR = "id"; + @NonNls + private static final String VALUES_ATTR = "values"; + + public ApplicationStatisticsPersistenceComponent() { + } + + public static ApplicationStatisticsPersistenceComponent getInstance() { + return ApplicationManager.getApplication().getComponent(ApplicationStatisticsPersistenceComponent.class); + } + + public void loadState(final Element element) { + List groups = element.getChildren(GROUP_TAG); + + for (Object group : groups) { + Element groupElement = (Element) group; + String groupName = groupElement.getAttributeValue(GROUP_NAME_ATTR); + + final GroupDescriptor groupDescriptor = GroupDescriptor.create(groupName); + + List projectsList = groupElement.getChildren(PROJECT_TAG); + for (Object project : projectsList) { + Element projectElement = (Element) project; + String projectId = projectElement.getAttributeValue(PROJECT_ID_ATTR); + String frameworks = projectElement.getAttributeValue(VALUES_ATTR); + if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(frameworks)) { + Set frameworkDescriptors = new HashSet(); + for (String key : StringUtil.split(frameworks, TOKENIZER)) { + frameworkDescriptors.add(new UsageDescriptor(key, 1)); + } + getApplicationData(groupDescriptor).put(projectId, frameworkDescriptors); + } + } + } + } + + public Element getState() { + Element element = new Element("state"); + + for (Map.Entry>> appData : getApplicationData().entrySet()) { + Element groupElement = new Element(GROUP_TAG); + groupElement.setAttribute(GROUP_NAME_ATTR, appData.getKey().getId()); + boolean isEmptyGroup = true; + + for (Map.Entry> projectData : appData.getValue().entrySet()) { + Element projectElement = new Element(PROJECT_TAG); + projectElement.setAttribute(PROJECT_ID_ATTR, projectData.getKey()); + final Set projectDataValue = projectData.getValue(); + if (!projectDataValue.isEmpty()) { + projectElement.setAttribute(VALUES_ATTR, joinUsages(projectDataValue)); + groupElement.addContent(projectElement); + isEmptyGroup = false; + } + } + + if (!isEmptyGroup) { + element.addContent(groupElement); + } + } + + return element; + } + + private static String joinUsages(@NotNull Set usages) { + return StringUtil.join(usages, new Function() { + @Override + public String fun(UsageDescriptor usageDescriptor) { + return usageDescriptor.getKey(); + } + }, TOKENIZER); + } + + @NotNull + @NonNls + public File[] getExportFiles() { + return new File[]{PathManager.getOptionsFile("framework.usages")}; + } + + @NotNull + public String getPresentableName() { + return "Application Usages Statistics"; + } + + @NonNls + @NotNull + public String getComponentName() { + return "ApplicationStatisticsPersistenceComponent"; + } + + public void initComponent() { + ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerListener() { + @Override + public void projectOpened(Project project) { + } + + @Override + public boolean canCloseProject(Project project) { + return true; + } + + @Override + public void projectClosed(Project project) { + } + + @Override + public void projectClosing(Project project) { + if (project != null) { + for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { + if (usagesCollector instanceof AbstractApplicationUsagesCollector) { + ((AbstractApplicationUsagesCollector) usagesCollector).persistProjectUsages(project); + } + } + } + } + }); + } + + public void disposeComponent() { + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java index 9f4ab0c910c3..b77ea2367816 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java @@ -17,58 +17,69 @@ package com.intellij.internal.statistic.persistence; import com.intellij.internal.statistic.StatisticsUploadAssistant; +import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.PatchedUsage; import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.openapi.util.Pair; import com.intellij.util.containers.HashSet; +import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import java.util.Map; import java.util.Set; public class BasicSentUsagesPersistenceComponent extends SentUsagesPersistence { - public BasicSentUsagesPersistenceComponent() { - } + public BasicSentUsagesPersistenceComponent() { + } - protected Set mySentDescriptors = new HashSet(); - @NonNls private long mySentTime = 0; + protected Map> mySentDescriptors = new HashMap>(); + @NonNls + private long mySentTime = 0; - @Override - public boolean isAllowed() { - return true; - } + @Override + public boolean isAllowed() { + return true; + } - @Override - public boolean isShowNotification() { - return false; - } + @Override + public boolean isShowNotification() { + return false; + } - @Override - public long getLastTimeSent() { - return mySentTime; - } + @Override + public long getLastTimeSent() { + return mySentTime; + } - public void setSentTime(long time) { - mySentTime = time; - } + public void setSentTime(long time) { + mySentTime = time; + } - public void persistPatch(@NotNull Set patchedDescriptors) { - for (PatchedUsage patchedUsage : patchedDescriptors) { - UsageDescriptor usageDescriptor = StatisticsUploadAssistant.findDescriptor(mySentDescriptors, Pair.create(patchedUsage.getGroup(), patchedUsage.getKey())); - if (usageDescriptor != null) { - usageDescriptor.setValue(usageDescriptor.getValue() + patchedUsage.getDelta()); - } - else { - mySentDescriptors.add(new UsageDescriptor(patchedUsage.getGroup(), patchedUsage.getKey(), patchedUsage.getValue())); - } + public void persistPatch(@NotNull Map> patchedDescriptorMap) { + for (Map.Entry> entry : patchedDescriptorMap.entrySet()) { + final GroupDescriptor groupDescriptor = entry.getKey(); + for (PatchedUsage patchedUsage : entry.getValue()) { + UsageDescriptor usageDescriptor = StatisticsUploadAssistant.findDescriptor(mySentDescriptors, Pair.create(groupDescriptor, patchedUsage.getKey())); + if (usageDescriptor != null) { + usageDescriptor.setValue(usageDescriptor.getValue() + patchedUsage.getDelta()); + } else { + if (!mySentDescriptors.containsKey(groupDescriptor)) { + mySentDescriptors.put(groupDescriptor, new HashSet()); + } + mySentDescriptors.get(groupDescriptor).add(new UsageDescriptor(patchedUsage.getKey(), patchedUsage.getValue())); + } + } + } + + setSentTime(System.currentTimeMillis()); } - setSentTime(System.currentTimeMillis()); - } - @NotNull - public Set getSentUsages() { - return mySentDescriptors; - } + @NotNull + public Map> getSentUsages + () { + return mySentDescriptors; + } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java index ca271e3a1cd7..cffc0edec7ba 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java @@ -16,18 +16,20 @@ package com.intellij.internal.statistic.persistence; +import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.PatchedUsage; import com.intellij.internal.statistic.beans.UsageDescriptor; import org.jetbrains.annotations.NotNull; +import java.util.Map; import java.util.Set; public abstract class SentUsagesPersistence { - public abstract void persistPatch(@NotNull Set patchedDescriptors); + public abstract void persistPatch(@NotNull Map> patchedDescriptors); @NotNull - public abstract Set getSentUsages(); + public abstract Map> getSentUsages(); public abstract boolean isAllowed(); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java index 1262fa18c79d..9140f257eac3 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java @@ -76,7 +76,7 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste String valueData = groupElement.getAttributeValue(DATA_ATTR); if (!StringUtil.isEmptyOrSpaces(groupId) && !StringUtil.isEmptyOrSpaces(valueData)) { - getSentUsages().addAll(ConvertUsagesUtil.convertValueString(GroupDescriptor.create(groupId, groupPriority), valueData)); + getSentUsages().putAll(ConvertUsagesUtil.convertValueString(GroupDescriptor.create(groupId, groupPriority), valueData)); } } @@ -99,7 +99,7 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste public Element getState() { Element element = new Element("state"); - for (Map.Entry> entry : ConvertUsagesUtil.groupDescriptors(getSentUsages()) + for (Map.Entry> entry : ConvertUsagesUtil.sortDescriptorsByPriority(getSentUsages()) .entrySet()) { Element projectElement = new Element(GROUP_TAG); projectElement.setAttribute(GROUP_ID_ATTR, entry.getKey().getId()); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java index 4fef4c3f2521..43ab15bfc3ce 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java @@ -72,7 +72,7 @@ public class StatisticsNotificationManager { else if ("settings".equals(description)) { final ShowSettingsUtil util = ShowSettingsUtil.getInstance(); IdeFrame ideFrame = WindowManagerEx.getInstanceEx().findFrameFor(null); - util.editConfigurable((JFrame)ideFrame, new StatisticsConfigurable()); + util.editConfigurable((JFrame)ideFrame, new StatisticsConfigurable(true)); notification.expire(); } } diff --git a/platform/platform-resources/src/componentSets/Platform.xml b/platform/platform-resources/src/componentSets/Platform.xml index b41fe5ed2b1e..fa0f63758036 100644 --- a/platform/platform-resources/src/componentSets/Platform.xml +++ b/platform/platform-resources/src/componentSets/Platform.xml @@ -118,20 +118,16 @@ com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent + + com.intellij.internal.statistic.persistence.ApplicationStatisticsPersistenceComponent + com.intellij.internal.statistic.persistence.ApplicationStatisticsPersistenceComponent + + com.intellij.openapi.util.FoundationLoader - - com.intellij.facet.impl.statistics.FrameworkStatisticsPersistenceComponent - com.intellij.facet.impl.statistics.FrameworkStatisticsPersistenceComponent - - - - com.intellij.openapi.vcs.statistics.VcsStatisticsPersistenceComponent - com.intellij.openapi.vcs.statistics.VcsStatisticsPersistenceComponent - diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java deleted file mode 100644 index 968e52aae1a8..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.openapi.vcs.statistics; - -import com.intellij.openapi.project.Project; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.util.containers.HashMap; -import org.jetbrains.annotations.NotNull; - -import java.util.Map; -import java.util.Set; - -public abstract class VcsStatisticsPersistence { - private Map> myVcsUsagesMap = new HashMap>(); - - public VcsStatisticsPersistence() { - } - - public void persist(@NotNull Project project, @NotNull Set vcs) { - myVcsUsagesMap.put(project.getName(), vcs); - } - - @NotNull - public Map> getVcsUsageMap() { - return myVcsUsagesMap; - } - -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java deleted file mode 100644 index 96a7cf527c12..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.openapi.vcs.statistics; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.components.ApplicationComponent; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.project.ProjectManagerListener; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.util.Function; -import com.intellij.util.containers.HashSet; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.List; -import java.util.Map; -import java.util.Set; - -@State( - name = "VcsUsages", - storages = { - @Storage( - id = "vcs", - file = "$APP_CONFIG$/vcs.usages.xml" - )} -) -public class VcsStatisticsPersistenceComponent extends VcsStatisticsPersistence - implements ApplicationComponent, PersistentStateComponent { - private static final String TOKENIZER = ","; - - @NonNls private static final String PROJECT_TAG = "project"; - @NonNls private static final String PROJECT_ID_ATTR = "id"; - @NonNls private static final String USAGES_ATTR = "usages"; - - public VcsStatisticsPersistenceComponent() { - } - - public static VcsStatisticsPersistenceComponent getInstance() { - return ApplicationManager.getApplication().getComponent(VcsStatisticsPersistenceComponent.class); - } - - public void loadState(final Element element) { - List projectsList = element.getChildren(PROJECT_TAG); - for (Object project : projectsList) { - Element projectElement = (Element)project; - String projectId = projectElement.getAttributeValue(PROJECT_ID_ATTR); - String vcs = projectElement.getAttributeValue(USAGES_ATTR); - if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(vcs)) { - Set vcsDescriptors = new HashSet(); - for (String key : StringUtil.split(vcs, TOKENIZER)) { - vcsDescriptors.add(new UsageDescriptor(VcsUsagesCollector.createGroupDescriptor(), key, 1)); - } - getVcsUsageMap().put(projectId, vcsDescriptors); - } - } - } - - public Element getState() { - Element element = new Element("state"); - - for (Map.Entry> vcsUsageEntry : getVcsUsageMap().entrySet()) { - Element projectElement = new Element(PROJECT_TAG); - projectElement.setAttribute(PROJECT_ID_ATTR, vcsUsageEntry.getKey()); - projectElement.setAttribute(USAGES_ATTR, joinUsages(vcsUsageEntry.getValue())); - - element.addContent(projectElement); - } - - return element; - } - - private static String joinUsages(@NotNull Set usages) { - return StringUtil.join(usages, new Function() { - @Override - public String fun(UsageDescriptor usageDescriptor) { - return usageDescriptor.getKey(); - } - }, TOKENIZER); - } - - @NotNull - @NonNls - public File[] getExportFiles() { - return new File[]{PathManager.getOptionsFile("vcs.usages")}; - } - - @NotNull - public String getPresentableName() { - return "Vcs Usages"; - } - - @NonNls - @NotNull - public String getComponentName() { - return "VcsStatisticsPersistenceComponent"; - } - - public void initComponent() { - ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerListener() { - @Override - public void projectOpened(Project project) { - } - - @Override - public boolean canCloseProject(Project project) { - return true; - } - - @Override - public void projectClosed(Project project) { - } - - @Override - public void projectClosing(Project project) { - if (project != null) { - VcsUsagesCollector.persistProjectUsages(project); - } - } - }); - } - - public void disposeComponent() { - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java index ffbbc803b855..0c027b0f8d6e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java @@ -15,10 +15,10 @@ */ package com.intellij.openapi.vcs.statistics; +import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; -import com.intellij.openapi.vcs.impl.VcsDescriptor; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -28,77 +28,25 @@ import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.Map; import java.util.Set; -public class VcsUsagesCollector extends UsagesCollector { - private static final String GROUP_ID = "vcs"; +public class VcsUsagesCollector extends AbstractApplicationUsagesCollector { + private static final String GROUP_ID = "vcs"; - public static void persistProjectUsages(@NotNull Project project) { - persistProjectUsages(project, getProjectUsages(project)); - } - - public static void persistProjectUsages(@NotNull Project project, @NotNull Set usages) { - persistProjectUsages(project, usages, VcsStatisticsPersistenceComponent.getInstance()); - } - - public static void persistProjectUsages(@NotNull Project project, - @NotNull Set usages, - @NotNull VcsStatisticsPersistenceComponent persistence) { - persistence.persist(project, usages); - } - - @NotNull - public static Set getApplicationUsages() { - return getApplicationUsages(VcsStatisticsPersistenceComponent.getInstance()); - } - - @NotNull - public static Set getApplicationUsages(@NotNull final VcsStatisticsPersistenceComponent persistence) { - final Map vcsUsagesMap = new HashMap(); - - for (Set descriptors : persistence.getVcsUsageMap().values()) { - for (UsageDescriptor descriptor : descriptors) { - final String key = descriptor.getKey(); - final Integer count = vcsUsagesMap.get(key); - vcsUsagesMap.put(key, count == null ? 1 : count.intValue() + 1); - } + @NotNull + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); } - return ContainerUtil.map2Set(vcsUsagesMap.entrySet(), new Function, UsageDescriptor>() { - @Override - public UsageDescriptor fun(Map.Entry vcsUsage) { - return new UsageDescriptor(createGroupDescriptor(), vcsUsage.getKey(), vcsUsage.getValue()); - } - }); - } - - @NotNull - public String getGroupId() { - return GROUP_ID; - } - - @NotNull - public Set getUsages(@Nullable Project project) { - if (project != null) { - persistProjectUsages(project, getProjectUsages(project)); + @NotNull + public Set getProjectUsages(@NotNull Project project) { + return ContainerUtil.map2Set(ProjectLevelVcsManager.getInstance(project).getAllActiveVcss(), new Function() { + @Override + public UsageDescriptor fun(AbstractVcs vcs) { + return new UsageDescriptor(vcs.getName(), 1); + } + }); } - - return getApplicationUsages(); - } - - public static Set getProjectUsages(@NotNull Project project) { - return ContainerUtil.map2Set(ProjectLevelVcsManager.getInstance(project).getAllActiveVcss(), new Function() { - @Override - public UsageDescriptor fun(AbstractVcs vcs) { - return new UsageDescriptor(createGroupDescriptor(), vcs.getName(), 1); - } - }); - } - - public static GroupDescriptor createGroupDescriptor() { - return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); - } }