IDEADEV-41249
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInsight / intention / impl / config / IntentionManagerImpl.java
blobd3ae32d304d3fa88a4def366b44137d54d8ab6a5
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.
17 package com.intellij.codeInsight.intention.impl.config;
19 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
20 import com.intellij.codeInsight.intention.IntentionAction;
21 import com.intellij.codeInsight.intention.IntentionActionBean;
22 import com.intellij.codeInsight.intention.IntentionManager;
23 import com.intellij.codeInspection.LocalQuickFix;
24 import com.intellij.codeInspection.ProblemDescriptor;
25 import com.intellij.codeInspection.actions.RunInspectionIntention;
26 import com.intellij.codeInspection.ex.DisableInspectionToolAction;
27 import com.intellij.codeInspection.ex.EditInspectionToolsSettingsAction;
28 import com.intellij.codeInspection.ex.EditInspectionToolsSettingsInSuppressedPlaceIntention;
29 import com.intellij.openapi.diagnostic.Logger;
30 import com.intellij.openapi.extensions.ExtensionPoint;
31 import com.intellij.openapi.extensions.ExtensionPointListener;
32 import com.intellij.openapi.extensions.Extensions;
33 import com.intellij.openapi.extensions.PluginDescriptor;
34 import com.intellij.openapi.project.Project;
35 import com.intellij.openapi.application.ApplicationManager;
36 import com.intellij.psi.PsiElement;
37 import com.intellij.psi.PsiFile;
38 import com.intellij.util.Alarm;
39 import com.intellij.util.IncorrectOperationException;
40 import org.jetbrains.annotations.NonNls;
41 import org.jetbrains.annotations.NotNull;
42 import org.jetbrains.annotations.Nullable;
44 import java.util.ArrayList;
45 import java.util.Collections;
46 import java.util.List;
48 /**
49 * @author dsl
51 public class IntentionManagerImpl extends IntentionManager {
52 private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.impl.config.IntentionManagerImpl");
54 private final List<IntentionAction> myActions = Collections.synchronizedList(new ArrayList<IntentionAction>());
55 private final IntentionManagerSettings mySettings;
57 private final Alarm myInitActionsAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
59 public IntentionManagerImpl(IntentionManagerSettings intentionManagerSettings) {
60 mySettings = intentionManagerSettings;
62 addAction(new EditInspectionToolsSettingsInSuppressedPlaceIntention());
64 final ExtensionPoint<IntentionActionBean> point = Extensions.getArea(null).getExtensionPoint(EP_INTENTION_ACTIONS);
66 point.addExtensionPointListener(new ExtensionPointListener<IntentionActionBean>() {
67 public void extensionAdded(final IntentionActionBean extension, @Nullable final PluginDescriptor pluginDescriptor) {
68 registerIntentionFromBean(extension);
71 public void extensionRemoved(final IntentionActionBean extension, @Nullable final PluginDescriptor pluginDescriptor) {
73 });
76 private void registerIntentionFromBean(final IntentionActionBean extension) {
77 final Runnable runnable = new Runnable() {
78 public void run() {
79 final String descriptionDirectoryName = extension.getDescriptionDirectoryName();
80 final String[] categories = extension.getCategories();
81 final IntentionAction instance = createIntentionActionWrapper(extension, categories);
82 if (categories == null) {
83 addAction(instance);
85 else {
86 if (descriptionDirectoryName != null) {
87 addAction(instance);
88 mySettings.registerIntentionMetaData(instance, categories, descriptionDirectoryName, extension.getMetadataClassLoader());
90 else {
91 registerIntentionAndMetaData(instance, categories);
96 //todo temporary hack, need smarter logic:
97 // * on the first request, wait until all the initialization is finished
98 // * ensure this request doesn't come on EDT
99 // * while waiting, check for ProcessCanceledException
100 if (ApplicationManager.getApplication().isUnitTestMode()) {
101 runnable.run();
102 } else {
103 myInitActionsAlarm.addRequest(runnable, 300);
107 private static IntentionAction createIntentionActionWrapper(final IntentionActionBean intentionActionBean, final String[] categories) {
108 return new IntentionActionWrapper(intentionActionBean,categories);
111 public void registerIntentionAndMetaData(IntentionAction action, String... category) {
112 registerIntentionAndMetaData(action, category, getDescriptionDirectoryName(action));
115 @NotNull
116 private static String getDescriptionDirectoryName(final IntentionAction action) {
117 if (action instanceof IntentionActionWrapper) {
118 final IntentionActionWrapper wrapper = (IntentionActionWrapper)action;
119 return getDescriptionDirectoryName(wrapper.getImplementationClassName());
121 else {
122 return getDescriptionDirectoryName(action.getClass().getName());
126 private static String getDescriptionDirectoryName(final String fqn) {
127 return fqn.substring(fqn.lastIndexOf('.') + 1).replaceAll("\\$", "");
130 public void registerIntentionAndMetaData(@NotNull IntentionAction action, @NotNull String[] category, @NotNull @NonNls String descriptionDirectoryName) {
131 addAction(action);
132 mySettings.registerIntentionMetaData(action, category, descriptionDirectoryName);
135 public void registerIntentionAndMetaData(final IntentionAction action,
136 final String[] category,
137 final String description,
138 final String exampleFileExtension,
139 final String[] exampleTextBefore,
140 final String[] exampleTextAfter) {
141 addAction(action);
143 IntentionActionMetaData metaData = new IntentionActionMetaData(action, category,
144 new PlainTextDescriptor(description, "description.html"),
145 mapToDescriptors(exampleTextBefore, "before." + exampleFileExtension),
146 mapToDescriptors(exampleTextAfter, "after." + exampleFileExtension));
147 mySettings.registerMetaData(metaData);
150 @Override
151 public void unregisterIntention(IntentionAction intentionAction) {
152 myActions.remove(intentionAction);
153 mySettings.unregisterMetaData(intentionAction);
156 private static TextDescriptor[] mapToDescriptors(String[] texts, String fileName) {
157 TextDescriptor[] result = new TextDescriptor[texts.length];
158 for (int i = 0; i < texts.length; i++) {
159 result [i] = new PlainTextDescriptor(texts [i], fileName);
161 return result;
164 public List<IntentionAction> getStandardIntentionOptions(@NotNull final HighlightDisplayKey displayKey, final PsiElement context) {
165 List<IntentionAction> options = new ArrayList<IntentionAction>(9);
166 options.add(new EditInspectionToolsSettingsAction(displayKey));
167 options.add(new RunInspectionIntention(displayKey));
168 options.add(new DisableInspectionToolAction(displayKey));
169 return options;
172 public LocalQuickFix convertToFix(final IntentionAction action) {
173 if (action instanceof LocalQuickFix) {
174 return (LocalQuickFix)action;
176 return new LocalQuickFix() {
177 @NotNull
178 public String getName() {
179 return action.getText();
182 @NotNull
183 public String getFamilyName() {
184 return action.getFamilyName();
187 public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
188 final PsiFile psiFile = descriptor.getPsiElement().getContainingFile();
189 try {
190 action.invoke(project, new LazyEditor(psiFile), psiFile);
192 catch (IncorrectOperationException e) {
193 LOG.error(e);
199 public void addAction(IntentionAction action) {
200 myActions.add(action);
203 public IntentionAction[] getIntentionActions() {
204 return myActions.toArray(new IntentionAction[myActions.size()]);