diff --git a/codeInsight/impl/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/codeInsight/impl/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java index 4115797e631e..0a99b79ec0f7 100644 --- a/codeInsight/impl/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java +++ b/codeInsight/impl/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java @@ -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 result = new THashSet(); for (Language language : viewProvider.getPrimaryLanguages()) { diff --git a/inspections/impl/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java b/inspections/impl/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java index 20a921130085..6b6f511f70ff 100644 --- a/inspections/impl/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java +++ b/inspections/impl/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java @@ -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>> resMap = new HashMap>>(); - 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>> resMap = + new HashMap>>(); + 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() { + @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>>() { + public Map> 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>> resMap, + public static InspectionResultsView showOfflineView(final Project project, + final Map>> 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>(), new HashMap>()); - 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; } diff --git a/inspections/impl/com/intellij/codeInspection/export/ExportToHTMLDialog.java b/inspections/impl/com/intellij/codeInspection/export/ExportToHTMLDialog.java index 04337acc22c5..f29a6a3b11b4 100644 --- a/inspections/impl/com/intellij/codeInspection/export/ExportToHTMLDialog.java +++ b/inspections/impl/com/intellij/codeInspection/export/ExportToHTMLDialog.java @@ -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(); } } \ No newline at end of file diff --git a/inspections/impl/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java b/inspections/impl/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java index e89f2b6d1dba..1dfe9654e647 100644 --- a/inspections/impl/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java +++ b/inspections/impl/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java @@ -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 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; diff --git a/inspections/impl/com/intellij/codeInspection/offlineViewer/OfflineViewParseUtil.java b/inspections/impl/com/intellij/codeInspection/offlineViewer/OfflineViewParseUtil.java index 37d634607a53..ea23ad3333ca 100644 --- a/inspections/impl/com/intellij/codeInspection/offlineViewer/OfflineViewParseUtil.java +++ b/inspections/impl/com/intellij/codeInspection/offlineViewer/OfflineViewParseUtil.java @@ -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 parentTypes = new ArrayList(); final List parentNames = new ArrayList(); 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 descriptors = package2Result.get(packageName); if (descriptors == null) { - descriptors = new HashSet(); + descriptors = new THashSet(new TObjectHashingStrategy() { //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); diff --git a/inspections/impl/com/intellij/codeInspection/reference/RefFileImpl.java b/inspections/impl/com/intellij/codeInspection/reference/RefFileImpl.java index 938c2c873514..276cfae4d275 100644 --- a/inspections/impl/com/intellij/codeInspection/reference/RefFileImpl.java +++ b/inspections/impl/com/intellij/codeInspection/reference/RefFileImpl.java @@ -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) { diff --git a/inspections/impl/com/intellij/codeInspection/ui/InspectionResultsView.java b/inspections/impl/com/intellij/codeInspection/ui/InspectionResultsView.java index 5e077c874e3f..2e937667545d 100644 --- a/inspections/impl/com/intellij/codeInspection/ui/InspectionResultsView.java +++ b/inspections/impl/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -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(){ diff --git a/inspections/impl/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java b/inspections/impl/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java index 63837186d06d..b78b0ef2b984 100644 --- a/inspections/impl/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java +++ b/inspections/impl/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java @@ -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 diff --git a/inspections/impl/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java b/inspections/impl/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java index 970f4fd89356..5ce88bb94e02 100644 --- a/inspections/impl/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java +++ b/inspections/impl/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java @@ -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(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 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 getWorkedTools(InspectionNode node) { + final Set result = new HashSet(); + 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> tools = context.getTools().get(shortName); + for (Pair 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 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 tools, HTMLExporter exporter) { + StringBuffer packageIndex = new StringBuffer(); + packageIndex.append(""); + + final Map> content = new HashMap>(); + + 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 packageNames = new ArrayList(content.keySet()); + + Collections.sort(packageNames, RefEntityAlphabeticalComparator.getInstance()); + for (String packageName : packageNames) { + appendPackageReference(packageIndex, packageName); + final ArrayList packageContent = new ArrayList(content.get(packageName)); + Collections.sort(packageContent, RefEntityAlphabeticalComparator.getInstance()); + StringBuffer contentIndex = new StringBuffer(); + contentIndex.append(""); + for (RefElement refElement : packageContent) { + if (refElement instanceof RefImplicitConstructor) { + //noinspection AssignmentToForLoopParameter + refElement = ((RefImplicitConstructor)refElement).getOwnerClass(); + } + + contentIndex.append(""); + contentIndex.append(refElement.getName()); + contentIndex.append("
"); + + exporter.createPage(refElement); + } + + contentIndex.append(""); + 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(""); - - final Map> content = tool.getPackageContent(); - ArrayList packageNames = new ArrayList(content.keySet()); - - Collections.sort(packageNames, RefEntityAlphabeticalComparator.getInstance()); - for (String packageName : packageNames) { - appendPackageReference(packageIndex, packageName); - final ArrayList packageContent = new ArrayList(content.get(packageName)); - Collections.sort(packageContent, RefEntityAlphabeticalComparator.getInstance()); + final Set modules = new HashSet(); + for (InspectionTool tool : tools) { + modules.addAll(tool.getModuleProblems()); + } + if (modules != null) { + final List sortedModules = new ArrayList(modules); + Collections.sort(sortedModules, RefEntityAlphabeticalComparator.getInstance()); + for (RefModule module : sortedModules) { + appendPackageReference(packageIndex, module.getName()); StringBuffer contentIndex = new StringBuffer(); contentIndex.append(""); - for (RefElement refElement : packageContent) { - if (refElement instanceof RefImplicitConstructor) { - //noinspection AssignmentToForLoopParameter - refElement = ((RefImplicitConstructor)refElement).getOwnerClass(); - } - contentIndex.append(""); - contentIndex.append(refElement.getName()); - contentIndex.append("
"); - - exporter.createPage(refElement); - } + contentIndex.append(""); + contentIndex.append(module.getName()); + contentIndex.append("
"); + exporter.createPage(module); contentIndex.append(""); - HTMLExporter.writeFile(exporter.getRootFolder(), packageName + "-index.html", contentIndex, myView.getProject()); + HTMLExporter.writeFile(exporter.getRootFolder(), module.getName() + "-index.html", contentIndex, myView.getProject()); } - - final Set modules = tool.getModuleProblems(); - if (modules != null) { - final List sortedModules = new ArrayList(modules); - Collections.sort(sortedModules, RefEntityAlphabeticalComparator.getInstance()); - for (RefModule module : sortedModules) { - appendPackageReference(packageIndex, module.getName()); - StringBuffer contentIndex = new StringBuffer(); - contentIndex.append(""); - - contentIndex.append(""); - contentIndex.append(module.getName()); - contentIndex.append("
"); - exporter.createPage(module); - - contentIndex.append(""); - HTMLExporter.writeFile(exporter.getRootFolder(), module.getName() + "-index.html", contentIndex, myView.getProject()); - } - } - - - packageIndex.append(""); - - HTMLExporter.writeFile(exporter.getRootFolder(), "index.html", packageIndex, myView.getProject()); } - @SuppressWarnings({"HardCodedStringLiteral"}) - private static void appendPackageReference(StringBuffer packageIndex, String packageName) { - packageIndex.append(""); - packageIndex.append(packageName); - packageIndex.append("
"); - } + + packageIndex.append(""); + + HTMLExporter.writeFile(exporter.getRootFolder(), "index.html", packageIndex, myView.getProject()); + } + + @SuppressWarnings({"HardCodedStringLiteral"}) + private static void appendPackageReference(StringBuffer packageIndex, String packageName) { + packageIndex.append(""); + packageIndex.append(packageName); + packageIndex.append("
"); + } } diff --git a/inspections/impl/com/intellij/codeInspection/util/XMLExportUtl.java b/inspections/impl/com/intellij/codeInspection/util/XMLExportUtl.java index a9a9f2f77626..69a88b7ff605 100644 --- a/inspections/impl/com/intellij/codeInspection/util/XMLExportUtl.java +++ b/inspections/impl/com/intellij/codeInspection/util/XMLExportUtl.java @@ -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(); diff --git a/resources_eng/src/messages/InspectionsBundle.properties b/resources_eng/src/messages/InspectionsBundle.properties index f076c42d27c6..799eded3aed3 100644 --- a/resources_eng/src/messages/InspectionsBundle.properties +++ b/resources_eng/src/messages/InspectionsBundle.properties @@ -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 \ No newline at end of file +offline.view.parse.exception.title=Nothing found to display +parsing.inspections.dump.progress.title=Parsing inspections XML dump \ No newline at end of file