bbc2c2410dee68d732a75a24e1ddaedde0668a83
[idea/community.git] / platform / lang-impl / src / com / intellij / unscramble / AnalyzeStacktraceUtil.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package com.intellij.unscramble;
18
19 import com.intellij.execution.ExecutionManager;
20 import com.intellij.execution.Executor;
21 import com.intellij.execution.executors.DefaultRunExecutor;
22 import com.intellij.execution.filters.Filter;
23 import com.intellij.execution.filters.TextConsoleBuilder;
24 import com.intellij.execution.filters.TextConsoleBuilderFactory;
25 import com.intellij.execution.impl.ConsoleViewImpl;
26 import com.intellij.execution.ui.ConsoleView;
27 import com.intellij.execution.ui.ConsoleViewContentType;
28 import com.intellij.execution.ui.ExecutionConsole;
29 import com.intellij.execution.ui.RunContentDescriptor;
30 import com.intellij.execution.ui.actions.CloseAction;
31 import com.intellij.openapi.Disposable;
32 import com.intellij.openapi.actionSystem.*;
33 import com.intellij.openapi.application.ApplicationManager;
34 import com.intellij.openapi.command.CommandProcessor;
35 import com.intellij.openapi.editor.Document;
36 import com.intellij.openapi.editor.Editor;
37 import com.intellij.openapi.editor.EditorFactory;
38 import com.intellij.openapi.editor.EditorSettings;
39 import com.intellij.openapi.extensions.ExtensionPointName;
40 import com.intellij.openapi.extensions.Extensions;
41 import com.intellij.openapi.ide.CopyPasteManager;
42 import com.intellij.openapi.project.Project;
43 import com.intellij.openapi.util.Disposer;
44 import com.intellij.openapi.util.text.StringUtil;
45 import com.intellij.util.ui.JBUI;
46 import org.jetbrains.annotations.NotNull;
47 import org.jetbrains.annotations.Nullable;
48
49 import javax.swing.*;
50 import java.awt.*;
51 import java.awt.datatransfer.DataFlavor;
52
53 /**
54  * @author yole
55  */
56 public class AnalyzeStacktraceUtil {
57   public static final ExtensionPointName<Filter> EP_NAME = ExtensionPointName.create("com.intellij.analyzeStacktraceFilter");
58
59   private AnalyzeStacktraceUtil() {
60   }
61
62   public static void printStacktrace(@NotNull ConsoleView consoleView, @NotNull String unscrambledTrace) {
63     ApplicationManager.getApplication().assertIsDispatchThread();
64     String text = unscrambledTrace + "\n";
65     String consoleText = ((ConsoleViewImpl)consoleView).getText();
66     if (!text.equals(consoleText)) {
67       consoleView.clear();
68       consoleView.print(text, ConsoleViewContentType.ERROR_OUTPUT);
69       consoleView.scrollTo(0);
70     }
71   }
72
73   @Nullable
74   public static String getTextInClipboard() {
75     return CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor);
76   }
77
78   public interface ConsoleFactory {
79     JComponent createConsoleComponent(ConsoleView consoleView, DefaultActionGroup toolbarActions);
80   }
81
82   public static void addConsole(Project project, @Nullable ConsoleFactory consoleFactory, final String tabTitle, String text) {
83     addConsole(project, consoleFactory, tabTitle, text, null);
84   }
85
86   public static RunContentDescriptor addConsole(Project project,
87                                                 @Nullable ConsoleFactory consoleFactory,
88                                                 final String tabTitle,
89                                                 String text,
90                                                 @Nullable Icon icon) {
91     final TextConsoleBuilder builder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
92     builder.filters(Extensions.getExtensions(EP_NAME, project));
93     final ConsoleView consoleView = builder.getConsole();
94
95     final DefaultActionGroup toolbarActions = new DefaultActionGroup();
96     JComponent consoleComponent = consoleFactory != null
97                                   ? consoleFactory.createConsoleComponent(consoleView, toolbarActions)
98                                   : new MyConsolePanel(consoleView, toolbarActions);
99     final RunContentDescriptor descriptor =
100       new RunContentDescriptor(consoleView, null, consoleComponent, tabTitle, icon) {
101       @Override
102       public boolean isContentReuseProhibited() {
103         return true;
104       }
105     };
106
107     final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
108     for (AnAction action: consoleView.createConsoleActions()) {
109       toolbarActions.add(action);
110     }
111     final ConsoleViewImpl console = (ConsoleViewImpl)consoleView;
112     console.getEditor().getSettings().setCaretRowShown(true);
113     toolbarActions.add(new AnnotateStackTraceAction(console.getEditor(), console.getHyperlinks()));
114     toolbarActions.add(new CloseAction(executor, descriptor, project));
115     ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor);
116     consoleView.allowHeavyFilters();
117     if (consoleFactory == null) {
118       printStacktrace(consoleView, text);
119     }
120     return descriptor;
121   }
122
123   private static final class MyConsolePanel extends JPanel {
124     public MyConsolePanel(ExecutionConsole consoleView, ActionGroup toolbarActions) {
125       super(new BorderLayout());
126       JPanel toolbarPanel = new JPanel(new BorderLayout());
127       toolbarPanel.add(ActionManager.getInstance()
128                          .createActionToolbar(ActionPlaces.ANALYZE_STACKTRACE_PANEL_TOOLBAR, toolbarActions, false)
129                          .getComponent());
130       add(toolbarPanel, BorderLayout.WEST);
131       add(consoleView.getComponent(), BorderLayout.CENTER);
132     }
133   }
134
135   public static StacktraceEditorPanel createEditorPanel(Project project, @NotNull Disposable parentDisposable) {
136     EditorFactory editorFactory = EditorFactory.getInstance();
137     Document document = editorFactory.createDocument("");
138     Editor editor = editorFactory.createEditor(document, project);
139     EditorSettings settings = editor.getSettings();
140     settings.setFoldingOutlineShown(false);
141     settings.setLineMarkerAreaShown(false);
142     settings.setIndentGuidesShown(false);
143     settings.setLineNumbersShown(false);
144     settings.setRightMarginShown(false);
145
146     StacktraceEditorPanel editorPanel = new StacktraceEditorPanel(project, editor);
147     editorPanel.setPreferredSize(JBUI.size(600, 400));
148     Disposer.register(parentDisposable, editorPanel);
149     return editorPanel;
150   }
151
152   public static final class StacktraceEditorPanel extends JPanel implements DataProvider, Disposable {
153     private final Project myProject;
154     private final Editor myEditor;
155
156     public StacktraceEditorPanel(Project project, Editor editor) {
157       super(new BorderLayout());
158       myProject = project;
159       myEditor = editor;
160       add(myEditor.getComponent());
161     }
162
163     @Override
164     public Object getData(String dataId) {
165       if (CommonDataKeys.EDITOR.is(dataId)) {
166         return myEditor;
167       }
168       return null;
169     }
170
171     public Editor getEditor() {
172       return myEditor;
173     }
174
175     public final void setText(@NotNull final String text) {
176       Runnable runnable = new Runnable() {
177         @Override
178         public void run() {
179           ApplicationManager.getApplication().runWriteAction(new Runnable() {
180             @Override
181             public void run() {
182               final Document document = myEditor.getDocument();
183               document.replaceString(0, document.getTextLength(), StringUtil.convertLineSeparators(text));
184             }
185           });
186         }
187       };
188       CommandProcessor.getInstance().executeCommand(myProject, runnable, "", this);
189     }
190
191     public void pasteTextFromClipboard() {
192       String text = getTextInClipboard();
193       if (text != null) {
194         setText(text);
195       }
196
197     }
198
199     @Override
200     public void dispose() {
201       EditorFactory.getInstance().releaseEditor(myEditor);
202     }
203
204     public String getText() {
205       return myEditor.getDocument().getText();
206     }
207
208     public JComponent getEditorComponent() {
209       return myEditor.getContentComponent();
210     }
211   }
212 }