From 835379b22ae279ecd0c4be3bed4350906b89aae2 Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 16 Feb 2011 16:08:07 +0300 Subject: [PATCH 01/28] VCS: ignored files component - register project message bus listener with disposable, and not in case of externalization --- .../vcs/changes/ChangeListManagerImpl.java | 5 ++--- .../vcs/changes/IgnoredFilesComponent.java | 18 +++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index 4198baf3233f..a80422b44c35 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -117,7 +117,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec myChangesViewManager = myProject.isDefault() ? new DummyChangesView(myProject) : ChangesViewManager.getInstance(myProject); myFileStatusManager = FileStatusManager.getInstance(myProject); myComposite = new FileHolderComposite(project); - myIgnoredIdeaLevel = new IgnoredFilesComponent(myProject); + myIgnoredIdeaLevel = new IgnoredFilesComponent(myProject, true); myUpdater = new UpdateRequestsQueue(myProject, ourUpdateAlarm, new ActualUpdater()); myWorker = new ChangeListWorker(myProject, new MyChangesDeltaForwarder(myProject, ourUpdateAlarm)); @@ -993,10 +993,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec public void writeExternal(Element element) throws WriteExternalException { if (! myProject.isDefault()) { - final IgnoredFilesComponent ignoredFilesComponent; + final IgnoredFilesComponent ignoredFilesComponent = new IgnoredFilesComponent(myProject, false); final ChangeListWorker worker; synchronized (myDataLock) { - ignoredFilesComponent = new IgnoredFilesComponent(myProject); ignoredFilesComponent.add(myIgnoredIdeaLevel.getFilesToIgnore()); worker = myWorker.copy(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java index 63737b88891b..310644cb9a44 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java @@ -28,20 +28,20 @@ import java.util.List; import java.util.Set; public class IgnoredFilesComponent { - private final Project myProject; private final Set myFilesToIgnore; - public IgnoredFilesComponent(final Project project) { - myProject = project; + public IgnoredFilesComponent(final Project project, final boolean registerListener) { myFilesToIgnore = new LinkedHashSet(); - project.getMessageBus().connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { - public void before(List events) {} + if (registerListener) { + project.getMessageBus().connect(project).subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { + public void before(List events) {} - public void after(List events) { - resetCaches(); - } - }); + public void after(List events) { + resetCaches(); + } + }); + } } public void add(final IgnoredFileBean... filesToIgnore) { From 63872f43c249774628e189af5b7657a7e213be92 Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 16 Feb 2011 17:09:43 +0300 Subject: [PATCH 02/28] VCS: lighter changes delta calculation --- .../vcs/changes/ChangeListsIndexes.java | 21 +++++++++++++++---- .../openapi/vcs/changes/ChangesDelta.java | 15 +++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListsIndexes.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListsIndexes.java index 96cdbe14625a..7fde7a2827a3 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListsIndexes.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListsIndexes.java @@ -24,10 +24,7 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nullable; import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class ChangeListsIndexes { private final Map myFileToStatus; @@ -107,6 +104,22 @@ public class ChangeListsIndexes { } } + public void getDelta(final ChangeListsIndexes newIndexes, final Set> toRemove, Set> toAdd) { + // this is old + final Set oldKeySet = myFileToVcs.keySet(); + final Set toRemoveSet = new HashSet(oldKeySet); + final Set newKeySet = newIndexes.myFileToVcs.keySet(); + final Set toAddSet = new HashSet(newKeySet); + toRemoveSet.removeAll(newKeySet); + toAddSet.removeAll(oldKeySet); + for (String s : toRemoveSet) { + toRemove.add(new Pair(s, myFileToVcs.get(s))); + } + for (String s : toAddSet) { + toAdd.add(new Pair(s, newIndexes.myFileToVcs.get(s))); + } + } + public List> getAffectedFilesUnderVcs() { final ArrayList> result = new ArrayList>(); for (Map.Entry entry : myFileToVcs.entrySet()) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java index be5e4611f6de..fcb32c5f88d6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java @@ -23,6 +23,7 @@ import com.intellij.openapi.vcs.VcsKey; import com.intellij.openapi.vcs.impl.CollectionsDelta; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -44,18 +45,16 @@ public class ChangesDelta { myInitialized = true; return true; //+- } - final List> becameAffected = became.getAffectedFilesUnderVcs(); - final Set> toRemove = CollectionsDelta.notInSecond(wasAffected, becameAffected); - final Set> toAdd = CollectionsDelta.notInSecond(becameAffected, wasAffected); + final Set> toRemove = new HashSet>(); + final Set> toAdd = new HashSet>(); + was.getDelta(became, toRemove, toAdd); - if (toRemove != null) { - for (Pair pair : toRemove) { - myDeltaListener.minus(convertPair(pair)); - } + for (Pair pair : toRemove) { + myDeltaListener.minus(convertPair(pair)); } sendPlus(toAdd); - return toRemove != null || toAdd != null; + return ! toRemove.isEmpty() || ! toAdd.isEmpty(); } private void sendPlus(final Collection> toAdd) { From 436c0a3a4402cc97163395fee80cdbeafee74052 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 15:19:25 +0100 Subject: [PATCH 03/28] right-align type text; make hint a real popup --- .../codeInsight/lookup/impl/LookupImpl.java | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 62de31d716a7..080c341109f5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -566,9 +566,10 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { /** * @return point in layered pane coordinate system. + * @param component */ - public Point calculatePosition(){ - Dimension dim = getComponent().getPreferredSize(); + public Point calculatePosition(final JComponent component){ + Dimension dim = component.getPreferredSize(); int lookupStart = getLookupStart(); if (lookupStart < 0) { LOG.error(lookupStart + "; minprefix=" + myMinPrefixLength + "; offset=" + myEditor.getCaretModel().getOffset() + "; element=" + @@ -587,7 +588,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { JLayeredPane layeredPane = rootPane.getLayeredPane(); Point layeredPanePoint=SwingUtilities.convertPoint(internalComponent,location, layeredPane); layeredPanePoint.x -= myCellRenderer.getIconIndent(); - layeredPanePoint.x -= getComponent().getInsets().left; + layeredPanePoint.x -= component.getInsets().left; int shiftLow = layeredPane.getHeight() - (layeredPanePoint.y + dim.height); int shiftHigh = layeredPanePoint.y - dim.height; @@ -684,7 +685,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { getComponent().setBorder(null); updateScrollbarVisibility(); - Point p = calculatePosition(); + Point p = calculatePosition(getComponent()); HintManagerImpl.getInstanceImpl().showEditorHint(this, myEditor, p, HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false); final JLayeredPane layeredPane = getComponent().getRootPane().getLayeredPane(); @@ -1121,7 +1122,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } updateScrollbarVisibility(); - HintManagerImpl.adjustEditorHintPosition(this, editor, calculatePosition()); + HintManagerImpl.adjustEditorHintPosition(this, editor, calculatePosition(getComponent())); layoutStatusIcons(); if (reused) { @@ -1134,7 +1135,8 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { final int itemTextPadding = 2; final int borderWidth = 1; - Point bestPoint = calculatePosition(); + final JPanel hintComponent = createAutopopupHintComponent(itemTextPadding, borderWidth); + Point bestPoint = calculatePosition(hintComponent); bestPoint.x += myCellRenderer.getIconIndent() - itemTextPadding - borderWidth; Point editorPoint = SwingUtilities.convertPoint( editor.getComponent().getRootPane().getLayeredPane(), @@ -1145,8 +1147,11 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { final HintHint hintHint = new HintHint(editor, editorPoint).setHighlighterType(true).setContentActive(true); final HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl(); - myAutopopupHint = new LightweightHint(createAutopopupHintComponent(itemTextPadding, borderWidth)); - hintManager.showEditorHint(myAutopopupHint, editor, bestPoint, HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false, hintHint); + myAutopopupHint = new LightweightHint(hintComponent); + myAutopopupHint.setForceShowAsPopup(true); + myAutopopupHint.setForceLightweightPopup(true); + hintManager.showEditorHint(myAutopopupHint, editor, new Point(bestPoint), HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false, hintHint); + HintManagerImpl.adjustEditorHintPosition(myAutopopupHint, editor, bestPoint); } } @@ -1189,11 +1194,10 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { final GridBagConstraints c = new GridBagConstraints(); c.gridx = 1; c.gridy = i; - c.ipadx = 4; c.fill = GridBagConstraints.HORIZONTAL; - final JLabel comp = new JLabel(" " + StringUtil.notNullize(presentation.getTypeText())); + final JLabel comp = new JLabel(" " + StringUtil.notNullize(presentation.getTypeText()) + " "); comp.setFont(comp.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); - comp.setAlignmentX(Component.RIGHT_ALIGNMENT); + comp.setHorizontalAlignment(SwingConstants.RIGHT); pane.add(comp, c); } } @@ -1215,13 +1219,14 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } } - pane.setBorder(new LineBorder(Color.darkGray, borderWidth)); + //pane.setBorder(new LineBorder(Color.darkGray, borderWidth)); return pane; } private void hideAutopopupHint() { if (myAutopopupHint != null) { myAutopopupHint.hide(); + myPositionedAbove = null; } } From 7e3213f6db6404639db3fe608d3c23dad8db0121 Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 16 Feb 2011 17:24:29 +0300 Subject: [PATCH 04/28] VCS: lighter ignored component copying --- .../intellij/openapi/vcs/changes/ChangeListManagerImpl.java | 4 ++-- .../intellij/openapi/vcs/changes/IgnoredFilesComponent.java | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index a80422b44c35..a49c00e2d7ff 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -993,10 +993,10 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec public void writeExternal(Element element) throws WriteExternalException { if (! myProject.isDefault()) { - final IgnoredFilesComponent ignoredFilesComponent = new IgnoredFilesComponent(myProject, false); + final IgnoredFilesComponent ignoredFilesComponent; final ChangeListWorker worker; synchronized (myDataLock) { - ignoredFilesComponent.add(myIgnoredIdeaLevel.getFilesToIgnore()); + ignoredFilesComponent = new IgnoredFilesComponent(myIgnoredIdeaLevel); worker = myWorker.copy(); } new ChangeListManagerSerialization(ignoredFilesComponent, worker).writeExternal(element); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java index 310644cb9a44..91336c7589cd 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java @@ -44,6 +44,10 @@ public class IgnoredFilesComponent { } } + public IgnoredFilesComponent(final IgnoredFilesComponent other) { + myFilesToIgnore = new LinkedHashSet(other.myFilesToIgnore); + } + public void add(final IgnoredFileBean... filesToIgnore) { synchronized(myFilesToIgnore) { Collections.addAll(myFilesToIgnore, filesToIgnore); From afc186d240f9b6c78656161a43d6b7886ba7dbb8 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 15:45:08 +0100 Subject: [PATCH 05/28] don't blink --- .../codeInsight/lookup/impl/LookupImpl.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 080c341109f5..ed0fc9b58609 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1130,8 +1130,6 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } } else if (myHintMode) { - hideAutopopupHint(); - final int itemTextPadding = 2; final int borderWidth = 1; @@ -1147,10 +1145,19 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { final HintHint hintHint = new HintHint(editor, editorPoint).setHighlighterType(true).setContentActive(true); final HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl(); - myAutopopupHint = new LightweightHint(hintComponent); - myAutopopupHint.setForceShowAsPopup(true); - myAutopopupHint.setForceLightweightPopup(true); - hintManager.showEditorHint(myAutopopupHint, editor, new Point(bestPoint), HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false, hintHint); + if (myAutopopupHint == null) { + final JPanel panel = new JPanel(new BorderLayout()); + panel.add(hintComponent); + myAutopopupHint = new LightweightHint(panel); + myAutopopupHint.setForceShowAsPopup(true); + myAutopopupHint.setForceLightweightPopup(true); + hintManager.showEditorHint(myAutopopupHint, editor, new Point(bestPoint), + HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false, hintHint); + } else { + final JComponent panel = myAutopopupHint.getComponent(); + panel.remove(0); + panel.add(hintComponent); + } HintManagerImpl.adjustEditorHintPosition(myAutopopupHint, editor, bestPoint); } } From d251ca89c8f2b56afd54946cff0fb8e3a7538c6b Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 15:51:23 +0100 Subject: [PATCH 06/28] correct psi length calculation in commit --- .../src/com/intellij/psi/impl/PsiDocumentManagerImpl.java | 8 ++++---- .../intellij/psi/impl/source/text/BlockSupportImpl.java | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java index 9b854eae16fd..b622e1770fd2 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java @@ -458,18 +458,18 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec } throw new AssertionError(msg); } - } else if (document.getTextLength() - textBlock.getTextEndOffset() != file.getTextLength() - psiEndOffset) { + } else if (document.getTextLength() - textBlock.getTextEndOffset() != myTreeElementBeingReparsedSoItWontBeCollected.getTextLength() - psiEndOffset) { throw new AssertionError("PSI/document inconsistency before reparse: file=" + file); } } else { startOffset = 0; endOffset = document.getTextLength(); - lengthShift = document.getTextLength() - file.getTextLength(); + lengthShift = document.getTextLength() - myTreeElementBeingReparsedSoItWontBeCollected.getTextLength(); } myBlockSupport.reparseRange(file, startOffset, endOffset, lengthShift, chars); - if (file.getTextLength() != document.getTextLength()) { + if (myTreeElementBeingReparsedSoItWontBeCollected.getTextLength() != document.getTextLength()) { if (ApplicationManagerEx.getApplicationEx().isInternal()) { boolean x = false; if (x) { @@ -477,7 +477,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec } String fileText = file.getText(); String documentText = document.getText(); - throw new AssertionError("commitDocument left PSI inconsistent; file len=" + file.getTextLength() + + throw new AssertionError("commitDocument left PSI inconsistent; file len=" + myTreeElementBeingReparsedSoItWontBeCollected.getTextLength() + "; doc len=" + document.getTextLength() + "; doc.getText() == file.getText(): " + Comparing.equal(fileText, documentText) + ";\n file text=" + fileText + diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java index be89f30f561b..a80d4f9daf7b 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java @@ -87,11 +87,10 @@ public class BlockSupportImpl extends BlockSupport { file.getViewProvider().beforeContentsSynchronized(); final PsiFileImpl fileImpl = (PsiFileImpl)file; Project project = fileImpl.getProject(); - final FileElement treeFileElement = fileImpl.getTreeElement(); - final CharTable charTable = treeFileElement.getCharTable(); - // hack - final int textLength = file.getTextLength() + lengthShift; + final CharTable charTable = fileImpl.getTreeElement().getCharTable(); + final FileElement treeFileElement = fileImpl.getTreeElement(); + final int textLength = treeFileElement.getTextLength() + lengthShift; if (treeFileElement.getElementType() instanceof ITemplateDataElementType || isTooDeep(file)) { // unable to perform incremental reparse for template data in JSP, or in exceptionally deep trees From 1e07dd8b003360127825c1c373930c80f0a8f0a5 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 16 Feb 2011 17:51:55 +0300 Subject: [PATCH 07/28] fixed vanishing of hyperlinks printed to console before getComponent() is called [rev by Anna] --- .../src/com/intellij/execution/impl/ConsoleViewImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index b2df5569aaf8..080598e3b09b 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -904,7 +904,6 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo } public void printHyperlink(final String hyperlinkText, final HyperlinkInfo info) { - if (myEditor == null) return; printHyperlink(hyperlinkText, ConsoleViewContentType.NORMAL_OUTPUT, info); } From e12053ab02f3909741ef4d4a5bf4ee04ba2f4721 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 15:55:48 +0100 Subject: [PATCH 08/28] comment for kirillk --- .../src/com/intellij/codeInsight/lookup/impl/LookupImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index ed0fc9b58609..68e544cc82f8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1158,6 +1158,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { panel.remove(0); panel.add(hintComponent); } + //todo[kirillk] comment the following line HintManagerImpl.adjustEditorHintPosition(myAutopopupHint, editor, bestPoint); } } From 3f34233eb794d1263d02f3ac793266eb826dd198 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 15:58:06 +0100 Subject: [PATCH 09/28] when no variants are left, finish the autopopup even in the new mode --- .../completion/CompletionProgressIndicator.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 47597c8c9ed1..a6bb506cbe7b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -463,13 +463,14 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } private boolean hideAutopopupIfMeaningless() { - if (ourHintAutopopup) { - return false; - } - if (isAutopopupCompletion() && !myLookup.isSelectionTouched() && !myLookup.isCalculating()) { myLookup.refreshUi(); - for (LookupElement item : myLookup.getItems()) { + final List items = myLookup.getItems(); + if (!items.isEmpty() && ourHintAutopopup) { + return false; + } + + for (LookupElement item : items) { if (!(item.getPrefixMatcher().getPrefix() + myLookup.getAdditionalPrefix()).equals(item.getLookupString())) { return false; } From 8814bb5de5ccf064125ddc2f81b7c18f224ccd59 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 16 Feb 2011 17:57:03 +0300 Subject: [PATCH 10/28] create console when debug session is started even if tool window isn't shown yet --- .../xdebugger/impl/XDebugSessionImpl.java | 15 ++++++----- .../xdebugger/impl/ui/XDebugSessionTab.java | 27 ++++++++----------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index 365a0c64bab4..527c56c76e74 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -86,6 +86,7 @@ public class XDebugSessionImpl implements XDebugSession { private boolean myStopped; private boolean myPauseActionSupported; private boolean myShowTabOnSuspend; + private ConsoleView myConsoleView; public XDebugSessionImpl(final @NotNull ExecutionEnvironment env, final @NotNull ProgramRunner runner, @@ -197,6 +198,8 @@ public class XDebugSessionImpl implements XDebugSession { stopImpl(); } }); + //todo[nik] make 'createConsole()' method return ConsoleView + myConsoleView = (ConsoleView)myDebugProcess.createConsole(); if (!myShowTabOnSuspend) { initSessionTab(); } @@ -214,7 +217,7 @@ public class XDebugSessionImpl implements XDebugSession { mySessionTab.setEnvironment(myEnvironment); } Disposer.register(myProject, mySessionTab); - mySessionTab.attachToSession(this, myRunner, myEnvironment, mySessionData); + mySessionTab.attachToSession(this, myRunner, myEnvironment, mySessionData, myConsoleView); myDebugProcess.sessionInitialized(); } @@ -514,18 +517,16 @@ public class XDebugSessionImpl implements XDebugSession { } private void printMessage(final String message, final String hyperLinkText, @Nullable final HyperlinkInfo info) { - assertSessionTabInitialized(); DebuggerUIUtil.invokeOnEventDispatch(new Runnable() { public void run() { - final ConsoleView consoleView = (ConsoleView)mySessionTab.getConsole(); - consoleView.print(message, ConsoleViewContentType.SYSTEM_OUTPUT); + myConsoleView.print(message, ConsoleViewContentType.SYSTEM_OUTPUT); if (info != null) { - consoleView.printHyperlink(hyperLinkText, info); + myConsoleView.printHyperlink(hyperLinkText, info); } else if (hyperLinkText != null) { - consoleView.print(hyperLinkText, ConsoleViewContentType.SYSTEM_OUTPUT); + myConsoleView.print(hyperLinkText, ConsoleViewContentType.SYSTEM_OUTPUT); } - consoleView.print("\n", ConsoleViewContentType.SYSTEM_OUTPUT); + myConsoleView.print("\n", ConsoleViewContentType.SYSTEM_OUTPUT); } }); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index ae440c5402c3..d6a64dc1faa8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -16,8 +16,6 @@ package com.intellij.xdebugger.impl.ui; import com.intellij.debugger.ui.DebuggerContentInfo; -import com.intellij.execution.DefaultExecutionResult; -import com.intellij.execution.ExecutionResult; import com.intellij.execution.Executor; import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.executors.DefaultDebugExecutor; @@ -26,6 +24,7 @@ import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.runners.RestartAction; import com.intellij.execution.runners.RunContentBuilder; +import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunnerLayoutUi; @@ -136,16 +135,9 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { } public RunContentDescriptor attachToSession(final @NotNull XDebugSession session, final @Nullable ProgramRunner runner, - final @Nullable ExecutionEnvironment env, - final @NotNull XDebugSessionData sessionData) { - return initUI(session, sessionData, env, runner); - } - - @NotNull - private static ExecutionResult createExecutionResult(@NotNull final XDebugSession session) { - final XDebugProcess debugProcess = session.getDebugProcess(); - ProcessHandler processHandler = debugProcess.getProcessHandler(); - return new DefaultExecutionResult(debugProcess.createConsole(), processHandler); + final @Nullable ExecutionEnvironment env, + final @NotNull XDebugSessionData sessionData, ConsoleView consoleView) { + return initUI(session, sessionData, env, runner, consoleView); } public XWatchesView getWatchesView() { @@ -153,10 +145,13 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { } private RunContentDescriptor initUI(final @NotNull XDebugSession session, final @NotNull XDebugSessionData sessionData, - final @Nullable ExecutionEnvironment environment, final @Nullable ProgramRunner runner) { - ExecutionResult executionResult = createExecutionResult(session); - myConsole = executionResult.getExecutionConsole(); - myRunContentDescriptor = new RunContentDescriptor(myConsole, executionResult.getProcessHandler(), myUi.getComponent(), getSessionName()); + final @Nullable ExecutionEnvironment environment, + final @Nullable ProgramRunner runner, + ConsoleView consoleView) { + final XDebugProcess debugProcess = session.getDebugProcess(); + ProcessHandler processHandler = debugProcess.getProcessHandler(); + myConsole = consoleView; + myRunContentDescriptor = new RunContentDescriptor(myConsole, processHandler, myUi.getComponent(), getSessionName()); myUi.addContent(createFramesContent(session), 0, PlaceInGrid.left, false); myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false); From 9306626a343198ae854fc622064b8c0612987901 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 16 Feb 2011 18:28:02 +0300 Subject: [PATCH 11/28] getter added --- .../src/com/intellij/xdebugger/XDebugSession.java | 3 +++ .../src/com/intellij/xdebugger/impl/XDebugSessionImpl.java | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java index 7ecd867a0197..19d2128e47ba 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java @@ -17,6 +17,7 @@ package com.intellij.xdebugger; import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.openapi.project.Project; import com.intellij.xdebugger.breakpoints.XBreakpoint; @@ -125,4 +126,6 @@ public interface XDebugSession extends AbstractDebuggerSession { void smartStepInto(XSmartStepIntoHandler handler, V variant); void updateExecutionPosition(); + + ConsoleView getConsoleView(); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index 527c56c76e74..ccc2a479ee71 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -207,6 +207,11 @@ public class XDebugSessionImpl implements XDebugSession { return mySessionTab; } + @Override + public ConsoleView getConsoleView() { + return myConsoleView; + } + public XDebugSessionTab getSessionTab() { return mySessionTab; } From 40fd4d8c7e9694775b4f49ae4e5583f8a4cacad7 Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 16 Feb 2011 18:33:50 +0300 Subject: [PATCH 12/28] VCS: change list manager: lighter data copying --- .../openapi/vcs/changes/ChangeListManagerImpl.java | 8 +++----- .../src/com/intellij/openapi/vcs/changes/Modifier.java | 6 +++++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index a49c00e2d7ff..0517740f2f0c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -79,7 +79,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec private FileHolderComposite myComposite; - private final ChangeListWorker myWorker; + private ChangeListWorker myWorker; private VcsException myUpdateException = null; @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) @@ -421,10 +421,8 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec myModifier.clearQueue(); // update member from copy if (takeChanges) { - myWorker.takeData(dataHolder.getChangeListWorker()); - } - - if (takeChanges) { + myWorker = dataHolder.getChangeListWorker(); + myModifier.setWorker(myWorker); if (LOG.isDebugEnabled()) { LOG.debug("refresh procedure finished, size: " + dataHolder.getComposite().getVFHolder(FileHolder.HolderType.UNVERSIONED).getSize()); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/Modifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/Modifier.java index a3317e39667d..431f8c399ba7 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/Modifier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/Modifier.java @@ -27,7 +27,7 @@ import java.util.List; * (after update is done) */ public class Modifier implements ChangeListsWriteOperations { - private final ChangeListWorker myWorker; + private ChangeListWorker myWorker; private boolean myInsideUpdate; private final List myCommandQueue; private final DelayedNotificator myNotificator; @@ -113,4 +113,8 @@ public class Modifier implements ChangeListsWriteOperations { myNotificator.callNotify(command); } } + + public void setWorker(ChangeListWorker worker) { + myWorker = worker; + } } From 63d8ef23b9749c13a05f653f1323dca27a93a794 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 16 Feb 2011 16:42:27 +0100 Subject: [PATCH 13/28] jdk 6+: do not swallow error message endings --- .../src/com/intellij/compiler/OutputParser.java | 3 ++- .../impl/javaCompiler/CompilerParsingThread.java | 13 +++++++++++++ .../javaCompiler/javac/JavacOutputParser.java | 12 ++++++++++++ .../lang/ant/config/execution/OutputParser.java | 15 ++++++++++++--- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/OutputParser.java b/java/compiler/impl/src/com/intellij/compiler/OutputParser.java index 4f5c325155ee..37f688263173 100644 --- a/java/compiler/impl/src/com/intellij/compiler/OutputParser.java +++ b/java/compiler/impl/src/com/intellij/compiler/OutputParser.java @@ -15,9 +15,9 @@ */ package com.intellij.compiler; +import com.intellij.compiler.impl.javaCompiler.FileObject; import com.intellij.openapi.compiler.CompilerMessageCategory; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.compiler.impl.javaCompiler.FileObject; import org.jetbrains.annotations.NonNls; import java.util.ArrayList; @@ -29,6 +29,7 @@ public abstract class OutputParser { public interface Callback { @NonNls String getNextLine(); @NonNls String getCurrentLine(); + void pushBack(String line); void setProgressText(String text); void fileProcessed(@NonNls String path); void fileGenerated(@NonNls FileObject path); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java index 58e74794bec9..e440d1d8666f 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java @@ -44,6 +44,7 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { private final boolean myIsUnitTestMode; private FileObject myClassFileToProcess = null; private String myLastReadLine = null; + private String myPushBackLine = null; private volatile boolean myProcessExited = false; private final CompileContext myContext; @@ -104,6 +105,12 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { } public final String getNextLine() { + final String pushBack = myPushBackLine; + if (pushBack != null) { + myPushBackLine = null; + myLastReadLine = pushBack; + return pushBack; + } final String line = readLine(myCompilerOutStreamReader); if (LOG.isDebugEnabled()) { LOG.debug("LIne read: #" + line + "#"); @@ -120,6 +127,12 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { return myLastReadLine; } + @Override + public void pushBack(String line) { + myLastReadLine = null; + myPushBackLine = line; + } + public final void fileGenerated(FileObject path) { // javac first logs file generated, then starts to write the file to disk, // so this thread sometimes can stumble on not yet existing file, diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOutputParser.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOutputParser.java index b1c2e5c5e428..f5d106e3494f 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOutputParser.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOutputParser.java @@ -127,6 +127,14 @@ public class JavacOutputParser extends OutputParser { final CharSequence chars = prevLine == null ? line : prevLine; final int offset = Math.max(0, Math.min(chars.length(), nextLine.indexOf('^'))); colNum = EditorUtil.calcColumnNumber(null, chars,0, offset, myTabSize); + String messageEnd = callback.getNextLine(); + while (isMessageEnd(messageEnd)) { + messages.add(messageEnd.trim()); + messageEnd = callback.getNextLine(); + } + if (messageEnd != null) { + callback.pushBack(messageEnd); + } break; } if (prevLine != null) { @@ -168,6 +176,10 @@ public class JavacOutputParser extends OutputParser { return true; } + private static boolean isMessageEnd(String line) { + return line != null && line.length() > 0 && Character.isWhitespace(line.charAt(0)); + } + private static List convertMessages(List messages) { if(messages.size() <= 1) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/OutputParser.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/OutputParser.java index a739bf0167c9..3c5b1ca1cc10 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/execution/OutputParser.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/OutputParser.java @@ -15,9 +15,9 @@ */ package com.intellij.lang.ant.config.execution; +import com.intellij.compiler.impl.javaCompiler.FileObject; import com.intellij.compiler.impl.javaCompiler.javac.JavacOutputParser; import com.intellij.compiler.impl.javaCompiler.jikes.JikesOutputParser; -import com.intellij.compiler.impl.javaCompiler.FileObject; import com.intellij.execution.process.OSProcessHandler; import com.intellij.lang.ant.AntBundle; import com.intellij.openapi.application.ApplicationManager; @@ -240,7 +240,7 @@ public class OutputParser{ } com.intellij.compiler.OutputParser.Callback callback = new com.intellij.compiler.OutputParser.Callback() { - private int myIndex = 0; + private int myIndex = -1; @Nullable public String getCurrentLine() { @@ -251,7 +251,16 @@ public class OutputParser{ } public String getNextLine() { - return javacMessages.get(myIndex++); + final int next = myIndex + 1; + if (next >= javacMessages.size()) { + return null; + } + return javacMessages.get(myIndex = next); + } + + @Override + public void pushBack(String line) { + myIndex--; } public void message(final CompilerMessageCategory category, From 331a63b056535e4b52f175b4a99efd07e7c9a9b0 Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 16 Feb 2011 18:51:50 +0300 Subject: [PATCH 14/28] IDEA-65604 Subversion SSH: CCE at org.jetbrains.idea.svn.SvnAuthenticationManager$IdeaSVNHostOptions$2.get --- .../idea/svn/SvnAuthenticationManager.java | 23 +++++++++++++------ .../auth/SvnAuthenticationInteraction.java | 2 +- .../idea/svn/SvnAuthenticationTest.java | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationManager.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationManager.java index 0542feabb651..f07993844566 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationManager.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationManager.java @@ -40,10 +40,7 @@ import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNProperties; import org.tmatesoft.svn.core.SVNURL; -import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider; -import org.tmatesoft.svn.core.auth.ISVNProxyManager; -import org.tmatesoft.svn.core.auth.SVNAuthentication; -import org.tmatesoft.svn.core.auth.SVNSSLAuthentication; +import org.tmatesoft.svn.core.auth.*; import org.tmatesoft.svn.core.internal.wc.*; import org.tmatesoft.svn.core.io.SVNRepository; @@ -568,8 +565,9 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im } @Override - public boolean promptForSSLPlaintextPassphraseSaving(SVNURL url, String realm, File certificateFile) { - final int answer = Messages.showYesNoDialog(myProject, String.format("Your passphrase for client certificate:\n%s\ncan only be stored to disk unencrypted. Would you like to store it in plaintext?", + public boolean promptForSSLPlaintextPassphraseSaving(SVNURL url, String realm, File certificateFile, String certificateName) { + final int answer = Messages.showYesNoDialog(myProject, + String.format("Your passphrase for " + certificateName + ":\n%s\ncan only be stored to disk unencrypted. Would you like to store it in plaintext?", certificateFile.getPath()), "Store the passphrase in plaintext?", Messages.getQuestionIcon()); return answer == 0; @@ -655,8 +653,19 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im promptAndSaveWhenWeLackEncryption(realm, auth, new Getter() { @Override public Boolean get() { + File file = null; + String certificateName = null; + if (auth instanceof SVNSSLAuthentication) { + file = ((SVNSSLAuthentication) auth).getCertificateFile(); + certificateName = "client certificate"; + } else if (auth instanceof SVNSSHAuthentication) { + file = ((SVNSSHAuthentication) auth).getPrivateKeyFile(); + certificateName = "private key file"; + } else { + assert false; + } return myInteraction.promptForSSLPlaintextPassphraseSaving(myUrl, realm, - ((SVNSSLAuthentication) auth).getCertificateFile()); + file, certificateName); } }); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationInteraction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationInteraction.java index a43f6fad829d..a256435d0b7c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationInteraction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationInteraction.java @@ -23,7 +23,7 @@ public interface SvnAuthenticationInteraction { void warnOnAuthStorageDisabled(final SVNURL url); void warnOnPasswordStorageDisabled(final SVNURL url); void warnOnSSLPassphraseStorageDisabled(final SVNURL url); - boolean promptForSSLPlaintextPassphraseSaving(final SVNURL url, String realm, File certificateFile); + boolean promptForSSLPlaintextPassphraseSaving(final SVNURL url, String realm, File certificateFile, String certificateName); boolean promptForPlaintextPasswordSaving(final SVNURL url, String realm); boolean promptInAwt(); } diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java index 50247afa3b93..a0c44d748bb2 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java @@ -1248,7 +1248,7 @@ public class SvnAuthenticationTest extends PlatformTestCase { } @Override - public boolean promptForSSLPlaintextPassphraseSaving(SVNURL url, String realm, File certificateFile) { + public boolean promptForSSLPlaintextPassphraseSaving(SVNURL url, String realm, File certificateFile, String certificateName) { ++ myNumSSLPlaintextPrompt; return mySSLPlaintextAnswer; } From d31a8dc10e8818fbbed7edfd12f68efd2f825a51 Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Wed, 16 Feb 2011 17:56:24 +0300 Subject: [PATCH 15/28] usages statistics refactored + fixed tests --- .../libraries/impl/LibraryUsageCollector.java | 14 +- .../FrameworkStatisticsPersistence.java | 42 --- ...ameworkStatisticsPersistenceComponent.java | 146 -------- .../statistics/FrameworkUsagesCollector.java | 65 +--- .../FeaturesUsageCollector.java | 7 +- .../ide/plugins/PluginsUsagesCollector.java | 6 +- .../AbstractApplicationUsagesCollector.java | 82 +++++ .../statistic/StatisticsUploadAssistant.java | 325 ++++++++++-------- .../internal/statistic/UsagesCollector.java | 3 +- .../statistic/beans/ConvertUsagesUtil.java | 51 ++- .../statistic/beans/PatchedUsage.java | 6 +- .../statistic/beans/UsageDescriptor.java | 35 +- .../configurable/StatisticsConfigurable.java | 16 +- .../ApplicationStatisticsPersistence.java | 37 ++ ...icationStatisticsPersistenceComponent.java | 184 ++++++++++ .../BasicSentUsagesPersistenceComponent.java | 79 +++-- .../persistence/SentUsagesPersistence.java | 6 +- .../UsageStatisticsPersistenceComponent.java | 4 +- .../StatisticsNotificationManager.java | 2 +- .../src/componentSets/Platform.xml | 14 +- .../statistics/VcsStatisticsPersistence.java | 42 --- .../VcsStatisticsPersistenceComponent.java | 146 -------- .../vcs/statistics/VcsUsagesCollector.java | 80 +---- 23 files changed, 620 insertions(+), 772 deletions(-) delete mode 100644 platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java delete mode 100644 platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/AbstractApplicationUsagesCollector.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java delete mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java delete mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/impl/LibraryUsageCollector.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/impl/LibraryUsageCollector.java index fdff8b12dd91..dad76bc77c8b 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/impl/LibraryUsageCollector.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/impl/LibraryUsageCollector.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.roots.ui.configuration.libraries.impl; +import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -34,12 +35,13 @@ import java.util.*; /** * @author nik */ -public class LibraryUsageCollector extends UsagesCollector { +public class LibraryUsageCollector extends AbstractApplicationUsagesCollector { + @NonNls private static final String GROUP_ID = "libraries"; @NotNull @Override - public Set getUsages(@Nullable Project project) { + public Set getProjectUsages(@Nullable Project project) { if (project == null) return Collections.emptySet(); final Set> usedKinds = new HashSet>(); @@ -56,15 +58,13 @@ public class LibraryUsageCollector extends UsagesCollector { final HashSet usageDescriptors = new HashSet(); for (LibraryKind kind : usedKinds) { - final GroupDescriptor group = GroupDescriptor.create(GROUP_ID); - usageDescriptors.add(new UsageDescriptor(group, kind.getKindId(), 1)); + usageDescriptors.add(new UsageDescriptor(kind.getKindId(), 1)); } return usageDescriptors; } @NotNull @Override - public String getGroupId() { - return GROUP_ID; - } + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID); } } diff --git a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java deleted file mode 100644 index b1d9a0894c75..000000000000 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.facet.impl.statistics; - -import com.intellij.openapi.project.Project; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.util.containers.HashMap; -import org.jetbrains.annotations.NotNull; - -import java.util.Map; -import java.util.Set; - -public abstract class FrameworkStatisticsPersistence { - private Map> myFrameworks = new HashMap>(); - - public FrameworkStatisticsPersistence() { - } - - public void persistFrameworks(@NotNull Project project, @NotNull Set frameworks) { - myFrameworks.put(project.getName(), frameworks); - } - - @NotNull - public Map> getFrameworks() { - return myFrameworks; - } - -} diff --git a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java deleted file mode 100644 index 717dabff6e15..000000000000 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.facet.impl.statistics; - -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.components.ApplicationComponent; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.project.ProjectManagerListener; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.Function; -import com.intellij.util.containers.HashSet; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.List; -import java.util.Map; -import java.util.Set; - -@State( - name = "FrameworkUsages", - storages = { - @Storage( - id = "frameworks", - file = "$APP_CONFIG$/framework.usages.xml" - )} -) -public class FrameworkStatisticsPersistenceComponent extends FrameworkStatisticsPersistence - implements ApplicationComponent, PersistentStateComponent { - private static final String TOKENIZER = ","; - - @NonNls private static final String PROJECT_TAG = "project"; - @NonNls private static final String PROJECT_ID_ATTR = "id"; - @NonNls private static final String FRAMEWORKS_ATTR = "frameworks"; - - public FrameworkStatisticsPersistenceComponent() { - } - - public static FrameworkStatisticsPersistenceComponent getInstance() { - return ApplicationManager.getApplication().getComponent(FrameworkStatisticsPersistenceComponent.class); - } - - public void loadState(final Element element) { - List projectsList = element.getChildren(PROJECT_TAG); - for (Object project : projectsList) { - Element projectElement = (Element)project; - String projectId = projectElement.getAttributeValue(PROJECT_ID_ATTR); - String frameworks = projectElement.getAttributeValue(FRAMEWORKS_ATTR); - if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(frameworks)) { - Set frameworkDescriptors = new HashSet(); - for (String key : StringUtil.split(frameworks, TOKENIZER)) { - frameworkDescriptors.add(new UsageDescriptor(FrameworkUsagesCollector.getGroupDescriptor(), key, 1)); - } - getFrameworks().put(projectId, frameworkDescriptors); - } - } - } - - public Element getState() { - Element element = new Element("state"); - - for (Map.Entry> frameworks : getFrameworks().entrySet()) { - Element projectElement = new Element(PROJECT_TAG); - projectElement.setAttribute(PROJECT_ID_ATTR, frameworks.getKey()); - projectElement.setAttribute(FRAMEWORKS_ATTR, joinUsages(frameworks.getValue())); - - element.addContent(projectElement); - } - - return element; - } - - private static String joinUsages(@NotNull Set usages) { - return StringUtil.join(usages, new Function() { - @Override - public String fun(UsageDescriptor usageDescriptor) { - return usageDescriptor.getKey(); - } - }, TOKENIZER); - } - - @NotNull - @NonNls - public File[] getExportFiles() { - return new File[]{PathManager.getOptionsFile("framework.usages")}; - } - - @NotNull - public String getPresentableName() { - return "Framework Usages"; - } - - @NonNls - @NotNull - public String getComponentName() { - return "FrameworkStatisticsPersistenceComponent"; - } - - public void initComponent() { - ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerListener() { - @Override - public void projectOpened(Project project) { - } - - @Override - public boolean canCloseProject(Project project) { - return true; - } - - @Override - public void projectClosed(Project project) { - } - - @Override - public void projectClosing(Project project) { - if (project != null) { - FrameworkUsagesCollector.persistProjectUsages(project); - } - } - }); - } - - public void disposeComponent() { - } -} diff --git a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java index abad35157269..30e78582fb7d 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkUsagesCollector.java @@ -17,84 +17,31 @@ package com.intellij.facet.impl.statistics; import com.intellij.facet.Facet; import com.intellij.facet.FacetManager; +import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; -import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; -import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Map; import java.util.Set; -public class FrameworkUsagesCollector extends UsagesCollector { +public class FrameworkUsagesCollector extends AbstractApplicationUsagesCollector { public static final String GROUP_ID = "frameworks"; - public static void persistProjectUsages(@NotNull Project project) { - persistProjectUsages(project, getProjectUsages(project)); - } - - public static void persistProjectUsages(@NotNull Project project, @NotNull Set usages) { - persistProjectUsages(project, usages, FrameworkStatisticsPersistenceComponent.getInstance()); - } - - public static void persistProjectUsages(@NotNull Project project, - @NotNull Set usages, - @NotNull FrameworkStatisticsPersistence persistence) { - persistence.persistFrameworks(project, usages); - } - - @NotNull - public Set getApplicationUsages() { - return getApplicationUsages(FrameworkStatisticsPersistenceComponent.getInstance()); - } - - @NotNull - public Set getApplicationUsages(@NotNull final FrameworkStatisticsPersistence persistence) { - final Map facets = new HashMap(); - - for (Set frameworks : persistence.getFrameworks().values()) { - for (UsageDescriptor framework : frameworks) { - final String key = framework.getKey(); - final Integer count = facets.get(key); - facets.put(key, count == null ? 1 : count.intValue() + 1); - } - } - - return ContainerUtil.map2Set(facets.entrySet(), new Function, UsageDescriptor>() { - @Override - public UsageDescriptor fun(Map.Entry facet) { - return new UsageDescriptor(getGroupDescriptor(), facet.getKey(), facet.getValue()); - } - }); - } - @NotNull @Override - public String getGroupId() { - return GROUP_ID; - } - - public static GroupDescriptor getGroupDescriptor() { + public GroupDescriptor getGroupId() { return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); } + @NotNull - public Set getUsages(@Nullable Project project) { - if (project != null) { - persistProjectUsages(project, getProjectUsages(project)); - } - - return getApplicationUsages(); - } - - public static Set getProjectUsages(@NotNull Project project) { + public Set getProjectUsages(@NotNull Project project) { final Set facets = new HashSet(); for (Module module : ModuleManager.getInstance(project).getModules()) { for (Facet facet : FacetManager.getInstance(module).getAllFacets()) { @@ -105,7 +52,7 @@ public class FrameworkUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(facets, new Function() { @Override public UsageDescriptor fun(String facet) { - return new UsageDescriptor(getGroupDescriptor(), facet, 1); + return new UsageDescriptor(facet, 1); } }); } diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java b/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java index b983a6d9adc1..44bec87c2dd1 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java +++ b/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java @@ -29,8 +29,8 @@ public class FeaturesUsageCollector extends UsagesCollector { @NotNull @Override - public String getGroupId() { - return "productivity"; + public GroupDescriptor getGroupId() { + return GroupDescriptor.create("productivity", GroupDescriptor.LOWER_PRIORITY); } @NotNull @@ -44,8 +44,7 @@ public class FeaturesUsageCollector extends UsagesCollector { for (String featureId : registry.getFeatureIds()) { final FeatureDescriptor featureDescriptor = registry.getFeatureDescriptor(featureId); if (featureDescriptor != null) { - usages.add(new UsageDescriptor( - GroupDescriptor.create(getGroupId(), GroupDescriptor.LOWER_PRIORITY), featureId, featureDescriptor.getUsageCount())); + usages.add(new UsageDescriptor(featureId, featureDescriptor.getUsageCount())); } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java index 006b58967ada..c4fc51be1450 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java @@ -30,8 +30,8 @@ public class PluginsUsagesCollector extends UsagesCollector { private static final String GROUP_ID = "disabled-plugins"; @NotNull - public String getGroupId() { - return GROUP_ID; + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); } @NotNull @@ -39,7 +39,7 @@ public class PluginsUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(PluginManager.getDisabledPlugins(), new Function() { @Override public UsageDescriptor fun(String descriptor) { - return new UsageDescriptor(GroupDescriptor.create(getGroupId(), GroupDescriptor.HIGHER_PRIORITY), descriptor, 1); + return new UsageDescriptor(descriptor, 1); } }); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/AbstractApplicationUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/AbstractApplicationUsagesCollector.java new file mode 100644 index 000000000000..f7173bc60d65 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/AbstractApplicationUsagesCollector.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.statistic; + +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.persistence.ApplicationStatisticsPersistence; +import com.intellij.internal.statistic.persistence.ApplicationStatisticsPersistenceComponent; +import com.intellij.openapi.project.Project; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.hash.HashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.Set; + +public abstract class AbstractApplicationUsagesCollector extends UsagesCollector { + public void persistProjectUsages(@NotNull Project project) { + persistProjectUsages(project, getProjectUsages(project)); + } + + public void persistProjectUsages(@NotNull Project project, @NotNull Set usages) { + persistProjectUsages(project, usages, ApplicationStatisticsPersistenceComponent.getInstance()); + } + + public void persistProjectUsages(@NotNull Project project, + @NotNull Set usages, + @NotNull ApplicationStatisticsPersistence persistence) { + persistence.persistFrameworks(getGroupId(), project, usages); + } + + @NotNull + public Set getApplicationUsages() { + return getApplicationUsages(ApplicationStatisticsPersistenceComponent.getInstance()); + } + + @NotNull + public Set getApplicationUsages(@NotNull final ApplicationStatisticsPersistence persistence) { + final Map facets = new HashMap(); + + for (Set frameworks : persistence.getApplicationData(getGroupId()).values()) { + for (UsageDescriptor framework : frameworks) { + final String key = framework.getKey(); + final Integer count = facets.get(key); + facets.put(key, count == null ? 1 : count.intValue() + 1); + } + } + + return ContainerUtil.map2Set(facets.entrySet(), new Function, UsageDescriptor>() { + @Override + public UsageDescriptor fun(Map.Entry facet) { + return new UsageDescriptor(facet.getKey(), facet.getValue()); + } + }); + } + + @NotNull + public Set getUsages(@Nullable Project project) { + if (project != null) { + persistProjectUsages(project, getProjectUsages(project)); + } + + return getApplicationUsages(); + } + + @NotNull + public abstract Set getProjectUsages(@NotNull Project project); +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java index b6a2105b5064..ac676de86be8 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java @@ -30,7 +30,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; -import com.intellij.util.text.DateFormatUtil; +import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,173 +38,204 @@ import java.util.*; public class StatisticsUploadAssistant { - public String getData() { - return getData(Collections.emptySet()); - } + public String getData() { + return getData(Collections.emptySet()); + } - public static boolean showNotification() { - return UsageStatisticsPersistenceComponent.getInstance().isShowNotification(); - } + public static boolean showNotification() { + return UsageStatisticsPersistenceComponent.getInstance().isShowNotification(); + } - public static boolean isTimeToSend() { - if (ApplicationManagerEx.getApplicationEx().isInternal()) return true; // todo remove + public static boolean isTimeToSend() { + if (ApplicationManagerEx.getApplicationEx().isInternal()) return true; // todo remove - return isTimeToSend(UsageStatisticsPersistenceComponent.getInstance()); - } + return isTimeToSend(UsageStatisticsPersistenceComponent.getInstance()); + } - public static boolean isTimeToSend(UsageStatisticsPersistenceComponent settings) { - final long timeDelta = System.currentTimeMillis() - settings.getLastTimeSent(); + public static boolean isTimeToSend(UsageStatisticsPersistenceComponent settings) { + final long timeDelta = System.currentTimeMillis() - settings.getLastTimeSent(); - return Math.abs(timeDelta) > settings.getPeriod().getMillis(); - } + return Math.abs(timeDelta) > settings.getPeriod().getMillis(); + } - public static boolean isSendAllowed() { - if (ApplicationManagerEx.getApplicationEx().isInternal()) return true; // todo remove + public static boolean isSendAllowed() { + if (ApplicationManagerEx.getApplicationEx().isInternal()) return true; // todo remove - return isSendAllowed(UsageStatisticsPersistenceComponent.getInstance()); - } + return isSendAllowed(UsageStatisticsPersistenceComponent.getInstance()); + } - public static boolean isSendAllowed(final SentUsagesPersistence settings) { - return settings != null && settings.isAllowed(); - } + public static boolean isSendAllowed(final SentUsagesPersistence settings) { + return settings != null && settings.isAllowed(); + } - public static String getData(@NotNull Set disabledGroups) { - return getStringPatch(disabledGroups, ProjectManager.getInstance().getOpenProjects()); - } + public static String getData(@NotNull Set disabledGroups) { + return getStringPatch(disabledGroups, ProjectManager.getInstance().getOpenProjects()); + } - public static void persistSentPatch(@NotNull String patchStr) { - persistSentPatch(patchStr, UsageStatisticsPersistenceComponent.getInstance()); - } + public static void persistSentPatch(@NotNull String patchStr) { + persistSentPatch(patchStr, UsageStatisticsPersistenceComponent.getInstance()); + } - public static void persistSentPatch(@NotNull String patchStr, @NotNull SentUsagesPersistence persistenceComponent) { - Set patchedUsages = - ContainerUtil.map2Set(ConvertUsagesUtil.convertString(patchStr), new Function() { - @Override - public PatchedUsage fun(UsageDescriptor usageDescriptor) { - return new PatchedUsage(usageDescriptor); + public static void persistSentPatch(@NotNull String patchStr, @NotNull SentUsagesPersistence persistenceComponent) { + Map> patchedUsages = mapToPatchedUsagesMap(ConvertUsagesUtil.convertString(patchStr)); + + if (patchedUsages.size() > 0) persistenceComponent.persistPatch(patchedUsages); + } + + @NotNull + public static String getStringPatch(@NotNull Set disabledGroups, Project... project) { + return getStringPatch(disabledGroups, project, UsageStatisticsPersistenceComponent.getInstance(), 0); + } + + @NotNull + public static String getStringPatch(@NotNull Set disabledGroups, + @NotNull Project[] projects, + @NotNull SentUsagesPersistence usagesPersistence, + int maxSize) { + final Map> patchedUsages = getPatchedUsages(disabledGroups, projects, usagesPersistence); + + return getStringPatch(patchedUsages, maxSize); + } + + public static String getStringPatch(@NotNull Map> patchedUsages, int maxSize) { + if (patchedUsages.size() == 0) return ""; + + String patchStr = ConvertUsagesUtil.convertUsages(patchedUsages); + if (maxSize > 0 && patchStr.getBytes().length > maxSize) { + patchStr = ConvertUsagesUtil.cutPatchString(patchStr, maxSize); } - }); - if (patchedUsages.size() > 0) persistenceComponent.persistPatch(patchedUsages); - } - - @NotNull - public static String getStringPatch(@NotNull Set disabledGroups, Project... project) { - return getStringPatch(disabledGroups, project, UsageStatisticsPersistenceComponent.getInstance(), 0); - } - - @NotNull - public static String getStringPatch(@NotNull Set disabledGroups, - @NotNull Project[] projects, - @NotNull SentUsagesPersistence usagesPersistence, - int maxSize) { - final Set patchedUsages = getPatchedUsages(disabledGroups, projects, usagesPersistence); - - return getStringPatch(patchedUsages, maxSize); - } - - public static String getStringPatch(@NotNull Set patchedUsages, int maxSize) { - if (patchedUsages.size() == 0) return ""; - - String patchStr = ConvertUsagesUtil.convertUsages(patchedUsages); - if (maxSize > 0 && patchStr.getBytes().length > maxSize) { - patchStr = ConvertUsagesUtil.cutPatchString(patchStr, maxSize); + return patchStr; } - return patchStr; - } + @NotNull + public static Map> getPatchedUsages(@NotNull Set disabledGroups, + @NotNull Project[] projects, + @NotNull SentUsagesPersistence usagesPersistence) { + Map> usages = new HashMap>(); - @NotNull - public static Set getPatchedUsages(@NotNull Set disabledGroups, - @NotNull Project[] projects, - @NotNull SentUsagesPersistence usagesPersistence) { - Set usages = new HashSet(); + for (Project project : projects) { + final Map> allUsages = getAllUsages(project, disabledGroups); + final Map> sentUsages = filterDisabled(disabledGroups, usagesPersistence.getSentUsages()); - for (Project project : projects) { - final Set allUsages = getAllUsages(project, disabledGroups); - final Set sentUsages = filterDisabled(disabledGroups, usagesPersistence.getSentUsages()); - - usages.addAll(getPatchedUsages(allUsages, sentUsages)); - } - return usages; - } - - private static Set filterDisabled(@NotNull Set disabledGroups, @NotNull Set usages) { - Set filtered = new HashSet(); - - for (UsageDescriptor usage : usages) { - if (!disabledGroups.contains(usage.getGroup().getId())) { - filtered.add(usage); - } - } - return filtered; - } - - @NotNull - public static Set getPatchedUsages(@NotNull final Set allUsages, - @NotNull SentUsagesPersistence usagesPersistence) { - return getPatchedUsages(allUsages, usagesPersistence.getSentUsages()); - } - - @NotNull - public static Set getPatchedUsages(@NotNull final Set allUsages, final Set sentUsages) { - final Set patchedUsages = ContainerUtil.map2Set(allUsages, new Function() { - @Override - public PatchedUsage fun(UsageDescriptor usageDescriptor) { - return new PatchedUsage(usageDescriptor); - } - }); - - for (UsageDescriptor sentUsage : sentUsages) { - final PatchedUsage descriptor = findDescriptor(patchedUsages, Pair.create(sentUsage.getGroup(), sentUsage.getKey())); - if (descriptor == null) { - patchedUsages.add(new PatchedUsage(sentUsage.getGroup(), sentUsage.getKey(), -sentUsage.getValue())); - } - else { - descriptor.subValue(sentUsage.getValue()); - } + usages.putAll(getPatchedUsages(allUsages, sentUsages)); + } + return usages; } - return packCollection(patchedUsages, new Condition() { - @Override - public boolean value(PatchedUsage patchedUsage) { - return patchedUsage.getDelta() != 0; - } - }); - } + @NotNull + private static Map> filterDisabled(@NotNull Set disabledGroups, @NotNull Map> usages) { + Map> filtered = new HashMap>(); - @NotNull - private static Set packCollection(@NotNull Collection set, @NotNull Condition condition) { - final Set result = new LinkedHashSet(); - for (T t : set) { - if (condition.value(t)) { - result.add(t); - } + for (Map.Entry> usage : usages.entrySet()) { + if (!disabledGroups.contains(usage.getKey().getId())) { + filtered.put(usage.getKey(), usage.getValue()); + } + } + return filtered; } - return result; - } - - @Nullable - public static T findDescriptor(@NotNull Set descriptors, - @NotNull final Pair id) { - return ContainerUtil.find(descriptors, new Condition() { - @Override - public boolean value(T t) { - return id.getFirst().equals(t.getGroup()) && id.getSecond().equals(t.getKey()); - } - }); - } - - @NotNull - public static Set getAllUsages(@Nullable Project project, @NotNull Set disabledGroups) { - final Set usageDescriptors = new TreeSet(); - - for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { - if (!disabledGroups.contains(usagesCollector.getGroupId())) { - usageDescriptors.addAll(usagesCollector.getUsages(project)); - } + + @NotNull + public static Map> getPatchedUsages(@NotNull final Map> allUsages, + @NotNull SentUsagesPersistence usagesPersistence) { + return getPatchedUsages(allUsages, usagesPersistence.getSentUsages()); + } + + @NotNull + public static Map> getPatchedUsages(@NotNull final Map> allUsages, final Map> sentUsageMap) { + Map> patchedUsages = mapToPatchedUsagesMap(allUsages); + + for (Map.Entry> sentUsageEntry : sentUsageMap.entrySet()) { + final GroupDescriptor sentUsageGroupDescriptor = sentUsageEntry.getKey(); + + final Set sentUsages = sentUsageEntry.getValue(); + + for (UsageDescriptor sentUsage : sentUsages) { + final PatchedUsage descriptor = findDescriptor(patchedUsages, Pair.create(sentUsageGroupDescriptor, sentUsage.getKey())); + if (descriptor == null) { + if (!patchedUsages.containsKey(sentUsageGroupDescriptor)) { + patchedUsages.put(sentUsageGroupDescriptor, new HashSet()); + } + patchedUsages.get(sentUsageGroupDescriptor).add(new PatchedUsage(sentUsage.getKey(), -sentUsage.getValue())); + } else { + descriptor.subValue(sentUsage.getValue()); + } + } + + } + + return packCollection(patchedUsages, new Condition() { + @Override + public boolean value(PatchedUsage patchedUsage) { + return patchedUsage.getDelta() != 0; + } + }); + } + + private static Map> mapToPatchedUsagesMap(Map> allUsages) { + Map> patchedUsages = new HashMap>(); + for (Map.Entry> entry : allUsages.entrySet()) { + patchedUsages.put(entry.getKey(), ContainerUtil.map2Set(entry.getValue(), new Function() { + @Override + public PatchedUsage fun(UsageDescriptor usageDescriptor) { + return new PatchedUsage(usageDescriptor); + } + })); + } + return patchedUsages; + } + + @NotNull + private static Map> packCollection(@NotNull Map> patchedUsages, Condition condition) { + Map> result = new HashMap>(); + for (GroupDescriptor descriptor : patchedUsages.keySet()) { + final Set usages = packCollection(patchedUsages.get(descriptor), condition); + if (usages.size() > 0) { + result.put(descriptor, usages); + } + } + + return result; + } + + @NotNull + private static Set packCollection(@NotNull Collection set, @NotNull Condition condition) { + final Set result = new LinkedHashSet(); + for (T t : set) { + if (condition.value(t)) { + result.add(t); + } + } + return result; + } + + @Nullable + public static T findDescriptor(@NotNull Map> descriptors, + @NotNull final Pair id) { + final Set usages = descriptors.get(id.getFirst()); + if (usages == null) return null; + + return ContainerUtil.find(usages, new Condition() { + @Override + public boolean value(T t) { + return id.getSecond().equals(t.getKey()); + } + }); + } + + @NotNull + public static Map> getAllUsages(@Nullable Project project, @NotNull Set disabledGroups) { + Map> usageDescriptors = new HashMap>(); + + for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { + final GroupDescriptor groupDescriptor = usagesCollector.getGroupId(); + + if (!disabledGroups.contains(groupDescriptor.getId())) { + usageDescriptors.put(groupDescriptor, usagesCollector.getUsages(project)); + } + } + + return usageDescriptors; } - return usageDescriptors; - } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java index e07246e0556a..46e03564bf5d 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java @@ -15,6 +15,7 @@ */ package com.intellij.internal.statistic; +import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -28,5 +29,5 @@ public abstract class UsagesCollector { public abstract @NotNull Set getUsages(@Nullable Project project); - public abstract @NotNull String getGroupId(); + public abstract @NotNull GroupDescriptor getGroupId(); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java index 8fd58411e437..e8f2c6e8acd8 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java @@ -16,6 +16,8 @@ package com.intellij.internal.statistic.beans; +import com.intellij.util.containers.hash.HashMap; + import java.util.*; public class ConvertUsagesUtil { @@ -26,19 +28,14 @@ public class ConvertUsagesUtil { private ConvertUsagesUtil() { } - // @NotNull - public static String convertUsages(Set descriptors) { - assert descriptors != null; - final Map> descriptorGroups = groupDescriptors(descriptors); - - return convertUsages(descriptorGroups); - } // @NotNull - public static String convertUsages(Map> map) { + public static String convertUsages(Map> map) { assert map != null; + final Map> sortedMap = sortDescriptorsByPriority(map); + StringBuffer buffer = new StringBuffer(); - for (Map.Entry> entry : map.entrySet()) { + for (Map.Entry> entry : sortedMap.entrySet()) { buffer.append(entry.getKey().getId()); buffer.append(GROUP_SEPARATOR); buffer.append(convertValueMap(entry.getValue())); @@ -49,7 +46,7 @@ public class ConvertUsagesUtil { } //@NotNull - public static String convertValueMap(Set descriptors) { + public static String convertValueMap(Set descriptors) { assert descriptors != null; final StringBuffer buffer = new StringBuffer(); for (UsageDescriptor usageDescriptor : descriptors) { @@ -76,14 +73,14 @@ public class ConvertUsagesUtil { } //@NotNull - public static Set convertString(String usages) { + public static Map> convertString(String usages) { assert usages != null; - Set descriptors = new LinkedHashSet(); + Map> descriptors = new HashMap>(); for (String groupStr : usages.split(GROUPS_SEPARATOR.toString())) { if (!isEmptyOrSpaces(groupStr)) { final StringPair group = getPair(groupStr, GROUP_SEPARATOR.toString()); if (group != null) { - descriptors.addAll(convertValueString(GroupDescriptor.create(group.first), group.second)); + descriptors.putAll(convertValueString(GroupDescriptor.create(group.first), group.second)); } } } @@ -91,9 +88,9 @@ public class ConvertUsagesUtil { } //@NotNull - public static Set convertValueString(GroupDescriptor groupId, String valueData) { + public static Map> convertValueString(GroupDescriptor groupId, String valueData) { assert groupId != null; - final Set descriptors = new LinkedHashSet(); + final Map> descriptors = new HashMap>(); for (String value : valueData.split(GROUP_VALUE_SEPARATOR.toString())) { if (!isEmptyOrSpaces(value)) { final StringPair pair = getPair(value, "="); @@ -102,7 +99,10 @@ public class ConvertUsagesUtil { if (!isEmptyOrSpaces(count)) { try { final int i = Integer.parseInt(count); - descriptors.add(new UsageDescriptor(groupId, pair.first, i)); + if (!descriptors.containsKey(groupId)) { + descriptors.put(groupId, new LinkedHashSet()); + } + descriptors.get(groupId).add(new UsageDescriptor(pair.first, i)); } catch (NumberFormatException ignored) { } } @@ -129,22 +129,17 @@ public class ConvertUsagesUtil { } //@NotNull - public static Map> groupDescriptors(Set descriptors) { + public static Map> sortDescriptorsByPriority(Map> descriptors) { assert descriptors != null; - final SortedMap> map = new TreeMap>(new Comparator() { + final SortedMap> map = new TreeMap>(new Comparator() { public int compare(GroupDescriptor g1, GroupDescriptor g2) { final int priority = (int) (g2.getPriority() - g1.getPriority()); return priority == 0 ? g1.getId().compareTo(g2.getId()) : priority; } }); - for (UsageDescriptor descriptor : descriptors) { - final GroupDescriptor group = descriptor.getGroup(); - if (!map.containsKey(group)) { - map.put(group, new HashSet()); - } - map.get(group).add(descriptor); - } + map.putAll(descriptors); + return map; } @@ -158,7 +153,7 @@ public class ConvertUsagesUtil { } } - public static boolean isEmptyOrSpaces(final String s) { - return s == null || s.trim().length() == 0; - } + public static boolean isEmptyOrSpaces(final String s) { + return s == null || s.trim().length() == 0; + } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java index f91433e4b6bb..f300bd74362f 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java @@ -18,11 +18,11 @@ package com.intellij.internal.statistic.beans; public class PatchedUsage extends UsageDescriptor { public PatchedUsage(UsageDescriptor descriptor) { - super(descriptor.getGroup(), descriptor.getKey(), descriptor.getValue()); + super(descriptor.getKey(), descriptor.getValue()); } - public PatchedUsage(GroupDescriptor group, String key, int value) { - super(group, key, value); + public PatchedUsage(String key, int value) { + super(key, value); } public int getDelta() { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java index 2ec188afa17d..4b5a4c9c66d6 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java @@ -16,15 +16,12 @@ package com.intellij.internal.statistic.beans; public class UsageDescriptor implements Comparable { - private final GroupDescriptor myGroup; private final String myKey; private int myValue; - public UsageDescriptor(GroupDescriptor group, String key, int value) { - assert group != null; - assert key != null; + public UsageDescriptor(String key, int value) { + assert key != null; - myGroup = group; myKey = key; myValue = value; } @@ -33,10 +30,6 @@ public class UsageDescriptor implements Comparable { return myKey; } - public GroupDescriptor getGroup() { - return myGroup; - } - public int getValue() { return myValue; } @@ -45,29 +38,15 @@ public class UsageDescriptor implements Comparable { myValue = i; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof UsageDescriptor)) return false; - - UsageDescriptor that = (UsageDescriptor) o; - - if (!myGroup.equals(that.myGroup)) return false; - if (!myKey.equals(that.myKey)) return false; - - return true; + public int getMyValue() { + return myValue; } - @Override - public int hashCode() { - int result = myGroup.hashCode(); - result = 31 * result + myKey.hashCode(); - return result; + public void setMyValue(int myValue) { + this.myValue = myValue; } public int compareTo(UsageDescriptor ud) { - final int byGroup = this.getGroup().compareTo(ud.getGroup()); - - return byGroup == 0 ? this.getKey().compareTo(ud.myKey) : byGroup; + return this.getKey().compareTo(ud.myKey); } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java index 9af6117dbd03..c7ff27d0a279 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java @@ -29,7 +29,18 @@ import javax.swing.*; public class StatisticsConfigurable implements SearchableConfigurable { - private StatisticsConfigurationComponent myConfig; + private boolean modifiedByDefault; + + public StatisticsConfigurable() { + this(false); + } + + public StatisticsConfigurable(boolean isModifiedByDefault) { + modifiedByDefault = isModifiedByDefault; + } + + + private StatisticsConfigurationComponent myConfig; @Nls public String getDisplayName() { @@ -56,7 +67,7 @@ public class StatisticsConfigurable implements SearchableConfigurable { final UsageStatisticsPersistenceComponent persistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); return myConfig.isAllowed() != persistenceComponent.isAllowed() || myConfig.getPeriod() != persistenceComponent.getPeriod() || - persistenceComponent.isShowNotification(); + modifiedByDefault; } public void apply() throws ConfigurationException { @@ -65,6 +76,7 @@ public class StatisticsConfigurable implements SearchableConfigurable { persistenceComponent.setPeriod(myConfig.getPeriod()); persistenceComponent.setAllowed(myConfig.isAllowed()); persistenceComponent.setShowNotification(false); + modifiedByDefault = false; } public void reset() { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java new file mode 100644 index 000000000000..b5021df47287 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java @@ -0,0 +1,37 @@ +package com.intellij.internal.statistic.persistence; + +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; +import java.util.Set; + +public abstract class ApplicationStatisticsPersistence { + private Map>> myApplicationData = new HashMap>>(); + + public ApplicationStatisticsPersistence() { + } + + public void persistFrameworks(@NotNull GroupDescriptor groupDescriptor, @NotNull Project project, @NotNull Set frameworks) { + if (!myApplicationData.containsKey(groupDescriptor)) { + myApplicationData.put(groupDescriptor, new HashMap>()); + } + myApplicationData.get(groupDescriptor).put(project.getName(), frameworks); + } + + @NotNull + public Map> getApplicationData(@NotNull GroupDescriptor groupDescriptor) { + final Map> map = myApplicationData.get(groupDescriptor); + + return map == null ? new HashMap>(): map; + } + + @NotNull + public Map>> getApplicationData() { + return myApplicationData; + } + +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java new file mode 100644 index 000000000000..fb8d0fd6bffe --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java @@ -0,0 +1,184 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.internal.statistic.persistence; + +import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.HashSet; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@State( + name = "StatisticsApplicationUsages", + storages = { + @Storage( + id = "statistics.application.usages", + file = "$APP_CONFIG$/statistics.application.usages.xml" + )} +) +public class ApplicationStatisticsPersistenceComponent extends ApplicationStatisticsPersistence + implements ApplicationComponent, PersistentStateComponent { + private static final String TOKENIZER = ","; + + @NonNls + private static final String GROUP_TAG = "group"; + @NonNls + private static final String GROUP_NAME_ATTR = "name"; + + @NonNls + private static final String PROJECT_TAG = "project"; + @NonNls + private static final String PROJECT_ID_ATTR = "id"; + @NonNls + private static final String VALUES_ATTR = "values"; + + public ApplicationStatisticsPersistenceComponent() { + } + + public static ApplicationStatisticsPersistenceComponent getInstance() { + return ApplicationManager.getApplication().getComponent(ApplicationStatisticsPersistenceComponent.class); + } + + public void loadState(final Element element) { + List groups = element.getChildren(GROUP_TAG); + + for (Object group : groups) { + Element groupElement = (Element) group; + String groupName = groupElement.getAttributeValue(GROUP_NAME_ATTR); + + final GroupDescriptor groupDescriptor = GroupDescriptor.create(groupName); + + List projectsList = groupElement.getChildren(PROJECT_TAG); + for (Object project : projectsList) { + Element projectElement = (Element) project; + String projectId = projectElement.getAttributeValue(PROJECT_ID_ATTR); + String frameworks = projectElement.getAttributeValue(VALUES_ATTR); + if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(frameworks)) { + Set frameworkDescriptors = new HashSet(); + for (String key : StringUtil.split(frameworks, TOKENIZER)) { + frameworkDescriptors.add(new UsageDescriptor(key, 1)); + } + getApplicationData(groupDescriptor).put(projectId, frameworkDescriptors); + } + } + } + } + + public Element getState() { + Element element = new Element("state"); + + for (Map.Entry>> appData : getApplicationData().entrySet()) { + Element groupElement = new Element(GROUP_TAG); + groupElement.setAttribute(GROUP_NAME_ATTR, appData.getKey().getId()); + boolean isEmptyGroup = true; + + for (Map.Entry> projectData : appData.getValue().entrySet()) { + Element projectElement = new Element(PROJECT_TAG); + projectElement.setAttribute(PROJECT_ID_ATTR, projectData.getKey()); + final Set projectDataValue = projectData.getValue(); + if (!projectDataValue.isEmpty()) { + projectElement.setAttribute(VALUES_ATTR, joinUsages(projectDataValue)); + groupElement.addContent(projectElement); + isEmptyGroup = false; + } + } + + if (!isEmptyGroup) { + element.addContent(groupElement); + } + } + + return element; + } + + private static String joinUsages(@NotNull Set usages) { + return StringUtil.join(usages, new Function() { + @Override + public String fun(UsageDescriptor usageDescriptor) { + return usageDescriptor.getKey(); + } + }, TOKENIZER); + } + + @NotNull + @NonNls + public File[] getExportFiles() { + return new File[]{PathManager.getOptionsFile("framework.usages")}; + } + + @NotNull + public String getPresentableName() { + return "Application Usages Statistics"; + } + + @NonNls + @NotNull + public String getComponentName() { + return "ApplicationStatisticsPersistenceComponent"; + } + + public void initComponent() { + ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerListener() { + @Override + public void projectOpened(Project project) { + } + + @Override + public boolean canCloseProject(Project project) { + return true; + } + + @Override + public void projectClosed(Project project) { + } + + @Override + public void projectClosing(Project project) { + if (project != null) { + for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { + if (usagesCollector instanceof AbstractApplicationUsagesCollector) { + ((AbstractApplicationUsagesCollector) usagesCollector).persistProjectUsages(project); + } + } + } + } + }); + } + + public void disposeComponent() { + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java index 9f4ab0c910c3..b77ea2367816 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java @@ -17,58 +17,69 @@ package com.intellij.internal.statistic.persistence; import com.intellij.internal.statistic.StatisticsUploadAssistant; +import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.PatchedUsage; import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.openapi.util.Pair; import com.intellij.util.containers.HashSet; +import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import java.util.Map; import java.util.Set; public class BasicSentUsagesPersistenceComponent extends SentUsagesPersistence { - public BasicSentUsagesPersistenceComponent() { - } + public BasicSentUsagesPersistenceComponent() { + } - protected Set mySentDescriptors = new HashSet(); - @NonNls private long mySentTime = 0; + protected Map> mySentDescriptors = new HashMap>(); + @NonNls + private long mySentTime = 0; - @Override - public boolean isAllowed() { - return true; - } + @Override + public boolean isAllowed() { + return true; + } - @Override - public boolean isShowNotification() { - return false; - } + @Override + public boolean isShowNotification() { + return false; + } - @Override - public long getLastTimeSent() { - return mySentTime; - } + @Override + public long getLastTimeSent() { + return mySentTime; + } - public void setSentTime(long time) { - mySentTime = time; - } + public void setSentTime(long time) { + mySentTime = time; + } - public void persistPatch(@NotNull Set patchedDescriptors) { - for (PatchedUsage patchedUsage : patchedDescriptors) { - UsageDescriptor usageDescriptor = StatisticsUploadAssistant.findDescriptor(mySentDescriptors, Pair.create(patchedUsage.getGroup(), patchedUsage.getKey())); - if (usageDescriptor != null) { - usageDescriptor.setValue(usageDescriptor.getValue() + patchedUsage.getDelta()); - } - else { - mySentDescriptors.add(new UsageDescriptor(patchedUsage.getGroup(), patchedUsage.getKey(), patchedUsage.getValue())); - } + public void persistPatch(@NotNull Map> patchedDescriptorMap) { + for (Map.Entry> entry : patchedDescriptorMap.entrySet()) { + final GroupDescriptor groupDescriptor = entry.getKey(); + for (PatchedUsage patchedUsage : entry.getValue()) { + UsageDescriptor usageDescriptor = StatisticsUploadAssistant.findDescriptor(mySentDescriptors, Pair.create(groupDescriptor, patchedUsage.getKey())); + if (usageDescriptor != null) { + usageDescriptor.setValue(usageDescriptor.getValue() + patchedUsage.getDelta()); + } else { + if (!mySentDescriptors.containsKey(groupDescriptor)) { + mySentDescriptors.put(groupDescriptor, new HashSet()); + } + mySentDescriptors.get(groupDescriptor).add(new UsageDescriptor(patchedUsage.getKey(), patchedUsage.getValue())); + } + } + } + + setSentTime(System.currentTimeMillis()); } - setSentTime(System.currentTimeMillis()); - } - @NotNull - public Set getSentUsages() { - return mySentDescriptors; - } + @NotNull + public Map> getSentUsages + () { + return mySentDescriptors; + } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java index ca271e3a1cd7..cffc0edec7ba 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java @@ -16,18 +16,20 @@ package com.intellij.internal.statistic.persistence; +import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.PatchedUsage; import com.intellij.internal.statistic.beans.UsageDescriptor; import org.jetbrains.annotations.NotNull; +import java.util.Map; import java.util.Set; public abstract class SentUsagesPersistence { - public abstract void persistPatch(@NotNull Set patchedDescriptors); + public abstract void persistPatch(@NotNull Map> patchedDescriptors); @NotNull - public abstract Set getSentUsages(); + public abstract Map> getSentUsages(); public abstract boolean isAllowed(); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java index 1262fa18c79d..9140f257eac3 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java @@ -76,7 +76,7 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste String valueData = groupElement.getAttributeValue(DATA_ATTR); if (!StringUtil.isEmptyOrSpaces(groupId) && !StringUtil.isEmptyOrSpaces(valueData)) { - getSentUsages().addAll(ConvertUsagesUtil.convertValueString(GroupDescriptor.create(groupId, groupPriority), valueData)); + getSentUsages().putAll(ConvertUsagesUtil.convertValueString(GroupDescriptor.create(groupId, groupPriority), valueData)); } } @@ -99,7 +99,7 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste public Element getState() { Element element = new Element("state"); - for (Map.Entry> entry : ConvertUsagesUtil.groupDescriptors(getSentUsages()) + for (Map.Entry> entry : ConvertUsagesUtil.sortDescriptorsByPriority(getSentUsages()) .entrySet()) { Element projectElement = new Element(GROUP_TAG); projectElement.setAttribute(GROUP_ID_ATTR, entry.getKey().getId()); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java index 4fef4c3f2521..43ab15bfc3ce 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java @@ -72,7 +72,7 @@ public class StatisticsNotificationManager { else if ("settings".equals(description)) { final ShowSettingsUtil util = ShowSettingsUtil.getInstance(); IdeFrame ideFrame = WindowManagerEx.getInstanceEx().findFrameFor(null); - util.editConfigurable((JFrame)ideFrame, new StatisticsConfigurable()); + util.editConfigurable((JFrame)ideFrame, new StatisticsConfigurable(true)); notification.expire(); } } diff --git a/platform/platform-resources/src/componentSets/Platform.xml b/platform/platform-resources/src/componentSets/Platform.xml index b41fe5ed2b1e..fa0f63758036 100644 --- a/platform/platform-resources/src/componentSets/Platform.xml +++ b/platform/platform-resources/src/componentSets/Platform.xml @@ -118,20 +118,16 @@ com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent + + com.intellij.internal.statistic.persistence.ApplicationStatisticsPersistenceComponent + com.intellij.internal.statistic.persistence.ApplicationStatisticsPersistenceComponent + + com.intellij.openapi.util.FoundationLoader - - com.intellij.facet.impl.statistics.FrameworkStatisticsPersistenceComponent - com.intellij.facet.impl.statistics.FrameworkStatisticsPersistenceComponent - - - - com.intellij.openapi.vcs.statistics.VcsStatisticsPersistenceComponent - com.intellij.openapi.vcs.statistics.VcsStatisticsPersistenceComponent - diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java deleted file mode 100644 index 968e52aae1a8..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.openapi.vcs.statistics; - -import com.intellij.openapi.project.Project; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.util.containers.HashMap; -import org.jetbrains.annotations.NotNull; - -import java.util.Map; -import java.util.Set; - -public abstract class VcsStatisticsPersistence { - private Map> myVcsUsagesMap = new HashMap>(); - - public VcsStatisticsPersistence() { - } - - public void persist(@NotNull Project project, @NotNull Set vcs) { - myVcsUsagesMap.put(project.getName(), vcs); - } - - @NotNull - public Map> getVcsUsageMap() { - return myVcsUsagesMap; - } - -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java deleted file mode 100644 index 96a7cf527c12..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.openapi.vcs.statistics; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.components.ApplicationComponent; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.project.ProjectManagerListener; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.internal.statistic.beans.UsageDescriptor; -import com.intellij.util.Function; -import com.intellij.util.containers.HashSet; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.List; -import java.util.Map; -import java.util.Set; - -@State( - name = "VcsUsages", - storages = { - @Storage( - id = "vcs", - file = "$APP_CONFIG$/vcs.usages.xml" - )} -) -public class VcsStatisticsPersistenceComponent extends VcsStatisticsPersistence - implements ApplicationComponent, PersistentStateComponent { - private static final String TOKENIZER = ","; - - @NonNls private static final String PROJECT_TAG = "project"; - @NonNls private static final String PROJECT_ID_ATTR = "id"; - @NonNls private static final String USAGES_ATTR = "usages"; - - public VcsStatisticsPersistenceComponent() { - } - - public static VcsStatisticsPersistenceComponent getInstance() { - return ApplicationManager.getApplication().getComponent(VcsStatisticsPersistenceComponent.class); - } - - public void loadState(final Element element) { - List projectsList = element.getChildren(PROJECT_TAG); - for (Object project : projectsList) { - Element projectElement = (Element)project; - String projectId = projectElement.getAttributeValue(PROJECT_ID_ATTR); - String vcs = projectElement.getAttributeValue(USAGES_ATTR); - if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(vcs)) { - Set vcsDescriptors = new HashSet(); - for (String key : StringUtil.split(vcs, TOKENIZER)) { - vcsDescriptors.add(new UsageDescriptor(VcsUsagesCollector.createGroupDescriptor(), key, 1)); - } - getVcsUsageMap().put(projectId, vcsDescriptors); - } - } - } - - public Element getState() { - Element element = new Element("state"); - - for (Map.Entry> vcsUsageEntry : getVcsUsageMap().entrySet()) { - Element projectElement = new Element(PROJECT_TAG); - projectElement.setAttribute(PROJECT_ID_ATTR, vcsUsageEntry.getKey()); - projectElement.setAttribute(USAGES_ATTR, joinUsages(vcsUsageEntry.getValue())); - - element.addContent(projectElement); - } - - return element; - } - - private static String joinUsages(@NotNull Set usages) { - return StringUtil.join(usages, new Function() { - @Override - public String fun(UsageDescriptor usageDescriptor) { - return usageDescriptor.getKey(); - } - }, TOKENIZER); - } - - @NotNull - @NonNls - public File[] getExportFiles() { - return new File[]{PathManager.getOptionsFile("vcs.usages")}; - } - - @NotNull - public String getPresentableName() { - return "Vcs Usages"; - } - - @NonNls - @NotNull - public String getComponentName() { - return "VcsStatisticsPersistenceComponent"; - } - - public void initComponent() { - ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerListener() { - @Override - public void projectOpened(Project project) { - } - - @Override - public boolean canCloseProject(Project project) { - return true; - } - - @Override - public void projectClosed(Project project) { - } - - @Override - public void projectClosing(Project project) { - if (project != null) { - VcsUsagesCollector.persistProjectUsages(project); - } - } - }); - } - - public void disposeComponent() { - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java index ffbbc803b855..0c027b0f8d6e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsUsagesCollector.java @@ -15,10 +15,10 @@ */ package com.intellij.openapi.vcs.statistics; +import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; -import com.intellij.openapi.vcs.impl.VcsDescriptor; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -28,77 +28,25 @@ import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.Map; import java.util.Set; -public class VcsUsagesCollector extends UsagesCollector { - private static final String GROUP_ID = "vcs"; +public class VcsUsagesCollector extends AbstractApplicationUsagesCollector { + private static final String GROUP_ID = "vcs"; - public static void persistProjectUsages(@NotNull Project project) { - persistProjectUsages(project, getProjectUsages(project)); - } - - public static void persistProjectUsages(@NotNull Project project, @NotNull Set usages) { - persistProjectUsages(project, usages, VcsStatisticsPersistenceComponent.getInstance()); - } - - public static void persistProjectUsages(@NotNull Project project, - @NotNull Set usages, - @NotNull VcsStatisticsPersistenceComponent persistence) { - persistence.persist(project, usages); - } - - @NotNull - public static Set getApplicationUsages() { - return getApplicationUsages(VcsStatisticsPersistenceComponent.getInstance()); - } - - @NotNull - public static Set getApplicationUsages(@NotNull final VcsStatisticsPersistenceComponent persistence) { - final Map vcsUsagesMap = new HashMap(); - - for (Set descriptors : persistence.getVcsUsageMap().values()) { - for (UsageDescriptor descriptor : descriptors) { - final String key = descriptor.getKey(); - final Integer count = vcsUsagesMap.get(key); - vcsUsagesMap.put(key, count == null ? 1 : count.intValue() + 1); - } + @NotNull + public GroupDescriptor getGroupId() { + return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); } - return ContainerUtil.map2Set(vcsUsagesMap.entrySet(), new Function, UsageDescriptor>() { - @Override - public UsageDescriptor fun(Map.Entry vcsUsage) { - return new UsageDescriptor(createGroupDescriptor(), vcsUsage.getKey(), vcsUsage.getValue()); - } - }); - } - - @NotNull - public String getGroupId() { - return GROUP_ID; - } - - @NotNull - public Set getUsages(@Nullable Project project) { - if (project != null) { - persistProjectUsages(project, getProjectUsages(project)); + @NotNull + public Set getProjectUsages(@NotNull Project project) { + return ContainerUtil.map2Set(ProjectLevelVcsManager.getInstance(project).getAllActiveVcss(), new Function() { + @Override + public UsageDescriptor fun(AbstractVcs vcs) { + return new UsageDescriptor(vcs.getName(), 1); + } + }); } - - return getApplicationUsages(); - } - - public static Set getProjectUsages(@NotNull Project project) { - return ContainerUtil.map2Set(ProjectLevelVcsManager.getInstance(project).getAllActiveVcss(), new Function() { - @Override - public UsageDescriptor fun(AbstractVcs vcs) { - return new UsageDescriptor(createGroupDescriptor(), vcs.getName(), 1); - } - }); - } - - public static GroupDescriptor createGroupDescriptor() { - return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); - } } From 63a059b8b53b6c604ab3ff1538b9f8675f677887 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 16 Feb 2011 17:08:14 +0100 Subject: [PATCH 16/28] IDEA-65290 (Add configuration option to inspection "Serializable class without 'readObject()' and 'writeObject()'" to ignore anonymous inner classes.) IDEA-65287 (Add configuration option to inspection "Serializable class without 'serialVersionUID' to ignore anonymous inner classes.) --- .../siyeh/InspectionGadgetsBundle.properties | 6 +- ...bleFieldInSerializableClassInspection.java | 13 +++- .../siyeh/ig/serialization/Serializable.form | 47 ------------- ...bleHasSerialVersionUIDFieldInspection.java | 8 ++- ...ableHasSerializationMethodsInspection.java | 8 +++ ...rClassHasSerialVersionUIDFieldVisitor.java | 12 +++- ...sWithNonSerializableOuterClassVisitor.java | 9 ++- .../serialization/SerializableInspection.java | 69 ++++++++++++------- 8 files changed, 90 insertions(+), 82 deletions(-) delete mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/serialization/Serializable.form diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index 5734a1f02ef7..0a9522cf8c9c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -268,7 +268,7 @@ instance.variable.may.not.be.initialized.display.name=Instance field may not be instance.variable.may.not.be.initialized.problem.descriptor=Instance field #ref may not be initialized during object construction #loc instance.Variable.may.not.be.initialized.problem.descriptor.junit=Instance field #ref may not be initialized during object construction or 'setUp()' call #loc primitive.fields.ignore.option=Ignore primitive fields -instance.variable.used.before.initialized.display.name=Instance field used before initialized +instance.variable.used.before.initialized.display.name=Instance field used before initialization instance.variable.used.before.initialized.problem.descriptor=Instance field #ref used before initialized #loc non.final.static.variable.initialization.display.name=Non-final static field is used during class initialization non.final.static.variable.initialization.problem.descriptor=Non-final static field #ref used during class initialization #loc @@ -1841,4 +1841,6 @@ package.dot.html.may.be.package.info.problem.descriptor=package.html -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerialVersionUIDFieldInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerialVersionUIDFieldInspection.java index 2bec2c00829f..0d1a8ebd457a 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerialVersionUIDFieldInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerialVersionUIDFieldInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,11 +22,13 @@ import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.AddSerialVersionUIDFix; import com.siyeh.ig.psiutils.SerializationUtils; +import org.intellij.lang.annotations.Pattern; import org.jetbrains.annotations.NotNull; public class SerializableHasSerialVersionUIDFieldInspection extends SerializableInspection { + @Pattern("[a-zA-Z_0-9.-]+") @Override @NotNull public String getID() { @@ -70,6 +72,10 @@ public class SerializableHasSerialVersionUIDFieldInspection aClass instanceof PsiEnumConstantInitializer) { return; } + if (ignoreAnonymousInnerClasses && + aClass instanceof PsiAnonymousClass) { + return; + } final PsiField serialVersionUIDField = aClass.findFieldByName( HardcodedMethodConstants.SERIAL_VERSION_UID, false); if (serialVersionUIDField != null) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerializationMethodsInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerializationMethodsInspection.java index fd39f8b830ba..fa3ed0d17fc9 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerializationMethodsInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerializationMethodsInspection.java @@ -15,6 +15,7 @@ */ package com.siyeh.ig.serialization; +import com.intellij.psi.PsiAnonymousClass; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiEnumConstantInitializer; import com.intellij.psi.PsiTypeParameter; @@ -26,12 +27,14 @@ import org.jetbrains.annotations.NotNull; public class SerializableHasSerializationMethodsInspection extends SerializableInspection { + @Override @NotNull public String getDisplayName() { return InspectionGadgetsBundle.message( "serializable.has.serialization.methods.display.name"); } + @Override @NotNull public String buildErrorString(Object... infos) { final boolean hasReadObject = ((Boolean)infos[0]).booleanValue(); @@ -48,6 +51,7 @@ public class SerializableHasSerializationMethodsInspection } } + @Override public BaseInspectionVisitor buildVisitor() { return new SerializableHasSerializationMethodsVisitor(); } @@ -65,6 +69,10 @@ public class SerializableHasSerializationMethodsInspection aClass instanceof PsiEnumConstantInitializer) { return; } + if (ignoreAnonymousInnerClasses && + aClass instanceof PsiAnonymousClass) { + return; + } if (!SerializationUtils.isSerializable(aClass)) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldVisitor.java index d1e758bafc86..a7d26d7aa874 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.siyeh.ig.serialization; +import com.intellij.psi.PsiAnonymousClass; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiModifier; @@ -28,7 +29,8 @@ class SerializableInnerClassHasSerialVersionUIDFieldVisitor private final SerializableInspection inspection; - public SerializableInnerClassHasSerialVersionUIDFieldVisitor(SerializableInspection inspection) { + public SerializableInnerClassHasSerialVersionUIDFieldVisitor( + SerializableInspection inspection) { this.inspection = inspection; } @@ -38,6 +40,10 @@ class SerializableInnerClassHasSerialVersionUIDFieldVisitor aClass.isEnum()) { return; } + if (inspection.ignoreAnonymousInnerClasses && + aClass instanceof PsiAnonymousClass) { + return; + } if (hasSerialVersionUIDField(aClass)) { return; } @@ -57,7 +63,7 @@ class SerializableInnerClassHasSerialVersionUIDFieldVisitor registerClassError(aClass); } - private boolean hasSerialVersionUIDField(PsiClass aClass) { + private static boolean hasSerialVersionUIDField(PsiClass aClass) { final PsiField[] fields = aClass.getFields(); boolean hasSerialVersionUID = false; for (PsiField field : fields) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassVisitor.java index c404b45afb58..b9accba4ab2e 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassVisitor.java @@ -15,6 +15,7 @@ */ package com.siyeh.ig.serialization; +import com.intellij.psi.PsiAnonymousClass; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiModifier; import com.siyeh.ig.BaseInspectionVisitor; @@ -24,10 +25,10 @@ import org.jetbrains.annotations.NotNull; class SerializableInnerClassWithNonSerializableOuterClassVisitor extends BaseInspectionVisitor { - private final SerializableInnerClassWithNonSerializableOuterClassInspection inspection; + private final SerializableInspection inspection; public SerializableInnerClassWithNonSerializableOuterClassVisitor( - SerializableInnerClassWithNonSerializableOuterClassInspection inspection) { + SerializableInspection inspection) { this.inspection = inspection; } @@ -36,6 +37,10 @@ class SerializableInnerClassWithNonSerializableOuterClassVisitor aClass.isEnum()) { return; } + if (inspection.ignoreAnonymousInnerClasses && + aClass instanceof PsiAnonymousClass) { + return; + } final PsiClass containingClass = aClass.getContainingClass(); if (containingClass == null) { return; diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInspection.java index dfecdac65843..cea1a5826af0 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableInspection.java @@ -19,22 +19,29 @@ import com.intellij.codeInspection.ui.AddAction; import com.intellij.codeInspection.ui.ListTable; import com.intellij.codeInspection.ui.ListWrappingTableModel; import com.intellij.codeInspection.ui.RemoveAction; +import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.PsiClass; import com.intellij.psi.util.InheritanceUtil; +import com.intellij.ui.ScrollPaneFactory; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.psiutils.SerializationUtils; +import com.siyeh.ig.ui.CheckBox; +import com.siyeh.ig.ui.UiUtils; import org.jdom.Element; import javax.swing.*; +import java.awt.*; import java.util.ArrayList; import java.util.List; public abstract class SerializableInspection extends BaseInspection { - /** @noinspection PublicField */ + @SuppressWarnings({"PublicField"}) + public boolean ignoreAnonymousInnerClasses = false; + @SuppressWarnings({"PublicField"}) public String superClassString = "java.awt.Component"; protected List superClassList = new ArrayList(); @@ -44,8 +51,41 @@ public abstract class SerializableInspection extends BaseInspection { @Override public JComponent createOptionsPanel() { - final Form form = new Form(); - return form.getContentPanel(); + final JComponent panel = new JPanel(new GridBagLayout()); + + final ListTable table = new ListTable(new ListWrappingTableModel( + superClassList, InspectionGadgetsBundle.message( + "ignore.classes.in.hierarchy.column.name"))); + final JScrollPane scrollPane = + ScrollPaneFactory.createScrollPane(table); + final ActionToolbar toolbar = + UiUtils.createAddRemoveTreeAnnotationChooserToolbar(table, + InspectionGadgetsBundle.message( + "choose.super.class.to.ignore")); + final CheckBox checkBox = new CheckBox(InspectionGadgetsBundle.message( + "ignore.anonymous.inner.classes"), this, + "ignoreAnonymousInnerClasses"); + + final GridBagConstraints constraints = new GridBagConstraints(); + constraints.gridx = 0; + constraints.gridy = 0; + constraints.insets.left = 4; + constraints.insets.right = 4; + constraints.fill = GridBagConstraints.HORIZONTAL; + panel.add(toolbar.getComponent(), constraints); + + constraints.gridy = 1; + constraints.weightx = 1.0; + constraints.weighty = 1.0; + constraints.fill = GridBagConstraints.BOTH; + panel.add(scrollPane, constraints); + + constraints.gridy = 2; + constraints.weighty = 0.0; + constraints.fill = GridBagConstraints.HORIZONTAL; + panel.add(checkBox, constraints); + + return panel; } @Override @@ -71,27 +111,4 @@ public abstract class SerializableInspection extends BaseInspection { } return false; } - - private class Form { - - private JPanel contentPanel; - private ListTable table; - private JButton addButton; - private JButton removeButton; - - Form() { - addButton.setAction(new AddAction(table)); - removeButton.setAction(new RemoveAction(table)); - } - - private void createUIComponents() { - table = new ListTable(new ListWrappingTableModel(superClassList, - InspectionGadgetsBundle.message( - "ignore.classes.in.hierarchy.column.name"))); - } - - public JPanel getContentPanel() { - return contentPanel; - } - } } \ No newline at end of file From d3a08b9513255906dca7d795d948125feb84ecb1 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Wed, 16 Feb 2011 19:50:31 +0300 Subject: [PATCH 17/28] heavyweight editor hints look fix --- .../com/intellij/codeInsight/lookup/impl/LookupImpl.java | 2 -- .../src/com/intellij/codeInsight/hint/HintManagerImpl.java | 2 +- .../platform-impl/src/com/intellij/ui/LightweightHint.java | 6 +++--- platform/platform-resources-en/src/misc/registry.properties | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 68e544cc82f8..9e8ae7915aec 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1158,8 +1158,6 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { panel.remove(0); panel.add(hintComponent); } - //todo[kirillk] comment the following line - HintManagerImpl.adjustEditorHintPosition(myAutopopupHint, editor, bestPoint); } } diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java index e8abfbfcd70b..c9291dc10394 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java @@ -369,7 +369,7 @@ public class HintManagerImpl extends HintManager implements Disposable { p = rectangle.getLocation(); SwingUtilities.convertPointFromScreen(p, layeredPane); } - else if ((layeredPane.getWidth() < p.x + size.width) && !hintInfo.isAwtTooltip()) { + else if ((layeredPane.getWidth() < p.x + size.width) && !hintInfo.isAwtTooltip() && !hint.isRealPopup()) { p.x = Math.max(0, layeredPane.getWidth() - size.width); } diff --git a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java index 8743c13f8324..a95522649c04 100644 --- a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java +++ b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java @@ -185,11 +185,11 @@ public class LightweightHint extends UserDataHolderBase implements Hint { .setMovable(myTitle != null) .setTitle(myTitle) .setModalContext(false) - .setShowShadow(!myForceLightweightPopup && myForceShowAsPopup) + .setShowShadow(isRealPopup()) .setCancelKeyEnabled(false) .setCancelOnClickOutside(myCancelOnClickOutside) .setCancelOnOtherWindowOpen(myCancelOnOtherWindowOpen) - .setForceHeavyweight(!myForceLightweightPopup && myForceShowAsPopup) + .setForceHeavyweight(!myForceLightweightPopup && isRealPopup()) .createPopup(); beforeShow(); @@ -241,7 +241,7 @@ public class LightweightHint extends UserDataHolderBase implements Hint { } public final boolean isRealPopup() { - return myIsRealPopup; + return myIsRealPopup | myForceShowAsPopup; } public void hide() { diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 7e58a12cb257..314156f91f45 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -35,7 +35,7 @@ ide.debugMode=false ide.debugMode.description=Record additonal information to make bug reports more informative ide.forcedShowTooltip=alt ide.forcedShowTooltip.description=Shortcut for forced show tooltip -ide.popup.dropShadow=false +ide.popup.dropShadow=true ide.consumeKnownToolkitBugs=true ide.appIcon.progress=true From fd3f92202fef5e5782e0288a1662dc7af910d381 Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 16 Feb 2011 20:02:35 +0300 Subject: [PATCH 18/28] IDEA-53590 Moving ignored files automatically marks them for add --- .../intellij/openapi/vcs/VcsVFSListener.java | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java index 09ae9dde27a2..29de04c41f31 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.actions.VcsContextFactory; import com.intellij.openapi.vcs.changes.ChangeListManager; +import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.vcsUtil.VcsUtil; @@ -37,6 +38,8 @@ import java.util.*; * @author yole */ public abstract class VcsVFSListener implements Disposable { + private VcsDirtyScopeManager myDirtyScopeManager; + protected static class MovedFileInfo { public final String myOldPath; public String myNewPath; @@ -59,6 +62,7 @@ public abstract class VcsVFSListener implements Disposable { protected final List myDeletedFiles = new ArrayList(); protected final List myDeletedWithoutConfirmFiles = new ArrayList(); protected final List myMovedFiles = new ArrayList(); + protected final List myDirtyFiles = new ArrayList(); protected enum VcsDeleteType {SILENT, CONFIRM, IGNORE} @@ -66,6 +70,7 @@ public abstract class VcsVFSListener implements Disposable { myProject = project; myVcs = vcs; myChangeListManager = ChangeListManager.getInstance(project); + myDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); final MyVirtualFileAdapter myVFSListener = new MyVirtualFileAdapter(); final MyCommandAdapter myCommandListener = new MyCommandAdapter(); @@ -200,7 +205,14 @@ public abstract class VcsVFSListener implements Disposable { protected void processMovedFile(VirtualFile file, String newParentPath, String newName) { - if (FileStatusManager.getInstance(myProject).getStatus(file) != FileStatus.UNKNOWN) { + final FileStatus status = FileStatusManager.getInstance(myProject).getStatus(file); + if (status == FileStatus.IGNORED) { + if (file.getParent() != null) { + myDirtyFiles.add(file.getParent()); + myDirtyFiles.add(file); // will be at new path + } + } + if (status != FileStatus.UNKNOWN && status != FileStatus.IGNORED) { final String newPath = newParentPath + "/" + newName; boolean foundExistingInfo = false; for (MovedFileInfo info : myMovedFiles) { @@ -359,7 +371,8 @@ public abstract class VcsVFSListener implements Disposable { if (myProject != event.getProject()) return; myCommandLevel--; if (myCommandLevel == 0) { - if (!myAddedFiles.isEmpty() || !myDeletedFiles.isEmpty() || !myDeletedWithoutConfirmFiles.isEmpty() || !myMovedFiles.isEmpty()) { + if (!myAddedFiles.isEmpty() || !myDeletedFiles.isEmpty() || !myDeletedWithoutConfirmFiles.isEmpty() || !myMovedFiles.isEmpty() || + ! myDirtyFiles.isEmpty()) { // avoid reentering commandFinished handler - saving the documents may cause a "before file deletion" event firing, // which will cause closing the text editor, which will itself run a command that will be caught by this listener myCommandLevel++; @@ -379,6 +392,20 @@ public abstract class VcsVFSListener implements Disposable { if (!myMovedFiles.isEmpty()) { executeMoveRename(); } + if (! myDirtyFiles.isEmpty()) { + final List files = new ArrayList(); + final List dirs = new ArrayList(); + for (VirtualFile dirtyFile : myDirtyFiles) { + if (dirtyFile != null) { + if (dirtyFile.isDirectory()) { + dirs.add(dirtyFile); + } else { + files.add(dirtyFile); + } + } + } + myDirtyScopeManager.filesDirty(files, dirs); + } } } } From 7414445e899bd5fbbddeb025104b194a65f857ab Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 17:19:17 +0100 Subject: [PATCH 19/28] completion stats should care of class qualified names (IDEA-65112) --- .../completion/JavaCompletionStatistician.java | 6 ++++-- .../completion/normalSorting/FqnStats.java | 4 ++++ .../completion/NormalCompletionOrderingTest.java | 13 +++++++++++++ .../fixtures/JavaCodeInsightTestFixture.java | 2 +- .../impl/JavaCodeInsightTestFixtureImpl.java | 4 +--- 5 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normalSorting/FqnStats.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java index d782d4137cbc..d05c520a1a67 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java @@ -23,13 +23,11 @@ import com.intellij.psi.*; import com.intellij.psi.statistics.JavaStatisticsManager; import com.intellij.psi.statistics.StatisticsInfo; import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NonNls; /** * @author peter */ public class JavaCompletionStatistician extends CompletionStatistician{ - @NonNls public static final String CLASS_NAME_COMPLETION_PREFIX = "classNameCompletion#"; public StatisticsInfo serialize(final LookupElement element, final CompletionLocation location) { final Object o = element.getObject(); @@ -76,6 +74,10 @@ public class JavaCompletionStatistician extends CompletionStatistician{ if (!isClass && type == CompletionType.BASIC) return JavaStatisticsManager.createInfo(qualifierType, (PsiMember)o); return StatisticsInfo.EMPTY; } + + if (isClass) { + return JavaStatisticsManager.createInfo(qualifierType, (PsiMember)o); + } } if (qualifierType != null) return StatisticsInfo.EMPTY; diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/FqnStats.java b/java/java-tests/testData/codeInsight/completion/normalSorting/FqnStats.java new file mode 100644 index 000000000000..9ba38412a11f --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/FqnStats.java @@ -0,0 +1,4 @@ +class Foo { + Baaax + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java index 8144fd1e8772..c2337c2f945d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java @@ -182,4 +182,17 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { checkPreferredItems(0, "XcodeProjectTemplate", "XcodeConfigurable"); } + public void testFqnStats() { + myFixture.addClass("public interface Baaaaaaar {}"); + myFixture.addClass("package zoo; public interface Baaaaaaar {}"); + + final LookupImpl lookup = invokeCompletion(getTestName(false) + ".java"); + assertEquals("Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(0)).getQualifiedName()); + assertEquals("zoo.Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(1)).getQualifiedName()); + incUseCount(lookup, 1); + + assertEquals("zoo.Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(0)).getQualifiedName()); + assertEquals("Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(1)).getQualifiedName()); + } + } \ No newline at end of file diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java index f7a308580bac..d168a632b97c 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java @@ -29,7 +29,7 @@ import java.io.IOException; public interface JavaCodeInsightTestFixture extends CodeInsightTestFixture { JavaPsiFacade getJavaFacade(); - PsiClass addClass(@NotNull @NonNls final String classText) throws IOException; + PsiClass addClass(@NotNull @NonNls final String classText); @NotNull PsiClass findClass(@NotNull @NonNls String name); diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java index c14dff95cc19..d6ae873272de 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java @@ -27,8 +27,6 @@ import com.intellij.testFramework.fixtures.TempDirTestFixture; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import java.io.IOException; - /** * @author yole */ @@ -44,7 +42,7 @@ public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl i } @Override - public PsiClass addClass(@NotNull @NonNls final String classText) throws IOException { + public PsiClass addClass(@NotNull @NonNls final String classText) { assertInitialized(); final PsiClass psiClass = addClass(getTempDirPath(), classText); final VirtualFile file = psiClass.getContainingFile().getVirtualFile(); From d43faca81d1fe2a88321114404367987ac1b80c6 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 17:37:30 +0100 Subject: [PATCH 20/28] IDEA-65252 Static nested classes are first proposal on values --- ...ocalVariablesLiteralsAndAnnoMethodsWeigher.java | 5 +++++ .../normalSorting/DispreferInnerClasses.java | 14 ++++++++++++++ .../completion/NormalCompletionOrderingTest.java | 8 +++++++- .../codeInsight/lookup/ComparingClassifier.java | 3 ++- 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normalSorting/DispreferInnerClasses.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java index 4d9450ad5f64..c8a837d1177a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java @@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull; public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends CompletionWeigher { enum MyResult { + className, classLiteral, normal, superMethodParameters, @@ -54,6 +55,10 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends Completio if (object instanceof PsiAnnotationMethod && ((PsiAnnotationMethod)object).getContainingClass().isAnnotationType()) { return MyResult.annoMethod; } + + if (object instanceof PsiClass) { + return MyResult.className; + } } return MyResult.normal; diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/DispreferInnerClasses.java b/java/java-tests/testData/codeInsight/completion/normalSorting/DispreferInnerClasses.java new file mode 100644 index 000000000000..db2e1d04d69a --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/DispreferInnerClasses.java @@ -0,0 +1,14 @@ +abstract class Base { + public static @interface IfNotParsed {} + + static class X {} +} + +class Derived extends Base { + +} +class B { + void foo(Derived b) { + b. + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java index c2337c2f945d..e3b88bd2b5e5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java @@ -8,6 +8,7 @@ import com.intellij.JavaTestUtil; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.impl.LookupImpl; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import java.util.List; @@ -192,7 +193,12 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { incUseCount(lookup, 1); assertEquals("zoo.Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(0)).getQualifiedName()); - assertEquals("Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(1)).getQualifiedName()); + assertEquals("Baaaaaaar", ((JavaPsiClassReferenceElement)lookup.getItems().get(1)).getQualifiedName()); + } + + public void testDispreferInnerClasses() { + checkPreferredItems(0); //no chosen items + assertFalse(getLookup().getItems().get(0).getObject() instanceof PsiClass); } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java index a4f49b76467a..42e363939a57 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.lookup; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -71,7 +72,7 @@ public abstract class ComparingClassifier extends Classifier { @Override public void describeItems(LinkedHashMap map) { final TreeMap> treeMap = groupByWeights(new ArrayList(map.keySet())); - if (treeMap.size() > 1) { + if (treeMap.size() > 1 || ApplicationManager.getApplication().isUnitTestMode()) { for (Map.Entry> entry: treeMap.entrySet()){ for (T t : entry.getValue()) { final StringBuilder builder = map.get(t); From 05516baf2a771d50ed37dd004a501a7c754246fa Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 18:11:50 +0100 Subject: [PATCH 21/28] those shadows look horrible on linux, revert --- .../platform-impl/src/com/intellij/ui/LightweightHint.java | 6 ++---- platform/platform-resources-en/src/misc/registry.properties | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java index a95522649c04..ee8865ba3a0e 100644 --- a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java +++ b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java @@ -20,13 +20,11 @@ import com.intellij.ide.IdeTooltip; import com.intellij.ide.IdeTooltipManager; import com.intellij.ide.TooltipEvent; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt; import com.intellij.ui.awt.RelativePoint; -import com.intellij.ui.popup.AbstractPopup; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -185,11 +183,11 @@ public class LightweightHint extends UserDataHolderBase implements Hint { .setMovable(myTitle != null) .setTitle(myTitle) .setModalContext(false) - .setShowShadow(isRealPopup()) + .setShowShadow(!myForceLightweightPopup && myForceShowAsPopup) .setCancelKeyEnabled(false) .setCancelOnClickOutside(myCancelOnClickOutside) .setCancelOnOtherWindowOpen(myCancelOnOtherWindowOpen) - .setForceHeavyweight(!myForceLightweightPopup && isRealPopup()) + .setForceHeavyweight(!myForceLightweightPopup && myForceShowAsPopup) .createPopup(); beforeShow(); diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 314156f91f45..7e58a12cb257 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -35,7 +35,7 @@ ide.debugMode=false ide.debugMode.description=Record additonal information to make bug reports more informative ide.forcedShowTooltip=alt ide.forcedShowTooltip.description=Shortcut for forced show tooltip -ide.popup.dropShadow=true +ide.popup.dropShadow=false ide.consumeKnownToolkitBugs=true ide.appIcon.progress=true From 47be5ffb301789b8d9c256e90a3b13384318f540 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 18:12:20 +0100 Subject: [PATCH 22/28] shadows in hint autopopup, update the size correctly --- .../src/com/intellij/codeInsight/lookup/impl/LookupImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 9e8ae7915aec..f3d7b0b46e91 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1150,13 +1150,13 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { panel.add(hintComponent); myAutopopupHint = new LightweightHint(panel); myAutopopupHint.setForceShowAsPopup(true); - myAutopopupHint.setForceLightweightPopup(true); hintManager.showEditorHint(myAutopopupHint, editor, new Point(bestPoint), HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false, hintHint); } else { final JComponent panel = myAutopopupHint.getComponent(); panel.remove(0); panel.add(hintComponent); + HintManagerImpl.adjustEditorHintPosition(myAutopopupHint, editor, bestPoint); } } } From c35483cfef4dc0cb0db95b98073344a280978161 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 18:28:14 +0100 Subject: [PATCH 23/28] shorter list --- .../com/intellij/codeInsight/lookup/impl/LookupImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index f3d7b0b46e91..5d2853265639 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1131,7 +1131,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } else if (myHintMode) { final int itemTextPadding = 2; - final int borderWidth = 1; + final int borderWidth = 0; final JPanel hintComponent = createAutopopupHintComponent(itemTextPadding, borderWidth); Point bestPoint = calculatePosition(hintComponent); @@ -1162,7 +1162,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } private JPanel createAutopopupHintComponent(int itemTextPadding, int borderWidth) { - int maxAutopopupItems = 10; + int maxAutopopupItems = 7; JPanel pane = new JPanel(new GridBagLayout()); pane.setBackground(HintUtil.INFORMATION_COLOR); @@ -1221,7 +1221,9 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { KeymapUtil .getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION)) + " for more suggestions)"; - pane.add(new JLabel(moreText), c); + final JLabel label = new JLabel(moreText); + label.setFont(label.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); + pane.add(label, c); } } From deec377e9668310838a61b5485e1e5a6294eb8a2 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 18:31:24 +0100 Subject: [PATCH 24/28] use registry --- .../completion/CompletionProgressIndicator.java | 10 +++++++--- .../platform-resources-en/src/misc/registry.properties | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index a6bb506cbe7b..5fcd8bf67dc6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -38,6 +38,7 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.ElementPattern; import com.intellij.psi.PsiFile; @@ -102,7 +103,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } }; private final Semaphore myDuringCompletionSemaphore = new Semaphore(); - private static final boolean ourHintAutopopup = "true".equals(System.getProperty("hint.autopopup", "false")); private volatile int myCount; @@ -336,7 +336,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } - if (isAutopopupCompletion() && ourHintAutopopup) { + if (isAutopopupCompletion() && showHintAutopopup()) { myLookup.setHintMode(true); } else { @@ -348,6 +348,10 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement updateFocus(); } + private static boolean showHintAutopopup() { + return "true".equals(Registry.stringValue("hint.autopopup")); + } + final boolean isInsideIdentifier() { return getIdentifierEndOffset() != getSelectionEndOffset(); } @@ -466,7 +470,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement if (isAutopopupCompletion() && !myLookup.isSelectionTouched() && !myLookup.isCalculating()) { myLookup.refreshUi(); final List items = myLookup.getItems(); - if (!items.isEmpty() && ourHintAutopopup) { + if (!items.isEmpty() && showHintAutopopup()) { return false; } diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 7e58a12cb257..e7786120e6e3 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -116,4 +116,6 @@ vcs.show.history.numbers=true navbar.updateMergeTime=250 navbar.userActivityMergeTime=500 -inspectionGadgets.telemetry.enabled=false \ No newline at end of file +inspectionGadgets.telemetry.enabled=false + +hint.autopopup=false \ No newline at end of file From cdc9a9a5f0c892ff9cfda52cd0af898357a289a0 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Wed, 16 Feb 2011 20:35:01 +0300 Subject: [PATCH 25/28] IDEA-65144 New library created from downloaded jars is not visible --- .../org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java index a0e12bcf9500..b11a8c027973 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java @@ -157,7 +157,7 @@ public class RepositoryAttachHandler implements LibraryTableAttachHandler { FileUtil.copy(repoFile, toFile); } } - String url = VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(toFile.getPath())); + final String url = VfsUtil.getUrlForLibraryRoot(toFile); manager.refreshAndFindFileByUrl(url); if (MavenExtraArtifactType.DOCS.getDefaultClassifier().equals(each.getClassifier())) { libraryEditor.addRoot(url, JavadocOrderRootType.getInstance()); From 28d7b61b7789097d442f3074d67d6b1d20efff37 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 16 Feb 2011 18:50:14 +0100 Subject: [PATCH 26/28] more compiler logs --- .../javaCompiler/CompilerParsingThread.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java index e440d1d8666f..6dabf6c78cdc 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java @@ -144,6 +144,9 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { processCompiledClass(previousPath); } catch (CacheCorruptedException e) { + if (CompileDriver.ourDebugMode) { + e.printStackTrace(); + } myError = e; LOG.info(e); killProcess(); @@ -177,6 +180,9 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { buffer = StringBuilderSpinAllocator.alloc(); } catch (SpinAllocator.AllocatorExhaustedException e) { + if (CompileDriver.ourDebugMode) { + e.printStackTrace(); + } LOG.info(e); buffer = new StringBuilder(); releaseBuffer = false; @@ -220,6 +226,16 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { try { while(!reader.ready()) { if (isProcessTerminated()) { + if (CompileDriver.ourDebugMode) { + String text; + try { + text = reader.ready()? "ready" : "not ready"; + } + catch (IOException e) { + text = "Exception " + e.getMessage(); + } + System.out.println("COMPILER PARSING THREAD: reader not ready before isTerminatedCheck(), after the check: isReady= " + text); + } return -1; } try { @@ -231,7 +247,7 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { return reader.read(); } catch (IOException e) { - return -1; // When process terminated Process.getInputStream()'s underlaying stream becomes closed on Linux. + return -1; // When process terminated Process.getInputStream()'s underlying stream becomes closed on Linux. } } From a7ee426a7f2fe41d4a52f291d2ed6402d1922622 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 16 Feb 2011 21:26:45 +0300 Subject: [PATCH 27/28] Focus Tracer --- .../internal/focus/FocusTracesAction.java | 67 +++++++++++ .../internal/focus/FocusTracesDialog.form | 54 +++++++++ .../internal/focus/FocusTracesDialog.java | 105 ++++++++++++++++++ .../openapi/wm/impl/FocusManagerImpl.java | 17 +++ .../openapi/wm/impl/FocusRequestInfo.java | 56 ++++++++++ .../src/idea/PlatformActions.xml | 4 + 6 files changed, 303 insertions(+) create mode 100644 platform/platform-impl/src/com/intellij/internal/focus/FocusTracesAction.java create mode 100644 platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.form create mode 100644 platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java create mode 100644 platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java diff --git a/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesAction.java b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesAction.java new file mode 100644 index 000000000000..e90aa6a7b251 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesAction.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.focus; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.impl.FocusManagerImpl; +import com.intellij.openapi.wm.impl.FocusRequestInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +public class FocusTracesAction extends AnAction implements DumbAware { + private static boolean myActive = false; + + public static boolean isActive() { + return myActive; + } + + @Override + public void actionPerformed(AnActionEvent e) { + final Project project = e.getData(PlatformDataKeys.PROJECT); + final IdeFocusManager manager = IdeFocusManager.getGlobalInstance(); + if (! (manager instanceof FocusManagerImpl)) return; + final FocusManagerImpl focusManager = (FocusManagerImpl)manager; + + myActive = !myActive; + + if (!myActive) { + final List requests = focusManager.getRequests(); + new FocusTracesDialog(project, new ArrayList(requests)).show(); + requests.clear(); + } + } + + @Override + public void update(AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + if (myActive) { + presentation.setText("Stop Focus Tracing"); + } else { + presentation.setText("Start Focus Tracing"); + } + presentation.setEnabled(e.getData(PlatformDataKeys.PROJECT) != null); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.form b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.form new file mode 100644 index 000000000000..9dc1d1074339 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.form @@ -0,0 +1,54 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java new file mode 100644 index 000000000000..5699b2a290cf --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java @@ -0,0 +1,105 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.internal.focus; + +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.wm.impl.FocusRequestInfo; +import com.intellij.ui.table.JBTable; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumnModel; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +public class FocusTracesDialog extends DialogWrapper { + private JTextPane myStacktrace; + private JBTable myRequestsTable; + private JPanel myRootPanel; + private final List myRequests; + private static final String[] COLUMNS = {"Time", "Forced", "Component"}; + + public FocusTracesDialog(Project project, ArrayList requests) { + super(project); + myRequests = requests; + setTitle("Focus Traces"); + init(); + final String[][] data = new String[requests.size()][]; + for (int i = 0; i < data.length; i++) { + final FocusRequestInfo r = requests.get(i); + data[i] = new String[]{r.getDate(), String.valueOf(r.isForced()), r.getComponent()}; + } + myRequestsTable.setModel(new DefaultTableModel(data, COLUMNS)); + final ListSelectionListener selectionListener = new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + final int index = myRequestsTable.getSelectedRow(); + if (-1 < index && index < myRequests.size()) { + myStacktrace.setText(myRequests.get(index).getStackTrace()); + } + else { + myStacktrace.setText(""); + } + } + }; + myRequestsTable.getSelectionModel().addListSelectionListener(selectionListener); + final TableColumnModel columnModel = myRequestsTable.getColumnModel(); + columnModel.getColumn(0).setMaxWidth(120); + columnModel.getColumn(1).setMaxWidth(60); + columnModel.getSelectionModel().addListSelectionListener(selectionListener); + columnModel.setColumnSelectionAllowed(false); + myRequestsTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myRequestsTable.changeSelection(0, 0, false, true); + } + + @Override + protected String getDimensionServiceKey() { + return "ide.internal.focus.trace.dialog"; + } + + @Override + protected JComponent createCenterPanel() { + return myRootPanel; + } + + @Override + public JComponent getPreferredFocusedComponent() { + return myRequestsTable; + } + + @Override + protected Action[] createActions() { + return new Action[] {getOKAction(), getCopyStackTraceAction()}; + } + + private Action getCopyStackTraceAction() { + return new AbstractAction("&Copy stacktrace") { + @Override + public void actionPerformed(ActionEvent e) { + CopyPasteManager.getInstance().setContents(new StringSelection(myStacktrace.getText())); + } + }; + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index c685df5286fc..8ea3b8bdbf78 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -16,12 +16,14 @@ package com.intellij.openapi.wm.impl; import com.intellij.ide.IdeEventQueue; +import com.intellij.internal.focus.FocusTracesAction; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationAdapter; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.EdtRunnable; @@ -60,6 +62,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { private FocusCommand myFocusCommandOnAppActivation; private ActionCallback myCallbackOnActivation; + private final boolean isInternalMode = ApplicationManagerEx.getApplicationEx().isInternal(); + private List myRequests = new ArrayList(); private final IdeEventQueue myQueue; private final KeyProcessorConext myKeyProcessorContext = new KeyProcessorConext(); @@ -156,6 +160,9 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { @NotNull public ActionCallback requestFocus(@NotNull final FocusCommand command, final boolean forced) { + if (isInternalMode) { + recordCommand(command, new Throwable(), forced); + } final ActionCallback result = new ActionCallback(); if (!forced) { @@ -183,6 +190,16 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { return result; } + public List getRequests() { + return myRequests; + } + + private void recordCommand(FocusCommand command, Throwable trace, boolean forced) { + if (FocusTracesAction.isActive()) { + myRequests.add(new FocusRequestInfo(command.getDominationComponent(), trace, forced)); + } + } + private void _requestFocus(final FocusCommand command, final boolean forced, final ActionCallback result) { if (checkForRejectOrByPass(command, forced, result)) return; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java new file mode 100644 index 000000000000..387b3ca4bd26 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.wm.impl; + +import com.intellij.util.ExceptionUtil; + +import java.awt.*; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author Konstantin Bulenkov + */ +public final class FocusRequestInfo { + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS"); + private final String when; + private final Throwable trace; + private final String component; + private final boolean forced; + + public FocusRequestInfo(Component component, Throwable trace, boolean forced) { + this.forced = forced; + this.component = component == null ? "null" : component.toString(); + this.trace = trace; + when = DATE_FORMAT.format(new Date()); + } + + public String getStackTrace() { + return ExceptionUtil.getThrowableText(trace); + } + + public String getComponent() { + return component; + } + + public boolean isForced() { + return forced; + } + + public String getDate() { + return when; + } +} diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 0edd287cb336..f448f143b688 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -441,6 +441,10 @@ + + + + From a304cbf6f471d36dc20764ae617bc9cb619ccb6b Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 16 Feb 2011 21:24:25 +0300 Subject: [PATCH 28/28] git log null byte problem again %x00 Changed %x00 to %x04. made parseTimestamp catch NumberFormatException and log it, but return current Date() instead of failing. --- plugins/git4idea/src/git4idea/GitUtil.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java index 45b6bddfb3c1..54e17021f122 100644 --- a/plugins/git4idea/src/git4idea/GitUtil.java +++ b/plugins/git4idea/src/git4idea/GitUtil.java @@ -312,7 +312,14 @@ public class GitUtil { * @return timestamp as {@link Date} object */ public static Date parseTimestamp(String value) { - return new Date(Long.parseLong(value.trim()) * 1000); + final long parsed; + try { + parsed = Long.parseLong(value.trim()); + return new Date(parsed * 1000); + } catch (NumberFormatException e) { + LOG.error("Error parsing timestamp from " + value, e); + return new Date(); + } } /** @@ -743,7 +750,7 @@ public class GitUtil { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG); h.setSilent(true); h.setNoSSH(true); - h.addParameters("--pretty=format:%x00%x01" + GitChangeUtils.COMMITTED_CHANGELIST_FORMAT, "--name-status"); + h.addParameters("--pretty=format:%x04%x01" + GitChangeUtils.COMMITTED_CHANGELIST_FORMAT, "--name-status"); parametersSpecifier.consume(h); String output = h.run(); @@ -753,7 +760,7 @@ public class GitUtil { boolean firstStep = true; while (s.hasMoreData()) { final String line = s.line(); - final boolean lineIsAStart = line.startsWith("\u0000\u0001"); + final boolean lineIsAStart = line.startsWith("\u0004\u0001"); if ((!firstStep) && lineIsAStart) { final StringScanner innerScanner = new StringScanner(sb.toString()); sb.setLength(0);