2 * Copyright 2000-2015 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.idea;
18 import com.intellij.ide.Bootstrap;
19 import com.intellij.openapi.application.PathManager;
20 import com.intellij.openapi.util.Comparing;
21 import com.intellij.openapi.util.SystemInfoRt;
22 import com.intellij.openapi.util.io.FileUtilRt;
23 import com.intellij.util.ArrayUtilRt;
24 import com.intellij.util.Restarter;
25 import com.intellij.util.ui.JBUI;
26 import com.intellij.util.ui.UIUtil;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.Locale;
36 @SuppressWarnings({"UseOfSystemOutOrSystemErr", "MethodNamesDifferingOnlyByCase"})
38 public static final int NO_GRAPHICS = 1;
39 public static final int UPDATE_FAILED = 2;
40 public static final int STARTUP_EXCEPTION = 3;
41 public static final int JDK_CHECK_FAILED = 4;
42 public static final int DIR_CHECK_FAILED = 5;
43 public static final int INSTANCE_CHECK_FAILED = 6;
44 public static final int LICENSE_ERROR = 7;
45 public static final int PLUGIN_ERROR = 8;
47 private static final String AWT_HEADLESS = "java.awt.headless";
48 private static final String PLATFORM_PREFIX_PROPERTY = "idea.platform.prefix";
49 private static final String[] NO_ARGS = {};
51 private static boolean isHeadless;
52 private static boolean isCommandLine;
56 public static void main(String[] args) {
57 if (args.length == 1 && "%f".equals(args[0])) {
64 System.setProperty(AWT_HEADLESS, Boolean.TRUE.toString());
66 else if (GraphicsEnvironment.isHeadless()) {
67 showMessage("Startup Error", "Unable to detect graphics environment", true);
68 System.exit(NO_GRAPHICS);
70 else if (args.length == 0) {
75 showMessage("Update Failed", t);
76 System.exit(UPDATE_FAILED);
81 Bootstrap.main(args, Main.class.getName() + "Impl", "start");
84 showMessage("Start Failed", t);
85 System.exit(STARTUP_EXCEPTION);
89 public static boolean isHeadless() {
93 public static boolean isCommandLine() {
97 public static void setFlags(String[] args) {
98 isHeadless = isHeadless(args);
99 isCommandLine = isCommandLine(args);
102 private static boolean isHeadless(String[] args) {
103 if (Boolean.valueOf(System.getProperty(AWT_HEADLESS))) {
107 if (args.length == 0) {
111 String firstArg = args[0];
112 return Comparing.strEqual(firstArg, "ant") ||
113 Comparing.strEqual(firstArg, "duplocate") ||
114 Comparing.strEqual(firstArg, "traverseUI") ||
115 (firstArg.length() < 20 && firstArg.endsWith("inspect"));
118 private static boolean isCommandLine(String[] args) {
119 if (isHeadless()) return true;
120 return args.length > 0 && Comparing.strEqual(args[0], "diff");
123 public static boolean isUITraverser(final String[] args) {
124 return args.length > 0 && Comparing.strEqual(args[0], "traverseUI");
127 private static void installPatch() throws IOException {
128 String platform = System.getProperty(PLATFORM_PREFIX_PROPERTY, "idea");
129 String patchFileName = ("jetbrains.patch.jar." + platform).toLowerCase(Locale.US);
130 String tempDir = System.getProperty("java.io.tmpdir");
132 // always delete previous patch copy
133 File patchCopy = new File(tempDir, patchFileName + "_copy");
134 File log4jCopy = new File(tempDir, "log4j.jar." + platform + "_copy");
135 File jnaUtilsCopy = new File(tempDir, "jna-utils.jar." + platform + "_copy");
136 File jnaCopy = new File(tempDir, "jna.jar." + platform + "_copy");
137 if (!FileUtilRt.delete(patchCopy) || !FileUtilRt.delete(log4jCopy) || !FileUtilRt.delete(jnaUtilsCopy) || !FileUtilRt.delete(jnaCopy)) {
138 throw new IOException("Cannot delete temporary files in " + tempDir);
141 File patch = new File(tempDir, patchFileName);
142 if (!patch.exists()) return;
144 File log4j = new File(PathManager.getLibPath(), "log4j.jar");
145 if (!log4j.exists()) throw new IOException("Log4J is missing: " + log4j);
147 File jnaUtils = new File(PathManager.getLibPath(), "jna-utils.jar");
148 if (!jnaUtils.exists()) throw new IOException("jna-utils.jar is missing: " + jnaUtils);
150 File jna = new File(PathManager.getLibPath(), "jna.jar");
151 if (!jna.exists()) throw new IOException("jna is missing: " + jna);
153 copyFile(patch, patchCopy, true);
154 copyFile(log4j, log4jCopy, false);
155 copyFile(jna, jnaCopy, false);
156 copyFile(jnaUtils, jnaUtilsCopy, false);
159 if (Restarter.isSupported()) {
160 List<String> args = new ArrayList<String>();
162 if (SystemInfoRt.isWindows) {
163 File launcher = new File(PathManager.getBinPath(), "VistaLauncher.exe");
164 args.add(Restarter.createTempExecutable(launcher).getPath());
167 //noinspection SpellCheckingInspection
168 Collections.addAll(args,
169 System.getProperty("java.home") + "/bin/java",
172 "-Djna.boot.library.path=",
173 "-Djna.debug_load=true",
174 "-Djna.debug_load.jna=true",
176 patchCopy.getPath() + File.pathSeparator + log4jCopy.getPath() + File.pathSeparator + jnaCopy.getPath() + File.pathSeparator + jnaUtilsCopy.getPath(),
177 "-Djava.io.tmpdir=" + tempDir,
178 "-Didea.updater.log=" + PathManager.getLogPath(),
179 "-Dswing.defaultlaf=" + UIManager.getSystemLookAndFeelClassName(),
180 "com.intellij.updater.Runner",
182 PathManager.getHomePath());
184 status = Restarter.scheduleRestart(ArrayUtilRt.toStringArray(args));
187 String message = "Patch update is not supported - please do it manually";
188 showMessage("Update Error", message, true);
194 private static void copyFile(File original, File copy, boolean move) throws IOException {
196 if (!original.renameTo(copy) || !FileUtilRt.delete(original)) {
197 throw new IOException("Cannot create temporary file: " + copy);
201 FileUtilRt.copy(original, copy);
202 if (!copy.exists()) {
203 throw new IOException("Cannot create temporary file: " + copy);
208 public static void showMessage(String title, Throwable t) {
209 StringWriter message = new StringWriter();
210 message.append("Internal error. Please report to http://");
211 boolean studio = "AndroidStudio".equalsIgnoreCase(System.getProperty(PLATFORM_PREFIX_PROPERTY));
212 message.append(studio ? "code.google.com/p/android/issues" : "youtrack.jetbrains.com");
213 message.append("\n\n");
214 t.printStackTrace(new PrintWriter(message));
215 showMessage(title, message.toString(), true);
218 @SuppressWarnings({"UseJBColor", "UndesirableClassUsage"})
219 public static void showMessage(String title, String message, boolean error) {
220 if (isCommandLine() || GraphicsEnvironment.isHeadless()) {
221 PrintStream stream = error ? System.err : System.out;
222 stream.println("\n" + title + ": " + message);
225 try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }
226 catch (Throwable ignore) { }
228 JTextPane textPane = new JTextPane();
229 textPane.setEditable(false);
230 textPane.setText(message.replaceAll("\t", " "));
231 textPane.setBackground(UIUtil.getPanelBackground());
232 textPane.setCaretPosition(0);
233 JScrollPane scrollPane = new JScrollPane(
234 textPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
235 scrollPane.setBorder(null);
237 int maxHeight = Math.min(JBUI.scale(600), Toolkit.getDefaultToolkit().getScreenSize().height - 150);
238 Dimension component = scrollPane.getPreferredSize();
239 if (component.height >= maxHeight) {
240 Object setting = UIManager.get("ScrollBar.width");
241 int width = setting instanceof Integer ? ((Integer)setting).intValue() : 20;
242 scrollPane.setPreferredSize(new Dimension(component.width + width, maxHeight));
245 int type = error ? JOptionPane.ERROR_MESSAGE : JOptionPane.INFORMATION_MESSAGE;
246 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), scrollPane, title, type);