mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
offline view for 'file elements' inspections
This commit is contained in:
@@ -375,7 +375,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
|
||||
return message;
|
||||
}
|
||||
|
||||
private static PsiElement[] getElementsIntersectingRange(PsiFile file, final int startOffset, final int endOffset) {
|
||||
public static PsiElement[] getElementsIntersectingRange(PsiFile file, final int startOffset, final int endOffset) {
|
||||
final FileViewProvider viewProvider = file.getViewProvider();
|
||||
final Set<PsiElement> result = new THashSet<PsiElement>();
|
||||
for (Language language : viewProvider.getPrimaryLanguages()) {
|
||||
|
||||
+65
-23
@@ -22,10 +22,15 @@ import com.intellij.codeInspection.ui.InspectionResultsView;
|
||||
import com.intellij.ide.highlighter.XmlFileType;
|
||||
import com.intellij.ide.util.BrowseFilesListener;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.profile.Profile;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
@@ -33,11 +38,13 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ViewOfflineResultsAction extends AnAction {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.actions.ViewOfflineResultsAction");
|
||||
|
||||
public void update(AnActionEvent event) {
|
||||
final Presentation presentation = event.getPresentation();
|
||||
@@ -49,30 +56,62 @@ public class ViewOfflineResultsAction extends AnAction {
|
||||
public void actionPerformed(AnActionEvent event) {
|
||||
final Project project = event.getData(DataKeys.PROJECT);
|
||||
|
||||
LOG.assertTrue(project != null);
|
||||
|
||||
final VirtualFile[] virtualFiles = FileChooser.chooseFiles(project, BrowseFilesListener.SINGLE_DIRECTORY_DESCRIPTOR);
|
||||
if (virtualFiles == null || virtualFiles.length == 0) return;
|
||||
if (!virtualFiles[0].isDirectory()) return;
|
||||
|
||||
final Map<String, Map<String, Set<OfflineProblemDescriptor>>> resMap = new HashMap<String, Map<String, Set<OfflineProblemDescriptor>>>();
|
||||
final VirtualFile[] files = virtualFiles[0].getChildren();
|
||||
String profileName = null;
|
||||
try {
|
||||
for (VirtualFile inspectionFile : files) {
|
||||
if (inspectionFile.isDirectory()) continue;
|
||||
final String shortName = inspectionFile.getNameWithoutExtension();
|
||||
if (shortName.equals(InspectionApplication.DESCRIPTIONS)) {
|
||||
profileName = OfflineViewParseUtil.parseProfileName(LoadTextUtil.loadText(inspectionFile).toString());
|
||||
} else if (inspectionFile.getFileType() instanceof XmlFileType){
|
||||
resMap.put(shortName, OfflineViewParseUtil.parse(LoadTextUtil.loadText(inspectionFile).toString()));
|
||||
final Map<String, Map<String, Set<OfflineProblemDescriptor>>> resMap =
|
||||
new HashMap<String, Map<String, Set<OfflineProblemDescriptor>>>();
|
||||
final String [] profileName = new String[1];
|
||||
final Runnable process = new Runnable() {
|
||||
public void run() {
|
||||
final VirtualFile[] files = virtualFiles[0].getChildren();
|
||||
try {
|
||||
for (final VirtualFile inspectionFile : files) {
|
||||
if (inspectionFile.isDirectory()) continue;
|
||||
final String shortName = inspectionFile.getNameWithoutExtension();
|
||||
if (shortName.equals(InspectionApplication.DESCRIPTIONS)) {
|
||||
profileName[0] = ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<String>() {
|
||||
@Nullable
|
||||
public String compute() {
|
||||
return OfflineViewParseUtil.parseProfileName(LoadTextUtil.loadText(inspectionFile).toString());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (inspectionFile.getFileType() instanceof XmlFileType) {
|
||||
resMap.put(shortName, ApplicationManager.getApplication().runReadAction(
|
||||
new Computable<Map<String, Set<OfflineProblemDescriptor>>>() {
|
||||
public Map<String, Set<OfflineProblemDescriptor>> compute() {
|
||||
return OfflineViewParseUtil.parse(LoadTextUtil.loadText(inspectionFile).toString());
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final Exception e) { //all parse exceptions
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showInfoMessage(e.getMessage(), InspectionsBundle.message("offline.view.parse.exception.title"));
|
||||
}
|
||||
});
|
||||
throw new ProcessCanceledException(); //cancel process
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) { //all parse exceptions
|
||||
Messages.showInfoMessage(e.getMessage(), InspectionsBundle.message("offline.view.parse.exception.title"));
|
||||
return;
|
||||
}
|
||||
|
||||
showOfflineView(project, profileName, resMap);
|
||||
};
|
||||
ProgressManager.getInstance().runProcessWithProgressAsynchronously(project, InspectionsBundle.message("parsing.inspections.dump.progress.title"), process, new Runnable() {
|
||||
public void run() {
|
||||
SwingUtilities.invokeLater(new Runnable(){
|
||||
public void run() {
|
||||
showOfflineView(project, profileName[0], resMap);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
@@ -111,7 +150,8 @@ public class ViewOfflineResultsAction extends AnAction {
|
||||
return showOfflineView(project, resMap, inspectionProfile, profileName);
|
||||
}
|
||||
|
||||
public static InspectionResultsView showOfflineView(final Project project, final Map<String, Map<String, Set<OfflineProblemDescriptor>>> resMap,
|
||||
public static InspectionResultsView showOfflineView(final Project project,
|
||||
final Map<String, Map<String, Set<OfflineProblemDescriptor>>> resMap,
|
||||
final InspectionProfile inspectionProfile,
|
||||
final String profileName) {
|
||||
final AnalysisScope scope = new AnalysisScope(project);
|
||||
@@ -120,15 +160,17 @@ public class ViewOfflineResultsAction extends AnAction {
|
||||
inspectionContext.setExternalProfile(inspectionProfile);
|
||||
inspectionContext.setCurrentScope(scope);
|
||||
inspectionContext.initializeTools(scope, new HashMap<String, Set<InspectionTool>>(), new HashMap<String, Set<InspectionTool>>());
|
||||
final InspectionResultsView view = new InspectionResultsView(project, inspectionProfile, scope,
|
||||
inspectionContext,
|
||||
final InspectionResultsView view = new InspectionResultsView(project, inspectionProfile, scope, inspectionContext,
|
||||
new OfflineInspectionRVContentProvider(resMap, project));
|
||||
((RefManagerImpl)inspectionContext.getRefManager()).inspectionReadActionStarted();
|
||||
view.update();
|
||||
TreeUtil.selectFirstNode(view.getTree());
|
||||
if (inspectionContext.getContentManager() != null) { //test
|
||||
inspectionContext.addView(view, InspectionsBundle.message("offline.view.title") +
|
||||
" (" + (profileName != null ? profileName : InspectionsBundle.message("offline.view.editor.settings.title")) + ")");
|
||||
inspectionContext.addView(view, InspectionsBundle.message("offline.view.title") + " (" + (profileName != null
|
||||
? profileName
|
||||
: InspectionsBundle.message(
|
||||
"offline.view.editor.settings.title")) +
|
||||
")");
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.intellij.codeInspection.export;
|
||||
|
||||
import com.intellij.codeEditor.printing.ExportToHTMLSettings;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.ui.OptionGroup;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -14,10 +14,12 @@ public class ExportToHTMLDialog extends DialogWrapper{
|
||||
private JCheckBox myCbOpenInBrowser;
|
||||
private final Project myProject;
|
||||
private TextFieldWithBrowseButton myTargetDirectoryField;
|
||||
private boolean myCanBeOpenInBrowser;
|
||||
|
||||
public ExportToHTMLDialog(Project project) {
|
||||
public ExportToHTMLDialog(Project project, final boolean canBeOpenInBrowser) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
myCanBeOpenInBrowser = canBeOpenInBrowser;
|
||||
setOKButtonText(InspectionsBundle.message("inspection.export.save.button"));
|
||||
setTitle(InspectionsBundle.message("inspection.export.dialog.title"));
|
||||
init();
|
||||
@@ -33,6 +35,7 @@ public class ExportToHTMLDialog extends DialogWrapper{
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
if (!myCanBeOpenInBrowser) return null;
|
||||
OptionGroup optionGroup = new OptionGroup(InspectionsBundle.message("inspection.export.options.panel.title"));
|
||||
|
||||
myCbOpenInBrowser = new JCheckBox();
|
||||
@@ -44,14 +47,18 @@ public class ExportToHTMLDialog extends DialogWrapper{
|
||||
|
||||
public void reset() {
|
||||
ExportToHTMLSettings exportToHTMLSettings = ExportToHTMLSettings.getInstance(myProject);
|
||||
myCbOpenInBrowser.setSelected(exportToHTMLSettings.OPEN_IN_BROWSER);
|
||||
if (myCanBeOpenInBrowser) {
|
||||
myCbOpenInBrowser.setSelected(exportToHTMLSettings.OPEN_IN_BROWSER);
|
||||
}
|
||||
myTargetDirectoryField.setText(exportToHTMLSettings.OUTPUT_DIRECTORY);
|
||||
}
|
||||
|
||||
public void apply() {
|
||||
ExportToHTMLSettings exportToHTMLSettings = ExportToHTMLSettings.getInstance(myProject);
|
||||
|
||||
exportToHTMLSettings.OPEN_IN_BROWSER = myCbOpenInBrowser.isSelected();
|
||||
if (myCanBeOpenInBrowser) {
|
||||
exportToHTMLSettings.OPEN_IN_BROWSER = myCbOpenInBrowser.isSelected();
|
||||
}
|
||||
exportToHTMLSettings.OUTPUT_DIRECTORY = myTargetDirectoryField.getText();
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.offlineViewer;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.LocalInspectionsPass;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.DescriptorProviderInspection;
|
||||
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.reference.RefEntity;
|
||||
import com.intellij.codeInspection.ui.ProblemDescriptionNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -61,10 +62,9 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode {
|
||||
final PsiElement psiElement = ((RefElement)element).getElement();
|
||||
if (psiElement != null) {
|
||||
final PsiElementVisitor visitor = ((LocalInspectionToolWrapper)myTool).getTool().buildVisitor(holder, false);
|
||||
final List<PsiElement> elementsInRange = CodeInsightUtil.getElementsInRange(psiElement.getContainingFile(),
|
||||
psiElement.getTextRange().getStartOffset(),
|
||||
psiElement.getTextRange().getEndOffset(),
|
||||
true);
|
||||
final PsiElement[] elementsInRange = LocalInspectionsPass.getElementsIntersectingRange(psiElement.getContainingFile(),
|
||||
psiElement.getTextRange().getStartOffset(),
|
||||
psiElement.getTextRange().getEndOffset());
|
||||
for (PsiElement el : elementsInRange) {
|
||||
el.accept(visitor);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode {
|
||||
int curIdx = 0;
|
||||
for (ProblemDescriptor descriptor : list) {
|
||||
final PsiMember member = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiMember.class, false);
|
||||
if (member != null && member.equals(psiElement)) {
|
||||
if (psiElement instanceof PsiFile || (member != null && member.equals(psiElement))) {
|
||||
if (curIdx == idx) {
|
||||
setUserObject(descriptor);
|
||||
return descriptor;
|
||||
|
||||
+26
-11
@@ -12,12 +12,17 @@ import com.intellij.codeInspection.ex.InspectionApplication;
|
||||
import com.intellij.codeInspection.reference.SmartRefElementPointerImpl;
|
||||
import com.thoughtworks.xstream.io.xml.XppReader;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class OfflineViewParseUtil {
|
||||
@NonNls private static final String PACKAGE = "package";
|
||||
@@ -41,7 +46,16 @@ public class OfflineViewParseUtil {
|
||||
reader.moveDown();
|
||||
if (SmartRefElementPointerImpl.ENTRY_POINT.equals(reader.getNodeName())) {
|
||||
descriptor.setType(reader.getAttribute(SmartRefElementPointerImpl.TYPE_ATTR));
|
||||
descriptor.setFQName(reader.getAttribute(SmartRefElementPointerImpl.FQNAME_ATTR));
|
||||
final String fqName = reader.getAttribute(SmartRefElementPointerImpl.FQNAME_ATTR);
|
||||
descriptor.setFQName(fqName);
|
||||
|
||||
if (!fqName2IdxMap.containsKey(fqName)) {
|
||||
fqName2IdxMap.put(fqName, 0);
|
||||
}
|
||||
int idx = fqName2IdxMap.get(fqName);
|
||||
descriptor.setProblemIndex(idx);
|
||||
fqName2IdxMap.put(fqName, idx + 1);
|
||||
|
||||
final List<String> parentTypes = new ArrayList<String>();
|
||||
final List<String> parentNames = new ArrayList<String>();
|
||||
int deep = 0;
|
||||
@@ -97,14 +111,6 @@ public class OfflineViewParseUtil {
|
||||
reader.moveUp();
|
||||
}
|
||||
|
||||
final String fqName = descriptor.getFQName();
|
||||
if (!fqName2IdxMap.containsKey(fqName)) {
|
||||
fqName2IdxMap.put(fqName, 0);
|
||||
}
|
||||
int idx = fqName2IdxMap.get(fqName);
|
||||
descriptor.setProblemIndex(idx);
|
||||
fqName2IdxMap.put(fqName, idx + 1);
|
||||
|
||||
reader.moveUp();
|
||||
}
|
||||
}
|
||||
@@ -119,7 +125,16 @@ public class OfflineViewParseUtil {
|
||||
final OfflineProblemDescriptor descriptor) {
|
||||
Set<OfflineProblemDescriptor> descriptors = package2Result.get(packageName);
|
||||
if (descriptors == null) {
|
||||
descriptors = new HashSet<OfflineProblemDescriptor>();
|
||||
descriptors = new THashSet<OfflineProblemDescriptor>(new TObjectHashingStrategy<OfflineProblemDescriptor>() { //consider problem index
|
||||
public int computeHashCode(final OfflineProblemDescriptor descriptor) {
|
||||
return 31 * descriptor.hashCode() + descriptor.getProblemIndex();
|
||||
}
|
||||
|
||||
public boolean equals(final OfflineProblemDescriptor descriptor1, final OfflineProblemDescriptor descriptor2) {
|
||||
if (!descriptor1.equals(descriptor2)) return false;
|
||||
return descriptor1.getProblemIndex() == descriptor2.getProblemIndex();
|
||||
}
|
||||
});
|
||||
package2Result.put(packageName, descriptors);
|
||||
}
|
||||
descriptors.add(descriptor);
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.codeInspection.reference;
|
||||
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
@@ -88,6 +89,12 @@ public class RefFileImpl extends RefElementImpl implements RefFile {
|
||||
});
|
||||
}
|
||||
|
||||
public String getExternalName() {
|
||||
final PsiFile psiFile = getElement();
|
||||
final VirtualFile virtualFile = psiFile != null ? psiFile.getVirtualFile() : null;
|
||||
return virtualFile != null ? virtualFile.getUrl() : getName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getAccessModifier() {
|
||||
return null;
|
||||
@@ -99,7 +106,7 @@ public class RefFileImpl extends RefElementImpl implements RefFile {
|
||||
|
||||
@Nullable
|
||||
public static RefElement fileFromExternalName(final RefManager manager, final String fqName) {
|
||||
final VirtualFile virtualFile = VirtualFileManager.getInstance().findFileByUrl(fqName);
|
||||
final VirtualFile virtualFile = VirtualFileManager.getInstance().findFileByUrl(PathMacroManager.getInstance(manager.getProject()).expandPath(fqName));
|
||||
if (virtualFile != null) {
|
||||
final PsiFile psiFile = PsiManager.getInstance(manager.getProject()).findFile(virtualFile);
|
||||
if (psiFile != null) {
|
||||
|
||||
@@ -282,10 +282,16 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren
|
||||
group.add(actionsManager.createPrevOccurenceAction(getOccurenceNavigator()));
|
||||
group.add(actionsManager.createNextOccurenceAction(getOccurenceNavigator()));
|
||||
group.add(myGlobalInspectionContext.createToggleAutoscrollAction());
|
||||
group.add(new ExportHTMLAction(this));
|
||||
final ExportHTMLAction exportAction = new ExportHTMLAction(this);
|
||||
group.add(exportAction);
|
||||
group.add(new HelpAction());
|
||||
|
||||
return ActionManager.getInstance().createActionToolbar(ActionPlaces.CODE_INSPECTION, group, false).getComponent();
|
||||
final JComponent toolbarComponent =
|
||||
ActionManager.getInstance().createActionToolbar(ActionPlaces.CODE_INSPECTION, group, false).getComponent();
|
||||
final Component actionButton = toolbarComponent.getComponent(ArrayUtil.find(group.getChildren(null), exportAction) + 1);
|
||||
exportAction.setPoint(new RelativePoint(actionButton, new Point(0, actionButton.getHeight())));
|
||||
|
||||
return toolbarComponent;
|
||||
}
|
||||
|
||||
public void dispose(){
|
||||
|
||||
@@ -48,6 +48,12 @@ public class InspectionResultsViewComparator implements Comparator {
|
||||
if (descriptor1.getLine() != descriptor2.getLine()) return descriptor1.getLine() - descriptor2.getLine();
|
||||
return descriptor1.getFQName().compareTo(descriptor2.getFQName());
|
||||
}
|
||||
if (userObject1 instanceof OfflineProblemDescriptor) { //todo sort properly
|
||||
return 1;
|
||||
}
|
||||
if (userObject2 instanceof OfflineProblemDescriptor) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (node1 instanceof RefElementNode && node2 instanceof RefElementNode){ //sort by filename and inside file by start offset
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
package com.intellij.codeInspection.ui.actions;
|
||||
|
||||
import com.intellij.codeEditor.printing.ExportToHTMLSettings;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
|
||||
import com.intellij.codeInspection.ex.InspectionApplication;
|
||||
import com.intellij.codeInspection.ex.InspectionTool;
|
||||
import com.intellij.codeInspection.export.ExportToHTMLDialog;
|
||||
import com.intellij.codeInspection.export.HTMLExportFrameMaker;
|
||||
@@ -19,15 +22,32 @@ import com.intellij.codeInspection.ui.InspectionResultsView;
|
||||
import com.intellij.codeInspection.ui.InspectionTreeNode;
|
||||
import com.intellij.codeInspection.util.RefEntityAlphabeticalComparator;
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.ide.highlighter.XmlFileType;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.ListPopup;
|
||||
import com.intellij.openapi.ui.popup.PopupStep;
|
||||
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -36,6 +56,10 @@ import java.util.*;
|
||||
*/
|
||||
public class ExportHTMLAction extends AnAction {
|
||||
private InspectionResultsView myView;
|
||||
@NonNls private static final String PROBLEMS = "problems";
|
||||
private RelativePoint myPoint;
|
||||
@NonNls private static final String HTML = "HTML";
|
||||
@NonNls private static final String XML = "XML";
|
||||
|
||||
public ExportHTMLAction(final InspectionResultsView view) {
|
||||
super(InspectionsBundle.message("inspection.action.export.html"), null, IconLoader.getIcon("/actions/export.png"));
|
||||
@@ -43,147 +67,231 @@ public class ExportHTMLAction extends AnAction {
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
exportHTML();
|
||||
}
|
||||
|
||||
private void exportHTML() {
|
||||
ExportToHTMLDialog exportToHTMLDialog = new ExportToHTMLDialog(myView.getProject());
|
||||
final ExportToHTMLSettings exportToHTMLSettings = ExportToHTMLSettings.getInstance(myView.getProject());
|
||||
if (exportToHTMLSettings.OUTPUT_DIRECTORY == null) {
|
||||
exportToHTMLSettings.OUTPUT_DIRECTORY = PathManager.getHomePath() + File.separator + "exportToHTML";
|
||||
}
|
||||
exportToHTMLDialog.reset();
|
||||
exportToHTMLDialog.show();
|
||||
if (!exportToHTMLDialog.isOK()) {
|
||||
return;
|
||||
}
|
||||
exportToHTMLDialog.apply();
|
||||
|
||||
final String outputDirectoryName = exportToHTMLSettings.OUTPUT_DIRECTORY;
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
final Runnable exportRunnable = new Runnable() {
|
||||
public void run() {
|
||||
HTMLExportFrameMaker maker = new HTMLExportFrameMaker(outputDirectoryName, myView.getProject());
|
||||
maker.start();
|
||||
try {
|
||||
exportHTML(maker);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
// Do nothing here.
|
||||
}
|
||||
|
||||
maker.done();
|
||||
final ListPopup popup = JBPopupFactory.getInstance().createListPopup(
|
||||
new BaseListPopupStep<String>(InspectionsBundle.message("inspection.action.export.popup.title"), new String[]{HTML, XML}) {
|
||||
public PopupStep onChosen(final String selectedValue, final boolean finalChoice) {
|
||||
exportHTML(Comparing.strEqual(selectedValue, HTML));
|
||||
return PopupStep.FINAL_CHOICE;
|
||||
}
|
||||
};
|
||||
});
|
||||
popup.show(myPoint);
|
||||
}
|
||||
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(exportRunnable, InspectionsBundle.message(
|
||||
"inspection.generating.html.progress.title"), true, myView.getProject())) {
|
||||
return;
|
||||
}
|
||||
public void setPoint(final RelativePoint point) {
|
||||
myPoint = point;
|
||||
}
|
||||
|
||||
if (exportToHTMLSettings.OPEN_IN_BROWSER) {
|
||||
BrowserUtil.launchBrowser(exportToHTMLSettings.OUTPUT_DIRECTORY + File.separator + "index.html");
|
||||
}
|
||||
private void exportHTML(final boolean exportToHTML) {
|
||||
ExportToHTMLDialog exportToHTMLDialog = new ExportToHTMLDialog(myView.getProject(), exportToHTML);
|
||||
final ExportToHTMLSettings exportToHTMLSettings = ExportToHTMLSettings.getInstance(myView.getProject());
|
||||
if (exportToHTMLSettings.OUTPUT_DIRECTORY == null) {
|
||||
exportToHTMLSettings.OUTPUT_DIRECTORY = PathManager.getHomePath() + File.separator + "inspections";
|
||||
}
|
||||
});
|
||||
}
|
||||
exportToHTMLDialog.reset();
|
||||
exportToHTMLDialog.show();
|
||||
if (!exportToHTMLDialog.isOK()) {
|
||||
return;
|
||||
}
|
||||
exportToHTMLDialog.apply();
|
||||
|
||||
public void exportHTML(HTMLExportFrameMaker frameMaker) {
|
||||
final String outputDirectoryName = exportToHTMLSettings.OUTPUT_DIRECTORY;
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
final Runnable exportRunnable = new Runnable() {
|
||||
public void run() {
|
||||
if (!exportToHTML) {
|
||||
dupm2XML(outputDirectoryName);
|
||||
} else {
|
||||
HTMLExportFrameMaker maker = new HTMLExportFrameMaker(outputDirectoryName, myView.getProject());
|
||||
maker.start();
|
||||
try {
|
||||
exportHTML(maker);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
// Do nothing here.
|
||||
}
|
||||
|
||||
maker.done();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(exportRunnable,
|
||||
exportToHTML ? InspectionsBundle.message("inspection.generating.html.progress.title")
|
||||
: InspectionsBundle.message("inspection.generating.xml.progress.title"), true, myView.getProject())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (exportToHTML && exportToHTMLSettings.OPEN_IN_BROWSER) {
|
||||
BrowserUtil.launchBrowser(exportToHTMLSettings.OUTPUT_DIRECTORY + File.separator + "index.html");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void dupm2XML(final String outputDirectoryName) {
|
||||
try {
|
||||
new File(outputDirectoryName).mkdirs();
|
||||
final InspectionTreeNode root = myView.getTree().getRoot();
|
||||
final Enumeration children = root.children();
|
||||
while (children.hasMoreElements()) {
|
||||
InspectionTreeNode node = (InspectionTreeNode)children.nextElement();
|
||||
if (node instanceof InspectionNode) {
|
||||
exportHTML(frameMaker, (InspectionNode)node);
|
||||
}
|
||||
else if (node instanceof InspectionGroupNode) {
|
||||
if (node instanceof InspectionGroupNode) {
|
||||
final Enumeration groupChildren = node.children();
|
||||
while (groupChildren.hasMoreElements()) {
|
||||
InspectionNode toolNode = (InspectionNode)groupChildren.nextElement();
|
||||
exportHTML(frameMaker, toolNode);
|
||||
Element problems = new Element(PROBLEMS);
|
||||
final InspectionTool tool = toolNode.getTool();
|
||||
final Set<InspectionTool> tools = getWorkedTools(toolNode);
|
||||
for (InspectionTool inspectionTool : tools) {
|
||||
inspectionTool.exportResults(problems);
|
||||
}
|
||||
PathMacroManager.getInstance(myView.getProject()).collapsePaths(problems);
|
||||
JDOMUtil.writeDocument(new Document(problems),
|
||||
outputDirectoryName + File.separator + tool.getShortName() + XmlFileType.DOT_DEFAULT_EXTENSION,
|
||||
CodeStyleSettingsManager.getSettings(null).getLineSeparator());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
final Element element = new Element(InspectionApplication.INSPECTIONS_NODE);
|
||||
final String profileName = myView.getCurrentProfileName();
|
||||
if (profileName != null) {
|
||||
element.setAttribute(InspectionApplication.PROFILE, profileName);
|
||||
}
|
||||
JDOMUtil.writeDocument(new Document(element),
|
||||
outputDirectoryName + File.separator + InspectionApplication.DESCRIPTIONS + XmlFileType.DOT_DEFAULT_EXTENSION,
|
||||
CodeStyleSettingsManager.getSettings(null).getLineSeparator());
|
||||
}
|
||||
catch (final IOException e) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
Messages.showErrorDialog(myView, e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private Set<InspectionTool> getWorkedTools(InspectionNode node) {
|
||||
final Set<InspectionTool> result = new HashSet<InspectionTool>();
|
||||
final InspectionTool tool = node.getTool();
|
||||
if (myView.getCurrentProfileName() != null){
|
||||
result.add(tool);
|
||||
return result;
|
||||
}
|
||||
final String shortName = tool.getShortName();
|
||||
final GlobalInspectionContextImpl context = myView.getGlobalInspectionContext();
|
||||
final Set<Pair<InspectionTool,InspectionProfile>> tools = context.getTools().get(shortName);
|
||||
for (Pair<InspectionTool, InspectionProfile> pair : tools) {
|
||||
result.add(pair.first);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void exportHTML(HTMLExportFrameMaker frameMaker) {
|
||||
final InspectionTreeNode root = myView.getTree().getRoot();
|
||||
final Enumeration children = root.children();
|
||||
while (children.hasMoreElements()) {
|
||||
InspectionTreeNode node = (InspectionTreeNode)children.nextElement();
|
||||
if (node instanceof InspectionNode) {
|
||||
exportHTML(frameMaker, (InspectionNode)node);
|
||||
}
|
||||
else if (node instanceof InspectionGroupNode) {
|
||||
final Enumeration groupChildren = node.children();
|
||||
while (groupChildren.hasMoreElements()) {
|
||||
InspectionNode toolNode = (InspectionNode)groupChildren.nextElement();
|
||||
exportHTML(frameMaker, toolNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void exportHTML(HTMLExportFrameMaker frameMaker, InspectionNode node) {
|
||||
Set<InspectionTool> tools = getWorkedTools(node);
|
||||
final InspectionTool tool = node.getTool();
|
||||
HTMLExporter exporter =
|
||||
new HTMLExporter(frameMaker.getRootFolder() + "/" + tool.getShortName(), tool.getComposer(), myView.getProject());
|
||||
frameMaker.startInspection(tool);
|
||||
exportHTML(tools, exporter);
|
||||
exporter.generateReferencedPages();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private void exportHTML(Set<InspectionTool> tools, HTMLExporter exporter) {
|
||||
StringBuffer packageIndex = new StringBuffer();
|
||||
packageIndex.append("<html><body>");
|
||||
|
||||
final Map<String, Set<RefElement>> content = new HashMap<String, Set<RefElement>>();
|
||||
|
||||
for (InspectionTool tool : tools) {
|
||||
content.putAll(tool.getPackageContent());
|
||||
}
|
||||
|
||||
private void exportHTML(HTMLExportFrameMaker frameMaker, InspectionNode node) {
|
||||
InspectionTool tool = node.getTool();
|
||||
HTMLExporter exporter = new HTMLExporter(frameMaker.getRootFolder() + "/" + tool.getFolderName(),
|
||||
tool.getComposer(), myView.getProject());
|
||||
frameMaker.startInspection(tool);
|
||||
exportHTML(tool, exporter);
|
||||
exporter.generateReferencedPages();
|
||||
ArrayList<String> packageNames = new ArrayList<String>(content.keySet());
|
||||
|
||||
Collections.sort(packageNames, RefEntityAlphabeticalComparator.getInstance());
|
||||
for (String packageName : packageNames) {
|
||||
appendPackageReference(packageIndex, packageName);
|
||||
final ArrayList<RefElement> packageContent = new ArrayList<RefElement>(content.get(packageName));
|
||||
Collections.sort(packageContent, RefEntityAlphabeticalComparator.getInstance());
|
||||
StringBuffer contentIndex = new StringBuffer();
|
||||
contentIndex.append("<html><body>");
|
||||
for (RefElement refElement : packageContent) {
|
||||
if (refElement instanceof RefImplicitConstructor) {
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
refElement = ((RefImplicitConstructor)refElement).getOwnerClass();
|
||||
}
|
||||
|
||||
contentIndex.append("<a HREF=\"");
|
||||
contentIndex.append(exporter.getURL(refElement));
|
||||
contentIndex.append("\" target=\"elementFrame\">");
|
||||
contentIndex.append(refElement.getName());
|
||||
contentIndex.append("</a><br>");
|
||||
|
||||
exporter.createPage(refElement);
|
||||
}
|
||||
|
||||
contentIndex.append("</body></html>");
|
||||
HTMLExporter.writeFile(exporter.getRootFolder(), packageName + "-index.html", contentIndex, myView.getProject());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public void exportHTML(InspectionTool tool, HTMLExporter exporter) {
|
||||
StringBuffer packageIndex = new StringBuffer();
|
||||
packageIndex.append("<html><body>");
|
||||
|
||||
final Map<String, Set<RefElement>> content = tool.getPackageContent();
|
||||
ArrayList<String> packageNames = new ArrayList<String>(content.keySet());
|
||||
|
||||
Collections.sort(packageNames, RefEntityAlphabeticalComparator.getInstance());
|
||||
for (String packageName : packageNames) {
|
||||
appendPackageReference(packageIndex, packageName);
|
||||
final ArrayList<RefElement> packageContent = new ArrayList<RefElement>(content.get(packageName));
|
||||
Collections.sort(packageContent, RefEntityAlphabeticalComparator.getInstance());
|
||||
final Set<RefModule> modules = new HashSet<RefModule>();
|
||||
for (InspectionTool tool : tools) {
|
||||
modules.addAll(tool.getModuleProblems());
|
||||
}
|
||||
if (modules != null) {
|
||||
final List<RefModule> sortedModules = new ArrayList<RefModule>(modules);
|
||||
Collections.sort(sortedModules, RefEntityAlphabeticalComparator.getInstance());
|
||||
for (RefModule module : sortedModules) {
|
||||
appendPackageReference(packageIndex, module.getName());
|
||||
StringBuffer contentIndex = new StringBuffer();
|
||||
contentIndex.append("<html><body>");
|
||||
for (RefElement refElement : packageContent) {
|
||||
if (refElement instanceof RefImplicitConstructor) {
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
refElement = ((RefImplicitConstructor)refElement).getOwnerClass();
|
||||
}
|
||||
|
||||
contentIndex.append("<a HREF=\"");
|
||||
contentIndex.append(exporter.getURL(refElement));
|
||||
contentIndex.append("\" target=\"elementFrame\">");
|
||||
contentIndex.append(refElement.getName());
|
||||
contentIndex.append("</a><br>");
|
||||
|
||||
exporter.createPage(refElement);
|
||||
}
|
||||
contentIndex.append("<a HREF=\"");
|
||||
contentIndex.append(exporter.getURL(module));
|
||||
contentIndex.append("\" target=\"elementFrame\">");
|
||||
contentIndex.append(module.getName());
|
||||
contentIndex.append("</a><br>");
|
||||
exporter.createPage(module);
|
||||
|
||||
contentIndex.append("</body></html>");
|
||||
HTMLExporter.writeFile(exporter.getRootFolder(), packageName + "-index.html", contentIndex, myView.getProject());
|
||||
HTMLExporter.writeFile(exporter.getRootFolder(), module.getName() + "-index.html", contentIndex, myView.getProject());
|
||||
}
|
||||
|
||||
final Set<RefModule> modules = tool.getModuleProblems();
|
||||
if (modules != null) {
|
||||
final List<RefModule> sortedModules = new ArrayList<RefModule>(modules);
|
||||
Collections.sort(sortedModules, RefEntityAlphabeticalComparator.getInstance());
|
||||
for (RefModule module : sortedModules) {
|
||||
appendPackageReference(packageIndex, module.getName());
|
||||
StringBuffer contentIndex = new StringBuffer();
|
||||
contentIndex.append("<html><body>");
|
||||
|
||||
contentIndex.append("<a HREF=\"");
|
||||
contentIndex.append(exporter.getURL(module));
|
||||
contentIndex.append("\" target=\"elementFrame\">");
|
||||
contentIndex.append(module.getName());
|
||||
contentIndex.append("</a><br>");
|
||||
exporter.createPage(module);
|
||||
|
||||
contentIndex.append("</body></html>");
|
||||
HTMLExporter.writeFile(exporter.getRootFolder(), module.getName() + "-index.html", contentIndex, myView.getProject());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
packageIndex.append("</body></html>");
|
||||
|
||||
HTMLExporter.writeFile(exporter.getRootFolder(), "index.html", packageIndex, myView.getProject());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private static void appendPackageReference(StringBuffer packageIndex, String packageName) {
|
||||
packageIndex.append("<a HREF=\"");
|
||||
packageIndex.append(packageName);
|
||||
packageIndex.append("-index.html\" target=\"packageFrame\">");
|
||||
packageIndex.append(packageName);
|
||||
packageIndex.append("</a><br>");
|
||||
}
|
||||
|
||||
packageIndex.append("</body></html>");
|
||||
|
||||
HTMLExporter.writeFile(exporter.getRootFolder(), "index.html", packageIndex, myView.getProject());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private static void appendPackageReference(StringBuffer packageIndex, String packageName) {
|
||||
packageIndex.append("<a HREF=\"");
|
||||
packageIndex.append(packageName);
|
||||
packageIndex.append("-index.html\" target=\"packageFrame\">");
|
||||
packageIndex.append(packageName);
|
||||
packageIndex.append("</a><br>");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ public class XMLExportUtl {
|
||||
final Element fileElement = new Element("file");
|
||||
fileElement.addContent(moduleFile.getUrl());
|
||||
problem.addContent(fileElement);
|
||||
appendFakePackage(problem);
|
||||
}
|
||||
|
||||
|
||||
if (refEntity instanceof RefMethod) {
|
||||
RefMethod refMethod = (RefMethod)refEntity;
|
||||
appendMethod(refMethod, problem);
|
||||
@@ -86,6 +86,8 @@ public class XMLExportUtl {
|
||||
else if (refEntity instanceof RefClass) {
|
||||
RefClass refClass = (RefClass)refEntity;
|
||||
appendClass(refClass, problem);
|
||||
} else if (refEntity instanceof RefFile) {
|
||||
appendFakePackage(problem);
|
||||
}
|
||||
else {
|
||||
LOG.info("Unknown refElement: " + refEntity);
|
||||
@@ -95,6 +97,12 @@ public class XMLExportUtl {
|
||||
return problem;
|
||||
}
|
||||
|
||||
private static void appendFakePackage(final Element problem) {
|
||||
final Element fakePackage = new Element("package");
|
||||
fakePackage.addContent(InspectionsBundle.message("inspection.export.results.default"));
|
||||
problem.addContent(fakePackage);
|
||||
}
|
||||
|
||||
private static void appendClass(RefClass refClass, Element parentNode) {
|
||||
PsiClass psiClass = refClass.getElement();
|
||||
PsiDocComment psiDocComment = psiClass.getDocComment();
|
||||
|
||||
@@ -230,7 +230,9 @@ inspection.offline.view.tool.display.name.title=Name
|
||||
inspection.export.results.unnamed=unnamed
|
||||
inspection.export.results.unknown.tool.display.name=unknown
|
||||
inspection.generating.html.progress.title=Generating HTML...
|
||||
inspection.generating.xml.progress.title=Dumping XML...
|
||||
inspection.action.export.html=Export
|
||||
inspection.action.export.popup.title=Export To
|
||||
inspection.tool.description.under.construction.text=Under construction
|
||||
inspection.tool.in.browser.id.title=ID
|
||||
inspection.tool.in.browser.description.title=Description
|
||||
@@ -677,4 +679,5 @@ report.not.annotated.getters.for.annotated.fields=report not annotated &getter f
|
||||
edit.inspection.options=Edit ''{0}'' Options
|
||||
offline.view.title=Offline View
|
||||
offline.view.editor.settings.title=Editor Settings
|
||||
offline.view.parse.exception.title=Nothing found to display
|
||||
offline.view.parse.exception.title=Nothing found to display
|
||||
parsing.inspections.dump.progress.title=Parsing inspections XML dump
|
||||
Reference in New Issue
Block a user