Configurable library jars usage statistics

This commit is contained in:
Ivan Chirkov
2014-09-30 19:46:22 +02:00
parent f5d4d94210
commit 097be10733
7 changed files with 260 additions and 0 deletions
@@ -0,0 +1,6 @@
<idea-plugin>
<extensions defaultExtensionNs="com.intellij">
<statistics.usagesCollector implementation="com.intellij.internal.statistic.libraryJar.LibraryJarUsagesCollector"/>
</extensions>
</idea-plugin>
@@ -0,0 +1,37 @@
/*
* Copyright 2000-2014 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.libraryJar;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Tag;
/**
* @author Ivan Chirkov
*/
@Tag("technology")
public class LibraryJarDescriptor {
/**
* Name of library/framework
*/
@Attribute("name")
public String myName;
/**
* Class used to identify library/framework
*/
@Attribute("class")
public String myClass;
}
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2014 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.libraryJar;
/**
* @author Ivan Chirkov
*/
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Property;
public class LibraryJarDescriptors {
@Property(surroundWithTag = false)
@AbstractCollection(surroundWithTag = false)
public LibraryJarDescriptor[] myDescriptors;
public LibraryJarDescriptor[] getDescriptors() {
return myDescriptors;
}
}
@@ -0,0 +1,94 @@
/*
* Copyright 2000-2014 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.libraryJar;
import com.intellij.facet.frameworks.SettingsConnectionService;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.xmlb.XmlSerializationException;
import com.intellij.util.xmlb.XmlSerializer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
/**
* @author Ivan Chirkov
*/
public class LibraryJarStatisticsService extends SettingsConnectionService {
private static final String FILE_NAME = "library-jar-statistics.xml";
private static final String DEFAULT_SETTINGS_URL = "http://jetbrains.com/idea/" + FILE_NAME;
private static final String DEFAULT_SERVICE_URL = "http://frameworks.jetbrains.com/statistics";
private static final LibraryJarStatisticsService myInstance = new LibraryJarStatisticsService();
private LibraryJarDescriptor[] myDescriptors;
public static LibraryJarStatisticsService getInstance() {
return myInstance;
}
protected LibraryJarStatisticsService() {
super(DEFAULT_SETTINGS_URL, DEFAULT_SERVICE_URL);
}
@NotNull
public LibraryJarDescriptor[] getTechnologyDescriptors() {
if (myDescriptors == null) {
final URL url = createVersionsUrl();
if (url == null) return new LibraryJarDescriptor[0];
final LibraryJarDescriptors descriptors = deserialize(url);
myDescriptors = descriptors == null ? new LibraryJarDescriptor[0] : descriptors.getDescriptors();
}
return myDescriptors;
}
@Nullable
private static LibraryJarDescriptors deserialize(@Nullable URL url) {
if (url == null) return null;
LibraryJarDescriptors libraryJarDescriptors = null;
try {
libraryJarDescriptors = XmlSerializer.deserialize(url, LibraryJarDescriptors.class);
}
catch (XmlSerializationException e) {
//
}
return libraryJarDescriptors;
}
@Nullable
private URL createVersionsUrl() {
final String serviceUrl = getServiceUrl();
if (StringUtil.isNotEmpty(serviceUrl)) {
try {
final String url = serviceUrl + "/" + FILE_NAME;
HttpConfigurable.getInstance().prepareURL(url);
return new URL(url);
}
catch (MalformedURLException ignored) {
}
catch (IOException e) {
// no route to host, unknown host, etc.
}
}
return null;
}
}
@@ -0,0 +1,82 @@
/*
* Copyright 2000-2014 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.libraryJar;
import com.intellij.internal.statistic.AbstractApplicationUsagesCollector;
import com.intellij.internal.statistic.CollectUsagesException;
import com.intellij.internal.statistic.beans.GroupDescriptor;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.ProjectScope;
import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Ivan Chirkov
*/
public class LibraryJarUsagesCollector extends AbstractApplicationUsagesCollector {
public static final Pattern MULTI_DIGIT_VERSION_PATTERN = Pattern.compile("(\\d+\\.\\d+).*");
private static final GroupDescriptor GROUP = GroupDescriptor.create("Libraries by jars", GroupDescriptor.LOWER_PRIORITY);
private static final Pattern PATH_PATTERN = Pattern.compile(".*/[\\w|\\-|\\.]+-([\\w|\\.]+)jar!/.*");
@NotNull
@Override
public Set<UsageDescriptor> getProjectUsages(@NotNull final Project project) throws CollectUsagesException {
final LibraryJarDescriptor[] descriptors = LibraryJarStatisticsService.getInstance().getTechnologyDescriptors();
final Set<UsageDescriptor> result = new HashSet<UsageDescriptor>(descriptors.length);
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
for (LibraryJarDescriptor descriptor : descriptors) {
String className = descriptor.myClass;
if (className != null) {
PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(className, ProjectScope.getLibrariesScope(project));
if (psiClass != null) {
Matcher matcher = PATH_PATTERN.matcher(psiClass.getContainingFile().getVirtualFile().getPath());
if (matcher.matches()) {
String version;
String fullVersion = matcher.group(1);
matcher = MULTI_DIGIT_VERSION_PATTERN.matcher(fullVersion);
if (matcher.matches()) {
version = matcher.group(1);
} else {
version = fullVersion.substring(0, fullVersion.indexOf("."));
}
result.add(new UsageDescriptor(descriptor.myName + "_" + version, 1));
}
}
}
}
}
});
return result;
}
@NotNull
@Override
public GroupDescriptor getGroupId() {
return GROUP;
}
}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<technologies>
<technology class="org.springframework.integration.channel.DirectChannel" name="spring-integration" />
</technologies>
+3
View File
@@ -21,6 +21,9 @@
<xi:include href="/META-INF/TypeMigration.xml" xpointer="xpointer(/idea-plugin/*)">
<xi:fallback/>
</xi:include>
<xi:include href="/META-INF/libraryJarUsage.xml" xpointer="xpointer(/idea-plugin/*)">
<xi:fallback/>
</xi:include>
<application-components>
<component>