From cdc0ba9ce0e98f876e57e92858837ced984880c6 Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 7 Feb 2011 10:30:28 +0300 Subject: [PATCH 01/10] compiler-api.jar removed because it is included into jdk6 --- java/compiler/impl/compiler-impl.iml | 9 --------- lib/dev/compilerapi.jar | Bin 72275 -> 0 bytes 2 files changed, 9 deletions(-) delete mode 100644 lib/dev/compilerapi.jar diff --git a/java/compiler/impl/compiler-impl.iml b/java/compiler/impl/compiler-impl.iml index a65d7e10171d..a247d6b5abef 100644 --- a/java/compiler/impl/compiler-impl.iml +++ b/java/compiler/impl/compiler-impl.iml @@ -18,15 +18,6 @@ - - - - - - - - - diff --git a/lib/dev/compilerapi.jar b/lib/dev/compilerapi.jar deleted file mode 100644 index b5bf1f3d8ed7ad3e0337c6d0a33081c4d10ad540..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72275 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 z 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%0Dup zXkcS&^kWz3KD|3WU=Mr(h{PfQ<*ry@KXHHMA{ju~imBO&uK;q206?a{(^^E- z|9}dVI&r{R)9)G#geJC?V59&LLLWegyU-?pERKI7=RXbpKWOIPx7s^IHG>%d&G!rR z2IhYY&GLI_g1MH1Lx7$Q0`!FW4ndr7{#$5(CynEeL&e){1XAUq+eSVg(EklC5D?ls z_?>`Z`M;vduMG#9jVxtRJqiFPSAn+Z4sZ|ae*y-K|G(oR5H|O^Y*-&aYF+@T@4||+ z|2MF|;UEx}pll7JilTAChz1qEoU6hN5os-B?Oe*(2P zGIIDG4S=`xwwm)F7aRC{)PxZTwbEQ6ySE@Dgc+^4iT=U{wrKT8(XvA z2^tVwMLeOA955bYGv2os$g=+p`0q)KU-B`?13=ycK*%-QohAqC{25i%UeDGR5H|!= z?qA%@ZX5E%e}QUbgKRNWc&?A(8k)) z$i6q9fj{txM0PMR0F>LskCjP*dH2M?nh285*fTB$SG~@1= zN@)C_aew6)(BLd0#6?d7+W7$>WGp|40C=;p{0pX#k+GhWrQ9nr3K(<+@6_h& z^uN`nU}WNCsb>%5+il08+Y$_98udJ%Ryu%^F;D>0ey75gm;YOZimq1rHkNwFznrWhP?i_$^aRg|5}r$9DLRgpj-NYDX8$RdO$#q{Qu{gfHV}hHZ*ei zYn8WCQv*hsThEh_|Nkog6aQ}K$h^zH=GgzQTK^_2w{J=TrrrGc6s7)8mHn#O!0T3S z-ve^j>S6T$1^&+EE4K%c-`ybcv&nINKm4U`m-*d|B0tO2{$H7&YmXmmK;U=)n(^~C z2jZW_0B@`JO8)k~k=x1%gu8vy05B^0=My#fqw(Jx@)Pb?(gGdDZik+e|AYa&i46Y< z>E1mB_ZxRRn49blx4Z+^?S?QdEEjOM%@=XqC>kSFdT z{V|sLc7K7Gw0;kruBU>KbVUX|Q zU0h%@1^*gbbekAJ?Au`%faS`q2W|P!*uTmq5bJiN!rlH4ul$MyWc}~MHtx6aw!8UV zW!zr(6Iy`!3pVd|q!84=9wk-I(rb(8sTL!T#)LdK(kiz}wz2cbAZchxai5<_>iq_O`Rd zT|=aI{Cn6R4i>+g$pRaC`>2%UCm8{6W~YBg{5@xGA24Fv!MnP+iwE3+{}lsx6nT3` zpY#p}=GCtlKX&nN9ZcRP8xZjJe(_xu{_^0#9cv40)DOTPje~#$wm}H+M;FkeS+ECy G-~JzOo6`dT From 6ca2f620f77c978fb4f4a188dc9262b23f7f5f4e Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 7 Feb 2011 10:34:07 +0300 Subject: [PATCH 02/10] more licenses for libs & maven libraries arranged --- build/scripts/libLicenses.gant | 11 ++++- .../maven/facade-impl/maven-facade-impl.iml | 44 +++---------------- 2 files changed, 16 insertions(+), 39 deletions(-) diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant index 2449222cde3a..a1eed990ad33 100644 --- a/build/scripts/libLicenses.gant +++ b/build/scripts/libLicenses.gant @@ -103,20 +103,27 @@ libraryLicense(name: "Ant", version: "1.7", license: "Apache 2.0", url: "http:// libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm", version: "3.3", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html") libraryLicense(name: "Axis", libraryName: "axis-1.4", version: "1.4", license: "Apache 2.0", url: "http://ws.apache.org/axis/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/axis-1.4.0/axis.LICENSE") libraryLicense(name: "CGLib", libraryName: "CGLIB", version: "2.2", license: "Apache", url: "http://cglib.sourceforge.net/", licenseUrl: "http://www.apache.org/foundation/licence-FAQ.html") +libraryLicense(name: "classworlds", libraryName: "classworlds-1.1.jar", version: "1.1", license: "codehaus", url: "http://classworlds.codehaus.org/", licenseUrl: "http://classworlds.codehaus.org/license.html") +libraryLicense(name: "Apache Commons BeanUtils", libraryName: "commons-beanutils.jar", version: "1.6", license: "Apache 2.0", url: "http://commons.apache.org/beanutils/") libraryLicense(name: "Apache Commons Codec", libraryName: "commons-codec", version: "1.3", license: "Apache 2.0", url: "http://commons.apache.org/codec/", licenseUrl: "http://commons.apache.org/license.html") libraryLicense(name: "Apache Commons Collections", libraryName: "commons-collections", version: "3.1", license: "Apache 2.0", url: "http://commons.apache.org/collections/", licenseUrl: "http://commons.apache.org/license.html") libraryLicense(name: "Apache Commons HTTPClient", libraryName: "http-client-3.1", version: "3.1  (with patch by JetBrains)", license: "Apache 2.0", url: "http://hc.apache.org/httpclient-3.x") libraryLicense(name: "Apache Commons Lang", libraryName: "commons-lang", version: "2.4", license: "Apache 2.0", url: "http://commons.apache.org/lang/", licenseUrl: "http://commons.apache.org/lang/license.html") -libraryLicense(name: "Apache Commons Logging", libraryName: "commons-logging", version: "1.1.1", license: "Apache 2.0", url: "http://commons.apache.org/logging/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/axis-1.4.0/commons-logging-1.0.4.LICENSE") +libraryLicense(name: "Apache Commons Logging", libraryName: "commons-logging", version: "1.1.1", license: "Apache 2.0", url: "http://commons.apache.org/logging/") +libraryLicense(name: "Apache Lucene", libraryName: "lucene-core-2.3.0.jar", version: "2.3.0", license: "Apache 2.0", url: "http://lucene.apache.org/java") libraryLicense(name: "Automaton", libraryName: "automaton.jar", version: "1.11", license: "BSD", url: "http://www.brics.dk/automaton/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php") libraryLicense(name: "DTDParser", version: "1.13", license: "LGPL", url: "http://sourceforge.net/projects/dtdparser/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1") libraryLicense(name: "Ganymed", version: "bundled with SVNKit", license: "BSD", url: "http://www.ganymed.ethz.ch/ssh2/", licenseUrl: "http://www.ganymed.ethz.ch/ssh2/LICENSE.txt") libraryLicense(name: "Guava", version: "R6", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://ant.apache.org/license.html") libraryLicense(name: "Gradle API", libraryName: "gradle-open-api-0.8.jar", version: "0.8", license: "Apache 2.0", url: "http://www.gradle.org/") libraryLicense(name: "Groovy", version: "1.7.3", license: "Apache 2.0", url: "http://groovy.codehaus.org/") +libraryLicense(name: "Gson", libraryName: "gson-1.3.jar", license: "Apache 2.0", url: "http://code.google.com/p/google-gson/") +libraryLicense(name: "ISO RELAX", libraryName: "isorelax.jar", license: "MIT License", url: "http://sourceforge.net/projects/iso-relax/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html") libraryLicense(name: "JavaCVS", version: "no version number available (with patches by JetBrains)", license: "Sun Public License", url: "http://javacvs.netbeans.org/library/", licenseUrl: "http://www.netbeans.org/about/legal/spl.html") +libraryLicense(name: "JAXB", libraryName: "JAXB", version: "2.1.10", license: "CDDL 1.1 & GPL 2", url: "http://jaxb.java.net/", licenseUrl: "http://glassfish.java.net/public/CDDL+GPL_1_1.html") libraryLicense(name: "Jaxen", version: "", license: "modified Apache", url: "http://www.jaxen.org/", licenseUrl: "http://www.jaxen.org/license.html") libraryLicense(name: "JavaHelp", version: "2.0_02", license: "included as license/javahelp_license.html in IntelliJ IDEA distribution", url: "http://java.sun.com/products/javahelp/") +libraryLicense(name: "JCIP Annotations", libraryName: "jcip-annotations.jar", license: "Creative Commons Attribution License", url: "http://www.jcip.net", licenseUrl: "http://creativecommons.org/licenses/by/2.5") libraryLicense(name: "JDOM", version: "1.1 (with patches by JetBrains)", license: "modified Apache", url: "http://www.jdom.org/", licenseUrl: "http://www.jdom.org/docs/faq.html#a0030") libraryLicense(name: "JGoodies Forms", libraryName: "jgoodies-forms", version: "CVS snapshot as of 5 May 2006", license: "BSD ", url: "http://www.jgoodies.com/freeware/forms/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html") libraryLicense(name: "JNA", libraryName: "jna", version: "3.2.4", license: "LGPL 2.1", url: "https://jna.dev.java.net/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php") @@ -130,6 +137,8 @@ libraryLicense(name: "NanoXML", version: "2.2.3", license: "zlib/libpng", url: " libraryLicense(name: "Eclipse JDT Core", libraryName: "Eclipse", version: "3.3", license: "CPL 1.0", url: "http://www.eclipse.org/jdt/core/index.php") libraryLicense(name: "Jakarta ORO", libraryName: "OroMatcher", version: "2.0.8", license: "Apache", url: "http://jakarta.apache.org/oro/", licenseUrl: "http://svn.apache.org/repos/asf/jakarta/oro/trunk/LICENSE") libraryLicense(name: "PicoContainer", libraryName: "picocontainer", version: "1.2", license: "BSD", url: "http://www.picocontainer.org/", licenseUrl: "http://docs.codehaus.org/display/PICO/License") +libraryLicense(name: "Plexus Utils", libraryName: "plexus-utils-1.5.5.jar", version: "1.5.5", license: "Apache 2.0", url: "http://plexus.codehaus.org/plexus-utils") +libraryLicense(name: "Relax NG Object Model", libraryName: "rngom-20051226-patched.jar", license: "MIT", url: "http://java.net/projects/rngom/", licenseUrl: "http://www.opensource.org/licenses/mit-license.php") libraryLicense(name: "SVNKit", libraryName: "svnkit.jar", version: "SVN version, 1.1 branch as of 1 Oct 2007", license: "link (commercial license)", url: "http://www.svnkit.com/", licenseUrl: "http://svnkit.com/license.html") libraryLicense(name: "TestNG", version: "5.7 snapshot", license: "Apache 2.0", url: "http://testng.org/doc/", licenseUrl: "http://code.google.com/p/testng/") libraryLicense(name: "Trilead SSH", libraryName: "trilead-ssh2-build213.jar", version: "build 213", license: "BSD style (see LICENSE.txt in trilead-ssh-build213.jar)", url: "http://www.trilead.com/SSH_Library/") diff --git a/plugins/maven/facade-impl/maven-facade-impl.iml b/plugins/maven/facade-impl/maven-facade-impl.iml index d6356b9cf3f3..85676062dd81 100644 --- a/plugins/maven/facade-impl/maven-facade-impl.iml +++ b/plugins/maven/facade-impl/maven-facade-impl.iml @@ -12,26 +12,9 @@ - + - - - - - - - - - - - - - - - - - @@ -41,7 +24,7 @@ - + @@ -75,23 +58,17 @@ - + + + + - - - - - - - - - @@ -101,15 +78,6 @@ - - - - - - - - - From 9414e45716cb427bbda098c4be7d2fde8a37b74a Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 7 Feb 2011 10:33:14 +0300 Subject: [PATCH 03/10] migrate to TransferToEdtQueue --- .../HighlightSuppressedWarningsHandler.java | 6 +- .../daemon/impl/DaemonCodeAnalyzerImpl.java | 3 +- .../daemon/impl/LocalInspectionsPass.java | 147 +++++++++--------- .../impl/LocalInspectionsPassFactory.java | 2 +- .../WholeFileLocalInspectionsPassFactory.java | 2 +- .../ex/GlobalInspectionContextImpl.java | 5 +- .../impl/TransferToPooledThreadQueue.java | 40 +++++ .../vfs/encoding/EncodingManagerImpl.java | 44 ++---- .../testFramework/LightPlatformTestCase.java | 2 +- .../usages/impl/UsageViewMemoryTest.java | 58 +++++++ .../util/xml/ui/DomUIFactoryImpl.java | 3 +- 11 files changed, 198 insertions(+), 114 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java create mode 100644 platform/usageView/testSrc/com/intellij/usages/impl/UsageViewMemoryTest.java diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java index 731956ee956d..6022b512656a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightSuppressedWarningsHandler.java @@ -108,7 +108,9 @@ public class HighlightSuppressedWarningsHandler extends HighlightUsagesHandlerBa public void computeUsages(List targets) { final Project project = myTarget.getProject(); final PsiElement parent = myTarget.getParent().getParent(); - final LocalInspectionsPass pass = new LocalInspectionsPass(myFile, myFile.getViewProvider().getDocument(), parent.getTextRange().getStartOffset(), parent.getTextRange().getEndOffset()); + final LocalInspectionsPass pass = new LocalInspectionsPass(myFile, myFile.getViewProvider().getDocument(), + parent.getTextRange().getStartOffset(), parent.getTextRange().getEndOffset(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, + false); final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); for (PsiLiteralExpression target : targets) { @@ -128,7 +130,7 @@ public class HighlightSuppressedWarningsHandler extends HighlightUsagesHandlerBa ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); Runnable inspect = new Runnable() { public void run() { - pass.doInspectInBatch(managerEx, Collections.singletonList(tool), false); + pass.doInspectInBatch(managerEx, Collections.singletonList(tool)); } }; if (indicator == null) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java index 832fb318eab1..8a665afa2fa4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java @@ -159,7 +159,8 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx List result = new ArrayList(); result.addAll(action1.getHighlights()); - LocalInspectionsPass action3 = new LocalInspectionsPass(psiFile, document, 0, psiFile.getTextLength()); + LocalInspectionsPass action3 = new LocalInspectionsPass(psiFile, document, 0, + psiFile.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true); action3.doCollectInformation(progress); result.addAll(action3.getHighlights()); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java index 503cd00a3c53..76a6ce8f008b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java @@ -46,7 +46,6 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.text.StringUtil; @@ -58,7 +57,7 @@ import com.intellij.util.ConcurrencyUtil; import com.intellij.util.Function; import com.intellij.util.Processor; import com.intellij.util.containers.ConcurrentHashMap; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.containers.TransferToEDTQueue; import com.intellij.xml.util.XmlStringUtil; import gnu.trove.THashMap; import gnu.trove.THashSet; @@ -67,9 +66,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; /** * @author max @@ -77,9 +74,11 @@ import java.util.concurrent.atomic.AtomicBoolean; public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass implements DumbAware { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.LocalInspectionsPass"); private static final int NUM_ELEMENTS_PER_CHECK_CANCELLED = 5; + public static final TextRange EMPTY_PRIORITY_RANGE = new TextRange(0, 0); private final int myStartOffset; private final int myEndOffset; private final TextRange myPriorityRange; + private final boolean myIgnoreSuppressed; private final ConcurrentMap> result = new ConcurrentHashMap>(); static final String PRESENTABLE_NAME = DaemonBundle.message("pass.inspection"); private volatile List myInfos = Collections.emptyList(); @@ -88,14 +87,17 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass private final InspectionProfileWrapper myProfileWrapper; private boolean myFailFastOnAcquireReadAction; - public LocalInspectionsPass(@NotNull PsiFile file, @Nullable Document document, int startOffset, int endOffset) { - this(file, document, startOffset, endOffset, new TextRange(0, 0)); - } - public LocalInspectionsPass(@NotNull PsiFile file, @Nullable Document document, int startOffset, int endOffset, @NotNull TextRange priorityRange) { + public LocalInspectionsPass(@NotNull PsiFile file, + @Nullable Document document, + int startOffset, + int endOffset, + @NotNull TextRange priorityRange, + boolean ignoreSuppressed) { super(file.getProject(), document, PRESENTABLE_NAME, file, true); myStartOffset = startOffset; myEndOffset = endOffset; myPriorityRange = priorityRange; + myIgnoreSuppressed = ignoreSuppressed; setId(Pass.LOCAL_INSPECTIONS); final KeymapManager keymapManager = KeymapManager.getInstance(); @@ -113,7 +115,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass if (customizationStrategy != null) { profileToUse = customizationStrategy.fun(profileToUse); } - + myProfileWrapper = profileToUse; mySeverityRegistrar = ((SeverityProvider)myProfileWrapper.getInspectionProfile().getProfileManager()).getSeverityRegistrar(); LOG.assertTrue(mySeverityRegistrar != null); @@ -128,7 +130,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass final InspectionManagerEx iManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); final InspectionProfileWrapper profile = myProfileWrapper; final List tools = DumbService.getInstance(myProject).filterByDumbAwareness(getInspectionTools(profile)); - inspect(tools, iManager, true, true, true, progress); + inspect(tools, iManager, true, true, progress); } finally { disposeDescriptors(); @@ -146,7 +148,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass result.clear(); } - public void doInspectInBatch(final InspectionManagerEx iManager, List toolWrappers, boolean ignoreSuppressed) { + public void doInspectInBatch(final InspectionManagerEx iManager, List toolWrappers) { Map tool2Wrapper = new THashMap(toolWrappers.size()); for (InspectionProfileEntry toolWrapper : toolWrappers) { tool2Wrapper.put(((LocalInspectionToolWrapper)toolWrapper).getTool(), (LocalInspectionToolWrapper)toolWrapper); @@ -154,7 +156,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass List tools = new ArrayList(tool2Wrapper.keySet()); ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); - inspect(tools, iManager, false, ignoreSuppressed, false, progress); + inspect(tools, iManager, false, false, progress); addDescriptorsFromInjectedResults(tool2Wrapper, iManager); List resultList = result.get(myFile); if (resultList == null) return; @@ -163,7 +165,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass LocalInspectionToolWrapper toolWrapper = tool2Wrapper.get(tool); if (toolWrapper == null) continue; for (ProblemDescriptor descriptor : inspectionResult.foundProblems) { - toolWrapper.addProblemDescriptors(Collections.singletonList(descriptor), ignoreSuppressed); + toolWrapper.addProblemDescriptors(Collections.singletonList(descriptor), myIgnoreSuppressed); } } } @@ -214,7 +216,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass private void inspect(final List tools, final InspectionManagerEx iManager, final boolean isOnTheFly, - final boolean ignoreSuppressed, boolean failFastOnAcquireReadAction, @NotNull final ProgressIndicator indicator) { myFailFastOnAcquireReadAction = failFastOnAcquireReadAction; @@ -231,8 +232,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass List> init = new ArrayList>(); boolean finished = false; try { - visitPriorityElementsAndInit(tools, iManager, isOnTheFly, ignoreSuppressed, indicator, inside, session, init); - visitRestElementsAndCleanup(tools,iManager,isOnTheFly,ignoreSuppressed, indicator, outside, session, init); + visitPriorityElementsAndInit(tools, iManager, isOnTheFly, indicator, inside, session, init); + visitRestElementsAndCleanup(tools,iManager,isOnTheFly, indicator, outside, session, init); finished = true; } finally { @@ -253,13 +254,12 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass indicator.checkCanceled(); myInfos = new ArrayList(); - addHighlightsFromResults(myInfos, ignoreSuppressed); + addHighlightsFromResults(myInfos); } private void visitPriorityElementsAndInit(@NotNull List tools, @NotNull final InspectionManagerEx iManager, final boolean isOnTheFly, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator, @NotNull final List elements, @NotNull final LocalInspectionToolSession session, @@ -276,7 +276,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass public void registerProblem(@NotNull ProblemDescriptor descriptor) { super.registerProblem(descriptor); if (applyIncrementally[0]) { - addDescriptorIncrementally(descriptor, tool, ignoreSuppressed, indicator); + addDescriptorIncrementally(descriptor, tool, indicator); } } }; @@ -295,7 +295,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass } }, myFailFastOnAcquireReadAction, indicator); if (!result) throw new ProcessCanceledException(); - inspectInjectedPsi(elements, tools, isOnTheFly, ignoreSuppressed, indicator, iManager, true); + inspectInjectedPsi(elements, tools, isOnTheFly, indicator, iManager, true); } private static PsiElementVisitor createVisitorAndAcceptElements(@NotNull LocalInspectionTool tool, @@ -324,7 +324,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass private void visitRestElementsAndCleanup(@NotNull List tools, @NotNull InspectionManagerEx iManager, final boolean isOnTheFly, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator, @NotNull final List elements, @NotNull final LocalInspectionToolSession session, @@ -341,7 +340,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass ProblemsHolder holder = trinity.second; PsiElementVisitor elementVisitor = trinity.third; for (int i = 0, elementsSize = elements.size(); i < elementsSize; i++) { - elements.get(i).accept(elementVisitor); + PsiElement element = elements.get(i); + element.accept(elementVisitor); if (i % NUM_ELEMENTS_PER_CHECK_CANCELLED == 0) indicator.checkCanceled(); } @@ -359,13 +359,12 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass if (!result) { throw new ProcessCanceledException(); } - inspectInjectedPsi(elements, tools, isOnTheFly, ignoreSuppressed, indicator, iManager, false); + inspectInjectedPsi(elements, tools, isOnTheFly, indicator, iManager, false); } private void inspectInjectedPsi(@NotNull final List elements, @NotNull final List tools, final boolean onTheFly, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator, @NotNull final InspectionManagerEx iManager, final boolean inVisibleRange) { @@ -380,7 +379,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass if (injected.isEmpty()) return; if (!JobUtil.invokeConcurrentlyUnderProgress(new ArrayList(injected), new Processor() { public boolean process(final PsiFile injectedPsi) { - doInspectInjectedPsi(injectedPsi, tools, onTheFly, ignoreSuppressed, indicator, iManager, inVisibleRange); + doInspectInjectedPsi(injectedPsi, tools, onTheFly, indicator, iManager, inVisibleRange); return true; } }, myFailFastOnAcquireReadAction, indicator)) throw new ProcessCanceledException(); @@ -389,7 +388,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass public Collection getHighlights() { List highlights = new ArrayList(); - addHighlightsFromResults(highlights, true); + addHighlightsFromResults(highlights); return highlights; } @@ -410,56 +409,52 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass severity, problemDescriptor.isAfterEndOfLine(), null, isFileLevel); } - private final AtomicBoolean haveInfosToProcess = new AtomicBoolean(); - private final ConcurrentLinkedQueue> infosToAdd = new ConcurrentLinkedQueue>(); + private final TransferToEDTQueue> myTransferToEDTQueue; + { + myTransferToEDTQueue = + new TransferToEDTQueue>(new Processor>() { + private final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile(); + private final InjectedLanguageManager ilManager = InjectedLanguageManager.getInstance(myProject); + private final List infos = new ArrayList(2); + private final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); + @Override + public boolean process(Trinity trinity) { + ProgressIndicator indicator = trinity.getThird(); + if (indicator.isCanceled()) { + return false; + } + + ProblemDescriptor descriptor = trinity.first; + LocalInspectionTool tool = trinity.second; + PsiElement psiElement = descriptor.getPsiElement(); + if (psiElement == null) return true; + PsiFile file = psiElement.getContainingFile(); + Document thisDocument = documentManager.getDocument(file); + + HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity(); + + infos.clear(); + createHighlightsForDescriptor(infos, emptyActionRegistered, ilManager, file, thisDocument, tool, severity, descriptor); + for (HighlightInfo info : infos) { + final EditorColorsScheme colorsScheme = getColorsScheme(); + UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, myFile, myStartOffset, myEndOffset, + info, colorsScheme, getId()); + } + + return true; + } + }, myProject.getDisposed()); + } + private final Set emptyActionRegistered = Collections.synchronizedSet(new HashSet()); private void addDescriptorIncrementally(@NotNull final ProblemDescriptor descriptor, @NotNull final LocalInspectionTool tool, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator) { - if (ignoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(descriptor.getPsiElement(), tool)) { + if (myIgnoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(descriptor.getPsiElement(), tool)) { return; } - - infosToAdd.offer(Pair.create(descriptor, tool)); - if (haveInfosToProcess.getAndSet(true)) return; - final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); - // extra invoke later is harmless, missing invoke is not - UIUtil.invokeLaterIfNeeded(new Runnable() { - public void run() { - if (myProject.isDisposed()) return; - InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile(); - InjectedLanguageManager ilManager = InjectedLanguageManager.getInstance(myProject); - List infos = new ArrayList(2); - while (haveInfosToProcess.compareAndSet(true, false)) { - for (Pair pair = infosToAdd.poll(); pair != null; pair = infosToAdd.poll()) { - if (indicator.isCanceled()) { - infosToAdd.clear(); - return; - } - - ProblemDescriptor descriptor = pair.first; - LocalInspectionTool tool = pair.second; - PsiElement psiElement = descriptor.getPsiElement(); - if (psiElement == null) continue; - PsiFile file = psiElement.getContainingFile(); - Document thisDocument = documentManager.getDocument(file); - - HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity(); - - infos.clear(); - createHighlightsForDescriptor(infos, emptyActionRegistered, ilManager, file, thisDocument, tool, severity, descriptor, ignoreSuppressed); - for (HighlightInfo info : infos) { - final EditorColorsScheme colorsScheme = getColorsScheme(); - - UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, myFile, myStartOffset, myEndOffset, - info, colorsScheme, getId()); - } - } - } - } - }); + myTransferToEDTQueue.offer(Trinity.create(descriptor, tool, indicator)); } private void appendDescriptors(PsiFile file, List descriptors, LocalInspectionTool tool) { @@ -519,7 +514,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, myStartOffset, myEndOffset, myInfos, getColorsScheme(), getId()); } - private void addHighlightsFromResults(final List outInfos, boolean ignoreSuppressed) { + private void addHighlightsFromResults(final List outInfos) { InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(myProject).getInspectionProfile(); PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); InjectedLanguageManager ilManager = InjectedLanguageManager.getInstance(myProject); @@ -534,8 +529,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass LocalInspectionTool tool = inspectionResult.tool; HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity(); for (ProblemDescriptor descriptor : inspectionResult.foundProblems) { - createHighlightsForDescriptor(outInfos, emptyActionRegistered, ilManager, file, documentRange, tool, severity, descriptor, - ignoreSuppressed); + createHighlightsForDescriptor(outInfos, emptyActionRegistered, ilManager, file, documentRange, tool, severity, descriptor); } } } @@ -548,10 +542,10 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass Document documentRange, LocalInspectionTool tool, HighlightSeverity severity, - ProblemDescriptor descriptor, boolean ignoreSuppressed) { + ProblemDescriptor descriptor) { PsiElement psiElement = descriptor.getPsiElement(); if (psiElement == null) return; - if (ignoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(psiElement, tool)) return; + if (myIgnoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(psiElement, tool)) return; HighlightInfoType level = highlightTypeFromDescriptor(descriptor, severity); HighlightInfo info = createHighlightInfo(descriptor, tool, level, emptyActionRegistered); if (info == null) return; @@ -677,7 +671,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass private void doInspectInjectedPsi(@NotNull PsiFile injectedPsi, @NotNull List tools, final boolean isOnTheFly, - final boolean ignoreSuppressed, @NotNull final ProgressIndicator indicator, @NotNull InspectionManagerEx iManager, final boolean inVisibleRange) { @@ -689,7 +682,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass } for (final LocalInspectionTool tool : tools) { indicator.checkCanceled(); - if (host != null && ignoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(host, tool)) { + if (host != null && myIgnoreSuppressed && InspectionManagerEx.inspectionResultSuppressed(host, tool)) { continue; } ProblemsHolder holder = new ProblemsHolder(iManager, injectedPsi, isOnTheFly) { @@ -697,7 +690,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass public void registerProblem(@NotNull ProblemDescriptor descriptor) { super.registerProblem(descriptor); if (isOnTheFly && inVisibleRange) { - addDescriptorIncrementally(descriptor, tool, ignoreSuppressed, indicator); + addDescriptorIncrementally(descriptor, tool, indicator); } } }; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java index 327772a905a3..368be146dd9b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java @@ -55,7 +55,7 @@ public class LocalInspectionsPassFactory extends AbstractProjectComponent implem if (textRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, editor.getDocument() ); TextRange visibleRange = VisibleHighlightingPassFactory.calculateVisibleRange(editor); - return new LocalInspectionsPass(file, editor.getDocument(), textRange.getStartOffset(), textRange.getEndOffset(), visibleRange){ + return new LocalInspectionsPass(file, editor.getDocument(), textRange.getStartOffset(), textRange.getEndOffset(), visibleRange, true){ List getInspectionTools(InspectionProfileWrapper profile) { List tools = super.getInspectionTools(profile); List result = new ArrayList(tools.size()); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java index c77f7236f3e3..2216b24dcbcf 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java @@ -90,7 +90,7 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone public TextEditorHighlightingPass createHighlightingPass(@NotNull final PsiFile file, @NotNull final Editor editor) { TextRange textRange = FileStatusMap.getDirtyTextRange(editor, Pass.LOCAL_INSPECTIONS); if (textRange == null || myFileTools.containsKey(file) && !myFileTools.get(file)) return null; - return new LocalInspectionsPass(file, editor.getDocument(), 0, file.getTextLength()) { + return new LocalInspectionsPass(file, editor.getDocument(), 0, file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true) { List getInspectionTools(InspectionProfileWrapper profile) { List tools = super.getInspectionTools(profile); List result = new ArrayList(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java index 731cc9c3faf9..639610151560 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -537,7 +537,8 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext { final FileViewProvider viewProvider = psiManager.findViewProvider(virtualFile); final com.intellij.openapi.editor.Document document = viewProvider == null ? null : viewProvider.getDocument(); if (document == null || virtualFile.getFileType().isBinary()) return; //do not inspect binary files - final LocalInspectionsPass pass = new LocalInspectionsPass(file, document, 0, file.getTextLength()); + final LocalInspectionsPass pass = new LocalInspectionsPass(file, document, 0, + file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true); try { final List lTools = new ArrayList(); for (Tools tool : localTools) { @@ -546,7 +547,7 @@ public class GlobalInspectionContextImpl implements GlobalInspectionContext { lTools.add(enabledTool); } } - pass.doInspectInBatch((InspectionManagerEx)manager, lTools, true); + pass.doInspectInBatch((InspectionManagerEx)manager, lTools); } catch (ProcessCanceledException e) { throw e; diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java new file mode 100644 index 000000000000..93cd04f40196 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/TransferToPooledThreadQueue.java @@ -0,0 +1,40 @@ +/* + * 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.application.impl; + +import com.intellij.concurrency.JobScheduler; +import com.intellij.openapi.util.Condition; +import com.intellij.util.Processor; +import com.intellij.util.containers.TransferToEDTQueue; +import org.jetbrains.annotations.NotNull; + +/** + * Allows to process elements in the Application pooled thread. + * Processes elements in batches, no longer than 200ms per batch, and reschedules processing later for longer batches. + * Usage: {@link #offer(Object)} } : schedules element for processing in a pooled thread + */ +public class TransferToPooledThreadQueue extends TransferToEDTQueue { + + public TransferToPooledThreadQueue(@NotNull Processor processorInEDT, @NotNull Condition shutUpCondition) { + super(processorInEDT, shutUpCondition); + } + + @Override + protected void schedule(Runnable updateRunnable) { + JobScheduler.getScheduler().execute(updateRunnable); + //ApplicationManager.getApplication().executeOnPooledThread(updateRunnable); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java index efe9acd263ff..2eaa2ddab020 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java @@ -24,6 +24,7 @@ package com.intellij.openapi.vfs.encoding; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.impl.TransferToPooledThreadQueue; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; @@ -44,6 +45,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Alarm; +import com.intellij.util.Processor; import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -54,9 +56,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.nio.charset.Charset; import java.util.Collection; -import java.util.Queue; import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; @State( @@ -72,16 +72,14 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt private final Alarm updateEncodingFromContent = new Alarm(Alarm.ThreadToUse.OWN_THREAD, this); private static final Key CACHED_CHARSET_FROM_CONTENT = Key.create("CACHED_CHARSET_FROM_CONTENT"); - private final Queue myChangedDocuments = new ConcurrentLinkedQueue(); - private final Runnable myEncodingUpdateRunnable = new Runnable() { - public void run() { - for (int i=0; i<50;i++) { - if (!pollAndHandleDocument()) return; - } - // requeue myself to handle the tail of the queue in next request - addCacheEncodingAlarm(); + + private final TransferToPooledThreadQueue myChangedDocuments = new TransferToPooledThreadQueue(new Processor() { + @Override + public boolean process(Document document) { + handleDocument(document); + return true; } - }; + }, ApplicationManager.getApplication().getDisposed()); public EncodingManagerImpl(EditorFactory editorFactory) { editorFactory.getEventMulticaster().addDocumentListener(new DocumentAdapter() { @@ -99,9 +97,8 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt } @NonNls public static final String PROP_CACHED_ENCODING_CHANGED = "cachedEncoding"; - private boolean pollAndHandleDocument() { - final Document document = myChangedDocuments.poll(); - if (document == null) return false; + + private void handleDocument(final Document document) { ApplicationManager.getApplication().runReadAction(new Runnable(){ public void run() { VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); @@ -114,28 +111,15 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt ((EncodingManagerImpl)EncodingManager.getInstance()).firePropertyChange(PROP_CACHED_ENCODING_CHANGED, oldCached, charset); } }); - return true; } public void dispose() { updateEncodingFromContent.cancelAllRequests(); - drainDocumentQueue(); - } - - public void drainDocumentQueue() { - while (pollAndHandleDocument()) { - // loop until empty - } + clearDocumentQueue(); } public void queueUpdateEncodingFromContent(@NotNull Document document) { myChangedDocuments.offer(document); - addCacheEncodingAlarm(); - } - - private void addCacheEncodingAlarm() { - updateEncodingFromContent.cancelAllRequests(); - updateEncodingFromContent.addRequest(myEncodingUpdateRunnable, 400); } public Charset getCachedCharsetFromContent(@NotNull Document document) { @@ -172,6 +156,10 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt return encodingManager.getEncoding(virtualFile, useParentDefaults); } + public void clearDocumentQueue() { + myChangedDocuments.stop(); + } + @Nullable private static Project guessProject(final VirtualFile virtualFile) { return ProjectLocator.getInstance().guessProjectForFile(virtualFile); diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java index e301bf877394..cd1da081ce42 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java @@ -469,7 +469,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da } } EncodingManager encodingManager = EncodingManager.getInstance(); - if (encodingManager instanceof EncodingManagerImpl) ((EncodingManagerImpl)encodingManager).drainDocumentQueue(); + if (encodingManager instanceof EncodingManagerImpl) ((EncodingManagerImpl)encodingManager).clearDocumentQueue(); FileDocumentManager manager = FileDocumentManager.getInstance(); if (manager instanceof FileDocumentManagerImpl) { diff --git a/platform/usageView/testSrc/com/intellij/usages/impl/UsageViewMemoryTest.java b/platform/usageView/testSrc/com/intellij/usages/impl/UsageViewMemoryTest.java new file mode 100644 index 000000000000..7d56cc69b840 --- /dev/null +++ b/platform/usageView/testSrc/com/intellij/usages/impl/UsageViewMemoryTest.java @@ -0,0 +1,58 @@ +/* + * 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.usages.impl; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.encoding.EncodingManager; +import com.intellij.openapi.vfs.encoding.EncodingManagerImpl; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.PsiFileImpl; +import com.intellij.testFramework.LeakHunter; +import com.intellij.testFramework.LightPlatformCodeInsightTestCase; +import com.intellij.usageView.UsageInfo; +import com.intellij.usages.*; +import com.intellij.util.ui.UIUtil; + +/** + * User: cdr + */ +public class UsageViewMemoryTest extends LightPlatformCodeInsightTestCase{ + public void testUsageViewDoesNotHoldPsiFilesOrDocuments() throws Exception { + PsiFile psiFile = createFile("X.java", "public class X{} //iuggjhfg"); + Usage[] usages = new Usage[100]; + for (int i = 0; i < usages.length; i++) { + usages[i] = createUsage(psiFile,i); + } + + UsageView usageView = UsageViewManager.getInstance(getProject()).createUsageView(UsageTarget.EMPTY_ARRAY, usages, new UsageViewPresentation(), null); + + Disposer.register(getTestRootDisposable(), usageView); + + UIUtil.dispatchAllInvocationEvents(); + ((EncodingManagerImpl)EncodingManager.getInstance()).clearDocumentQueue(); + + LeakHunter.checkLeak(usageView, PsiFileImpl.class); + LeakHunter.checkLeak(usageView, Document.class); + } + + private static Usage createUsage(PsiFile psiFile, int offset) { + PsiElement element = psiFile.findElementAt(offset % psiFile.getTextLength()); + assertNotNull(element); + return new UsageInfo2UsageAdapter(new UsageInfo(element)); + } +} diff --git a/xml/dom-impl/src/com/intellij/util/xml/ui/DomUIFactoryImpl.java b/xml/dom-impl/src/com/intellij/util/xml/ui/DomUIFactoryImpl.java index 4a241fe4550b..a03014ba0953 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/ui/DomUIFactoryImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/ui/DomUIFactoryImpl.java @@ -151,7 +151,8 @@ public class DomUIFactoryImpl extends DomUIFactory { psiDocumentManager.commitAllDocuments(); GeneralHighlightingPass ghp = new GeneralHighlightingPass(project, psiFile, document, 0, document.getTextLength(), true); - LocalInspectionsPass lip = new LocalInspectionsPass(psiFile, document, 0, document.getTextLength()); + LocalInspectionsPass lip = new LocalInspectionsPass(psiFile, document, 0, + document.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true); return new HighlightingPass[]{ghp, lip}; } From a58554e6d65103a657e95093306f944b93e25f75 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 7 Feb 2011 11:25:36 +0300 Subject: [PATCH 04/10] IDEA-65108 Inserting line break in text file can cause incorrect formatting and cursor placement on new line if the original line starts with an asterisk Javadoc-like processing is corrected for plain text files --- .../intellij/codeInsight/editorActions/EnterHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java index 904372541275..a43924d10098 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java @@ -259,8 +259,8 @@ public class EnterHandler extends BaseEnterHandler { final PsiElement parent = element.getParent(); if (text.equals(commentContext.commenter.getDocumentationCommentPrefix()) && isDocComment(parent, commentContext.commenter) || - text.startsWith(commentContext.commenter.getDocumentationCommentPrefix()) && element instanceof PsiComment - ) { + text.startsWith(commentContext.commenter.getDocumentationCommentPrefix()) && element instanceof PsiComment) + { PsiComment comment = isDocComment(parent, commentContext.commenter) ? (PsiComment)parent:(PsiComment)element; int commentEnd = comment.getTextRange().getEndOffset(); @@ -321,7 +321,7 @@ public class EnterHandler extends BaseEnterHandler { String indentInsideJavadoc = null; int line = myDocument.getLineNumber(myOffset); - if (line > 0) { + if (line > 0 && (commentContext.docAsterisk || commentContext.docStart)) { indentInsideJavadoc = CodeDocumentationUtil.getIndentInsideJavadoc(myDocument, myDocument.getLineStartOffset(line - 1)); } From 3dd076536c6220ae7c49e6c19884f50afada9238 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 7 Feb 2011 10:08:45 +0100 Subject: [PATCH 05/10] IDEA-64873 (Auto-fix for inspection "Instance field access not qualified with 'this'" creates broken code.) --- .../UnqualifiedFieldAccessInspection.java | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java index 69f12b130689..ea0fc190fa50 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010 Bas Leijdekkers + * Copyright 2006-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.siyeh.ig.style; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; @@ -74,18 +75,32 @@ public class UnqualifiedFieldAccessInspection extends BaseInspection { if (field == null) { return; } - final PsiClass containingClass = field.getContainingClass(); - if (containingClass == null) { + final PsiClass fieldClass = field.getContainingClass(); + if (fieldClass == null) { return; } - final PsiClass parentClass = + PsiClass containingClass = ClassUtils.getContainingClass(expression); @NonNls final String newExpression; - if (!containingClass.equals(parentClass)) { + if (InheritanceUtil.isInheritorOrSelf(containingClass, fieldClass, + true)) { + newExpression = "this." + expression.getText(); + } else { + containingClass = + ClassUtils.getContainingClass(containingClass); + if (containingClass == null) { + return; + } + while (!InheritanceUtil.isInheritorOrSelf(containingClass, + fieldClass, true)) { + containingClass = + ClassUtils.getContainingClass(containingClass); + if (containingClass == null) { + return; + } + } newExpression = containingClass.getQualifiedName() + ".this." + expression.getText(); - } else { - newExpression = "this." + expression.getText(); } replaceExpressionAndShorten(expression, newExpression); } From 3b7a92db4f675126ce8f27836c411875d7614333 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Mon, 7 Feb 2011 12:17:46 +0300 Subject: [PATCH 06/10] IDEA-64896 Enter Handler doesn't generate JavaDoc in specific case 1. Improved 'is doc complete' algorithm for the reported corner-case; 2. Corresponding test is added; --- .../editorActions/EnterHandler.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java index a43924d10098..c4aa0f10e9e4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java @@ -49,6 +49,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.IncorrectOperationException; import com.intellij.util.text.CharArrayUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class EnterHandler extends BaseEnterHandler { @@ -196,6 +197,9 @@ public class EnterHandler extends BaseEnterHandler { lexer.advance(); continue; } + else if (isInvalidPsi(comment)) { + return false; + } return lexer.getTokenEnd() - lexer.getTokenStart() == 1; } if (tokenType == commenter.getDocumentationCommentTokenType() || tokenType == commenter.getBlockCommentTokenType()) { @@ -205,6 +209,48 @@ public class EnterHandler extends BaseEnterHandler { } } + /** + * There is a following possible use-case: + *
+   * 
    + *
  • + * Particular document has valid text: + *
    +   *       [caret]
    +   *       class A {
    +   *           int foo() {
    +   *             return 1 */*comment*/ 1;
    +   *           }
    +   *       }
    +   *     
    + *
  • + *
  • + * The user starts comment (inserts comment start symbols): + *
    +   *       /**[caret]
    +   *       class A {
    +   *           int foo() {
    +   *             return 1 */*comment*/ 1;
    +   *           }
    +   *       }
    +   *     
    + *
  • + *
  • The user presses 'enter';
  • + *
+ *
+ * We want to understand that doc comment is incomplete now, i.e. don't want to consider '*/' before + * '*comment*/ 1;' as comment end. Current approach is to check if next PSI sibling to the current PSI comment is invalid. + * This method allows to perform such an examination. + */ + private static boolean isInvalidPsi(@NotNull PsiElement base) { + for (PsiElement current = base.getNextSibling(); current != null; current = current.getNextSibling()) { + if (current.getTextLength() != 0) { + return current instanceof PsiErrorElement; + } + } + return false; + } + private static boolean isDocComment(final PsiElement element, final CodeDocumentationAwareCommenter commenter) { if (!(element instanceof PsiComment)) return false; PsiComment comment = (PsiComment) element; From 83d3644a1fe63db8a7a45b9acf004f4eddda5df5 Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Mon, 7 Feb 2011 12:25:47 +0300 Subject: [PATCH 07/10] idea statistics --- .../LibrariesDownloadConnectionService.java | 60 +--- .../frameworks/SettingsConnectionService.java | 112 ++++++++ .../FrameworkStatisticsPersistence.java | 2 +- ...ameworkStatisticsPersistenceComponent.java | 4 +- .../statistics/FrameworkUsagesCollector.java | 26 +- platform/platform-impl/platform-impl.iml | 1 + .../FeaturesUsageCollector.java | 14 +- .../ide/plugins/PluginsUsagesCollector.java | 19 +- .../statistic/StatisticsUploadAssistant.java | 168 +++++++++++ .../statistic/UsagesCollector.java | 6 +- .../statistic/beans/ConvertUsagesUtil.java | 164 +++++++++++ .../statistic/beans/GroupDescriptor.java | 81 ++++++ .../statistic/beans/PatchedUsage.java | 8 +- .../statistic/beans/UsageDescriptor.java | 73 +++++ ...RemotelyConfigurableStatisticsService.java | 48 ++++ .../connect/StatServiceException.java | 36 +++ .../connect/StatisticsConnectionService.java | 72 +++++ .../connect/StatisticsDataSender.java | 25 ++ .../connect/StatisticsHttpClientSender.java | 62 ++++ .../statistic/connect/StatisticsResult.java | 38 +++ .../statistic/connect/StatisticsService.java | 22 ++ .../BasicSentUsagesPersistenceComponent.java | 11 +- .../persistence/SentUsagesPersistence.java | 6 +- .../SentUsagesPersistenceComponent.java | 14 +- .../statistic/tmp/SendStatisticsAction.java | 38 +++ .../updateSettings/impl/UpdateChecker.java | 37 ++- .../statistic/StatisticsUploadAssistant.java | 267 ------------------ .../statistic/beans/GroupDescriptor.java | 81 ------ .../statistic/beans/UsageDescriptor.java | 81 ------ .../src/META-INF/PlatformExtensionPoints.xml | 2 +- .../src/componentSets/Platform.xml | 4 +- .../statistics/VcsStatisticsPersistence.java | 2 +- .../VcsStatisticsPersistenceComponent.java | 4 +- .../vcs/statistics/VcsUsagesCollector.java | 23 +- resources/src/idea/IdeaActions.xml | 1 + 35 files changed, 1047 insertions(+), 565 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/facet/frameworks/SettingsConnectionService.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/UsagesCollector.java (87%) create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/beans/GroupDescriptor.java rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/beans/PatchedUsage.java (80%) create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/RemotelyConfigurableStatisticsService.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatServiceException.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsConnectionService.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsDataSender.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsHttpClientSender.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsResult.java create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsService.java rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/persistence/BasicSentUsagesPersistenceComponent.java (80%) rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/persistence/SentUsagesPersistence.java (83%) rename platform/platform-impl/src/com/intellij/{ => internal}/statistic/persistence/SentUsagesPersistenceComponent.java (86%) create mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/tmp/SendStatisticsAction.java delete mode 100644 platform/platform-impl/src/com/intellij/statistic/StatisticsUploadAssistant.java delete mode 100644 platform/platform-impl/src/com/intellij/statistic/beans/GroupDescriptor.java delete mode 100644 platform/platform-impl/src/com/intellij/statistic/beans/UsageDescriptor.java diff --git a/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadConnectionService.java b/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadConnectionService.java index 4c43bcccab22..2d5a3ddc9685 100644 --- a/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadConnectionService.java +++ b/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadConnectionService.java @@ -15,72 +15,16 @@ */ package com.intellij.facet.frameworks; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.text.StringUtil; -import org.jdom.Document; -import org.jdom.Element; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; - -public class LibrariesDownloadConnectionService { - private static final Logger LOG = Logger.getInstance("com.intellij.facet.frameworks.LibrariesDownloadConnectionService"); - - private static final String DOWNLOAD_SERVICE_SETTINGS_URL = "http://jetbrains.com/idea/download-assistant.xml "; - private static final String SERVICE_URL_ATTR_NAME = "url"; - - private static final String myAgentID = "IntelliJ IDEA"; +public class LibrariesDownloadConnectionService extends SettingsConnectionService { private static final LibrariesDownloadConnectionService myInstance = new LibrariesDownloadConnectionService(); - private String myServiceUrl; public static LibrariesDownloadConnectionService getInstance() { return myInstance; } private LibrariesDownloadConnectionService() { + super("http://jetbrains.com/idea/download-assistant.xml", "http://frameworks.jetbrains.com"); } - private static String readServiceUrl() { - try { - final URL url = new URL(DOWNLOAD_SERVICE_SETTINGS_URL); - final InputStream is = getStream(url); - final Document document = JDOMUtil.loadDocument(is); - final Element root = document.getRootElement(); - return StringUtil.notNullize(root.getAttributeValue(SERVICE_URL_ATTR_NAME), ""); - } - catch (MalformedURLException e) { - LOG.error(e); - } - catch (IOException e) { - // no route to host, unknown host, etc. - } - catch (Exception e) { - LOG.error(e); - } - // default - return "http://frameworks.jetbrains.com"; - } - - private static InputStream getStream(URL url) throws IOException { - final URLConnection connection = url.openConnection(); - if (connection instanceof HttpURLConnection) { - connection.setRequestProperty("User-agent", myAgentID); - } - return connection.getInputStream(); - } - - @Nullable - public String getServiceUrl() { - if (myServiceUrl == null) { - myServiceUrl = readServiceUrl(); - } - return myServiceUrl; - } } diff --git a/platform/lang-api/src/com/intellij/facet/frameworks/SettingsConnectionService.java b/platform/lang-api/src/com/intellij/facet/frameworks/SettingsConnectionService.java new file mode 100644 index 000000000000..cd638d426536 --- /dev/null +++ b/platform/lang-api/src/com/intellij/facet/frameworks/SettingsConnectionService.java @@ -0,0 +1,112 @@ +/* + * 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.facet.frameworks; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.util.containers.hash.HashMap; +import org.jdom.Document; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Map; + +public abstract class SettingsConnectionService { + private static final Logger LOG = Logger.getInstance("com.intellij.facet.frameworks.SettingsConnectionService"); + + protected static final String SERVICE_URL_ATTR_NAME = "url"; + + private static final String myAgentID = "IntelliJ IDEA"; + + private Map myAttributesMap; + + @NotNull + protected String[] getAttributeNames() { + return new String[] {SERVICE_URL_ATTR_NAME}; + } + + private String mySettingsUrl; + @Nullable private String myDefaultServiceUrl; + + protected SettingsConnectionService(@NotNull String settingsUrl, @Nullable String defaultServiceUrl) { + mySettingsUrl = settingsUrl; + myDefaultServiceUrl = defaultServiceUrl; + } + + public String getSettingsUrl() { + return mySettingsUrl; + } + + @Nullable + public String getDefaultServiceUrl() { + return myDefaultServiceUrl; + } + + @Nullable + private Map readSettings(String... attributes) { + Map settings = new HashMap(); + try { + final URL url = new URL(getSettingsUrl()); + final InputStream is = getStream(url); + final Document document = JDOMUtil.loadDocument(is); + final Element root = document.getRootElement(); + for (String s : attributes) { + settings.put(s, root.getAttributeValue(s)); + } + } + catch (MalformedURLException e) { + LOG.error(e); + } + catch (IOException e) { + // no route to host, unknown host, etc. + } + catch (Exception e) { + LOG.error(e); + } + + return settings; + } + + private static InputStream getStream(URL url) throws IOException { + final URLConnection connection = url.openConnection(); + if (connection instanceof HttpURLConnection) { + connection.setRequestProperty("User-agent", myAgentID); + } + return connection.getInputStream(); + } + + @Nullable + public String getServiceUrl() { + final String serviceUrl = getSettingValue(SERVICE_URL_ATTR_NAME); + + return serviceUrl == null ? getDefaultServiceUrl() : serviceUrl; + } + + @Nullable + protected String getSettingValue(@NotNull String attributeValue) { + if (myAttributesMap == null) { + myAttributesMap = readSettings(getAttributeNames()); + } + return myAttributesMap != null ? myAttributesMap.get(attributeValue) : null; + } +} 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 index e26ed8fb5932..b1d9a0894c75 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistence.java @@ -17,7 +17,7 @@ package com.intellij.facet.impl.statistics; import com.intellij.openapi.project.Project; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; 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 index 0c18a17355b7..717dabff6e15 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/statistics/FrameworkStatisticsPersistenceComponent.java @@ -16,6 +16,7 @@ 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; @@ -25,7 +26,6 @@ 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.statistic.beans.UsageDescriptor; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; import com.intellij.util.containers.HashSet; @@ -70,7 +70,7 @@ public class FrameworkStatisticsPersistenceComponent extends FrameworkStatistics if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(frameworks)) { Set frameworkDescriptors = new HashSet(); for (String key : StringUtil.split(frameworks, TOKENIZER)) { - frameworkDescriptors.add(new UsageDescriptor(FrameworkUsagesCollector.getGroupId(), key, 1)); + frameworkDescriptors.add(new UsageDescriptor(FrameworkUsagesCollector.getGroupDescriptor(), key, 1)); } getFrameworks().put(projectId, frameworkDescriptors); } 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 15e24c38ed6c..abad35157269 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 @@ -20,9 +20,9 @@ import com.intellij.facet.FacetManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; -import com.intellij.statistic.UsagesCollector; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.UsageDescriptor; +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; @@ -34,7 +34,7 @@ import java.util.Map; import java.util.Set; public class FrameworkUsagesCollector extends UsagesCollector { - private static final String GROUP_ID = "frameworks"; + public static final String GROUP_ID = "frameworks"; public static void persistProjectUsages(@NotNull Project project) { persistProjectUsages(project, getProjectUsages(project)); @@ -51,12 +51,12 @@ public class FrameworkUsagesCollector extends UsagesCollector { } @NotNull - public static Set getApplicationUsages() { + public Set getApplicationUsages() { return getApplicationUsages(FrameworkStatisticsPersistenceComponent.getInstance()); } @NotNull - public static Set getApplicationUsages(@NotNull final FrameworkStatisticsPersistence persistence) { + public Set getApplicationUsages(@NotNull final FrameworkStatisticsPersistence persistence) { final Map facets = new HashMap(); for (Set frameworks : persistence.getFrameworks().values()) { @@ -70,12 +70,18 @@ public class FrameworkUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(facets.entrySet(), new Function, UsageDescriptor>() { @Override public UsageDescriptor fun(Map.Entry facet) { - return new UsageDescriptor(getGroupId(), facet.getKey(), facet.getValue()); + return new UsageDescriptor(getGroupDescriptor(), facet.getKey(), facet.getValue()); } }); } - public static GroupDescriptor getGroupId() { + @NotNull + @Override + public String getGroupId() { + return GROUP_ID; + } + + public static GroupDescriptor getGroupDescriptor() { return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); } @@ -92,14 +98,14 @@ public class FrameworkUsagesCollector extends UsagesCollector { final Set facets = new HashSet(); for (Module module : ModuleManager.getInstance(project).getModules()) { for (Facet facet : FacetManager.getInstance(module).getAllFacets()) { - facets.add(facet.getName()); + facets.add(facet.getType().getStringId()); } } return ContainerUtil.map2Set(facets, new Function() { @Override public UsageDescriptor fun(String facet) { - return new UsageDescriptor(getGroupId(), facet, 1); + return new UsageDescriptor(getGroupDescriptor(), facet, 1); } }); } diff --git a/platform/platform-impl/platform-impl.iml b/platform/platform-impl/platform-impl.iml index 68fc2731b7bd..e2ea144cc57b 100644 --- a/platform/platform-impl/platform-impl.iml +++ b/platform/platform-impl/platform-impl.iml @@ -27,6 +27,7 @@ + diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java b/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java index 7d8707e88b5c..fcbf518cda18 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java +++ b/platform/platform-impl/src/com/intellij/featureStatistics/FeaturesUsageCollector.java @@ -16,9 +16,9 @@ package com.intellij.featureStatistics; import com.intellij.openapi.project.Project; -import com.intellij.statistic.UsagesCollector; -import com.intellij.statistic.beans.*; -import com.intellij.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.UsagesCollector; +import com.intellij.internal.statistic.beans.*; +import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,6 +27,12 @@ import java.util.Set; public class FeaturesUsageCollector extends UsagesCollector { + @NotNull + @Override + public String getGroupId() { + return "productivity"; + } + @NotNull @Override public Set getUsages(@Nullable Project project) { @@ -37,7 +43,7 @@ public class FeaturesUsageCollector extends UsagesCollector { final FeatureDescriptor featureDescriptor = registry.getFeatureDescriptor(featureId); if (featureDescriptor != null) { usages.add(new UsageDescriptor( - GroupDescriptor.create("productivity", GroupDescriptor.LOWER_PRIORITY), featureId, featureDescriptor.getUsageCount())); + GroupDescriptor.create(getGroupId(), GroupDescriptor.LOWER_PRIORITY), 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 560fac29c488..006b58967ada 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsUsagesCollector.java @@ -16,9 +16,9 @@ package com.intellij.ide.plugins; import com.intellij.openapi.project.Project; -import com.intellij.statistic.UsagesCollector; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.UsageDescriptor; +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 org.jetbrains.annotations.NotNull; @@ -27,18 +27,19 @@ import org.jetbrains.annotations.Nullable; import java.util.Set; public class PluginsUsagesCollector extends UsagesCollector { - private static final String GROUP_ID = "plugins"; + private static final String GROUP_ID = "disabled-plugins"; - public static GroupDescriptor getGroupId() { - return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); + @NotNull + public String getGroupId() { + return GROUP_ID; } @NotNull public Set getUsages(@Nullable Project project) { - return ContainerUtil.map2Set(PluginManager.getPlugins(), new Function() { + return ContainerUtil.map2Set(PluginManager.getDisabledPlugins(), new Function() { @Override - public UsageDescriptor fun(IdeaPluginDescriptor descriptor) { - return new UsageDescriptor(getGroupId(), descriptor.getName(), 1); + public UsageDescriptor fun(String descriptor) { + return new UsageDescriptor(GroupDescriptor.create(getGroupId(), GroupDescriptor.HIGHER_PRIORITY), descriptor, 1); } }); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java new file mode 100644 index 000000000000..a8fe0a736cec --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/StatisticsUploadAssistant.java @@ -0,0 +1,168 @@ +/* + * 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.ConvertUsagesUtil; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.PatchedUsage; +import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.persistence.SentUsagesPersistence; +import com.intellij.internal.statistic.persistence.SentUsagesPersistenceComponent; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Pair; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class StatisticsUploadAssistant { + + public String getData() { + return getData(Collections.emptySet()); + } + + public String getData(@NotNull Set disabledGroups) { + return getStringPatch(disabledGroups, ProjectManager.getInstance().getOpenProjects()); + } + + public void persistSentPatch(@NotNull String patchStr) { + persistSentPatch(patchStr, SentUsagesPersistenceComponent.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); + } + }); + + if (patchedUsages.size() > 0) persistenceComponent.persistPatch(patchedUsages); + } + + @NotNull + public static String getStringPatch(@NotNull Set disabledGroups, Project... project) { + return getStringPatch(disabledGroups, project, SentUsagesPersistenceComponent.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; + } + + @NotNull + public static Set getPatchedUsages(@NotNull Set disabledGroups, + @NotNull Project[] projects, + @NotNull SentUsagesPersistence usagesPersistence) { + Set usages = new HashSet(); + + for (Project project : projects) { + usages.addAll(getPatchedUsages(getAllUsages(project, disabledGroups), usagesPersistence.getSentUsages())); + } + return usages; + } + + @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()); + } + } + + return packCollection(patchedUsages, new Condition() { + @Override + public boolean value(PatchedUsage patchedUsage) { + return patchedUsage.getDelta() != 0; + } + }); + } + + @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 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)); + } + } + + return usageDescriptors; + } +} diff --git a/platform/platform-impl/src/com/intellij/statistic/UsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java similarity index 87% rename from platform/platform-impl/src/com/intellij/statistic/UsagesCollector.java rename to platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java index e0320bc0b2ca..e07246e0556a 100644 --- a/platform/platform-impl/src/com/intellij/statistic/UsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/UsagesCollector.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.statistic; +package com.intellij.internal.statistic; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,4 +27,6 @@ public abstract class UsagesCollector { public static ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.statistics.usagesCollector"); public abstract @NotNull Set getUsages(@Nullable Project project); + + public abstract @NotNull String 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 new file mode 100644 index 000000000000..8fd58411e437 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java @@ -0,0 +1,164 @@ +/* + * 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.statistic.beans; + + +import java.util.*; + +public class ConvertUsagesUtil { + private static final Character GROUP_SEPARATOR = ':'; + private static final Character GROUPS_SEPARATOR = ';'; + private static final Character GROUP_VALUE_SEPARATOR = ','; + + 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) { + assert map != null; + StringBuffer buffer = new StringBuffer(); + for (Map.Entry> entry : map.entrySet()) { + buffer.append(entry.getKey().getId()); + buffer.append(GROUP_SEPARATOR); + buffer.append(convertValueMap(entry.getValue())); + buffer.append(GROUPS_SEPARATOR); + } + + return buffer.toString(); + } + + //@NotNull + public static String convertValueMap(Set descriptors) { + assert descriptors != null; + final StringBuffer buffer = new StringBuffer(); + for (UsageDescriptor usageDescriptor : descriptors) { + buffer.append(usageDescriptor.getKey()); + buffer.append("="); + buffer.append(usageDescriptor.getValue()); + buffer.append(GROUP_VALUE_SEPARATOR); + } + buffer.deleteCharAt(buffer.length() - 1); + + return buffer.toString(); + } + + //@NotNull + public static String cutPatchString(String patchStr, int maxSize) { + assert patchStr != null; + for (int i = maxSize - 1; i >= 0; i--) { + final char c = patchStr.charAt(i); + if (c == GROUPS_SEPARATOR || c == GROUP_VALUE_SEPARATOR) { + return patchStr.substring(0, i); + } + } + return ""; + } + + //@NotNull + public static Set convertString(String usages) { + assert usages != null; + Set descriptors = new LinkedHashSet(); + 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)); + } + } + } + return descriptors; + } + + //@NotNull + public static Set convertValueString(GroupDescriptor groupId, String valueData) { + assert groupId != null; + final Set descriptors = new LinkedHashSet(); + for (String value : valueData.split(GROUP_VALUE_SEPARATOR.toString())) { + if (!isEmptyOrSpaces(value)) { + final StringPair pair = getPair(value, "="); + if (pair != null) { + final String count = pair.second; + if (!isEmptyOrSpaces(count)) { + try { + final int i = Integer.parseInt(count); + descriptors.add(new UsageDescriptor(groupId, pair.first, i)); + } catch (NumberFormatException ignored) { + } + } + } + } + } + + return descriptors; + } + + //@Nullable + public static StringPair getPair(String str, String separator) { + assert str != null; + assert separator != null; + final int i = str.indexOf(separator); + if (i > 0 && i < str.length() - 1) { + String key = str.substring(0, i).trim(); + String value = str.substring(i + 1).trim(); + if (!isEmptyOrSpaces(key) && !isEmptyOrSpaces(value)) { + return new StringPair(key, value); + } + } + return null; + } + + //@NotNull + public static Map> groupDescriptors(Set descriptors) { + assert descriptors != null; + 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); + } + return map; + } + + private static class StringPair { + public final String first; + public final String second; + + public StringPair(String first, String second) { + this.first = first; + this.second = second; + } + } + + 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/GroupDescriptor.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/GroupDescriptor.java new file mode 100644 index 000000000000..fcbff6c4f6a2 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/GroupDescriptor.java @@ -0,0 +1,81 @@ +/* + * 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.beans; + +public class GroupDescriptor implements Comparable { + public static final double DEFAULT_PRIORITY = 0.0; + public static final double HIGHER_PRIORITY = 100.0; + public static final double LOWER_PRIORITY = -100.0; + + private final String myId; + private double myPriority; + + public static GroupDescriptor create(String id) { + assert id != null; + return new GroupDescriptor(id); + } + + public static GroupDescriptor create(String id, double priority) { + assert id != null; + return new GroupDescriptor(id, priority); + } + + private GroupDescriptor(String id) { + this(id, DEFAULT_PRIORITY); + } + + private GroupDescriptor(String id, double priority) { + assert id != null; + myId = id; + myPriority = priority; + } + + + public String getId() { + return myId; + } + + public double getPriority() { + return myPriority; + } + + public void setPriority(double priority) { + myPriority = priority; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof GroupDescriptor)) return false; + + GroupDescriptor that = (GroupDescriptor) o; + + if (myId != null ? !myId.equals(that.myId) : that.myId != null) return false; + + return true; + } + + @Override + public int hashCode() { + return myId != null ? myId.hashCode() : 0; + } + + public int compareTo(GroupDescriptor gd) { + final int priority = (int) (this.getPriority() - gd.getPriority()); + return priority == 0 ? gd.getId().compareTo(gd.getId()) : priority; + } +} + diff --git a/platform/platform-impl/src/com/intellij/statistic/beans/PatchedUsage.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java similarity index 80% rename from platform/platform-impl/src/com/intellij/statistic/beans/PatchedUsage.java rename to platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java index d5c0ea3c53ec..f91433e4b6bb 100644 --- a/platform/platform-impl/src/com/intellij/statistic/beans/PatchedUsage.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/PatchedUsage.java @@ -13,17 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.statistic.beans; - -import org.jetbrains.annotations.NotNull; +package com.intellij.internal.statistic.beans; public class PatchedUsage extends UsageDescriptor { - public PatchedUsage(@NotNull UsageDescriptor descriptor) { + public PatchedUsage(UsageDescriptor descriptor) { super(descriptor.getGroup(), descriptor.getKey(), descriptor.getValue()); } - public PatchedUsage(@NotNull GroupDescriptor group, @NotNull String key, int value) { + public PatchedUsage(GroupDescriptor group, String key, int value) { super(group, key, value); } 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 new file mode 100644 index 000000000000..2ec188afa17d --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/UsageDescriptor.java @@ -0,0 +1,73 @@ +/* + * 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.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; + + myGroup = group; + myKey = key; + myValue = value; + } + + public String getKey() { + return myKey; + } + + public GroupDescriptor getGroup() { + return myGroup; + } + + public int getValue() { + return myValue; + } + + public void setValue(int i) { + 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; + } + + @Override + public int hashCode() { + int result = myGroup.hashCode(); + result = 31 * result + myKey.hashCode(); + return result; + } + + public int compareTo(UsageDescriptor ud) { + final int byGroup = this.getGroup().compareTo(ud.getGroup()); + + return byGroup == 0 ? this.getKey().compareTo(ud.myKey) : byGroup; + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/RemotelyConfigurableStatisticsService.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/RemotelyConfigurableStatisticsService.java new file mode 100644 index 000000000000..90877592027f --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/RemotelyConfigurableStatisticsService.java @@ -0,0 +1,48 @@ +package com.intellij.internal.statistic.connect; + +import com.intellij.internal.statistic.StatisticsUploadAssistant; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; + +public class RemotelyConfigurableStatisticsService implements StatisticsService { + + private StatisticsConnectionService myConnectionService; + private StatisticsDataSender sender; + private StatisticsUploadAssistant myAssistant; + + public RemotelyConfigurableStatisticsService(@NotNull StatisticsConnectionService connectionService, + @NotNull StatisticsDataSender sender, + @NotNull StatisticsUploadAssistant assistant) { + myConnectionService = connectionService; + this.sender = sender; + myAssistant = assistant; + } + + public StatisticsResult send() { + final String serviceUrl = myConnectionService.getServiceUrl(); + + if (serviceUrl == null) { + return new StatisticsResult(StatisticsResult.ResultCode.ERROR_IN_CONFIG, "ERROR"); + } + + if (!myConnectionService.isTransmissionPermitted()) { + return new StatisticsResult(StatisticsResult.ResultCode.NOT_PERMITTED, "NOT_PERMITTED"); + } + + String content = myAssistant.getData(); + + if (StringUtil.isEmptyOrSpaces(content)) { + return new StatisticsResult(StatisticsResult.ResultCode.NOTHING_TO_SEND, "NOTHING_TO_SEND"); + } + + try { + sender.send(serviceUrl, content); + myAssistant.persistSentPatch(content); + + return new StatisticsResult(StatisticsResult.ResultCode.SEND, "SUCCESS"); + } + catch (Exception e) { + return new StatisticsResult(StatisticsResult.ResultCode.SEND_WITH_ERRORS, e.getMessage() != null ? e.getMessage() : "NPE"); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatServiceException.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatServiceException.java new file mode 100644 index 000000000000..2964db2021ce --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatServiceException.java @@ -0,0 +1,36 @@ +/* + * 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.statistic.connect; + + +public class StatServiceException extends RuntimeException { + + public StatServiceException() { + super(); + } + + public StatServiceException(String s) { + super(s); + } + + public StatServiceException(String s, Throwable throwable) { + super(s, throwable); + } + + public StatServiceException(Throwable throwable) { + super(throwable); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsConnectionService.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsConnectionService.java new file mode 100644 index 000000000000..6a0df42f96eb --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsConnectionService.java @@ -0,0 +1,72 @@ +/* + * 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.statistic.connect; + +import com.intellij.facet.frameworks.SettingsConnectionService; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class StatisticsConnectionService extends SettingsConnectionService { + + private static final String SETTINGS_URL = "http://jetbrains.com/idea/statistics/stat-assistant.xml"; + private static final String DEFAULT_SERVICE_URL = "http://jetbrains.com/idea/statistics/index.jsp"; + + private static final String PERMISSION_ATTR_NAME = "permitted"; + private static final String DISABLED = "disabled"; + + public StatisticsConnectionService() { + this(SETTINGS_URL, DEFAULT_SERVICE_URL); + } + + public StatisticsConnectionService(@NotNull String settingsUrl, @Nullable String defaultServiceUrl) { + super(settingsUrl, defaultServiceUrl); + } + + @NotNull + @Override + public String[] getAttributeNames() { + return ArrayUtil.append(super.getAttributeNames(), PERMISSION_ATTR_NAME); + } + + public Boolean isTransmissionPermitted() { + final String permitted = getSettingValue(PERMISSION_ATTR_NAME); + + return permitted == null ? true : Boolean.parseBoolean(permitted); + } + + @NotNull + public Set getDisabledGroups() { + final String disabledGroupsString = getSettingValue(DISABLED); + + if (disabledGroupsString == null) return Collections.emptySet(); + + final List disabledGroupsList = StringUtil.split(disabledGroupsString, ","); + return ContainerUtil.map2Set(disabledGroupsList, new Function() { + @Override + public String fun(String s) { + return s.trim(); + } + }); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsDataSender.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsDataSender.java new file mode 100644 index 000000000000..0018ce34bf8a --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsDataSender.java @@ -0,0 +1,25 @@ +/* + * 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.statistic.connect; + + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface StatisticsDataSender { + + void send(@NotNull String url, @NotNull String content) throws StatServiceException; +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsHttpClientSender.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsHttpClientSender.java new file mode 100644 index 000000000000..ee1971138b1d --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsHttpClientSender.java @@ -0,0 +1,62 @@ +/* + * 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.statistic.connect; + +import com.intellij.openapi.updateSettings.impl.UpdateChecker; +import com.intellij.openapi.util.text.StringUtil; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.PostMethod; +import org.jetbrains.annotations.NotNull; + +public class StatisticsHttpClientSender implements StatisticsDataSender { + + public void send(@NotNull String url, @NotNull String content) throws StatServiceException { + PostMethod post = null; + + try { + HttpClient httpclient = new HttpClient(); + post = new PostMethod(url); + + post.setRequestBody(new NameValuePair[]{ + new NameValuePair("content", content), + new NameValuePair("uuid", UpdateChecker.getInstallationUID())}); + + httpclient.executeMethod(post); + + if (post.getStatusCode() != HttpStatus.SC_OK) { + throw new StatServiceException("Error during data sending... Code: " + post.getStatusCode()); + } + + final Header errors = post.getResponseHeader("errors"); + if (errors != null) { + final String value = errors.getValue(); + + throw new StatServiceException("Error during updating statistics " + (!StringUtil.isEmptyOrSpaces(value) ? " : " + value : "")); + } + } + catch (Exception e) { + throw new StatServiceException("Error during data sending...", e); + } + finally { + if (post != null) { + post.releaseConnection(); + } + } + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsResult.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsResult.java new file mode 100644 index 000000000000..20d447e52534 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsResult.java @@ -0,0 +1,38 @@ +/* + * 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.statistic.connect; + +public class StatisticsResult { + private ResultCode code; + private String description; + + public StatisticsResult(ResultCode code, String description) { + this.code = code; + this.description = description; + } + + public String getDescription() { + return description; + } + + public ResultCode getCode() { + return code; + } + + public enum ResultCode {SEND, NOT_PERMITTED, ERROR_IN_CONFIG, NOTHING_TO_SEND, SEND_WITH_ERRORS} + + +} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsService.java b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsService.java new file mode 100644 index 000000000000..3fe21714ecf1 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/connect/StatisticsService.java @@ -0,0 +1,22 @@ +/* + * 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.statistic.connect; + + +public interface StatisticsService { + + StatisticsResult send(); +} diff --git a/platform/platform-impl/src/com/intellij/statistic/persistence/BasicSentUsagesPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java similarity index 80% rename from platform/platform-impl/src/com/intellij/statistic/persistence/BasicSentUsagesPersistenceComponent.java rename to platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java index 63219377632d..a0f4d7499e57 100644 --- a/platform/platform-impl/src/com/intellij/statistic/persistence/BasicSentUsagesPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/BasicSentUsagesPersistenceComponent.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package com.intellij.statistic.persistence; +package com.intellij.internal.statistic.persistence; -import com.intellij.statistic.StatisticsUploadAssistant; -import com.intellij.statistic.beans.PatchedUsage; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.StatisticsUploadAssistant; +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 org.jetbrains.annotations.NotNull; @@ -33,7 +34,7 @@ public class BasicSentUsagesPersistenceComponent extends SentUsagesPersistence { public void persistPatch(@NotNull Set patchedDescriptors) { for (PatchedUsage patchedUsage : patchedDescriptors) { - UsageDescriptor usageDescriptor = StatisticsUploadAssistant.findDescriptor(mySentDescriptors, patchedUsage.getId()); + UsageDescriptor usageDescriptor = StatisticsUploadAssistant.findDescriptor(mySentDescriptors, Pair.create(patchedUsage.getGroup(), patchedUsage.getKey())); if (usageDescriptor != null) { usageDescriptor.setValue(usageDescriptor.getValue() + patchedUsage.getDelta()); } diff --git a/platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistence.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java similarity index 83% rename from platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistence.java rename to platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java index 41d490797012..9d2c55fb762a 100644 --- a/platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistence.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistence.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.intellij.statistic.persistence; +package com.intellij.internal.statistic.persistence; -import com.intellij.statistic.beans.PatchedUsage; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.PatchedUsage; +import com.intellij.internal.statistic.beans.UsageDescriptor; import org.jetbrains.annotations.NotNull; import java.util.Set; diff --git a/platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistenceComponent.java similarity index 86% rename from platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistenceComponent.java rename to platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistenceComponent.java index 7e2318475c1e..114949d6632c 100644 --- a/platform/platform-impl/src/com/intellij/statistic/persistence/SentUsagesPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/SentUsagesPersistenceComponent.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.intellij.statistic.persistence; +package com.intellij.internal.statistic.persistence; import com.intellij.openapi.application.ApplicationManager; 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.statistic.StatisticsUploadAssistant; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.ConvertUsagesUtil; +import com.intellij.internal.statistic.beans.GroupDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.openapi.util.text.StringUtil; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -66,7 +66,7 @@ public class SentUsagesPersistenceComponent extends BasicSentUsagesPersistenceCo String valueData = groupElement.getAttributeValue(DATA_ATTR); if (!StringUtil.isEmptyOrSpaces(groupId) && !StringUtil.isEmptyOrSpaces(valueData)) { - getSentUsages().addAll(StatisticsUploadAssistant.convertValueString(GroupDescriptor.create(groupId, groupPriority), valueData)); + getSentUsages().addAll(ConvertUsagesUtil.convertValueString(GroupDescriptor.create(groupId, groupPriority), valueData)); } } } @@ -80,12 +80,12 @@ public class SentUsagesPersistenceComponent extends BasicSentUsagesPersistenceCo public Element getState() { Element element = new Element("state"); - for (Map.Entry> entry : StatisticsUploadAssistant.groupDescriptors(getSentUsages()) + for (Map.Entry> entry : ConvertUsagesUtil.groupDescriptors(getSentUsages()) .entrySet()) { Element projectElement = new Element(GROUP_TAG); projectElement.setAttribute(GROUP_ID_ATTR, entry.getKey().getId()); projectElement.setAttribute(GROUP_PRIORITY_ATTR, Double.toString(entry.getKey().getPriority())); - projectElement.setAttribute(DATA_ATTR, StatisticsUploadAssistant.convertValueMap(entry.getValue())); + projectElement.setAttribute(DATA_ATTR, ConvertUsagesUtil.convertValueMap(entry.getValue())); element.addContent(projectElement); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/tmp/SendStatisticsAction.java b/platform/platform-impl/src/com/intellij/internal/statistic/tmp/SendStatisticsAction.java new file mode 100644 index 000000000000..eef096eadfae --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/statistic/tmp/SendStatisticsAction.java @@ -0,0 +1,38 @@ +/* + * 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.statistic.tmp; + +import com.intellij.internal.statistic.StatisticsUploadAssistant; +import com.intellij.internal.statistic.connect.StatisticsHttpClientSender; +import com.intellij.internal.statistic.connect.RemotelyConfigurableStatisticsService; +import com.intellij.internal.statistic.connect.StatisticsConnectionService; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; + +public class SendStatisticsAction extends AnAction { + + @Override + public void actionPerformed(AnActionEvent e) { + final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + if (project != null) { + final RemotelyConfigurableStatisticsService service = new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(), new StatisticsHttpClientSender(), new StatisticsUploadAssistant()); + + service.send(); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index be7eed7685b6..3d926199ca88 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -347,21 +347,9 @@ public final class UpdateChecker { public void run() { try { HttpConfigurable.getInstance().prepareURL(url); - final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(); - String uid = ""; - if (!propertiesComponent.isValueSet(INSTALLATION_UID)) { - try { - uid = UUID.randomUUID().toString(); - } - catch (Exception ignored) { - } - catch (InternalError ignored) { - } - propertiesComponent.setValue(INSTALLATION_UID, uid); - } - else { - uid = propertiesComponent.getValue(INSTALLATION_UID); - } + + String uid = getInstallationUID(); + final URL requestUrl = new URL(url + "?build=" + ApplicationInfo.getInstance().getBuild().asString() + "&uid=" + uid + ADDITIONAL_REQUEST_OPTIONS); final InputStream inputStream = requestUrl.openStream(); try { @@ -396,6 +384,25 @@ public final class UpdateChecker { return document[0]; } + public static String getInstallationUID() { + final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(); + String uid = ""; + if (!propertiesComponent.isValueSet(INSTALLATION_UID)) { + try { + uid = UUID.randomUUID().toString(); + } + catch (Exception ignored) { + } + catch (InternalError ignored) { + } + propertiesComponent.setValue(INSTALLATION_UID, uid); + } + else { + uid = propertiesComponent.getValue(INSTALLATION_UID); + } + return uid; + } + public static void showNoUpdatesDialog(boolean enableLink, final List updatePlugins, boolean showConfirmation) { NoUpdatesDialog dialog = new NoUpdatesDialog(true, updatePlugins, enableLink); dialog.setShowConfirmation(showConfirmation); diff --git a/platform/platform-impl/src/com/intellij/statistic/StatisticsUploadAssistant.java b/platform/platform-impl/src/com/intellij/statistic/StatisticsUploadAssistant.java deleted file mode 100644 index 1dc60bb6535d..000000000000 --- a/platform/platform-impl/src/com/intellij/statistic/StatisticsUploadAssistant.java +++ /dev/null @@ -1,267 +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.statistic; - -import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.project.Project; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.PatchedUsage; -import com.intellij.statistic.beans.UsageDescriptor; -import com.intellij.statistic.persistence.SentUsagesPersistence; -import com.intellij.statistic.persistence.SentUsagesPersistenceComponent; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.Function; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.HashSet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -public class StatisticsUploadAssistant { - - private static final Character GROUP_SEPARATOR = ':'; - private static final Character GROUPS_SEPARATOR = ';'; - private static final Character GROUP_VALUE_SEPARATOR = ','; - - private StatisticsUploadAssistant() { - } - - @NotNull - public static String getStringPatch(@Nullable Project project) { - return getStringPatch(project, 0); - } - - @NotNull - public static String getStringPatch(@Nullable Project project, int maxSize) { - return getStringPatch(project, SentUsagesPersistenceComponent.getInstance(), maxSize); - } - - @NotNull - public static String getStringPatch(@Nullable Project project, @NotNull SentUsagesPersistence usagesPersistence, int maxSize) { - final Set patchedUsages = getPatchedUsages(project, usagesPersistence); - - return getStringPatch(patchedUsages, usagesPersistence, maxSize); - } - - @NotNull - public static String getStringPatch(@NotNull Set patchedUsages, - @NotNull SentUsagesPersistence usagesPersistence, - int maxSize) { - if (patchedUsages.size() == 0) return ""; - - String patchStr = convertUsages(patchedUsages); - if (maxSize > 0 && patchStr.getBytes().length > maxSize) { - patchStr = cutPatchString(patchStr, maxSize); - - patchedUsages = ContainerUtil.map2Set(convertString(patchStr), new Function() { - @Override - public PatchedUsage fun(UsageDescriptor usageDescriptor) { - return new PatchedUsage(usageDescriptor); - } - }); - } - - if (patchedUsages.size() > 0) usagesPersistence.persistPatch(patchedUsages); - - return patchStr; - } - - @NotNull - public static Set getPatchedUsages(@Nullable Project project, @NotNull SentUsagesPersistence usagesPersistence) { - return getPatchedUsages(getAllUsages(project), usagesPersistence.getSentUsages()); - } - - @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, sentUsage.getId()); - if (descriptor == null) { - patchedUsages.add(new PatchedUsage(sentUsage.getGroup(), sentUsage.getKey(), - sentUsage.getValue())); - } - else { - descriptor.subValue(sentUsage.getValue()); - } - } - - return packCollection(patchedUsages, new Condition() { - @Override - public boolean value(PatchedUsage patchedUsage) { - return patchedUsage.getDelta() != 0; - } - }); - } - - @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; - } - - @NotNull - private static String cutPatchString(@NotNull String patchStr, int maxSize) { - for (int i = maxSize - 1; i >= 0; i--) { - final char c = patchStr.charAt(i); - if (c == GROUPS_SEPARATOR || c == GROUP_VALUE_SEPARATOR) { - return patchStr.substring(0, i); - } - } - return ""; - } - - @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.equals(t.getId()); - } - }); - } - - @NotNull - public static Set getAllUsages(@Nullable Project project) { - final Set usageDescriptors = new TreeSet(); - - for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { - usageDescriptors.addAll(usagesCollector.getUsages(project)); - } - - return usageDescriptors; - } - - @NotNull - public static String convertUsages(@NotNull Set descriptors) { - final Map> descriptorGroups = groupDescriptors(descriptors); - - return convertUsages(descriptorGroups); - } - - @NotNull - public static Map> groupDescriptors(@NotNull Set descriptors) { - final SortedMap> map = new TreeMap>(new Comparator() { - @Override - 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); - } - return map; - } - - @NotNull - private static String convertUsages(@NotNull Map> map) { - StringBuffer buffer = new StringBuffer(); - for (Map.Entry> entry : map.entrySet()) { - buffer.append(entry.getKey().getId()); - buffer.append(GROUP_SEPARATOR); - buffer.append(convertValueMap(entry.getValue())); - buffer.append(GROUPS_SEPARATOR); - } - - return buffer.toString(); - } - - @NotNull - public static Set convertString(@NotNull String usages) { - Set descriptors = new LinkedHashSet(); - for (String groupStr : StringUtil.split(usages, GROUPS_SEPARATOR.toString())) { - if (!StringUtil.isEmptyOrSpaces(groupStr)) { - final Pair group = getPair(groupStr, GROUP_SEPARATOR.toString()); - if (group != null) { - descriptors.addAll(convertValueString(GroupDescriptor.create(group.getFirst()), group.getSecond())); - } - } - } - return descriptors; - } - - @NotNull - public static String convertValueMap(@NotNull Set descriptors) { - final StringBuffer buffer = new StringBuffer(); - for (UsageDescriptor usageDescriptor : descriptors) { - buffer.append(usageDescriptor.getKey()); - buffer.append("="); - buffer.append(usageDescriptor.getValue()); - buffer.append(GROUP_VALUE_SEPARATOR); - } - buffer.deleteCharAt(buffer.length() - 1); - - return buffer.toString(); - } - - @NotNull - public static Set convertValueString(@NotNull GroupDescriptor groupId, String valueData) { - final Set descriptors = new LinkedHashSet(); - for (String value : StringUtil.split(valueData, GROUP_VALUE_SEPARATOR.toString())) { - if (!StringUtil.isEmptyOrSpaces(value)) { - final Pair pair = getPair(value, "="); - if (pair != null) { - final String count = pair.getSecond(); - if (!StringUtil.isEmptyOrSpaces(count)) { - try { - final int i = Integer.parseInt(count); - descriptors.add(new UsageDescriptor(groupId, pair.getFirst(), i)); - } catch (NumberFormatException ignored) {} - } - } - } - } - - return descriptors; - } - - @Nullable - private static Pair getPair(@NotNull String str, @NotNull String separator) { - final int i = str.indexOf(separator); - if (i > 0 && i < str.length() - 1) { - String key = str.substring(0, i).trim(); - String value = str.substring(i + 1).trim(); - if (!StringUtil.isEmptyOrSpaces(key) && !StringUtil.isEmptyOrSpaces(value)) { - return Pair.create(key, value); - } - } - return null; - } -} diff --git a/platform/platform-impl/src/com/intellij/statistic/beans/GroupDescriptor.java b/platform/platform-impl/src/com/intellij/statistic/beans/GroupDescriptor.java deleted file mode 100644 index 326769adf724..000000000000 --- a/platform/platform-impl/src/com/intellij/statistic/beans/GroupDescriptor.java +++ /dev/null @@ -1,81 +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.statistic.beans; - -import org.jetbrains.annotations.NotNull; - -public class GroupDescriptor implements Comparable { - public static final double DEFAULT_PRIORITY = 0.0; - public static final double HIGHER_PRIORITY = 100.0; - public static final double LOWER_PRIORITY = -100.0; - - private final String myId; - private double myPriority; - - public static GroupDescriptor create(@NotNull String id) { - return new GroupDescriptor(id); - } - - public static GroupDescriptor create(@NotNull String id, double priority) { - return new GroupDescriptor(id, priority); - } - - private GroupDescriptor(@NotNull String id) { - this(id, DEFAULT_PRIORITY); - } - - private GroupDescriptor(@NotNull String id, double priority) { - myId = id; - myPriority = priority; - } - - - public String getId() { - return myId; - } - - public double getPriority() { - return myPriority; - } - - public void setPriority(double priority) { - myPriority = priority; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof GroupDescriptor)) return false; - - GroupDescriptor that = (GroupDescriptor)o; - - if (myId != null ? !myId.equals(that.myId) : that.myId != null) return false; - - return true; - } - - @Override - public int hashCode() { - return myId != null ? myId.hashCode() : 0; - } - - @Override - public int compareTo(GroupDescriptor gd) { - final int priority = (int)(this.getPriority() - gd.getPriority()); - return priority == 0 ? gd.getId().compareTo(gd.getId()) : priority; - } -} - diff --git a/platform/platform-impl/src/com/intellij/statistic/beans/UsageDescriptor.java b/platform/platform-impl/src/com/intellij/statistic/beans/UsageDescriptor.java deleted file mode 100644 index e31a924be4f5..000000000000 --- a/platform/platform-impl/src/com/intellij/statistic/beans/UsageDescriptor.java +++ /dev/null @@ -1,81 +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.statistic.beans; - -import com.intellij.openapi.util.Pair; -import org.jetbrains.annotations.NotNull; - -public class UsageDescriptor implements Comparable { - - private final GroupDescriptor myGroup; - private final String myKey; - private int myValue; - - public UsageDescriptor(@NotNull GroupDescriptor group, @NotNull String key, int value) { - myGroup = group; - myKey = key; - myValue = value; - } - - public Pair getId() { - return Pair.create(getGroup(), getKey()); - } - - @NotNull - public String getKey() { - return myKey; - } - - @NotNull - public GroupDescriptor getGroup() { - return myGroup; - } - - public int getValue() { - return myValue; - } - - public void setValue(int i) { - 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; - } - - @Override - public int hashCode() { - int result = myGroup.hashCode(); - result = 31 * result + myKey.hashCode(); - return result; - } - - @Override - public int compareTo(UsageDescriptor ud) { - final int byGroup = this.getGroup().compareTo(ud.getGroup()); - - return byGroup == 0 ? this.getKey().compareTo(ud.myKey) : byGroup; - } -} diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 3f7291cee545..dcbdc60e0cb7 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -109,7 +109,7 @@ - + diff --git a/platform/platform-resources/src/componentSets/Platform.xml b/platform/platform-resources/src/componentSets/Platform.xml index a99994ac7cfd..262f9d54c624 100644 --- a/platform/platform-resources/src/componentSets/Platform.xml +++ b/platform/platform-resources/src/componentSets/Platform.xml @@ -114,8 +114,8 @@ - com.intellij.statistic.persistence.SentUsagesPersistenceComponent - com.intellij.statistic.persistence.SentUsagesPersistenceComponent + com.intellij.internal.statistic.persistence.SentUsagesPersistenceComponent + com.intellij.internal.statistic.persistence.SentUsagesPersistenceComponent 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 index 0850d38c3749..968e52aae1a8 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistence.java @@ -17,7 +17,7 @@ package com.intellij.openapi.vcs.statistics; import com.intellij.openapi.project.Project; -import com.intellij.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; 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 index 3cff5584312c..1e095cd4f677 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/statistics/VcsStatisticsPersistenceComponent.java @@ -26,7 +26,7 @@ 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.statistic.beans.UsageDescriptor; +import com.intellij.internal.statistic.beans.UsageDescriptor; import com.intellij.util.Function; import com.intellij.util.containers.HashSet; import org.jdom.Element; @@ -71,7 +71,7 @@ public class VcsStatisticsPersistenceComponent extends VcsStatisticsPersistence if (!StringUtil.isEmptyOrSpaces(projectId) && !StringUtil.isEmptyOrSpaces(vcs)) { Set vcsDescriptors = new HashSet(); for (String key : StringUtil.split(vcs, TOKENIZER)) { - vcsDescriptors.add(new UsageDescriptor(VcsUsagesCollector.getGroupId(), key, 1)); + vcsDescriptors.add(new UsageDescriptor(VcsUsagesCollector.createGroupDescriptor(), key, 1)); } getVcsUsageMap().put(projectId, vcsDescriptors); } 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 b534312e3b82..602a62853521 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 @@ -18,9 +18,9 @@ package com.intellij.openapi.vcs.statistics; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.impl.VcsDescriptor; -import com.intellij.statistic.UsagesCollector; -import com.intellij.statistic.beans.GroupDescriptor; -import com.intellij.statistic.beans.UsageDescriptor; +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.hash.HashMap; @@ -49,12 +49,12 @@ public class VcsUsagesCollector extends UsagesCollector { } @NotNull - public static Set getApplicationUsages() { + public Set getApplicationUsages() { return getApplicationUsages(VcsStatisticsPersistenceComponent.getInstance()); } @NotNull - public static Set getApplicationUsages(@NotNull final VcsStatisticsPersistenceComponent persistence) { + public Set getApplicationUsages(@NotNull final VcsStatisticsPersistenceComponent persistence) { final Map vcsUsagesMap = new HashMap(); for (Set descriptors : persistence.getVcsUsageMap().values()) { @@ -68,13 +68,14 @@ public class VcsUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(vcsUsagesMap.entrySet(), new Function, UsageDescriptor>() { @Override public UsageDescriptor fun(Map.Entry vcsUsage) { - return new UsageDescriptor(getGroupId(), vcsUsage.getKey(), vcsUsage.getValue()); + return new UsageDescriptor(createGroupDescriptor(), vcsUsage.getKey(), vcsUsage.getValue()); } }); } - public static GroupDescriptor getGroupId() { - return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); + @NotNull + public String getGroupId() { + return GROUP_ID; } @NotNull @@ -90,9 +91,13 @@ public class VcsUsagesCollector extends UsagesCollector { return ContainerUtil.map2Set(ProjectLevelVcsManager.getInstance(project).getAllVcss(), new Function() { @Override public UsageDescriptor fun(VcsDescriptor descriptor) { - return new UsageDescriptor(getGroupId(), descriptor.getName(), 1); + return new UsageDescriptor(createGroupDescriptor(), descriptor.getName(), 1); } }); } + + public static GroupDescriptor createGroupDescriptor() { + return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY); + } } diff --git a/resources/src/idea/IdeaActions.xml b/resources/src/idea/IdeaActions.xml index 838d33b3ec5d..ab01fb606c8a 100644 --- a/resources/src/idea/IdeaActions.xml +++ b/resources/src/idea/IdeaActions.xml @@ -262,6 +262,7 @@ + From 45d604351ed94428a9f777bfe8ebecf94536a93d Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 7 Feb 2011 11:12:26 +0300 Subject: [PATCH 08/10] fixed scope for 'mocks' library --- platform/extensions/extensions.iml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/extensions/extensions.iml b/platform/extensions/extensions.iml index 8648132b4918..40f44967ffeb 100644 --- a/platform/extensions/extensions.iml +++ b/platform/extensions/extensions.iml @@ -16,7 +16,7 @@ - + From 3053cfe89ba41f78b66241e6e35002862a9ba379 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 7 Feb 2011 10:36:31 +0300 Subject: [PATCH 09/10] javadoc --- .../lang-api/src/com/intellij/openapi/roots/ContentEntry.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ContentEntry.java b/platform/lang-api/src/com/intellij/openapi/roots/ContentEntry.java index de4f462f57a8..a7802c4fcb62 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/ContentEntry.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/ContentEntry.java @@ -21,9 +21,12 @@ import org.jetbrains.annotations.Nullable; /** * Represents a module content root. + * You can get existing entries with {@link com.intellij.openapi.roots.ModuleRootModel#getContentEntries()} or + * create a new one with {@link ModifiableRootModel#addContentEntry(com.intellij.openapi.vfs.VirtualFile)}. * * @author dsl * @see ModuleRootModel#getContentEntries() + * @see ModifiableRootModel#addContentEntry(com.intellij.openapi.vfs.VirtualFile) */ public interface ContentEntry extends Synthetic { /** From cb8a7746e3469b8278a7ef32859204cb24637206 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 7 Feb 2011 13:13:47 +0300 Subject: [PATCH 10/10] IDEA-65071 Spring integration: context files in the test hierarchy no longer use test classpath --- .../com/intellij/util/xml/PsiClassConverter.java | 16 +++++++++++++++- .../src/com/intellij/util/xml/DomJavaUtil.java | 15 +++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java b/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java index 32785e7a44c3..06f3f70cd596 100644 --- a/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java +++ b/java/java-impl/src/com/intellij/util/xml/PsiClassConverter.java @@ -17,13 +17,18 @@ package com.intellij.util.xml; import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.ClassKind; +import com.intellij.psi.xml.XmlElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -97,7 +102,16 @@ public class PsiClassConverter extends Converter implements CustomRefe @Nullable protected GlobalSearchScope getScope(final GenericDomValue domValue) { final Module module = domValue.getModule(); - return module == null ? null : GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, false); + if (module == null) return null; + XmlElement element = domValue.getXmlElement(); + if (element == null) return null; + PsiFile file = element.getContainingFile(); + if (file == null) return null; + file = file.getOriginalFile(); + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile == null) return null; + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex(); + return GlobalSearchScope.moduleRuntimeScope(module, fileIndex.isInTestSourceContent(virtualFile)); } public static class AnnotationType extends PsiClassConverter { diff --git a/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java b/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java index ca98d5d046bd..996af38a3a63 100644 --- a/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java +++ b/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java @@ -16,6 +16,9 @@ package com.intellij.util.xml; import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiFile; @@ -32,7 +35,7 @@ public class DomJavaUtil { } @Nullable - public static PsiClass findClass(@Nullable String name, @NotNull final PsiFile file, @Nullable final Module module, @Nullable final GlobalSearchScope searchScope) { + public static PsiClass findClass(@Nullable String name, @NotNull PsiFile file, @Nullable final Module module, @Nullable final GlobalSearchScope searchScope) { if (name == null) return null; if (name.indexOf('$')>=0) name = name.replace('$', '.'); @@ -40,7 +43,15 @@ public class DomJavaUtil { if (searchScope == null) { if (module != null) { - scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, false); + file = file.getOriginalFile(); + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile == null) { + scope = GlobalSearchScope.moduleRuntimeScope(module, true); + } + else { + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex(); + scope = GlobalSearchScope.moduleRuntimeScope(module, fileIndex.isInTestSourceContent(virtualFile)); + } } else { scope = file.getResolveScope();