update copyrights
[idea/community.git] / platform / bootstrap / src / com / intellij / idea / Main.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package com.intellij.idea;
18
19 import com.intellij.ide.Bootstrap;
20 import com.intellij.openapi.util.Comparing;
21 import org.jetbrains.annotations.NonNls;
22
23 import javax.swing.*;
24 import java.awt.*;
25 import java.io.*;
26 import java.net.URI;
27 import java.net.URISyntaxException;
28 import java.net.URL;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.List;
32
33 public class Main {
34   private static boolean isHeadless;
35
36   private Main() {
37   }
38
39   public static void main(final String[] args) {
40     if (installPatch()) {
41       JOptionPane.showMessageDialog(null, "The application cannot start right away since some critical files have been changed, " +
42                                           "please restart it manually.");
43       return;
44     }
45
46     isHeadless = isHeadless(args);
47     if (isHeadless) {
48       System.setProperty("java.awt.headless", Boolean.TRUE.toString());
49     }
50     else if (GraphicsEnvironment.isHeadless()) {
51       throw new HeadlessException("Unable to detect graphics environment");
52     }
53
54     Bootstrap.main(args, Main.class.getName() + "Impl", "start");
55   }
56
57   public static boolean isHeadless(final String[] args) {
58     @NonNls final String inspectAppCode = "inspect";
59     @NonNls final String antAppCode = "ant";
60     @NonNls final String duplocateCode = "duplocate";
61     @NonNls final String traverseUI = "traverseUI";
62     return args.length > 0 && (Comparing.strEqual(args[0], inspectAppCode) ||
63                                Comparing.strEqual(args[0], antAppCode) ||
64                                Comparing.strEqual(args[0], duplocateCode) ||
65                                Comparing.strEqual(args[0], traverseUI));
66   }
67
68   public static boolean isCommandLine(final String[] args) {
69     if (isHeadless(args)) return true;
70     @NonNls final String diffAppCode = "diff";
71     return args.length > 0 && Comparing.strEqual(args[0], diffAppCode);
72   }
73
74   public static boolean isHeadless() {
75     return isHeadless;
76   }
77
78   private static boolean installPatch() {
79     try {
80       File ideaHomeDir = getIdeaHomeDir();
81       if (ideaHomeDir == null) return false;
82
83       String platform = System.getProperty("idea.platform.prefix", "idea");
84       String patchFileName = "jetbrains.patch.jar." + platform;
85       File patchFile = new File(System.getProperty("java.io.tmpdir"), patchFileName);
86
87       if (!patchFile.exists()) return false;
88
89       try {
90         List<String> args = new ArrayList<String>();
91         if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
92           File launcherFile = new File(ideaHomeDir, "bin/vistalauncher.exe");
93           File launcherCopy = File.createTempFile("vistalauncher", ".exe");
94           launcherCopy.deleteOnExit();
95           copyFile(launcherFile, launcherCopy);
96           args.add(launcherCopy.getPath());
97         }
98
99         Collections.addAll(args,
100                            System.getProperty("java.home") + "/bin/java",
101                            "-classpath",
102                            patchFile.getPath(),
103                            "com.intellij.updater.Runner",
104                            "install",
105                            ideaHomeDir.getPath());
106         Process process = Runtime.getRuntime().exec(args.toArray(new String[args.size()]));
107
108         Thread outThread = new Thread(new StreamRedirector(process.getInputStream(), System.out));
109         Thread errThread = new Thread(new StreamRedirector(process.getErrorStream(), System.err));
110         outThread.start();
111         errThread.start();
112
113         try {
114           boolean requiresRestart = process.waitFor() == 42;
115           return requiresRestart;
116         }
117         finally {
118           outThread.join();
119           errThread.join();
120         }
121       }
122       finally {
123         patchFile.delete();
124       }
125     }
126     catch (Exception e) {
127       e.printStackTrace();
128     }
129     return false;
130   }
131
132   private static class StreamRedirector implements Runnable {
133     private final InputStream myIn;
134     private final OutputStream myOut;
135
136     private StreamRedirector(InputStream in, OutputStream out) {
137       myIn = in;
138       myOut = out;
139     }
140
141     public void run() {
142       try {
143         copyStream(myIn, myOut);
144       }
145       catch (IOException e) {
146         e.printStackTrace();
147       }
148     }
149   }
150
151   private static File getIdeaHomeDir() throws IOException {
152     URL url = Bootstrap.class.getResource("");
153     if (url == null || !"jar".equals(url.getProtocol())) return null;
154
155     String path = url.getPath();
156
157     int start = path.indexOf("file:/");
158     int end = path.indexOf("!/");
159     if (start == -1 || end == -1) return null;
160
161     String jarFileUrl = path.substring(start, end);
162
163     try {
164       File bootstrapJar = new File(new URI(jarFileUrl));
165       return bootstrapJar.getParentFile().getParentFile();
166     }
167     catch (URISyntaxException e) {
168       return null;
169     }
170   }
171
172   public static void copyFile(File from, File to) throws IOException {
173     to.getParentFile().mkdirs();
174
175     FileInputStream is = null;
176     FileOutputStream os = null;
177     try {
178       is = new FileInputStream(from);
179       os = new FileOutputStream(to);
180
181       copyStream(is, os);
182     }
183     finally {
184       if (is != null) {
185         try {
186           is.close();
187         }
188         catch (IOException e) {
189           e.printStackTrace();
190         }
191       }
192       if (os != null) {
193         try {
194           os.close();
195         }
196         catch (IOException e) {
197           e.printStackTrace();
198         }
199       }
200     }
201   }
202
203   public static void copyStream(InputStream from, OutputStream to) throws IOException {
204     byte[] buffer = new byte[65536];
205     while (true) {
206       int read = from.read(buffer);
207       if (read < 0) break;
208       to.write(buffer, 0, read);
209     }
210   }
211 }