Java tutorial
package org.jetbrains.jet.plugin;/* * Copyright 2010-2012 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. */ import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManager; import com.intellij.ide.util.PropertiesComponent; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.packaging.impl.elements.ManifestFileUtil; import com.intellij.util.text.VersionComparatorUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.plugin.quickfix.ConfigureKotlinLibraryNotificationProvider; import org.jetbrains.jet.utils.PathUtil; import javax.swing.event.HyperlinkEvent; import java.io.File; import java.io.IOException; import java.util.jar.Attributes; import java.util.jar.JarFile; /** * @author Evgeny Gerashchenko * @since 5/22/12 */ public class OutdatedKotlinRuntimeNotification extends AbstractProjectComponent { private static final String UNKNOWN_VERSION = "UNKNOWN"; private static final String SUPPRESSED_PROPERTY_NAME = "oudtdated.runtime.suppressed.plugin.version"; public OutdatedKotlinRuntimeNotification(final Project project) { super(project); } @Override public void projectOpened() { if (ApplicationManager.getApplication().isInternal()) return; String runtimeVersion = getRuntimeVersion(); final String pluginVersion = getPluginVersion(); if (runtimeVersion == null) return; // runtime is not present in project if ("@snapshot@".equals(pluginVersion)) return; // plugin is run from sources, can't compare versions // user already clicked suppress if (pluginVersion.equals(PropertiesComponent.getInstance(myProject).getValue(SUPPRESSED_PROPERTY_NAME))) return; boolean isRuntimeOutdated = "snapshot".equals(runtimeVersion) || UNKNOWN_VERSION.equals(runtimeVersion) || runtimeVersion.startsWith("internal-") != pluginVersion.startsWith("internal-") || VersionComparatorUtil.compare(pluginVersion, runtimeVersion) > 0; if (!isRuntimeOutdated) return; String message = String.format( "<p>Your version of Kotlin runtime library is %s, while plugin version is %s." + " Runtime library should be updated to avoid compatibility problems.</p>" + "<p><a href=\"update\">Update Runtime</a> <a href=\"ignore\">Ignore</a></p>", UNKNOWN_VERSION.equals(runtimeVersion) ? "older than 0.1.2296" : runtimeVersion, pluginVersion); Notifications.Bus.notify(new Notification("Outdated Kotlin Runtime", "Outdated Kotlin Runtime", message, NotificationType.WARNING, new NotificationListener() { @Override public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { if ("update".equals(event.getDescription())) { updateRuntime(); } else if ("ignore".equals(event.getDescription())) { PropertiesComponent.getInstance(myProject).setValue(SUPPRESSED_PROPERTY_NAME, pluginVersion); } else { throw new AssertionError(); } notification.expire(); } } }), myProject); } private void updateRuntime() { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { File runtimePath = PathUtil.getDefaultRuntimePath(); if (runtimePath == null) { Messages.showErrorDialog(myProject, "kotlin-runtime.jar is not found. Make sure plugin is properly installed.", "No Runtime Found"); return; } VirtualFile runtimeJar = getKotlinRuntimeJar(); assert runtimeJar != null; VirtualFile jarFile = JarFileSystem.getInstance().getVirtualFileForJar(runtimeJar); if (jarFile != null) { runtimeJar = jarFile; } try { FileUtil.copy(runtimePath, new File(runtimeJar.getPath())); } catch (IOException e) { throw new AssertionError(e); } runtimeJar.refresh(true, true); } }); } @Nullable private String getRuntimeVersion() { VirtualFile kotlinRuntimeJar = getKotlinRuntimeJar(); if (kotlinRuntimeJar == null) return null; VirtualFile manifestFile = kotlinRuntimeJar.findFileByRelativePath(JarFile.MANIFEST_NAME); if (manifestFile != null) { Attributes attributes = ManifestFileUtil.readManifest(manifestFile).getMainAttributes(); if (attributes.containsKey(Attributes.Name.IMPLEMENTATION_VERSION)) { return attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION); } } return UNKNOWN_VERSION; } @Nullable private VirtualFile getKotlinRuntimeJar() { LibraryTable table = ProjectLibraryTable.getInstance(myProject); Library kotlinRuntime = table.getLibraryByName(ConfigureKotlinLibraryNotificationProvider.LIBRARY_NAME); if (kotlinRuntime != null) { for (VirtualFile root : kotlinRuntime.getFiles(OrderRootType.CLASSES)) { if (root.getName().equals(ConfigureKotlinLibraryNotificationProvider.KOTLIN_RUNTIME_JAR)) { return root; } } } return null; } @NotNull private static String getPluginVersion() { IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId("org.jetbrains.kotlin")); assert plugin != null : "How can it be? Kotlin plugin is available, but its component is running. Complete nonsense."; return plugin.getVersion(); } }