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.
18 * Created by IntelliJ IDEA.
22 * To change template for new class use
23 * Code Style | Class Templates options (Tools | IDE Options).
25 package com.intellij.codeInspection.ui;
27 import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
28 import com.intellij.codeInspection.CommonProblemDescriptor;
29 import com.intellij.codeInspection.ProblemDescriptor;
30 import com.intellij.codeInspection.offline.OfflineProblemDescriptor;
31 import com.intellij.codeInspection.offlineViewer.OfflineRefElementNode;
32 import com.intellij.codeInspection.reference.RefElement;
33 import com.intellij.codeInspection.reference.RefEntity;
34 import com.intellij.openapi.diagnostic.Logger;
35 import com.intellij.openapi.editor.Document;
36 import com.intellij.openapi.util.Comparing;
37 import com.intellij.openapi.util.text.StringUtil;
38 import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeComparator;
39 import com.intellij.psi.PsiDocumentManager;
40 import com.intellij.psi.PsiElement;
41 import com.intellij.psi.PsiNamedElement;
42 import com.intellij.psi.PsiQualifiedNamedElement;
43 import com.intellij.psi.util.PsiUtilCore;
45 import java.util.Comparator;
47 public class InspectionResultsViewComparator implements Comparator {
48 private static final Logger LOG = Logger.getInstance(InspectionResultsViewComparator.class);
50 public boolean areEqual(Object o1, Object o2) {
51 return o1.getClass().equals(o2.getClass()) && compare(o1, o2) == 0;
55 public int compare(Object o1, Object o2) {
56 InspectionTreeNode node1 = (InspectionTreeNode)o1;
57 InspectionTreeNode node2 = (InspectionTreeNode)o2;
59 if (node1 instanceof InspectionSeverityGroupNode && node2 instanceof InspectionSeverityGroupNode) {
60 final InspectionSeverityGroupNode groupNode1 = (InspectionSeverityGroupNode)node1;
61 final InspectionSeverityGroupNode groupNode2 = (InspectionSeverityGroupNode)node2;
62 return -SeverityRegistrar.getSeverityRegistrar(groupNode1.getProject()).compare(groupNode1.getSeverityLevel().getSeverity(), groupNode2.getSeverityLevel().getSeverity());
64 if (node1 instanceof InspectionSeverityGroupNode) return -1;
65 if (node2 instanceof InspectionSeverityGroupNode) return 1;
67 if (node1 instanceof InspectionGroupNode && node2 instanceof InspectionGroupNode) {
68 return ((InspectionGroupNode)node1).getGroupTitle().compareToIgnoreCase(((InspectionGroupNode)node2).getGroupTitle());
70 if (node1 instanceof InspectionGroupNode) return -1;
71 if (node2 instanceof InspectionGroupNode) return 1;
73 if (node1 instanceof InspectionNode && node2 instanceof InspectionNode)
74 return InspectionsConfigTreeComparator.getDisplayTextToSort(node1.toString())
75 .compareToIgnoreCase(InspectionsConfigTreeComparator.getDisplayTextToSort(node2.toString()));
76 if (node1 instanceof InspectionNode) return -1;
77 if (node2 instanceof InspectionNode) return 1;
79 if (node1 instanceof InspectionModuleNode && node2 instanceof InspectionModuleNode) {
80 return Comparing.compare(node1.toString(), node2.toString());
82 if (node1 instanceof InspectionModuleNode) return -1;
83 if (node2 instanceof InspectionModuleNode) return 1;
85 if (node1 instanceof InspectionPackageNode && node2 instanceof InspectionPackageNode) {
86 return ((InspectionPackageNode)node1).getPackageName().compareToIgnoreCase(((InspectionPackageNode)node2).getPackageName());
88 if (node1 instanceof InspectionPackageNode) return -1;
89 if (node2 instanceof InspectionPackageNode) return 1;
91 if (node1 instanceof OfflineRefElementNode && node2 instanceof OfflineRefElementNode) {
92 final Object userObject1 = ((OfflineRefElementNode)node1).getOfflineDescriptor();
93 final Object userObject2 = ((OfflineRefElementNode)node2).getOfflineDescriptor();
94 final OfflineProblemDescriptor descriptor1 = (OfflineProblemDescriptor)userObject1;
95 final OfflineProblemDescriptor descriptor2 = (OfflineProblemDescriptor)userObject2;
96 if (descriptor1.getLine() != descriptor2.getLine()) return descriptor1.getLine() - descriptor2.getLine();
97 return descriptor1.getFQName().compareTo(descriptor2.getFQName());
100 if (node1 instanceof RefElementNode && node2 instanceof RefElementNode){ //sort by filename and inside file by start offset
101 return compareEntities(((RefElementNode)node1).getElement(), ((RefElementNode)node2).getElement());
103 if (node1 instanceof ProblemDescriptionNode && node2 instanceof ProblemDescriptionNode) {
104 final CommonProblemDescriptor descriptor1 = ((ProblemDescriptionNode)node1).getDescriptor();
105 final CommonProblemDescriptor descriptor2 = ((ProblemDescriptionNode)node2).getDescriptor();
106 if (descriptor1 instanceof ProblemDescriptor && descriptor2 instanceof ProblemDescriptor) {
107 //TODO: Do not materialise lazy pointers
108 return ((ProblemDescriptor)descriptor1).getLineNumber() - ((ProblemDescriptor)descriptor2).getLineNumber();
110 if (descriptor1 != null && descriptor2 != null) {
111 return descriptor1.getDescriptionTemplate().compareToIgnoreCase(descriptor2.getDescriptionTemplate());
113 if (descriptor1 == null) return descriptor2 == null ? 0 : -1;
117 if (node1 instanceof RefElementNode && node2 instanceof ProblemDescriptionNode) {
118 final CommonProblemDescriptor descriptor = ((ProblemDescriptionNode)node2).getDescriptor();
119 if (descriptor instanceof ProblemDescriptor) {
120 return compareEntity(((RefElementNode)node1).getElement(), ((ProblemDescriptor)descriptor).getPsiElement());
122 return compareEntities(((RefElementNode)node1).getElement(), ((ProblemDescriptionNode)node2).getElement());
125 if (node2 instanceof RefElementNode && node1 instanceof ProblemDescriptionNode) {
126 final CommonProblemDescriptor descriptor = ((ProblemDescriptionNode)node1).getDescriptor();
127 if (descriptor instanceof ProblemDescriptor) {
128 return -compareEntity(((RefElementNode)node2).getElement(), ((ProblemDescriptor)descriptor).getPsiElement());
130 return -compareEntities(((RefElementNode)node2).getElement(), ((ProblemDescriptionNode)node1).getElement());
132 if (node1 instanceof InspectionRootNode && node2 instanceof InspectionRootNode) {
133 //TODO Dmitry Batkovich: optimization, because only one root node is existed
137 LOG.error("node1: " + node1 + ", node2: " + node2);
141 private static int compareEntity(final RefEntity entity, final PsiElement element) {
142 if (entity instanceof RefElement) {
143 final PsiElement psiElement = ((RefElement)entity).getElement();
144 if (psiElement != null && element != null) {
145 return PsiUtilCore.compareElementsByPosition(psiElement, element);
147 if (element == null) return psiElement == null ? 0 : 1;
149 if (element instanceof PsiQualifiedNamedElement) {
150 return StringUtil.compare(entity.getQualifiedName(), ((PsiQualifiedNamedElement)element).getQualifiedName(), true);
152 if (element instanceof PsiNamedElement) {
153 return StringUtil.compare(entity.getName(), ((PsiNamedElement)element).getName(), true);
158 private static int compareEntities(final RefEntity entity1, final RefEntity entity2) {
159 if (entity1 instanceof RefElement && entity2 instanceof RefElement) {
160 final int positionComparing = PsiUtilCore.compareElementsByPosition(((RefElement)entity1).getElement(), ((RefElement)entity2).getElement());
161 if (positionComparing != 0) {
162 return positionComparing;
165 if (entity1 != null && entity2 != null) {
166 final int nameComparing = entity1.getName().compareToIgnoreCase(entity2.getName());
167 if (nameComparing != 0) {
168 return nameComparing;
170 return entity1.getQualifiedName().compareToIgnoreCase(entity2.getQualifiedName());
172 if (entity1 != null) return -1;
173 return entity2 != null ? 1 : 0;
176 private static class InspectionResultsViewComparatorHolder {
177 private static final InspectionResultsViewComparator ourInstance = new InspectionResultsViewComparator();
180 public static InspectionResultsViewComparator getInstance() {
181 return InspectionResultsViewComparatorHolder.ourInstance;