001    /*
002     * Copyright 2010-2015 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    
027    public class PathUtil {
028    
029        public static final String JPS_KOTLIN_HOME_PROPERTY = "jps.kotlin.home";
030    
031        public static final String JS_LIB_JAR_NAME = "kotlin-jslib.jar";
032        public static final String JS_LIB_SRC_JAR_NAME = "kotlin-jslib-sources.jar";
033        public static final String KOTLIN_JAVA_RUNTIME_JAR = "kotlin-runtime.jar";
034        public static final String KOTLIN_JAVA_REFLECT_JAR = "kotlin-reflect.jar";
035        public static final String KOTLIN_TEST_JAR = "kotlin-test.jar";
036        public static final String KOTLIN_JAVA_RUNTIME_SRC_JAR = "kotlin-runtime-sources.jar";
037        public static final String KOTLIN_COMPILER_JAR = "kotlin-compiler.jar";
038    
039        public static final String HOME_FOLDER_NAME = "kotlinc";
040        private static final File NO_PATH = new File("<no_path>");
041    
042        private PathUtil() {}
043    
044        @NotNull
045        public static KotlinPaths getKotlinPathsForIdeaPlugin() {
046            return ApplicationManager.getApplication().isUnitTestMode()
047                ? getKotlinPathsForDistDirectory()
048                : new KotlinPathsFromHomeDir(getCompilerPathForIdeaPlugin());
049        }
050    
051        @NotNull
052        public static KotlinPaths getKotlinPathsForJpsPlugin() {
053            // When JPS is run on TeamCity, it can not rely on Kotlin plugin layout,
054            // so the path to Kotlin is specified in a system property
055            String jpsKotlinHome = System.getProperty(JPS_KOTLIN_HOME_PROPERTY);
056            if (jpsKotlinHome != null) {
057                return new KotlinPathsFromHomeDir(new File(jpsKotlinHome));
058            }
059            return new KotlinPathsFromHomeDir(getCompilerPathForJpsPlugin());
060        }
061    
062        @NotNull
063        public static KotlinPaths getKotlinPathsForJpsPluginOrJpsTests() {
064            if ("true".equalsIgnoreCase(System.getProperty("kotlin.jps.tests"))) {
065                return getKotlinPathsForDistDirectory();
066            }
067            return getKotlinPathsForJpsPlugin();
068        }
069    
070        @NotNull
071        public static KotlinPaths getKotlinPathsForCompiler() {
072            if (!getPathUtilJar().isFile()) {
073                // Not running from a jar, i.e. it is it must be a unit test
074                return getKotlinPathsForDistDirectory();
075            }
076            return new KotlinPathsFromHomeDir(getCompilerPathForCompilerJar());
077        }
078    
079        @NotNull
080        public static KotlinPaths getKotlinPathsForDistDirectory() {
081            return new KotlinPathsFromHomeDir(new File("dist", HOME_FOLDER_NAME));
082        }
083    
084        @NotNull
085        private static File getCompilerPathForCompilerJar() {
086            File jar = getPathUtilJar();
087    
088            if (!jar.exists()) return NO_PATH;
089    
090            if (jar.getName().equals(KOTLIN_COMPILER_JAR)) {
091                File lib = jar.getParentFile();
092                return lib.getParentFile();
093            }
094    
095            return NO_PATH;
096        }
097    
098        @NotNull
099        private static File getCompilerPathForJpsPlugin() {
100            File jar = getPathUtilJar();
101    
102            if (!jar.exists()) return NO_PATH;
103    
104            if (jar.getName().equals("kotlin-jps-plugin.jar")) {
105                File pluginHome = jar.getParentFile().getParentFile().getParentFile();
106                return new File(pluginHome, HOME_FOLDER_NAME);
107            }
108    
109            return NO_PATH;
110        }
111    
112        @NotNull
113        private static File getCompilerPathForIdeaPlugin() {
114            File jar = getPathUtilJar();
115    
116            if (!jar.exists()) return NO_PATH;
117    
118            if (jar.getName().equals("kotlin-plugin.jar")) {
119                File lib = jar.getParentFile();
120                File pluginHome = lib.getParentFile();
121    
122                return new File(pluginHome, HOME_FOLDER_NAME);
123            }
124    
125            return NO_PATH;
126        }
127    
128        @NotNull
129        public static File getPathUtilJar() {
130            return getResourcePathForClass(PathUtil.class);
131        }
132    
133        @NotNull
134        public static File getResourcePathForClass(@NotNull Class aClass) {
135            String path = "/" + aClass.getName().replace('.', '/') + ".class";
136            String resourceRoot = PathManager.getResourceRoot(aClass, path);
137            if (resourceRoot == null) {
138                throw new IllegalStateException("Resource not found: " + path);
139            }
140            return new File(resourceRoot).getAbsoluteFile();
141        }
142    
143        @NotNull
144        public static List<File> getJdkClassesRoots() {
145            return JavaSdkUtil.getJdkClassesRoots(new File(System.getProperty("java.home")), true);
146        }
147    }