Cleanup (minor startup code refactoring)

This commit is contained in:
Roman Shevchenko
2016-04-07 16:11:41 +02:00
parent f83e056f0a
commit fb2bf3fa6e
2 changed files with 145 additions and 152 deletions
@@ -15,8 +15,6 @@
*/
package com.intellij.idea;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.PrivacyPolicy;
import com.intellij.ide.customize.CustomizeIDEWizardDialog;
import com.intellij.ide.customize.CustomizeIDEWizardStepsProvider;
import com.intellij.ide.plugins.PluginManagerCore;
@@ -25,14 +23,9 @@ import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.ConfigImportHelper;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.SystemInfoRt;
@@ -40,15 +33,10 @@ import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.io.win32.IdeaWin32;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.ui.HyperlinkAdapter;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.Consumer;
import com.intellij.util.EnvironmentUtil;
import com.intellij.util.PlatformUtils;
import com.intellij.util.lang.UrlClassLoader;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.SwingHelper;
import com.sun.jna.Native;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
@@ -58,15 +46,10 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.io.BuiltInServer;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.StyleSheet;
import java.awt.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
@@ -137,7 +120,12 @@ public class StartupUtil {
if (!checkSystemFolders()) {
System.exit(Main.DIR_CHECK_FAILED);
}
if (!lockSystemFolders(args)) {
ActivationResult result = lockSystemFolders(args);
if (result == ActivationResult.ACTIVATED) {
System.exit(0);
}
else if (result != ActivationResult.STARTED) {
System.exit(Main.INSTANCE_CHECK_FAILED);
}
@@ -154,20 +142,7 @@ public class StartupUtil {
if (!Main.isHeadless()) {
AppUIUtil.updateWindowIcon(JOptionPane.getRootFrame());
AppUIUtil.registerBundledFonts();
final Pair<PrivacyPolicy.Version, String> policy = PrivacyPolicy.getContent();
if (!PrivacyPolicy.isVersionAccepted(policy.getFirst())) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
showPrivacyPolicyAgreement(policy.getSecond());
}
});
PrivacyPolicy.setVersionAccepted(policy.getFirst());
}
catch (Exception ignored) {
}
}
AppUIUtil.showPrivacyPolicy();
}
appStarter.start(newConfigFolder);
@@ -305,7 +280,9 @@ public class StartupUtil {
}
}
private synchronized static boolean lockSystemFolders(String[] args) {
private enum ActivationResult { STARTED, ACTIVATED, FAILED }
private synchronized static @NotNull ActivationResult lockSystemFolders(String[] args) {
if (ourSocketLock != null) {
throw new AssertionError();
}
@@ -318,33 +295,30 @@ public class StartupUtil {
}
catch (Exception e) {
Main.showMessage("Cannot Lock System Folders", e);
return false;
return ActivationResult.FAILED;
}
if (status == SocketLock.ActivateStatus.NO_INSTANCE) {
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
@SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
@Override
public void run() {
synchronized (StartupUtil.class) {
ourSocketLock.dispose();
ourSocketLock = null;
}
ShutDownTracker.getInstance().registerShutdownTask(() -> {
//noinspection SynchronizeOnThis
synchronized (StartupUtil.class) {
ourSocketLock.dispose();
ourSocketLock = null;
}
});
return true;
return ActivationResult.STARTED;
}
else if (status == SocketLock.ActivateStatus.ACTIVATED) {
//noinspection UseOfSystemOutOrSystemErr
System.out.println("Already running");
return ActivationResult.ACTIVATED;
}
else if (Main.isHeadless() || status == SocketLock.ActivateStatus.CANNOT_ACTIVATE) {
String message = "Only one instance of " + ApplicationNamesInfo.getInstance().getFullProductName() + " can be run at a time.";
Main.showMessage("Too Many Instances", message, true);
}
if (status == SocketLock.ActivateStatus.ACTIVATED) {
System.out.println("Already running");
System.exit(0);
}
return false;
return ActivationResult.FAILED;
}
private static void fixProcessEnvironment(Logger log) {
@@ -438,76 +412,6 @@ public class StartupUtil {
log.info("JNU charset: " + System.getProperty("sun.jnu.encoding"));
}
/**
* @param htmlText Updated version of Privacy Policy text if any.
* If it's <code>null</code> the standard text from bundled resources would be used.
*/
public static void showPrivacyPolicyAgreement(@NotNull String htmlText) {
DialogWrapper dialog = new DialogWrapper(true) {
@Nullable
@Override
protected JComponent createCenterPanel() {
JPanel centerPanel = new JPanel(new BorderLayout(JBUI.scale(5), JBUI.scale(5)));
JEditorPane viewer = SwingHelper.createHtmlViewer(true, null, JBColor.WHITE, JBColor.BLACK);
viewer.setFocusable(true);
viewer.addHyperlinkListener(new HyperlinkAdapter() {
@Override
protected void hyperlinkActivated(HyperlinkEvent e) {
URL url = e.getURL();
if (url != null) {
BrowserUtil.browse(url);
}
else {
SwingHelper.scrollToReference(viewer, e.getDescription());
}
}
});
viewer.setText(htmlText);
StyleSheet styleSheet = ((HTMLDocument)viewer.getDocument()).getStyleSheet();
styleSheet.addRule("body {font-family: \"Segoe UI\", Tahoma, sans-serif;}");
styleSheet.addRule("body {margin-top:0;padding-top:0;}");
styleSheet.addRule("body {font-size:" + JBUI.scaleFontSize(13) + "pt;}");
styleSheet.addRule("h2, em {margin-top:" + JBUI.scaleFontSize(20) + "pt;}");
styleSheet.addRule("h1, h2, h3, p, h4, em {margin-bottom:0;padding-bottom:0;}");
styleSheet.addRule("p, h1 {margin-top:0;padding-top:"+JBUI.scaleFontSize(6)+"pt;}");
styleSheet.addRule("li {margin-bottom:" + JBUI.scaleFontSize(6) + "pt;}");
styleSheet.addRule("h2 {margin-top:0;padding-top:"+JBUI.scaleFontSize(13)+"pt;}");
viewer.setCaretPosition(0);
viewer.setBorder(JBUI.Borders.empty(0, 5, 5, 5));
centerPanel.add(new JLabel("Please read and accept these terms and conditions:"), BorderLayout.NORTH);
centerPanel
.add(new JBScrollPane(viewer, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER),
BorderLayout.CENTER);
return centerPanel;
}
@Override
protected void createDefaultActions() {
super.createDefaultActions();
init();
setOKButtonText("Accept");
setCancelButtonText("Reject and Exit");
setAutoAdjustable(false);
}
@Override
public void doCancelAction() {
super.doCancelAction();
ApplicationEx application = ApplicationManagerEx.getApplicationEx();
if (application == null) {
System.exit(Main.PRIVACY_POLICY_REJECTION);
}
else {
((ApplicationImpl)application).exit(true, true, false, false);
}
}
};
dialog.setModal(true);
dialog.setTitle(ApplicationNamesInfo.getInstance().getFullProductName() + " Privacy Policy Agreement");
dialog.setSize(JBUI.scale(509), JBUI.scale(395));
dialog.show();
}
static void runStartupWizard() {
ApplicationInfoEx appInfo = ApplicationInfoImpl.getShadowInstance();
@@ -535,4 +439,4 @@ public class StartupUtil {
PluginManagerCore.invalidatePlugins();
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -15,27 +15,39 @@
*/
package com.intellij.ui;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.PrivacyPolicy;
import com.intellij.idea.Main;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.PlatformUtils;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.SystemProperties;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.SwingHelper;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.StyleSheet;
import java.awt.*;
import java.io.File;
import java.io.InputStream;
@@ -43,6 +55,9 @@ import java.net.URL;
import java.util.List;
import java.util.Locale;
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER;
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
/**
* @author yole
*/
@@ -71,18 +86,13 @@ public class AppUIUtil {
return images;
}
public static void invokeLaterIfProjectAlive(@NotNull final Project project, @NotNull final Runnable runnable) {
public static void invokeLaterIfProjectAlive(@NotNull Project project, @NotNull Runnable runnable) {
final Application application = ApplicationManager.getApplication();
if (application.isDispatchThread()) {
runnable.run();
}
else {
application.invokeLater(runnable, new Condition() {
@Override
public boolean value(Object o) {
return !project.isOpen() || project.isDisposed();
}
});
application.invokeLater(runnable, o -> !project.isOpen() || project.isDisposed());
}
}
@@ -158,14 +168,11 @@ public class AppUIUtil {
}
}
public static void hideToolWindowBalloon(@NotNull final String id, @NotNull final Project project) {
invokeLaterIfProjectAlive(project, new Runnable() {
@Override
public void run() {
Balloon balloon = ToolWindowManager.getInstance(project).getToolWindowBalloon(id);
if (balloon != null) {
balloon.hide();
}
public static void hideToolWindowBalloon(@NotNull String id, @NotNull Project project) {
invokeLaterIfProjectAlive(project, () -> {
Balloon balloon = ToolWindowManager.getInstance(project).getToolWindowBalloon(id);
if (balloon != null) {
balloon.hide();
}
});
}
@@ -173,30 +180,112 @@ public class AppUIUtil {
private static final int MIN_ICON_SIZE = 32;
@Nullable
public static String findIcon(final String iconsPath) {
final File iconsDir = new File(iconsPath);
public static String findIcon(@NotNull String iconsPath) {
String[] childFiles = ObjectUtils.notNull(new File(iconsPath).list(), ArrayUtil.EMPTY_STRING_ARRAY);
// 1. look for .svg icon
for (String child : iconsDir.list()) {
for (String child : childFiles) {
if (child.endsWith(".svg")) {
return iconsPath + '/' + child;
}
}
// 2. look for .png icon of max size
int max = 0;
int best = MIN_ICON_SIZE - 1;
String iconPath = null;
for (String child : iconsDir.list()) {
if (!child.endsWith(".png")) continue;
final String path = iconsPath + '/' + child;
final Icon icon = new ImageIcon(path);
final int size = icon.getIconHeight();
if (size >= MIN_ICON_SIZE && size > max && size == icon.getIconWidth()) {
max = size;
iconPath = path;
for (String child : childFiles) {
if (child.endsWith(".png")) {
String path = iconsPath + '/' + child;
Icon icon = new ImageIcon(path);
int size = icon.getIconHeight();
if (size > best && size == icon.getIconWidth()) {
best = size;
iconPath = path;
}
}
}
return iconPath;
}
}
public static void showPrivacyPolicy() {
Pair<PrivacyPolicy.Version, String> policy = PrivacyPolicy.getContent();
if (!PrivacyPolicy.isVersionAccepted(policy.getFirst())) {
try {
SwingUtilities.invokeAndWait(() -> showPrivacyPolicyAgreement(policy.getSecond()));
PrivacyPolicy.setVersionAccepted(policy.getFirst());
}
catch (Exception e) {
Logger.getInstance(AppUIUtil.class).warn(e);
}
}
}
/**
* @param htmlText Updated version of Privacy Policy text if any.
* If it's {@code null}, the standard text from bundled resources would be used.
*/
public static void showPrivacyPolicyAgreement(@NotNull String htmlText) {
DialogWrapper dialog = new DialogWrapper(true) {
@Nullable
@Override
protected JComponent createCenterPanel() {
JPanel centerPanel = new JPanel(new BorderLayout(JBUI.scale(5), JBUI.scale(5)));
JEditorPane viewer = SwingHelper.createHtmlViewer(true, null, JBColor.WHITE, JBColor.BLACK);
viewer.setFocusable(true);
viewer.addHyperlinkListener(new HyperlinkAdapter() {
@Override
protected void hyperlinkActivated(HyperlinkEvent e) {
URL url = e.getURL();
if (url != null) {
BrowserUtil.browse(url);
}
else {
SwingHelper.scrollToReference(viewer, e.getDescription());
}
}
});
viewer.setText(htmlText);
StyleSheet styleSheet = ((HTMLDocument)viewer.getDocument()).getStyleSheet();
styleSheet.addRule("body {font-family: \"Segoe UI\", Tahoma, sans-serif;}");
styleSheet.addRule("body {margin-top:0;padding-top:0;}");
styleSheet.addRule("body {font-size:" + JBUI.scaleFontSize(13) + "pt;}");
styleSheet.addRule("h2, em {margin-top:" + JBUI.scaleFontSize(20) + "pt;}");
styleSheet.addRule("h1, h2, h3, p, h4, em {margin-bottom:0;padding-bottom:0;}");
styleSheet.addRule("p, h1 {margin-top:0;padding-top:"+JBUI.scaleFontSize(6)+"pt;}");
styleSheet.addRule("li {margin-bottom:" + JBUI.scaleFontSize(6) + "pt;}");
styleSheet.addRule("h2 {margin-top:0;padding-top:"+JBUI.scaleFontSize(13)+"pt;}");
viewer.setCaretPosition(0);
viewer.setBorder(JBUI.Borders.empty(0, 5, 5, 5));
centerPanel.add(new JLabel("Please read and accept these terms and conditions:"), BorderLayout.NORTH);
centerPanel.add(new JBScrollPane(viewer, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.CENTER);
return centerPanel;
}
@Override
protected void createDefaultActions() {
super.createDefaultActions();
init();
setOKButtonText("Accept");
setCancelButtonText("Reject and Exit");
setAutoAdjustable(false);
}
@Override
public void doCancelAction() {
super.doCancelAction();
ApplicationEx application = ApplicationManagerEx.getApplicationEx();
if (application == null) {
System.exit(Main.PRIVACY_POLICY_REJECTION);
}
else {
((ApplicationImpl)application).exit(true, true, false, false);
}
}
};
dialog.setModal(true);
dialog.setTitle(ApplicationNamesInfo.getInstance().getFullProductName() + " Privacy Policy Agreement");
dialog.setSize(JBUI.scale(509), JBUI.scale(395));
dialog.show();
}
}