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