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
;
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
) {
76 private void registerIntentionFromBean(final IntentionActionBean extension
) {
77 final Runnable runnable
= new Runnable() {
79 final String descriptionDirectoryName
= extension
.getDescriptionDirectoryName();
80 final String
[] categories
= extension
.getCategories();
81 final IntentionAction instance
= createIntentionActionWrapper(extension
, categories
);
82 if (categories
== null) {
86 if (descriptionDirectoryName
!= null) {
88 mySettings
.registerIntentionMetaData(instance
, categories
, descriptionDirectoryName
, extension
.getMetadataClassLoader());
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()) {
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
));
116 private static String
getDescriptionDirectoryName(final IntentionAction action
) {
117 if (action
instanceof IntentionActionWrapper
) {
118 final IntentionActionWrapper wrapper
= (IntentionActionWrapper
)action
;
119 return getDescriptionDirectoryName(wrapper
.getImplementationClassName());
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
) {
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
) {
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
);
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
);
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
));
172 public LocalQuickFix
convertToFix(final IntentionAction action
) {
173 if (action
instanceof LocalQuickFix
) {
174 return (LocalQuickFix
)action
;
176 return new LocalQuickFix() {
178 public String
getName() {
179 return action
.getText();
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();
190 action
.invoke(project
, new LazyEditor(psiFile
), psiFile
);
192 catch (IncorrectOperationException e
) {
199 public void addAction(IntentionAction action
) {
200 myActions
.add(action
);
203 public IntentionAction
[] getIntentionActions() {
204 return myActions
.toArray(new IntentionAction
[myActions
.size()]);