update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / ide / structureView / impl / java / SuperTypesGrouper.java
blob7fce7bfdf227abafc7cb881187bcbb1192b3abf5
1 /*
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.
16 package com.intellij.ide.structureView.impl.java;
18 import com.intellij.ide.IdeBundle;
19 import com.intellij.ide.util.treeView.AbstractTreeNode;
20 import com.intellij.ide.util.treeView.smartTree.*;
21 import com.intellij.openapi.util.IconLoader;
22 import com.intellij.openapi.util.Key;
23 import com.intellij.psi.PsiClass;
24 import com.intellij.psi.PsiMethod;
25 import com.intellij.psi.PsiModifier;
26 import com.intellij.util.ArrayUtil;
27 import gnu.trove.THashMap;
28 import org.jetbrains.annotations.NonNls;
29 import org.jetbrains.annotations.NotNull;
31 import java.lang.ref.WeakReference;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.Map;
36 public class SuperTypesGrouper implements Grouper{
37 public static final Key<WeakReference<PsiMethod>> SUPER_METHOD_KEY = Key.create("StructureTreeBuilder.SUPER_METHOD_KEY");
38 @NonNls public static final String ID = "SHOW_INTERFACES";
40 @NotNull
41 public Collection<Group> group(final AbstractTreeNode parent, Collection<TreeElement> children) {
42 if (isParentGrouped(parent)) return Collections.emptyList();
43 Map<Group, SuperTypeGroup> groups = new THashMap<Group, SuperTypeGroup>();
45 for (TreeElement child : children) {
46 if (child instanceof PsiMethodTreeElement) {
47 final PsiMethodTreeElement element = (PsiMethodTreeElement)child;
49 PsiMethod method = ((PsiMethodTreeElement)child).getMethod();
50 if (element.isInherited()) {
51 PsiClass groupClass = method.getContainingClass();
52 final SuperTypeGroup group = getOrCreateGroup(groupClass, SuperTypeGroup.OwnershipType.INHERITS, groups);
53 group.addMethod(child);
55 else {
56 PsiMethod[] superMethods = method.findSuperMethods();
58 if (superMethods.length > 0) {
59 //prefer interface, if there are any
60 for (int i = 1; i < superMethods.length; i++) {
61 PsiMethod superMethod = superMethods[i];
62 PsiClass containingClass = superMethod.getContainingClass();
63 if (containingClass != null && containingClass.isInterface()) {
64 ArrayUtil.swap(superMethods, 0, i);
65 break;
69 PsiMethod superMethod = superMethods[0];
70 method.putUserData(SUPER_METHOD_KEY, new WeakReference<PsiMethod>(superMethod));
71 PsiClass groupClass = superMethod.getContainingClass();
72 boolean overrides = methodOverridesSuper(method, superMethod);
73 final SuperTypeGroup.OwnershipType ownershipType =
74 overrides ? SuperTypeGroup.OwnershipType.OVERRIDES : SuperTypeGroup.OwnershipType.IMPLEMENTS;
75 SuperTypeGroup group = getOrCreateGroup(groupClass, ownershipType, groups);
76 group.addMethod(child);
81 return groups.keySet();
84 private static SuperTypeGroup getOrCreateGroup(final PsiClass groupClass, final SuperTypeGroup.OwnershipType ownershipType, final Map<Group, SuperTypeGroup> groups) {
85 SuperTypeGroup superTypeGroup =
86 new SuperTypeGroup(groupClass, ownershipType);
87 SuperTypeGroup existing = groups.get(superTypeGroup);
88 if (existing == null) {
89 groups.put(superTypeGroup, superTypeGroup);
90 existing = superTypeGroup;
92 return existing;
95 private static boolean isParentGrouped(AbstractTreeNode parent) {
96 while (parent != null) {
97 if (parent.getValue() instanceof SuperTypeGroup) return true;
98 parent = parent.getParent();
100 return false;
103 private static boolean methodOverridesSuper(PsiMethod method, PsiMethod superMethod) {
104 boolean overrides = false;
105 if (method.hasModifierProperty(PsiModifier.ABSTRACT)){
106 overrides = true;
108 else if (!superMethod.hasModifierProperty(PsiModifier.ABSTRACT)){
109 overrides = true;
111 return overrides;
115 @NotNull
116 public ActionPresentation getPresentation() {
117 return new ActionPresentationData(IdeBundle.message("action.structureview.group.methods.by.defining.type"), null,
118 IconLoader.getIcon("/general/implementingMethod.png"));
121 @NotNull
122 public String getName() {
123 return ID;