2 * Copyright 2000-2009 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.openapi.application;
18 import com.intellij.openapi.util.io.FileUtil;
19 import com.intellij.openapi.util.text.StringUtil;
20 import com.intellij.util.SystemProperties;
21 import com.intellij.util.ui.UIUtil;
22 import com.intellij.ui.AppUIUtil;
23 import org.jetbrains.annotations.NonNls;
24 import org.jetbrains.annotations.Nullable;
28 import java.util.PropertyResourceBundle;
33 public class ConfigImportHelper {
34 @NonNls private static final String BUILD_NUMBER_FILE = "build.txt";
35 @NonNls private static final String PLUGINS_PATH = "plugins";
36 @NonNls private static final String BIN_FOLDER = "bin";
38 private ConfigImportHelper() {}
40 public static void importConfigsTo(String newConfigPath) {
42 ImportOldConfigsPanel dlg;
43 if (UIUtil.hasJdk6Dialogs()) {
44 dlg = new ImportOldConfigsPanel();
47 dlg = new ImportOldConfigsPanel(JOptionPane.getRootFrame());
50 UIUtil.setToolkitModal(dlg);
51 AppUIUtil.updateDialogIcon(dlg);
53 if (dlg.isImportEnabled()) {
54 File instHome = dlg.getSelectedFile();
55 File oldConfigDir = getOldConfigDir(instHome);
56 if (!validateOldConfigDir(instHome, oldConfigDir)) continue;
58 doImport(newConfigPath, oldConfigDir);
66 public static void doImport(final String newConfigPath, final File oldConfigDir) {
68 xcopy(oldConfigDir, new File(newConfigPath));
70 catch (IOException e) {
71 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
72 ApplicationBundle.message("error.unable.to.import.settings", e.getMessage()),
73 ApplicationBundle.message("title.settings.import.failed"), JOptionPane.WARNING_MESSAGE);
77 public static boolean validateOldConfigDir(final File instHome, final File oldConfigDir) {
78 if (oldConfigDir == null) {
79 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
80 ApplicationBundle.message("error.invalid.installation.home", instHome.getAbsolutePath(),
81 ApplicationNamesInfo.getInstance().getFullProductName()));
85 if (!oldConfigDir.exists()) {
86 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
87 ApplicationBundle.message("error.no.settings.path",
88 oldConfigDir.getAbsolutePath()),
89 ApplicationBundle.message("title.settings.import.failed"), JOptionPane.WARNING_MESSAGE);
95 public static void xcopy(File src, File dest) throws IOException{
96 src = src.getCanonicalFile();
97 dest = dest.getCanonicalFile();
98 if (!src.isDirectory()){
99 throw new IOException(ApplicationBundle.message("config.import.invalid.directory.error", src.getAbsolutePath()));
101 if (!dest.isDirectory()){
102 throw new IOException(ApplicationBundle.message("config.import.invalid.directory.error", dest.getAbsolutePath()));
104 FileUtil.copyDir(src, dest);
106 // Delete plugins just imported. They're most probably incompatible with newer idea version.
107 File plugins = new File(dest, PLUGINS_PATH);
108 if (plugins.exists()) {
109 FileUtil.delete(plugins);
114 public static File getOldConfigDir(File oldInstallHome) {
115 int oldBuildNumber = getBuildNumber(oldInstallHome);
117 if (oldBuildNumber != -1 && oldBuildNumber <= 600) { // Pandora
118 //noinspection HardCodedStringLiteral
119 return new File(oldInstallHome, "config");
122 File[] launchFileCandidates = getLaunchFilesCandidates(oldInstallHome);
123 for (File file : launchFileCandidates) {
125 String configDir = PathManager.substituteVars(getConfigFromLaxFile(file), oldInstallHome.getPath());
126 if (configDir != null) {
127 File probableConfig = new File(configDir);
128 if (probableConfig.exists()) return probableConfig;
136 @SuppressWarnings({"HardCodedStringLiteral"})
137 private static File[] getLaunchFilesCandidates(File instHome) {
138 File bin = new File(instHome, BIN_FOLDER);
140 new File(bin, "idea.properties"),
141 new File(bin, "idea.lax"),
142 new File(bin, "idea.bat"),
143 new File(bin, "idea.sh"),
144 new File(new File(instHome, "Contents"), "Info.plist"),
145 new File(new File(new File(bin, "idea.app"), "Contents"), "Info.plist"),
146 new File(new File(new File(instHome, "idea.app"), "Contents"), "Info.plist")
150 @SuppressWarnings({"HardCodedStringLiteral"})
152 public static String getConfigFromLaxFile(File file) {
153 if (file.getName().endsWith(".properties")) {
155 InputStream fis = new BufferedInputStream(new FileInputStream(file));
156 PropertyResourceBundle bundle;
158 bundle = new PropertyResourceBundle(fis);
163 return bundle.getString("idea.config.path");
164 } catch (IOException e) {
169 String fileContent = getContent(file);
170 String configParam = "idea.config.path=";
171 int idx = fileContent.indexOf(configParam);
173 configParam = "<key>idea.config.path</key>";
174 idx = fileContent.indexOf(configParam);
175 if (idx == -1) return null;
176 idx = fileContent.indexOf("<string>", idx);
177 if (idx == -1) return null;
178 idx += "<string>".length();
179 return fixDirName(fileContent.substring(idx, fileContent.indexOf("</string>", idx)), true);
181 String configDir = "";
182 idx += configParam.length();
183 if (fileContent.length() > idx) {
184 if (fileContent.charAt(idx) == '"') {
186 while ((fileContent.length() > idx) && (fileContent.charAt(idx) != '"') && (fileContent.charAt(idx) != '\n') &&
187 (fileContent.charAt(idx) != '\r')) {
188 configDir += fileContent.charAt(idx);
192 while ((fileContent.length() > idx) && (!Character.isSpaceChar(fileContent.charAt(idx))) &&
193 (fileContent.charAt(idx) != '\n') &&
194 (fileContent.charAt(idx) != '\r')) {
195 configDir += fileContent.charAt(idx);
200 configDir = fixDirName(configDir, true);
201 if (configDir.length() > 0) {
202 configDir = (new File(configDir)).getPath();
209 private static String getContent(File file) {
211 StringBuffer content = new StringBuffer();
212 BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
215 String line = reader.readLine();
216 if (line == null) break;
217 content.append(line);
218 content.append('\n');
226 return content.toString();
228 catch (Exception e) {
233 public static String fixDirName(String dir, boolean replaceUserHome) {
234 if (StringUtil.startsWithChar(dir, '\"') && StringUtil.endsWithChar(dir, '\"')) {
235 dir = dir.substring(1, dir.length() - 1);
237 if (replaceUserHome) {
238 if (dir.startsWith("~\\") || dir.startsWith("~//") || StringUtil.startsWithConcatenationOf(dir, "~", File.separator)) {
239 dir = SystemProperties.getUserHome() + dir.substring(1);
245 public static boolean isInstallationHome(String installationHome) {
246 String mainJarName = StringUtil.toLowerCase(ApplicationNamesInfo.getInstance().getProductName()) + ".jar";
247 //noinspection HardCodedStringLiteral
248 boolean quickTest = new File(new File(installationHome, "lib"), mainJarName).exists() &&
249 new File(installationHome, BIN_FOLDER).exists();
250 if (!quickTest) return false;
252 File[] files = getLaunchFilesCandidates(new File(installationHome));
253 for (File file : files) {
254 if (file.exists()) return true;
260 private static int getBuildNumber(File installDirectory) {
261 installDirectory = installDirectory.getAbsoluteFile();
263 File buildTxt = new File(installDirectory, BUILD_NUMBER_FILE);
264 if ((!buildTxt.exists()) || (buildTxt.isDirectory())){
265 buildTxt = new File(new File(installDirectory, BIN_FOLDER), BUILD_NUMBER_FILE);
268 if (buildTxt.exists() && !buildTxt.isDirectory()){
269 int buildNumber = -1;
270 String buildNumberText = getContent(buildTxt);
271 if (buildNumberText != null) {
273 if (buildNumberText.length() > 1){
274 buildNumberText = buildNumberText.trim();
275 buildNumber = Integer.parseInt(buildNumberText);