replaced <code></code> with more concise {@code}
[idea/community.git] / platform / core-api / src / com / intellij / util / PathUtil.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.util;
17
18 import com.intellij.openapi.application.PathManager;
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.openapi.util.SystemInfo;
21 import com.intellij.openapi.util.io.FileUtil;
22 import com.intellij.openapi.util.io.FileUtilRt;
23 import com.intellij.openapi.util.text.StringUtil;
24 import com.intellij.openapi.vfs.LocalFileProvider;
25 import com.intellij.openapi.vfs.VirtualFile;
26 import com.intellij.openapi.vfs.VirtualFileManager;
27 import com.intellij.util.io.URLUtil;
28 import org.jetbrains.annotations.Contract;
29 import org.jetbrains.annotations.NonNls;
30 import org.jetbrains.annotations.NotNull;
31 import org.jetbrains.annotations.Nullable;
32
33 import java.io.File;
34
35 public class PathUtil {
36   private static final Logger LOG = Logger.getInstance("#com.intellij.util.PathUtil");
37
38   private PathUtil() { }
39
40   @Nullable
41   public static String getLocalPath(@Nullable VirtualFile file) {
42     if (file == null || !file.isValid()) {
43       return null;
44     }
45     if (file.getFileSystem().getProtocol().equals(URLUtil.JAR_PROTOCOL) && file.getParent() != null) {
46       return null;
47     }
48     return getLocalPath(file.getPath());
49   }
50
51   @NotNull
52   public static String getLocalPath(@NotNull String path) {
53     return FileUtil.toSystemDependentName(StringUtil.trimEnd(path, URLUtil.JAR_SEPARATOR));
54   }
55
56   @NotNull
57   public static VirtualFile getLocalFile(@NotNull VirtualFile file) {
58     if (!file.isValid()) {
59       return file;
60     }
61     if (file.getFileSystem() instanceof LocalFileProvider) {
62       final VirtualFile localFile = ((LocalFileProvider)file.getFileSystem()).getLocalVirtualFileFor(file);
63       if (localFile != null) {
64         return localFile;
65       }
66     }
67     return file;
68   }
69
70   @NotNull
71   public static String getJarPathForClass(@NotNull Class aClass) {
72     final String pathForClass = PathManager.getJarPathForClass(aClass);
73     assert pathForClass != null : aClass;
74     return pathForClass;
75   }
76
77   @NotNull
78   public static String toPresentableUrl(@NotNull String url) {
79     return getLocalPath(VirtualFileManager.extractPath(url));
80   }
81
82   public static String getCanonicalPath(@NonNls String path) {
83     return FileUtil.toCanonicalPath(path);
84   }
85
86   @NotNull
87   public static String getFileName(@NotNull String path) {
88     return PathUtilRt.getFileName(path);
89   }
90
91   @Nullable
92   public static String getFileExtension(@NotNull String name) {
93     int index = name.lastIndexOf('.');
94     if (index < 0) return null;
95     return name.substring(index + 1);
96   }
97
98   @NotNull
99   public static String getParentPath(@NotNull String path) {
100     return PathUtilRt.getParentPath(path);
101   }
102
103   @NotNull
104   public static String suggestFileName(@NotNull String text) {
105     return PathUtilRt.suggestFileName(text);
106   }
107
108   @NotNull
109   public static String suggestFileName(@NotNull String text, final boolean allowDots, final boolean allowSpaces) {
110     return PathUtilRt.suggestFileName(text, allowDots, allowSpaces);
111   }
112
113   public static boolean isValidFileName(@NotNull String fileName) {
114     return PathUtilRt.isValidFileName(fileName, true);
115   }
116
117   public static boolean isValidFileName(@NotNull String fileName, boolean strict) {
118     return PathUtilRt.isValidFileName(fileName, strict);
119   }
120
121   @Contract("null -> null; !null -> !null")
122   public static String toSystemIndependentName(@Nullable String path) {
123     return path == null ? null : FileUtilRt.toSystemIndependentName(path);
124   }
125
126   @Contract("null -> null; !null -> !null")
127   public static String toSystemDependentName(@Nullable String path) {
128     return path == null ? null : FileUtilRt.toSystemDependentName(path);
129   }
130
131   /**
132    * Ensures that the given argument doesn't contain {@code \} separators.
133    * <p>
134    * The violations are reported via the {@code LOG.error}.
135    * <p>
136    * TODO SystemIndependentInstrumentingBuilder now embeds assertions directly, so we can remove this method.
137    *
138    * @param className     Class name
139    * @param methodName    Method name
140    * @param parameterName Parameter name
141    * @param argument      Path
142    * @see SystemDependent
143    * @see SystemIndependent
144    */
145   @Deprecated
146   public static void assertArgumentIsSystemIndependent(String className, String methodName, String parameterName, String argument) {
147     if (argument != null && argument.contains("\\")) {
148       String message = String.format("Argument for @SystemIndependent parameter '%s' of %s.%s must be system-independent: %s",
149                                      parameterName, className, methodName, argument);
150
151       IllegalArgumentException exception = new IllegalArgumentException(message);
152
153       StackTraceElement[] stackTrace = new StackTraceElement[exception.getStackTrace().length - 1];
154       System.arraycopy(exception.getStackTrace(), 1, stackTrace, 0, stackTrace.length);
155       exception.setStackTrace(stackTrace);
156
157       LOG.error(exception);
158     }
159   }
160
161   @NotNull
162   public static String driveLetterToLowerCase(@NotNull String path) {
163     if (SystemInfo.isWindows && path.length() >= 2 && Character.isUpperCase(path.charAt(0)) && path.charAt(1) == ':') {
164       File file = new File(path);
165       if (file.isAbsolute()) {
166         return Character.toLowerCase(path.charAt(0)) + path.substring(1);
167       }
168     }
169     return path;
170   }
171
172   @NotNull
173   public static String makeFileName(@NotNull String name, @Nullable String extension) {
174     return StringUtil.isEmpty(extension) ? name : name + '.' + extension;
175   }
176 }