001    /*
002     * Copyright 2010-2016 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.utils;
018    
019    import com.intellij.openapi.application.ApplicationManager;
020    import com.intellij.openapi.application.PathManager;
021    import org.jetbrains.annotations.NotNull;
022    import org.jetbrains.jps.model.java.impl.JavaSdkUtil;
023    
024    import java.io.File;
025    import java.util.List;
026    import java.util.regex.Pattern;
027    
028    public class PathUtil {
029    
030        public static final String JPS_KOTLIN_HOME_PROPERTY = "jps.kotlin.home";
031    
032        public static final String JS_LIB_JAR_NAME = "kotlin-stdlib-js.jar";
033        public static final String ALLOPEN_PLUGIN_JAR_NAME = "allopen-compiler-plugin.jar";
034        public static final String NOARG_PLUGIN_JAR_NAME = "noarg-compiler-plugin.jar";
035        public static final String JS_LIB_SRC_JAR_NAME = "kotlin-stdlib-js-sources.jar";
036        public static final String KOTLIN_JAVA_RUNTIME_JAR = "kotlin-runtime.jar";
037        public static final String KOTLIN_JAVA_STDLIB_JAR = "kotlin-stdlib.jar";
038        public static final String KOTLIN_JAVA_REFLECT_JAR = "kotlin-reflect.jar";
039        public static final String KOTLIN_JAVA_SCRIPT_RUNTIME_JAR = "kotlin-script-runtime.jar";
040        public static final String KOTLIN_TEST_JAR = "kotlin-test.jar";
041        public static final String KOTLIN_TEST_JS_JAR = "kotlin-test-js.jar";
042        public static final String KOTLIN_JAVA_RUNTIME_SRC_JAR = "kotlin-runtime-sources.jar";
043        public static final String KOTLIN_COMPILER_JAR = "kotlin-compiler.jar";
044    
045        public static final Pattern KOTLIN_RUNTIME_JAR_PATTERN = Pattern.compile("kotlin-(stdlib|runtime)(-\\d[\\d.]+(-.+)?)?\\.jar");
046    
047        public static final String HOME_FOLDER_NAME = "kotlinc";
048        private static final File NO_PATH = new File("<no_path>");
049    
050        private PathUtil() {}
051    
052        @NotNull
053        public static KotlinPaths getKotlinPathsForIdeaPlugin() {
054            return ApplicationManager.getApplication().isUnitTestMode()
055                ? getKotlinPathsForDistDirectory()
056                : new KotlinPathsFromHomeDir(getCompilerPathForIdeaPlugin());
057        }
058    
059        @NotNull
060        public static KotlinPaths getKotlinPathsForJpsPlugin() {
061            // When JPS is run on TeamCity, it can not rely on Kotlin plugin layout,
062            // so the path to Kotlin is specified in a system property
063            String jpsKotlinHome = System.getProperty(JPS_KOTLIN_HOME_PROPERTY);
064            if (jpsKotlinHome != null) {
065                return new KotlinPathsFromHomeDir(new File(jpsKotlinHome));
066            }
067            return new KotlinPathsFromHomeDir(getCompilerPathForJpsPlugin());
068        }
069    
070        @NotNull
071        public static KotlinPaths getKotlinPathsForJpsPluginOrJpsTests() {
072            if ("true".equalsIgnoreCase(System.getProperty("kotlin.jps.tests"))) {
073                return getKotlinPathsForDistDirectory();
074            }
075            return getKotlinPathsForJpsPlugin();
076        }
077    
078        @NotNull
079        public static KotlinPaths getKotlinPathsForCompiler() {
080            if (!getPathUtilJar().isFile()) {
081                // Not running from a jar, i.e. it is it must be a unit test
082                return getKotlinPathsForDistDirectory();
083            }
084            return new KotlinPathsFromHomeDir(getCompilerPathForCompilerJar());
085        }
086    
087        @NotNull
088        public static KotlinPaths getKotlinPathsForDistDirectory() {
089            return new KotlinPathsFromHomeDir(new File("dist", HOME_FOLDER_NAME));
090        }
091    
092        @NotNull
093        private static File getCompilerPathForCompilerJar() {
094            File jar = getPathUtilJar();
095    
096            if (!jar.exists()) return NO_PATH;
097    
098            if (jar.getName().equals(KOTLIN_COMPILER_JAR)) {
099                File lib = jar.getParentFile();
100                return lib.getParentFile();
101            }
102    
103            return NO_PATH;
104        }
105    
106        @NotNull
107        private static File getCompilerPathForJpsPlugin() {
108            File jar = getPathUtilJar();
109    
110            if (!jar.exists()) return NO_PATH;
111    
112            if (jar.getName().equals("kotlin-jps-plugin.jar")) {
113                File pluginHome = jar.getParentFile().getParentFile().getParentFile();
114                return new File(pluginHome, HOME_FOLDER_NAME);
115            }
116    
117            return NO_PATH;
118        }
119    
120        @NotNull
121        private static File getCompilerPathForIdeaPlugin() {
122            File jar = getPathUtilJar();
123    
124            if (!jar.exists()) return NO_PATH;
125    
126            if (jar.getName().equals("kotlin-plugin.jar")) {
127                File lib = jar.getParentFile();
128                File pluginHome = lib.getParentFile();
129    
130                return new File(pluginHome, HOME_FOLDER_NAME);
131            }
132    
133            return NO_PATH;
134        }
135    
136        @NotNull
137        public static File getPathUtilJar() {
138            return getResourcePathForClass(PathUtil.class);
139        }
140    
141        @NotNull
142        public static File getResourcePathForClass(@NotNull Class aClass) {
143            String path = "/" + aClass.getName().replace('.', '/') + ".class";
144            String resourceRoot = PathManager.getResourceRoot(aClass, path);
145            if (resourceRoot == null) {
146                throw new IllegalStateException("Resource not found: " + path);
147            }
148            return new File(resourceRoot).getAbsoluteFile();
149        }
150    
151        @NotNull
152        public static List<File> getJdkClassesRoots() {
153            return JavaSdkUtil.getJdkClassesRoots(new File(System.getProperty("java.home")), true);
154        }
155    
156        @NotNull
157        public static List<File> getJdkClassesRoots(@NotNull File jdkHome) {
158            return JavaSdkUtil.getJdkClassesRoots(jdkHome, false);
159        }
160    }