IDEA-136072 (implicit usage of ${idea.(home|config|system).path} macros in property...
authorRoman Shevchenko <roman.shevchenko@jetbrains.com>
Tue, 10 Feb 2015 15:13:22 +0000 (16:13 +0100)
committerRoman Shevchenko <roman.shevchenko@jetbrains.com>
Tue, 10 Feb 2015 15:13:52 +0000 (16:13 +0100)
bin/idea.properties
platform/util/src/com/intellij/openapi/application/PathManager.java
platform/util/testSrc/com/intellij/openapi/application/PathManagerTest.java [new file with mode: 0644]

index a9cd05389fd5f7c87c02a6eb2582c59c5440b89a..9e8524cd8523790a830685814f054556b159d1da 100644 (file)
@@ -1,4 +1,4 @@
-# Use ${idea.home} macro to specify location relative to IDE installation home.
+# Use ${idea.home.path} macro to specify location relative to IDE installation home.
 # Use ${xxx} where xxx is any Java property (including defined in previous lines of this file) to refer to its value.
 # Note for Windows users: please make sure you're using forward slashes (e.g. c:/idea/system).
 
 # Use ${xxx} where xxx is any Java property (including defined in previous lines of this file) to refer to its value.
 # Note for Windows users: please make sure you're using forward slashes (e.g. c:/idea/system).
 
index 4e05116d7df5a689219b8e96c6ed7398b40cbb50..8b2e4eccd337d102d5f79d74f96f64690fd6aa36 100644 (file)
@@ -36,19 +36,23 @@ import org.picocontainer.PicoContainer;
 import java.io.*;
 import java.net.URL;
 import java.util.*;
 import java.io.*;
 import java.net.URL;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import static com.intellij.util.SystemProperties.getUserHome;
 
 public class PathManager {
   public static final String PROPERTIES_FILE = "idea.properties.file";
 
 import static com.intellij.util.SystemProperties.getUserHome;
 
 public class PathManager {
   public static final String PROPERTIES_FILE = "idea.properties.file";
-  public static final String PROPERTY_SYSTEM_PATH = "idea.system.path";
+  public static final String PROPERTY_HOME_PATH = "idea.home.path";
   public static final String PROPERTY_CONFIG_PATH = "idea.config.path";
   public static final String PROPERTY_CONFIG_PATH = "idea.config.path";
+  public static final String PROPERTY_SYSTEM_PATH = "idea.system.path";
   public static final String PROPERTY_PLUGINS_PATH = "idea.plugins.path";
   public static final String PROPERTY_PLUGINS_PATH = "idea.plugins.path";
-  public static final String PROPERTY_HOME_PATH = "idea.home.path";
   public static final String PROPERTY_LOG_PATH = "idea.log.path";
   public static final String PROPERTY_PATHS_SELECTOR = "idea.paths.selector";
   public static final String DEFAULT_OPTIONS_FILE_NAME = "other";
 
   public static final String PROPERTY_LOG_PATH = "idea.log.path";
   public static final String PROPERTY_PATHS_SELECTOR = "idea.paths.selector";
   public static final String DEFAULT_OPTIONS_FILE_NAME = "other";
 
+  private static final String PROPERTY_HOME = "idea.home";  // reduced variant of PROPERTY_HOME_PATH, now deprecated
+
   private static final String LIB_FOLDER = "lib";
   private static final String PLUGINS_FOLDER = "plugins";
   private static final String BIN_FOLDER = "bin";
   private static final String LIB_FOLDER = "lib";
   private static final String PLUGINS_FOLDER = "plugins";
   private static final String BIN_FOLDER = "bin";
@@ -58,9 +62,11 @@ public class PathManager {
   private static final String SYSTEM_FOLDER = "system";
   private static final String PATHS_SELECTOR = System.getProperty(PROPERTY_PATHS_SELECTOR);
 
   private static final String SYSTEM_FOLDER = "system";
   private static final String PATHS_SELECTOR = System.getProperty(PROPERTY_PATHS_SELECTOR);
 
+  private static final Pattern PROPERTY_REF = Pattern.compile("\\$\\{(.+?)}");
+
   private static String ourHomePath;
   private static String ourHomePath;
-  private static String ourSystemPath;
   private static String ourConfigPath;
   private static String ourConfigPath;
+  private static String ourSystemPath;
   private static String ourPluginsPath;
   private static String ourLogPath;
 
   private static String ourPluginsPath;
   private static String ourLogPath;
 
@@ -70,7 +76,7 @@ public class PathManager {
   public static String getHomePath() {
     if (ourHomePath != null) return ourHomePath;
 
   public static String getHomePath() {
     if (ourHomePath != null) return ourHomePath;
 
-    String fromProperty = System.getProperty(PROPERTY_HOME_PATH);
+    String fromProperty = System.getProperty(PROPERTY_HOME_PATH, System.getProperty(PROPERTY_HOME));
     if (fromProperty != null) {
       ourHomePath = getAbsolutePath(fromProperty);
       if (!new File(ourHomePath).isDirectory()) {
     if (fromProperty != null) {
       ourHomePath = getAbsolutePath(fromProperty);
       if (!new File(ourHomePath).isDirectory()) {
@@ -335,11 +341,6 @@ public class PathManager {
             try {
               Map<String, String> properties = FileUtil.loadProperties(fis);
 
             try {
               Map<String, String> properties = FileUtil.loadProperties(fis);
 
-              String home = properties.get("idea.home");
-              if (home != null && ourHomePath == null) {
-                ourHomePath = getAbsolutePath(substituteVars(home));
-              }
-
               Properties sysProperties = System.getProperties();
               for (String key : properties.keySet()) {
                 if (sysProperties.getProperty(key, null) == null) { // load the property from the property file only if it is not defined yet
               Properties sysProperties = System.getProperties();
               for (String key : properties.keySet()) {
                 if (sysProperties.getProperty(key, null) == null) { // load the property from the property file only if it is not defined yet
@@ -374,13 +375,30 @@ public class PathManager {
       s = ideaHomePath + File.separatorChar + BIN_FOLDER + File.separatorChar + s;
     }
 
       s = ideaHomePath + File.separatorChar + BIN_FOLDER + File.separatorChar + s;
     }
 
-    s = StringUtil.replace(s, "${idea.home}", ideaHomePath);
+    Matcher m = PROPERTY_REF.matcher(s);
+    while (m.find()) {
+      String key = m.group(1);
+      String value = System.getProperty(key);
+
+      if (value == null) {
+        if (PROPERTY_HOME_PATH.equals(key) || PROPERTY_HOME.equals(key)) {
+          value = ideaHomePath;
+        }
+        else if (PROPERTY_CONFIG_PATH.equals(key)) {
+          value = getConfigPath();
+        }
+        else if (PROPERTY_SYSTEM_PATH.equals(key)) {
+          value = getSystemPath();
+        }
+      }
+
+      if (value == null) {
+        //noinspection UseOfSystemOutOrSystemErr
+        System.err.println("Unknown property: " + key);
+        value = "";
+      }
 
 
-    Properties props = System.getProperties();
-    for (final Object key1 : props.keySet()) {
-      String key = (String)key1;
-      String value = props.getProperty(key);
-      s = StringUtil.replace(s, "${" + key + "}", value);
+      s = m.replaceAll(value);
     }
 
     return s;
     }
 
     return s;
diff --git a/platform/util/testSrc/com/intellij/openapi/application/PathManagerTest.java b/platform/util/testSrc/com/intellij/openapi/application/PathManagerTest.java
new file mode 100644 (file)
index 0000000..cf8aee5
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2015 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.
+ */
+package com.intellij.openapi.application;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.Random;
+
+import static org.junit.Assert.assertEquals;
+
+public class PathManagerTest {
+  private static final String TEST_RPOP = "__ij_subst_test__";
+  private static final String TEST_VALUE = "__" + new Random().nextInt(1000) + "__";
+
+  @Before
+  public void setUp() throws Exception {
+    System.setProperty(TEST_RPOP, TEST_VALUE);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    System.clearProperty(TEST_RPOP);
+  }
+
+  @Test
+  public void testVarSubstitution() {
+    assertEquals("", PathManager.substituteVars(""));
+    assertEquals("abc", PathManager.substituteVars("abc"));
+    assertEquals("a$b$c", PathManager.substituteVars("a$b$c"));
+
+    assertEquals("/" + TEST_VALUE + "/" + TEST_VALUE + "/", PathManager.substituteVars("/${" + TEST_RPOP + "}/${" + TEST_RPOP + "}/"));
+
+    assertEquals(PathManager.getHomePath() + "/build.txt", PathManager.substituteVars("${idea.home.path}/build.txt"));
+    assertEquals(PathManager.getHomePath() + "/build.txt", PathManager.substituteVars("${idea.home}/build.txt"));
+
+    assertEquals("/opt/idea/build.txt", PathManager.substituteVars("${idea.home.path}/build.txt", "/opt/idea"));
+
+    String config = System.clearProperty(PathManager.PROPERTY_CONFIG_PATH);
+    try {
+      assertEquals(PathManager.getConfigPath() + "/opts", PathManager.substituteVars("${idea.config.path}/opts"));
+    }
+    finally {
+      if (config != null) {
+        System.setProperty(PathManager.PROPERTY_CONFIG_PATH, config);
+      }
+    }
+
+    String system = System.clearProperty(PathManager.PROPERTY_SYSTEM_PATH);
+    try {
+      assertEquals(PathManager.getSystemPath() + "/logs2", PathManager.substituteVars("${idea.system.path}/logs2"));
+    }
+    finally {
+      if (system != null) {
+        System.setProperty(PathManager.PROPERTY_CONFIG_PATH, system);
+      }
+    }
+
+    assertEquals(PathManager.getBinPath() + File.separator + "../license", PathManager.substituteVars("../license"));
+
+    assertEquals("//", PathManager.substituteVars("/${unknown_property_ignore_the_error}/"));
+  }
+}