2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 package com.intellij.codeInspection.offlineViewer;
23 import com.intellij.codeInspection.CommonProblemDescriptor;
24 import com.intellij.codeInspection.ex.*;
25 import com.intellij.codeInspection.offline.OfflineProblemDescriptor;
26 import com.intellij.codeInspection.reference.RefElement;
27 import com.intellij.codeInspection.reference.RefEntity;
28 import com.intellij.codeInspection.reference.SmartRefElementPointer;
29 import com.intellij.codeInspection.ui.*;
30 import com.intellij.openapi.project.Project;
31 import com.intellij.openapi.util.Comparing;
32 import com.intellij.util.containers.HashSet;
33 import com.intellij.util.ui.tree.TreeUtil;
34 import org.jetbrains.annotations.NotNull;
35 import org.jetbrains.annotations.Nullable;
37 import javax.swing.tree.TreeNode;
38 import javax.swing.tree.TreePath;
41 public class OfflineInspectionRVContentProvider extends InspectionRVContentProvider {
42 private final Map<String, Map<String, Set<OfflineProblemDescriptor>>> myContent;
44 public OfflineInspectionRVContentProvider(@NotNull Map<String, Map<String, Set<OfflineProblemDescriptor>>> content,
45 @NotNull Project project) {
51 public boolean checkReportedProblems(@NotNull GlobalInspectionContextImpl context,
52 @NotNull final InspectionToolWrapper toolWrapper) {
53 final Map<String, Set<OfflineProblemDescriptor>> content = getFilteredContent(context, toolWrapper);
54 return content != null && !content.values().isEmpty();
58 public Iterable<? extends ScopeToolState> getTools(Tools tools) {
59 return Collections.singletonList(tools.getDefaultState());
64 public QuickFixAction[] getQuickFixes(@NotNull final InspectionToolWrapper toolWrapper, @NotNull final InspectionTree tree) {
65 final TreePath[] treePaths = tree.getSelectionPaths();
66 if (treePaths == null) return QuickFixAction.EMPTY;
67 final List<RefEntity> selectedElements = new ArrayList<RefEntity>();
68 final Map<RefEntity, CommonProblemDescriptor[]> actions = new HashMap<>();
69 for (TreePath selectionPath : treePaths) {
70 TreeUtil.traverseDepth((TreeNode)selectionPath.getLastPathComponent(), node -> {
71 if (!((InspectionTreeNode)node).isValid()) return true;
72 if (node instanceof OfflineProblemDescriptorNode) {
73 if (((OfflineProblemDescriptorNode)node).isQuickFixAppliedFromView()) return true;
74 final OfflineProblemDescriptorNode descriptorNode = (OfflineProblemDescriptorNode)node;
75 final RefEntity element = descriptorNode.getElement();
76 selectedElements.add(element);
77 CommonProblemDescriptor[] descriptors = actions.get(element);
78 final CommonProblemDescriptor descriptor = descriptorNode.getDescriptor();
79 final CommonProblemDescriptor[] descriptorAsArray = descriptor == null ? CommonProblemDescriptor.EMPTY_ARRAY
80 : new CommonProblemDescriptor[]{descriptor};
81 actions.put(element, descriptors == null ?
83 DefaultInspectionToolPresentation.mergeDescriptors(descriptors, descriptorAsArray));
85 else if (node instanceof RefElementNode) {
86 selectedElements.add(((RefElementNode)node).getElement());
92 if (selectedElements.isEmpty()) return null;
94 final RefEntity[] selectedRefElements = selectedElements.toArray(new RefEntity[selectedElements.size()]);
96 GlobalInspectionContextImpl context = tree.getContext();
97 InspectionToolPresentation presentation = context.getPresentation(toolWrapper);
98 return presentation.extractActiveFixes(selectedRefElements, actions, tree.getSelectedDescriptors());
102 public boolean isContentLoaded() {
107 public void appendToolNodeContent(@NotNull GlobalInspectionContextImpl context,
108 @NotNull final InspectionNode toolNode,
109 @NotNull final InspectionTreeNode parentNode,
110 final boolean showStructure,
111 @NotNull final Map<String, Set<RefEntity>> contents,
112 @NotNull final Map<RefEntity, CommonProblemDescriptor[]> problems) {
113 InspectionToolWrapper toolWrapper = toolNode.getToolWrapper();
114 final Map<String, Set<OfflineProblemDescriptor>> filteredContent = getFilteredContent(context, toolWrapper);
115 if (filteredContent != null && !filteredContent.values().isEmpty()) {
116 parentNode.add(toolNode);
117 buildTree(context, filteredContent, false, toolWrapper, OfflineProblemDescriptorContainer::new, showStructure,
119 toolNode.add(newChild);
126 @SuppressWarnings({"UnusedAssignment"})
127 private Map<String, Set<OfflineProblemDescriptor>> getFilteredContent(@NotNull GlobalInspectionContextImpl context,
128 @NotNull InspectionToolWrapper toolWrapper) {
129 Map<String, Set<OfflineProblemDescriptor>> content = myContent.get(toolWrapper.getShortName());
130 if (content == null) return null;
131 if (context.getUIOptions().FILTER_RESOLVED_ITEMS) {
132 final Map<String, Set<OfflineProblemDescriptor>> current = new HashMap<String, Set<OfflineProblemDescriptor>>(content);
133 content = null; //GC it
134 InspectionToolPresentation presentation = context.getPresentation(toolWrapper);
135 for (RefEntity refEntity : presentation.getIgnoredRefElements()) {
136 if (refEntity instanceof RefElement) {
137 excludeProblem(refEntity.getExternalName(), current);
145 private static void excludeProblem(final String externalName, final Map<String, Set<OfflineProblemDescriptor>> content) {
146 for (Iterator<String> iter = content.keySet().iterator(); iter.hasNext();) {
147 final String packageName = iter.next();
148 final Set<OfflineProblemDescriptor> excluded = new HashSet<OfflineProblemDescriptor>(content.get(packageName));
149 for (Iterator<OfflineProblemDescriptor> it = excluded.iterator(); it.hasNext();) {
150 final OfflineProblemDescriptor ex = it.next();
151 if (Comparing.strEqual(ex.getFQName(), externalName)) {
155 if (excluded.isEmpty()) {
158 content.put(packageName, excluded);
164 protected void appendDescriptor(@NotNull GlobalInspectionContextImpl context,
165 @NotNull final InspectionToolWrapper toolWrapper,
166 @NotNull final UserObjectContainer container,
167 @NotNull final InspectionTreeNode packageNode,
168 final boolean canPackageRepeat) {
169 InspectionToolPresentation presentation = context.getPresentation(toolWrapper);
170 final RefElementNode elemNode = addNodeToParent(container, presentation, packageNode);
171 if (toolWrapper instanceof LocalInspectionToolWrapper) {
172 final OfflineProblemDescriptorNode child =
173 OfflineProblemDescriptorNode.create(((OfflineProblemDescriptorContainer)container).getUserObject(),
174 (LocalInspectionToolWrapper)toolWrapper, presentation);
175 elemNode.insertByOrder(child, true);
180 private static class OfflineProblemDescriptorContainer implements UserObjectContainer<OfflineProblemDescriptor> {
182 private final OfflineProblemDescriptor myDescriptor;
184 public OfflineProblemDescriptorContainer(@NotNull OfflineProblemDescriptor descriptor) {
185 myDescriptor = descriptor;
190 public OfflineProblemDescriptorContainer getOwner() {
191 final OfflineProblemDescriptor descriptor = myDescriptor.getOwner();
192 if (descriptor != null) {
193 final OfflineProblemDescriptorContainer container = new OfflineProblemDescriptorContainer(descriptor);
194 return container.supportStructure() ? container : null;
201 public RefElementNode createNode(@NotNull InspectionToolPresentation presentation) {
202 return new OfflineRefElementNode(myDescriptor, presentation);
207 public OfflineProblemDescriptor getUserObject() {
212 public String getModule() {
213 return myDescriptor.getModuleName();
217 public boolean areEqual(final OfflineProblemDescriptor o1, final OfflineProblemDescriptor o2) {
218 if (o1 == null || o2 == null) {
222 if (!Comparing.strEqual(o1.getFQName(), o2.getFQName())) return false;
223 if (!Comparing.strEqual(o1.getType(), o2.getType())) return false;
229 public boolean supportStructure() {
230 return !Comparing.strEqual(myDescriptor.getType(), SmartRefElementPointer.MODULE) &&
231 !Comparing.strEqual(myDescriptor.getType(), "package") &&
232 !Comparing.strEqual(myDescriptor.getType(), SmartRefElementPointer.PROJECT);