move ts error filter to new API
[idea/community.git] / platform / lang-impl / src / com / intellij / execution / filters / AbstractFileHyperlinkFilter.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.execution.filters;
17
18 import com.intellij.openapi.application.ReadAction;
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.roots.ProjectFileIndex;
22 import com.intellij.openapi.util.io.FileUtil;
23 import com.intellij.openapi.util.text.StringUtil;
24 import com.intellij.openapi.vfs.VirtualFile;
25 import com.intellij.util.containers.ContainerUtil;
26 import org.jetbrains.annotations.NotNull;
27 import org.jetbrains.annotations.Nullable;
28 import org.jetbrains.io.LocalFileFinder;
29
30 import java.util.List;
31
32 public abstract class AbstractFileHyperlinkFilter implements Filter {
33   private static final Logger LOG = Logger.getInstance(AbstractFileHyperlinkFilter.class);
34
35   private final Project myProject;
36   private final ProjectFileIndex myFileIndex;
37   private final VirtualFile myBaseDir;
38
39   public AbstractFileHyperlinkFilter(@NotNull Project project, @Nullable String baseDir) {
40     myProject = project;
41     myFileIndex = ProjectFileIndex.SERVICE.getInstance(project);
42     myBaseDir = findDir(baseDir);
43   }
44
45   @Nullable
46   private static VirtualFile findDir(@Nullable String baseDir) {
47     if (baseDir == null) {
48       return null;
49     }
50     return ReadAction.compute(() -> {
51       String path = FileUtil.toSystemIndependentName(baseDir);
52       VirtualFile dir = LocalFileFinder.findFile(path);
53       return dir != null && dir.isValid() && dir.isDirectory() ? dir : null;
54     });
55   }
56
57   @Nullable
58   @Override
59   public final Result applyFilter(String line, int entireLength) {
60     List<FileHyperlinkRawData> links;
61     try {
62       links = parse(line);
63     }
64     catch (RuntimeException e) {
65       LOG.error("Failed to parse '" + line + "' with " + getClass(), e);
66       return null;
67     }
68     List<Filter.ResultItem> items = ContainerUtil.newArrayList();
69     for (FileHyperlinkRawData link : links) {
70       String filePath = FileUtil.toSystemIndependentName(link.getFilePath());
71       VirtualFile file = StringUtil.isEmptyOrSpaces(filePath) ? null : findFile(filePath);
72       if (file != null) {
73         OpenFileHyperlinkInfo info = new OpenFileHyperlinkInfo(myProject,
74                                                                file,
75                                                                link.getDocumentLine(),
76                                                                link.getDocumentColumn());
77         boolean grayedHyperLink = isGrayedHyperlink(file);
78         int offset = entireLength - line.length();
79         items.add(new Filter.ResultItem(offset + link.getHyperlinkStartInd(),
80                                         offset + link.getHyperlinkEndInd(),
81                                         info,
82                                         grayedHyperLink));
83       }
84     }
85     return items.isEmpty() ? null : new Result(items);
86   }
87
88   private boolean isGrayedHyperlink(@NotNull VirtualFile file) {
89     return !myFileIndex.isInContent(file) || myFileIndex.isInLibrary(file);
90   }
91
92   @NotNull
93   public abstract List<FileHyperlinkRawData> parse(@NotNull String line);
94
95   @Nullable
96   public VirtualFile findFile(@NotNull String filePath) {
97     VirtualFile file = LocalFileFinder.findFile(filePath);
98     if (file == null && myBaseDir != null) {
99       file = myBaseDir.findFileByRelativePath(filePath);
100     }
101     return file;
102   }
103 }