Drop absent jdk annotation notifier

This commit is contained in:
Nikolay Krasko
2015-08-21 15:40:34 +03:00
parent 341f09afd3
commit 9b5b5bb0ee
3 changed files with 3 additions and 240 deletions
@@ -16,11 +16,10 @@
package org.jetbrains.kotlin.idea.configuration
import com.intellij.openapi.project.Project
import com.intellij.notification.NotificationsManager
import com.intellij.notification.Notification
import com.intellij.openapi.projectRoots.Sdk
import org.jetbrains.kotlin.idea.configuration.ui.notifications.*
import com.intellij.notification.NotificationsManager
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.configuration.ui.notifications.ConfigureKotlinNotification
object ConfigureKotlinNotificationManager: KotlinSingleNotificationManager<ConfigureKotlinNotification> {
fun notify(project: Project) {
@@ -28,13 +27,6 @@ object ConfigureKotlinNotificationManager: KotlinSingleNotificationManager<Confi
}
}
@deprecated("Deprecated after moving to platform types")
object AbsentSdkAnnotationsNotificationManager: KotlinSingleNotificationManager<AbsentSdkAnnotationsNotification> {
fun notify(project: Project, sdks: Collection<Sdk>) {
notify(project, AbsentSdkAnnotationsNotification(sdks, getNotificationTitle(sdks), getNotificationString(sdks)))
}
}
interface KotlinSingleNotificationManager<T: Notification> {
fun notify(project: Project, notification: T) {
val notificationsManager = NotificationsManager.getNotificationsManager() ?: return
@@ -1,156 +0,0 @@
/*
* Copyright 2010-2015 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 org.jetbrains.kotlin.idea.configuration.ui;
import com.google.common.collect.Sets;
import com.intellij.ProjectTopics;
import com.intellij.notification.NotificationDisplayType;
import com.intellij.notification.NotificationsConfiguration;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootAdapter;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.*;
import com.intellij.util.Alarm;
import com.intellij.util.PlatformUtils;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.configuration.AbsentSdkAnnotationsNotificationManager;
import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtils;
import org.jetbrains.kotlin.idea.configuration.ui.notifications.NotificationsPackage;
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil;
import org.jetbrains.kotlin.idea.versions.KotlinRuntimeLibraryUtil;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Deprecated after moving to platform types.
*/
@Deprecated
public class AbsentJdkAnnotationsComponent extends AbstractProjectComponent {
public static final String EXTERNAL_ANNOTATIONS_GROUP_ID = "Kotlin External annotations";
private volatile Alarm notificationAlarm;
protected AbsentJdkAnnotationsComponent(Project project) {
super(project);
NotificationsConfiguration.getNotificationsConfiguration().
register(EXTERNAL_ANNOTATIONS_GROUP_ID, NotificationDisplayType.STICKY_BALLOON, true);
}
@Override
public void projectOpened() {
super.projectOpened();
MessageBusConnection connection = myProject.getMessageBus().connect();
notificationAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, myProject);
connection.subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() {
@Override
public void enteredDumbMode() {
}
@Override
public void exitDumbMode() {
scheduleNotificationCheck();
}
});
connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
@Override
public void rootsChanged(ModuleRootEvent event) {
scheduleNotificationCheck();
}
});
connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
for (VFileEvent event : events) {
if (event instanceof VFileCreateEvent || event instanceof VFileDeleteEvent ||
event instanceof VFileMoveEvent || event instanceof VFileCopyEvent) {
scheduleNotificationCheck();
break;
}
}
}
});
}
private void scheduleNotificationCheck() {
if (notificationAlarm.isDisposed()) {
return;
}
notificationAlarm.cancelAllRequests();
notificationAlarm.addRequest(new Runnable() {
@Override
public void run() {
DumbService.getInstance(myProject).smartInvokeLater(new Runnable() {
@Override
public void run() {
Collection<Sdk> sdks = collectSdksWithoutAnnotations();
if (!sdks.isEmpty()) {
AbsentSdkAnnotationsNotificationManager.INSTANCE$.notify(myProject, sdks);
}
}
});
}
}, TimeUnit.SECONDS.toMillis(1));
}
@NotNull
private Collection<Sdk> collectSdksWithoutAnnotations() {
Set<Sdk> sdks = Sets.newHashSet();
for (Module module : ConfigureKotlinInProjectUtils.getModulesWithKotlinFiles(myProject)) {
if (ProjectStructureUtil.isJavaKotlinModule(module)) {
Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null && !areAnnotationsCorrect(sdk)) {
sdks.add(sdk);
}
}
}
return sdks;
}
private static boolean areAnnotationsCorrect(@NotNull Sdk sdk) {
if (NotificationsPackage.isAndroidSdk(sdk)) {
return KotlinRuntimeLibraryUtil.androidSdkAnnotationsArePresent(sdk) && !KotlinRuntimeLibraryUtil.jdkAnnotationsArePresent(sdk);
}
else if (!isAndroidStudio()) {
return KotlinRuntimeLibraryUtil.jdkAnnotationsArePresent(sdk);
}
else {
// Android studio always recreates standard sdk from scratch so any addition configuration will be lost
return true;
}
}
private static boolean isAndroidStudio() {
return "AndroidStudio".equals(PlatformUtils.getPlatformPrefix());
}
}
@@ -1,73 +0,0 @@
/*
* Copyright 2010-2015 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 org.jetbrains.kotlin.idea.configuration.ui.notifications
import com.intellij.notification.Notification
import com.intellij.notification.NotificationListener
import com.intellij.notification.NotificationType
import com.intellij.openapi.projectRoots.Sdk
import org.jetbrains.kotlin.idea.configuration.ui.AbsentJdkAnnotationsComponent
import org.jetbrains.kotlin.idea.versions.KotlinRuntimeLibraryUtil
import javax.swing.event.HyperlinkEvent
public class AbsentSdkAnnotationsNotification(sdks: Collection<Sdk>, title: String, val text: String) :
Notification(
AbsentJdkAnnotationsComponent.EXTERNAL_ANNOTATIONS_GROUP_ID,
title, text,
NotificationType.WARNING,
AbsentAnnotationsListener(sdks) // Workaround for KT-4086
)
{
override fun equals(obj: Any?) = obj is AbsentSdkAnnotationsNotification && text == obj.text && getTitle() == obj.getTitle()
override fun hashCode(): Int = 31 * getTitle().hashCode() + text.hashCode()
}
fun isAndroidSdk(sdk: Sdk) = sdk.getSdkType().getName() == "Android SDK"
fun getNotificationTitle(sdks: Collection<Sdk>) = "Kotlin external annotations for ${getSdkKind(sdks)} are not set for " + getSdkName(sdks)
fun getNotificationString(sdks: Collection<Sdk>) = "<a href=\"configure\">Set up Kotlin ${getSdkKind(sdks)} annotations</a>"
private class AbsentAnnotationsListener(val sdks: Collection<Sdk>): NotificationListener {
override fun hyperlinkUpdate(notification: Notification, event: HyperlinkEvent) {
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
if (event.getDescription() == "configure") {
for (sdk in sdks) {
if (isAndroidSdk(sdk)) {
if (!KotlinRuntimeLibraryUtil.androidSdkAnnotationsArePresent(sdk)) {
KotlinRuntimeLibraryUtil.addAndroidSdkAnnotations(sdk);
}
if (KotlinRuntimeLibraryUtil.jdkAnnotationsArePresent(sdk)) {
KotlinRuntimeLibraryUtil.removeJdkAnnotations(sdk);
}
}
else {
KotlinRuntimeLibraryUtil.addJdkAnnotations(sdk);
}
}
}
notification.expire()
}
}
}
private fun getSdkKind(sdks: Collection<Sdk>) = if (sdks.size() > 1) "SDK" else if (isAndroidSdk(sdks.first())) "Android SDK" else "JDK"
private fun getSdkName(sdks: Collection<Sdk>) = if (sdks.size() > 1) "several SDKs" else "'${sdks.first().getName()}'"