diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpRangeProvider.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpRangeProvider.java index aa820b4a0012..9407752e3e63 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpRangeProvider.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpRangeProvider.java @@ -16,6 +16,7 @@ package org.intellij.lang.regexp; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; @@ -25,5 +26,5 @@ import com.intellij.psi.PsiElement; public interface RegExpRangeProvider { ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.regExpRangeProvider"); - TextRange getTextRange(PsiElement element); + Pair getRangePair(PsiElement element); } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpIntentionAction.java b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpIntentionAction.java index ba340f3b1c4b..da762fd5a68d 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpIntentionAction.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpIntentionAction.java @@ -16,6 +16,7 @@ package org.intellij.lang.regexp.intention; import com.intellij.codeInsight.intention.impl.QuickEditAction; +import com.intellij.lang.Language; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -43,23 +44,28 @@ public class CheckRegExpIntentionAction extends QuickEditAction implements Icona @Override protected Pair getRangePair(PsiFile file, Editor editor) { Pair pair = super.getRangePair(file, editor); - if (pair != null) return pair; - RegExpRangeProvider[] rangeProviders = RegExpRangeProvider.EP_NAME.getExtensions(); - PsiElement element = PsiUtilBase.getElementAtCaret(editor); - for (RegExpRangeProvider provider : rangeProviders) { - TextRange range = provider.getTextRange(element); - if (range != null) { - return Pair.create(element, range); + + if (pair == null) { + RegExpRangeProvider[] rangeProviders = RegExpRangeProvider.EP_NAME.getExtensions(); + PsiElement element = PsiUtilBase.getElementAtCaret(editor); + for (RegExpRangeProvider provider : rangeProviders) { + pair = provider.getRangePair(element); + if (pair != null) break; } } - return null; + return pair; } @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { final Pair pair = getRangePair(file, editor); /*super.isAvailable(project, editor, file) && */ - return pair != null && pair.first != null && pair.first.getLanguage() == RegExpLanguage.INSTANCE; + if (pair != null && pair.first != null) { + Language language = pair.first.getLanguage(); + Language baseLanguage = language.getBaseLanguage(); + return language == RegExpLanguage.INSTANCE || baseLanguage == RegExpLanguage.INSTANCE; + } + return false; } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CopyAbstractMethodImplementationHandler.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CopyAbstractMethodImplementationHandler.java index 3bd294820832..46f19ad29e43 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CopyAbstractMethodImplementationHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CopyAbstractMethodImplementationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -155,7 +155,9 @@ public class CopyAbstractMethodImplementationHandler { } for(PsiClass psiClass: myTargetClasses) { final Collection methods = OverrideImplementUtil.overrideOrImplementMethod(psiClass, myMethod, true); - PsiMethod overriddenMethod = methods.iterator().next(); + final Iterator iterator = methods.iterator(); + if (!iterator.hasNext()) continue; + PsiMethod overriddenMethod = iterator.next(); final PsiCodeBlock body = overriddenMethod.getBody(); final PsiCodeBlock sourceBody = sourceMethod.getBody(); assert body != null && sourceBody != null; diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index f79b0a38d312..f7a6904cd9dd 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -1675,20 +1675,12 @@ public class Mappings { } } - private void cleanupRemovedClass(final int className, ClassRepr cr) { - if (cr == null) { - cr = new Util().reprByName(className); - } - - if (cr != null) { - for (final int superSomething : cr.getSupers()) { - myClassToSubclasses.removeFrom(superSomething, cr.name); - } - + private void cleanupBackDependency(final int className, Collection clusters) { + if (clusters == null) { final int sourceFile = myClassToSourceFile.get(className); if (sourceFile > 0) { - final Collection clusters = mySourceFileToUsages.get(sourceFile); + clusters = mySourceFileToUsages.get(sourceFile); if (clusters != null) { for (final UsageRepr.Cluster cluster : clusters) { @@ -1698,8 +1690,8 @@ public class Mappings { if (u instanceof UsageRepr.ClassUsage) { final TIntHashSet residents = cluster.getResidence(u); - if (residents != null && residents.contains(cr.name)) { - myClassToClassDependency.removeFrom(((UsageRepr.ClassUsage)u).className, cr.name); + if (residents != null && residents.contains(className)) { + myClassToClassDependency.removeFrom(((UsageRepr.ClassUsage)u).className, className); } } } @@ -1708,6 +1700,20 @@ public class Mappings { } } } + } + + private void cleanupRemovedClass(final int className, ClassRepr cr, Collection clusters) { + if (cr == null) { + cr = new Util().reprByName(className); + } + + if (cr != null) { + for (final int superSomething : cr.getSupers()) { + myClassToSubclasses.removeFrom(superSomething, cr.name); + } + } + + cleanupBackDependency(className, clusters); myClassToClassDependency.remove(className); myClassToSubclasses.remove(className); @@ -1727,7 +1733,7 @@ public class Mappings { if (classes != null) { for (final ClassRepr cr : classes) { - cleanupRemovedClass(cr.name, cr); + cleanupRemovedClass(cr.name, cr, clusters); } } @@ -1741,7 +1747,7 @@ public class Mappings { delta.getDeletedClasses().forEach(new TIntProcedure() { @Override public boolean execute(int value) { - cleanupRemovedClass(value, null); + cleanupRemovedClass(value, null, null); return true; } }); @@ -1764,6 +1770,9 @@ public class Mappings { else { myClassToSourceFile.remove(c); } + + cleanupBackDependency(c, null); + return true; } }); diff --git a/platform/lang-impl/src/com/intellij/formatting/AbstractBlockAlignmentProcessor.java b/platform/lang-impl/src/com/intellij/formatting/AbstractBlockAlignmentProcessor.java index 256a370879af..945a8c453d3f 100644 --- a/platform/lang-impl/src/com/intellij/formatting/AbstractBlockAlignmentProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/AbstractBlockAlignmentProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -85,7 +85,7 @@ public abstract class AbstractBlockAlignmentProcessor implements BlockAlignmentP // alignment of blocks located before them and post error every time we detect endless cycle. Set blocksCausedRealignment = context.backwardShiftedAlignedBlocks.get(offsetResponsibleBlock); if (blocksCausedRealignment != null && blocksCausedRealignment.contains(context.targetBlock)) { - LOG.error(String.format("Please create dedicated ticket at the tracker with the content of the current editor attached!%n%n" + LOG.error(String.format("Please create dedicated ticket at the tracker with the content of the current editor attached%n%n" + "Formatting error - code block %s is set to be shifted right because of its alignment with " + "block %s more than once. I.e. moving the former block because of alignment algorithm causes " + "subsequent block to be shifted right as well - cyclic dependency. Debug info: %s", diff --git a/platform/lang-impl/src/com/intellij/formatting/BlockAlignmentProcessor.java b/platform/lang-impl/src/com/intellij/formatting/BlockAlignmentProcessor.java index a7dbd6448cf7..c00bdd6da16c 100644 --- a/platform/lang-impl/src/com/intellij/formatting/BlockAlignmentProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/BlockAlignmentProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -67,7 +67,7 @@ public interface BlockAlignmentProcessor { @NotNull public final LeafBlockWrapper targetBlock; @NotNull public final Map> alignmentMappings; @NotNull public final Map> backwardShiftedAlignedBlocks; - @NotNull public final CommonCodeStyleSettings.IndentOptions indentOptions; + @NotNull public final CommonCodeStyleSettings.IndentOptions indentOptions; public Context(@NotNull Document document, @NotNull AlignmentImpl alignment, diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java index c14dbeff1743..ae8a514bd9ee 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java @@ -85,6 +85,14 @@ class FormatProcessor { private final Map> myAlignmentMappings = new HashMap>(); + /** + * There is a possible case that we detect a 'cycled alignment' rules (see {@link #myBackwardShiftedAlignedBlocks}). We want + * just to skip processing for such alignments then. + *

+ * This container holds 'bad alignment' objects that should not be processed. + */ + private final Set myAlignmentsToSkip = new HashSet(); + private LeafBlockWrapper myWrapCandidate = null; private LeafBlockWrapper myFirstWrappedBlockOnLine = null; @@ -617,7 +625,7 @@ class FormatProcessor { AlignmentImpl alignment = CoreFormatterUtil.getAlignment(myCurrentBlock); WhiteSpace whiteSpace = myCurrentBlock.getWhiteSpace(); - if (alignment == null) { + if (alignment == null || myAlignmentsToSkip.contains(alignment)) { if (whiteSpace.containsLineFeeds()) { adjustSpacingByIndentOffset(); } @@ -637,11 +645,11 @@ class FormatProcessor { myDocument, alignment, myCurrentBlock, myAlignmentMappings, myBackwardShiftedAlignedBlocks, myIndentOption ); BlockAlignmentProcessor.Result result = alignmentProcessor.applyAlignment(context); + final LeafBlockWrapper offsetResponsibleBlock = alignment.getOffsetRespBlockBefore(myCurrentBlock); switch (result) { case TARGET_BLOCK_PROCESSED_NOT_ALIGNED: return true; case TARGET_BLOCK_ALIGNED: storeAlignmentMapping(); return true; case BACKWARD_BLOCK_ALIGNED: - LeafBlockWrapper offsetResponsibleBlock = alignment.getOffsetRespBlockBefore(myCurrentBlock); if (offsetResponsibleBlock == null) { return true; } @@ -654,13 +662,8 @@ class FormatProcessor { onCurrentLineChanged(); return false; case UNABLE_TO_ALIGN_BACKWARD_BLOCK: - if (whiteSpace.containsLineFeeds()) { - adjustSpacingByIndentOffset(); - } - else { - whiteSpace.arrangeSpaces(myCurrentBlock.getSpaceProperty()); - } - return true; + myAlignmentsToSkip.add(alignment); + return false; default: return true; } } diff --git a/platform/platform-api/src/com/intellij/ui/ToggleActionButton.java b/platform/platform-api/src/com/intellij/ui/ToggleActionButton.java new file mode 100644 index 000000000000..2643cb628373 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/ToggleActionButton.java @@ -0,0 +1,62 @@ +/* + * Copyright 2000-2012 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.ui; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.Toggleable; + +import javax.swing.*; + +/** + * @author yole + */ +public abstract class ToggleActionButton extends AnActionButton implements Toggleable { + @SuppressWarnings("NullableProblems") + public ToggleActionButton(String text, Icon icon) { + super(text, null, icon); + } + + /** + * Returns the selected (checked, pressed) state of the action. + * @param e the action event representing the place and context in which the selected state is queried. + * @return true if the action is selected, false otherwise + */ + public abstract boolean isSelected(AnActionEvent e); + + /** + * Sets the selected state of the action to the specified value. + * @param e the action event which caused the state change. + * @param state the new selected state of the action. + */ + public abstract void setSelected(AnActionEvent e, boolean state); + + @Override + public final void actionPerformed(AnActionEvent e) { + final boolean state = !isSelected(e); + setSelected(e, state); + final Boolean selected = state ? Boolean.TRUE : Boolean.FALSE; + final Presentation presentation = e.getPresentation(); + presentation.putClientProperty(Toggleable.SELECTED_PROPERTY, selected); + } + + @Override + public final void updateButton(AnActionEvent e) { + final Boolean selected = isSelected(e) ? Boolean.TRUE : Boolean.FALSE; + final Presentation presentation = e.getPresentation(); + presentation.putClientProperty(Toggleable.SELECTED_PROPERTY, selected); + } +} diff --git a/platform/util/src/com/intellij/util/SmartFMap.java b/platform/util/src/com/intellij/util/SmartFMap.java index 14c950094364..1a9e2a7dc880 100644 --- a/platform/util/src/com/intellij/util/SmartFMap.java +++ b/platform/util/src/com/intellij/util/SmartFMap.java @@ -61,6 +61,7 @@ public class SmartFMap implements Map { for (int i = 0; i < array.length; i += 2) { map.put((K)array[i], (V)array[i + 1]); } + map.put(key, value); return new SmartFMap(map); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/FinalPrivateMethodInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/FinalPrivateMethodInspection.java index b3672c4f8eb0..be630da46216 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/FinalPrivateMethodInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/FinalPrivateMethodInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.siyeh.ig.classlayout; +import com.intellij.codeInsight.AnnotationUtil; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.siyeh.InspectionGadgetsBundle; @@ -65,6 +66,9 @@ public class FinalPrivateMethodInspection extends BaseInspection { || !method.hasModifierProperty(PsiModifier.PRIVATE)) { return; } + if (AnnotationUtil.isAnnotated(method, "java.lang.SafeVarargs", false) && method.isVarArgs()) { + return; + } registerModifierError(PsiModifier.FINAL, method, PsiModifier.FINAL); } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/final_private_method/FinalPrivateMethod.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/final_private_method/FinalPrivateMethod.java new file mode 100644 index 000000000000..d750830d4f41 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/final_private_method/FinalPrivateMethod.java @@ -0,0 +1,12 @@ +package com.siyeh.igtest.classlayout.final_private_method; + +public class FinalPrivateMethod { + + private final void foo() {}; + + @java.lang.SafeVarargs + private final void foo(String s) {} + + @java.lang.SafeVarargs + private final void foo(int... i) {} +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/final_private_method/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/final_private_method/expected.xml new file mode 100644 index 000000000000..cfa07b88ff29 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/final_private_method/expected.xml @@ -0,0 +1,16 @@ + + + + FinalPrivateMethod.java + 5 + 'private' method declared 'final' + 'private' method declared <code>final</code> #loc + + + + FinalPrivateMethod.java + 8 + 'private' method declared 'final' + 'private' method declared <code>final</code> #loc + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/FinalPrivateMethodInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/FinalPrivateMethodInspectionTest.java new file mode 100644 index 000000000000..1ad073ed314c --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/FinalPrivateMethodInspectionTest.java @@ -0,0 +1,23 @@ +package com.siyeh.ig.classlayout; + +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.pom.java.LanguageLevel; +import com.siyeh.ig.IGInspectionTestCase; + +/** + * @author Bas Leijdekkers + */ +public class FinalPrivateMethodInspectionTest extends IGInspectionTestCase { + + @Override + protected Sdk getTestProjectSdk() { + LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7); + return JavaSdkImpl.getMockJdk17(); + } + + public void test() throws Exception { + doTest("com/siyeh/igtest/classlayout/final_private_method", new FinalPrivateMethodInspection()); + } +} diff --git a/plugins/android/src/org/jetbrains/android/exportSignedPackage/ExportSignedPackageWizard.java b/plugins/android/src/org/jetbrains/android/exportSignedPackage/ExportSignedPackageWizard.java index acd32ff25120..923dbb45b160 100644 --- a/plugins/android/src/org/jetbrains/android/exportSignedPackage/ExportSignedPackageWizard.java +++ b/plugins/android/src/org/jetbrains/android/exportSignedPackage/ExportSignedPackageWizard.java @@ -21,6 +21,7 @@ import com.intellij.ide.wizard.CommitStepException; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.SystemInfo; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.util.AndroidBundle; import org.jetbrains.annotations.NotNull; @@ -53,7 +54,8 @@ public class ExportSignedPackageWizard extends AbstractWizard 0; - if (facets.size() > 1) { + if (facets.size() > 1 || + SystemInfo.isMac /* wizards with only step are shown incorrectly on mac */) { addStep(new ChooseModuleStep(this, facets)); } else { diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java index 5d94112553d4..3642a15280e7 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacet.java @@ -115,6 +115,7 @@ public class AndroidFacet extends Facet { private final Object myClassMapLock = new Object(); private final Set myDirtyModes = EnumSet.noneOf(AndroidAutogeneratorMode.class); + private final Set myGeneratedWithErrorsModes = EnumSet.noneOf(AndroidAutogeneratorMode.class); private final Map> myAutogeneratedFiles = new HashMap>(); private volatile boolean myAutogenerationEnabled = false; @@ -141,9 +142,16 @@ public class AndroidFacet extends Facet { regenerate = regenerate || isGeneratedFileRemoved(mode); if (myAutogenerationEnabled && regenerate) { - if (AndroidCompileUtil.doGenerate(getModule(), mode)) { - synchronized (myDirtyModes) { - myDirtyModes.remove(mode); + final boolean result = AndroidCompileUtil.doGenerate(getModule(), mode); + + synchronized (myDirtyModes) { + myDirtyModes.remove(mode); + + if (result) { + myGeneratedWithErrorsModes.remove(mode); + } + else { + myGeneratedWithErrorsModes.add(mode); } } } @@ -817,4 +825,10 @@ public class AndroidFacet extends Facet { myDirtyModes.add(mode); } } + + public boolean areSourcesGeneratedWithErrors(@NotNull AndroidAutogeneratorMode mode) { + synchronized (myDirtyModes) { + return myGeneratedWithErrorsModes.contains(mode); + } + } } diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java b/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java index 2b01d6bf9ce2..733a27394c50 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidResourceFilesListener.java @@ -166,7 +166,8 @@ class AndroidResourceFilesListener extends VirtualFileAdapter { AndroidCompileUtil.collectAllResources(myFacet, resourceSet); synchronized (RESOURCES_SET_LOCK) { - if (resourceSet.equals(myResourceSet)) { + if (resourceSet.equals(myResourceSet) && + !myFacet.areSourcesGeneratedWithErrors(AndroidAutogeneratorMode.AAPT)) { return; } myResourceSet = resourceSet; diff --git a/plugins/android/src/org/jetbrains/android/intentions/AndroidAddStringResourceAction.java b/plugins/android/src/org/jetbrains/android/intentions/AndroidAddStringResourceAction.java index 428c40d72d73..47d47568c64e 100644 --- a/plugins/android/src/org/jetbrains/android/intentions/AndroidAddStringResourceAction.java +++ b/plugins/android/src/org/jetbrains/android/intentions/AndroidAddStringResourceAction.java @@ -184,7 +184,7 @@ public class AndroidAddStringResourceAction extends AbstractIntentionAction impl final AndroidFacet facet = AndroidFacet.getInstance(file); assert facet != null; - value = value.replace("'", "\\'").replace("\"", "\\\""); + value = AndroidResourceUtil.normalizeXmlResourceValue(value); final String aPackage = getPackage(facet); if (aPackage == null) { diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java index 8d98f268d299..525c75c81bd5 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java @@ -67,6 +67,7 @@ import org.jetbrains.android.sdk.AndroidPlatform; import org.jetbrains.android.sdk.AndroidSdkUtils; import org.jetbrains.android.util.AndroidBundle; import org.jetbrains.android.util.AndroidCommonUtils; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -418,11 +419,13 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { } } + final String normalizedAppName = AndroidResourceUtil.normalizeXmlResourceValue(myApplicationName); + if (appNameResElement == null) { - manager.addValueResource("string", appNameResource, myApplicationName); + manager.addValueResource("string", appNameResource, normalizedAppName); } else { - appNameResElement.setStringValue(myApplicationName); + appNameResElement.setStringValue(normalizedAppName); } final Manifest manifest = facet.getManifest(); diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java index 53e348ad7f02..602bff3ea171 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java @@ -60,6 +60,11 @@ public class AndroidResourceUtil { private AndroidResourceUtil() { } + @NotNull + public static String normalizeXmlResourceValue(@NotNull String value) { + return value.replace("'", "\\'").replace("\"", "\\\""); + } + static { REFERRABLE_RESOURCE_TYPES.addAll(Arrays.asList(ResourceType.values())); REFERRABLE_RESOURCE_TYPES.remove(ResourceType.ATTR); diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/AbstractVcsDataProvider.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/AbstractVcsDataProvider.java index 9e9ce796fdf4..2e088037e43a 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/AbstractVcsDataProvider.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/AbstractVcsDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -18,8 +18,7 @@ package com.intellij.cvsSupport2.cvsBrowser; import com.intellij.CvsBundle; import com.intellij.cvsSupport2.connections.CvsEnvironment; import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutor; -import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutorCallback; -import com.intellij.cvsSupport2.cvsExecution.ModalityContext; +import com.intellij.cvsSupport2.cvsExecution.DefaultCvsOperationExecutorCallback; import com.intellij.cvsSupport2.cvshandlers.CommandCvsHandler; import com.intellij.cvsSupport2.cvsoperations.common.CvsOperation; import com.intellij.cvsSupport2.cvsoperations.cvsContent.DirectoryContent; @@ -40,19 +39,19 @@ public abstract class AbstractVcsDataProvider implements RemoteResourceDataProvi myEnvironment = environment; } + @Override public void fillContentFor(final GetContentCallback callback, Consumer errorCallback) { myErrorCallback = errorCallback; if (ApplicationManager.getApplication().isUnitTestMode()) { executeCommand(createDirectoryContentProvider(callback.getElementPath()), callback); } else { - final GetDirectoriesListViaUpdateOperation provider = - new GetDirectoriesListViaUpdateOperation(myEnvironment, callback.getElementPath()); - final Consumer consumer = new Consumer() { + final DirectoryContentProvider provider = createDirectoryContentProvider(callback.getElementPath()); + provider.setStreamingListener(new Consumer() { + @Override public void consume(final DirectoryContent directoryContent) { callback.appendDirectoryContent(directoryContent); } - }; - provider.setStepByStepListener(consumer); + }); executeCommand(provider, callback); } } @@ -66,6 +65,7 @@ public abstract class AbstractVcsDataProvider implements RemoteResourceDataProvi super(title, cvsOperation, true); } + @Override protected boolean runInReadThread() { return false; } @@ -81,12 +81,11 @@ public abstract class AbstractVcsDataProvider implements RemoteResourceDataProvi final CvsOperationExecutor executor = new CvsOperationExecutor(false, callback.getProject(), callback.getModalityState()); executor.setIsQuietOperation(true); - final CancellableCvsHandler cvsHandler = - new CancellableCvsHandler(CvsBundle.message("browse.repository.operation.name"), (CvsOperation)command); - + final CancellableCvsHandler cvsHandler = new CancellableCvsHandler(CvsBundle.message("browse.repository.operation.name"), (CvsOperation)command); callback.useForCancel(cvsHandler.getProgressListener()); - executor.performActionSync(cvsHandler, new CvsOperationExecutorCallback() { + executor.performActionSync(cvsHandler, new DefaultCvsOperationExecutorCallback() { + @Override public void executionFinished(boolean successfully) { if (!successfully) { final List errors = cvsHandler.getErrorsExceptAborted(); @@ -96,12 +95,6 @@ public abstract class AbstractVcsDataProvider implements RemoteResourceDataProvi } callback.finished(); } - - public void executeInProgressAfterAction(ModalityContext modalityContext) { - } - - public void executionFinishedSuccessfully() { - } }); } } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/CvsElement.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/CvsElement.java index 5110486ae531..0c9482ed21b3 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/CvsElement.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/CvsElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -26,6 +26,8 @@ import java.util.*; public class CvsElement extends DefaultMutableTreeNode implements Comparable{ + public static final CvsElement[] EMPTY_ARRAY = {}; + protected RemoteResourceDataProvider myDataProvider; protected String myPath; protected final String myName; @@ -70,18 +72,22 @@ public class CvsElement extends DefaultMutableTreeNode implements Comparable 0; @@ -91,6 +97,7 @@ public class CvsElement extends DefaultMutableTreeNode implements Comparable { - private CvsElement[] myCurrentSelection = new CvsElement[0]; + private CvsElement[] myCurrentSelection = CvsElement.EMPTY_ARRAY; private Tree myTree; private DefaultTreeModel myModel; private CvsRootConfiguration myCvsRootConfiguration = null; @@ -60,8 +60,8 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene @NonNls public static final String SELECTION_CHANGED = "Selection Changed"; - public CvsTree(Project project, boolean allowRootSelection, @JdkConstants.TreeSelectionMode int selectionMode, boolean showModules, boolean showFiles, - Consumer errorCallback) { + public CvsTree(Project project, boolean allowRootSelection, @JdkConstants.TreeSelectionMode int selectionMode, + boolean showModules, boolean showFiles, Consumer errorCallback) { super(new BorderLayout()); myProject = project; mySelectionMode = selectionMode; @@ -75,6 +75,7 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene private void addSelectionListener() { myTree.addTreeSelectionListener(new TreeSelectionListener() { + @Override public void valueChanged(TreeSelectionEvent e) { setCurrentSelection(myTree.getSelectionPaths()); } @@ -91,12 +92,12 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene } private void setCurrentSelection(TreePath[] paths) { - ArrayList selection = new ArrayList(); + final ArrayList selection = new ArrayList(); if (paths != null) { for (TreePath path : paths) { - Object selectedObject = path.getLastPathComponent(); + final Object selectedObject = path.getLastPathComponent(); if (!(selectedObject instanceof CvsElement)) continue; - CvsElement cvsElement = (CvsElement)selectedObject; + final CvsElement cvsElement = (CvsElement)selectedObject; if (cvsElement.getElementPath().equals(".") && !myAllowRootSelection) continue; selection.add(cvsElement); } @@ -109,8 +110,8 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene if (myCvsRootConfiguration == null) { return new DefaultMutableTreeNode(); } - String rootName = myCvsRootConfiguration.toString(); - CvsElement result = CvsElementFactory.FOLDER_ELEMENT_FACTORY.createElement(rootName, myCvsRootConfiguration, project); + final String rootName = myCvsRootConfiguration.toString(); + final CvsElement result = CvsElementFactory.FOLDER_ELEMENT_FACTORY.createElement(rootName, myCvsRootConfiguration, project); result.setDataProvider(new RootDataProvider(myCvsRootConfiguration)); result.setPath("."); result.cannotBeCheckedOut(); @@ -135,7 +136,7 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene } public void init() { - TreeNode root = createRoot(myProject); + final TreeNode root = createRoot(myProject); myModel = new DefaultTreeModel(root, true); myTree = new Tree(myModel); add(ScrollPaneFactory.createScrollPane(myTree), BorderLayout.CENTER); @@ -144,7 +145,7 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene myTree.setCellRenderer(new Cvs2Renderer()); addSelectionListener(); - TreeUIHelper uiHelper = TreeUIHelper.getInstance(); + final TreeUIHelper uiHelper = TreeUIHelper.getInstance(); uiHelper.installTreeSpeedSearch(myTree); TreeUtil.installActions(myTree); @@ -152,6 +153,7 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene } private static class AlwaysNotifiedObservable extends Observable{ + @Override public void notifyObservers(Object arg) { setChanged(); super.notifyObservers(arg); @@ -174,6 +176,7 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene } } + @Override public void deactivated() { mySelectionObservable.deleteObservers(); synchronized (myListeners) { @@ -191,6 +194,7 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene final Application application = ApplicationManager.getApplication(); final ModalityState modalityState = application.getCurrentModalityState(); application.executeOnPooledThread(new Runnable() { + @Override public void run() { final RemoteResourceDataProvider dataProvider = element.getDataProvider(); dataProvider.fillContentFor(new MyGetContentCallback(element, modalityState, myProject), myErrorCallback); @@ -240,18 +244,22 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene return myModalityState; } + @Override public void deactivated() { if (myListener != null) { myListener.indirectCancel(); } } + @Override public void useForCancel(final CvsListenerWithProgress listener) { myListener = listener; } + @Override public void appendDirectoryContent(final DirectoryContent directoryContent) { ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override public void run() { final TreePath selectionPath = myTree.getSelectionPath(); if (selectionPath != null) { @@ -286,9 +294,11 @@ public class CvsTree extends JPanel implements CvsTabbedWindow.DeactivateListene } } + @Override public void finished() { removeListener(this); ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override public void run() { myLoadingNodeManager.removeFrom(myParentNode); myParentNode.setLoading(false); diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/RootDataProvider.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/RootDataProvider.java index 0822ecac3577..9373f6172547 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/RootDataProvider.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsBrowser/RootDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -21,6 +21,7 @@ import com.intellij.cvsSupport2.cvsoperations.cvsContent.GetModulesListOperation import com.intellij.cvsSupport2.cvsoperations.cvsContent.DirectoryContent; import com.intellij.cvsSupport2.cvsoperations.cvsContent.GetDirectoriesListViaUpdateOperation; import com.intellij.cvsSupport2.cvsoperations.cvsContent.*; +import com.intellij.util.Consumer; class RootDirectoryContentProvider extends CompositeOperation implements DirectoryContentProvider{ private final GetDirectoriesListViaUpdateOperation myDirectoryListOperation; @@ -34,12 +35,19 @@ class RootDirectoryContentProvider extends CompositeOperation implements Directo addOperation(myModuleListOperation); } + @Override public DirectoryContent getDirectoryContent() { - DirectoryContent result = new DirectoryContent(); + final DirectoryContent result = new DirectoryContent(); result.copyDataFrom(myDirectoryListOperation.getDirectoryContent()); result.copyDataFrom(myModuleListOperation.getDirectoryContent()); return result; } + + @Override + public void setStreamingListener(Consumer streamingListener) { + myDirectoryListOperation.setStreamingListener(streamingListener); + myModuleListOperation.setStreamingListener(streamingListener); + } } public class RootDataProvider extends AbstractVcsDataProvider{ @@ -51,10 +59,12 @@ public class RootDataProvider extends AbstractVcsDataProvider{ super(environment); } + @Override public AbstractVcsDataProvider getChildrenDataProvider() { return new FolderDataProvider(myEnvironment); } + @Override public DirectoryContentProvider createDirectoryContentProvider(String path) { return new RootDirectoryContentProvider(myEnvironment); } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutorCallback.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutorCallback.java index b41a2782845d..7111ca2747c5 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutorCallback.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/CvsOperationExecutorCallback.java @@ -21,18 +21,9 @@ package com.intellij.cvsSupport2.cvsExecution; */ public interface CvsOperationExecutorCallback { - CvsOperationExecutorCallback EMPTY = new CvsOperationExecutorCallback(){ - public void executionFinished(boolean successfully) { - } - - public void executionFinishedSuccessfully() { - } - - public void executeInProgressAfterAction(ModalityContext modaityContext) { - } - }; + CvsOperationExecutorCallback EMPTY = new DefaultCvsOperationExecutorCallback(); void executionFinished(boolean successfully); void executionFinishedSuccessfully(); - void executeInProgressAfterAction(ModalityContext modaityContext); + void executeInProgressAfterAction(ModalityContext modalityContext); } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/DefaultCvsOperationExecutorCallback.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/DefaultCvsOperationExecutorCallback.java new file mode 100644 index 000000000000..db2d80901297 --- /dev/null +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsExecution/DefaultCvsOperationExecutorCallback.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2012 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.cvsSupport2.cvsExecution; + +/** +* @author Bas Leijdekkers +*/ +public class DefaultCvsOperationExecutorCallback implements CvsOperationExecutorCallback { + + public void executionFinished(boolean successfully) { + } + + public void executionFinishedSuccessfully() { + } + + public void executeInProgressAfterAction(ModalityContext modaityContext) { + } +} diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentListener.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentListener.java index 3472a8f7ae13..56a5136a02b2 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentListener.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -43,10 +43,9 @@ class DirectoryContentListener { if ((myModuleName != null) && StringUtil.startsWithConcatenationOf(fileName, myModuleName, "/")) { fileName = fileName.substring(myModuleName.length() + 1); } - - int slashPos = fileName.indexOf('/'); + final int slashPos = fileName.indexOf('/'); if (slashPos > 0) { - String directoryName = fileName.substring(0, slashPos); + final String directoryName = fileName.substring(0, slashPos); myDirectoryContent.addSubDirectory(directoryName); } else { @@ -55,20 +54,24 @@ class DirectoryContentListener { } } else if (moduleMessage_ver1(message)) { - String moduleName = moduleNameFromMessage_ver1(message); + final String moduleName = moduleNameFromMessage_ver1(message); myDirectoryContent.addModule(moduleName); } else if (moduleMessage_ver2(message)) { - String moduleName = moduleNameFromMessage_ver2(message); + final String moduleName = moduleNameFromMessage_ver2(message); myDirectoryContent.addModule(moduleName); } } private String moduleNameFromMessage_ver2(final String message) { - String prefix = updatingModulePrefix2(); + final String prefix = updatingModulePrefix2(); return message.substring(prefix.length()); } + public String getModuleName() { + return myModuleName; + } + private static String moduleNameFromMessage_ver1(String message) { return message.substring(MODULE_MESSAGE_PREFIX.length()); } @@ -105,22 +108,17 @@ class DirectoryContentListener { } public static String directoryNameFromMessage(String message) { - byte directoryNameBeginMarker = '`'; - byte directoryNameendMarker = '\''; - int beginIndex = message.indexOf(directoryNameBeginMarker) + 1; - int endIndex = message.indexOf(directoryNameendMarker); + final byte directoryNameBeginMarker = '`'; + final byte directoryNameEndMarker = '\''; + final int beginIndex = message.indexOf(directoryNameBeginMarker) + 1; + final int endIndex = message.indexOf(directoryNameEndMarker); return message.substring(beginIndex, endIndex); } - public DirectoryContent getDirectoryContent() { return myDirectoryContent; } - //public void addModule(String name) { - // myDirectoryContent.addModule(name); - //} - public void setModuleName(final String moduleLocation) { myModuleName = moduleLocation; } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentProvider.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentProvider.java index c0ba1848c74c..0910cb3499b0 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentProvider.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/DirectoryContentProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -15,9 +15,13 @@ */ package com.intellij.cvsSupport2.cvsoperations.cvsContent; +import com.intellij.util.Consumer; + /** * author: lesya */ public interface DirectoryContentProvider { DirectoryContent getDirectoryContent(); + + void setStreamingListener(final Consumer streamingListener); } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetDirectoriesListViaUpdateOperation.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetDirectoriesListViaUpdateOperation.java index 3b4ec9f9d0eb..79712874cfdd 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetDirectoriesListViaUpdateOperation.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetDirectoriesListViaUpdateOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -29,63 +29,80 @@ import org.netbeans.lib.cvsclient.command.update.UpdateCommand; public class GetDirectoriesListViaUpdateOperation extends LocalPathIndifferentOperation implements DirectoryContentProvider { private final DirectoryContentListener myDirectoryContentListener = new DirectoryContentListener(); - private Consumer myStepByStepListener; + + private DirectoryContentListener myStreamingDirectoryContentListener = null; + private long timeStamp = System.currentTimeMillis(); + private Consumer myStreamingListener; public GetDirectoriesListViaUpdateOperation(CvsEnvironment env, final String parentDirectoryName) { super(new AdminReaderOnStoredRepositoryPath(createRepositoryPathProvider(parentDirectoryName)), env); + addFinishAction(new Runnable() { + @Override + public void run() { + if (myStreamingListener != null) { + myStreamingListener.consume(myStreamingDirectoryContentListener.getDirectoryContent()); + } + } + }); } public static RepositoryPathProvider createRepositoryPathProvider(final String parentDirName) { return new RepositoryPathProvider() { + @Override public String getRepositoryPath(String repository) { String result = repository; if (!StringUtil.endsWithChar(result, '/')) result += "/"; return result + parentDirName; } }; - } + @Override public void modifyOptions(GlobalOptions options) { super.modifyOptions(options); options.setDoNoChanges(true); } + @Override protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) { - UpdateCommand command = new UpdateCommand(); + final UpdateCommand command = new UpdateCommand(); command.setBuildDirectories(true); - - root.getRevisionOrDate().setForCommand(command); command.setRecursive(true); - + root.getRevisionOrDate().setForCommand(command); return command; } + @Override public void messageSent(String message, final byte[] byteMessage, boolean error, boolean tagged) { - final DirectoryContentListener tmp = new DirectoryContentListener(); - tmp.messageSent(message); - final DirectoryContent tmpContent = tmp.getDirectoryContent(); - final DirectoryContent mainContent = myDirectoryContentListener.getDirectoryContent(); - if (mainContent.getFilesRaw().containsAll(tmpContent.getFilesRaw()) && - mainContent.getSubDirectoriesRaw().containsAll(tmpContent.getSubDirectoriesRaw()) && - mainContent.getSubModulesRaw().containsAll(tmpContent.getSubModulesRaw())) { - } else { - myDirectoryContentListener.getDirectoryContent().copyDataFrom(tmpContent); - if (myStepByStepListener != null) { - myStepByStepListener.consume(tmpContent); + if (myStreamingListener != null) { + myStreamingDirectoryContentListener.messageSent(message); + final long timePassed = System.currentTimeMillis() - timeStamp; + final DirectoryContent streamingContent = myStreamingDirectoryContentListener.getDirectoryContent(); + final int size = streamingContent.getTotalSize(); + if (timePassed > 25L && size > 0) { + myStreamingListener.consume(streamingContent); + myStreamingDirectoryContentListener = new DirectoryContentListener(); + timeStamp = System.currentTimeMillis(); } } + else { + myDirectoryContentListener.messageSent(message); + } } + @Override public DirectoryContent getDirectoryContent() { return myDirectoryContentListener.getDirectoryContent(); } + @Override protected String getOperationName() { return "update"; } - public void setStepByStepListener(final Consumer stepByStepListener) { - myStepByStepListener = stepByStepListener; + @Override + public void setStreamingListener(final Consumer streamingListener) { + myStreamingListener = streamingListener; + myStreamingDirectoryContentListener = new DirectoryContentListener(); } } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModuleContentOperation.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModuleContentOperation.java index 486a5c4b6e86..2376b1949478 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModuleContentOperation.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModuleContentOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -22,6 +22,7 @@ import com.intellij.cvsSupport2.cvsoperations.javacvsSpecificImpls.AdminReaderOn import com.intellij.cvsSupport2.cvsoperations.javacvsSpecificImpls.AdminWriterStoringRepositoryPath; import com.intellij.cvsSupport2.cvsoperations.javacvsSpecificImpls.ConstantLocalFileReader; import com.intellij.cvsSupport2.javacvsImpl.io.DeafLocalFileWriter; +import com.intellij.util.Consumer; import org.jetbrains.annotations.NonNls; import org.netbeans.lib.cvsclient.command.Command; import org.netbeans.lib.cvsclient.command.GlobalOptions; @@ -37,9 +38,12 @@ import java.util.regex.Matcher; */ public class GetModuleContentOperation extends CompositeOperation implements DirectoryContentProvider { private final DirectoryContentListener myDirectoryContentListener = new DirectoryContentListener(); + private DirectoryContentListener myStreamingDirectoryContentListener = new DirectoryContentListener(); private final AdminWriterStoringRepositoryPath myAdminWriterStoringRepositoryPath; private String myModuleLocation; @NonNls private static final Pattern UPDATING_PATTERN = Pattern.compile("cvs .*: Updating (.+)"); + private Consumer myStreamingListener; + private long timeStamp = System.currentTimeMillis(); public GetModuleContentOperation(CvsEnvironment environment, final String moduleName) { myAdminWriterStoringRepositoryPath = new AdminWriterStoringRepositoryPath(moduleName, environment.getCvsRootAsString()); @@ -50,90 +54,128 @@ public class GetModuleContentOperation extends CompositeOperation implements Dir private LocalPathIndifferentOperation createGetModuleContentOperation(RepositoryPathProvider adminWriter, CvsEnvironment environment, final String moduleName) { - return new LocalPathIndifferentOperation(new AdminReaderOnStoredRepositoryPath(adminWriter), environment) { - private boolean myIsInModule = false; + final LocalPathIndifferentOperation operation = + new LocalPathIndifferentOperation(new AdminReaderOnStoredRepositoryPath(adminWriter), environment) { + private boolean myIsInModule = false; - protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) { - CheckoutCommand result = new CheckoutCommand(null); - result.addModule(moduleName); - result.setRecursive(true); - return result; - } + @Override + protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) { + final CheckoutCommand result = new CheckoutCommand(null); + result.addModule(moduleName); + result.setRecursive(true); + return result; + } - protected ILocalFileReader createLocalFileReader() { - return ConstantLocalFileReader.FOR_EXISTING_FILE; - } + @Override + protected ILocalFileReader createLocalFileReader() { + return ConstantLocalFileReader.FOR_EXISTING_FILE; + } - protected String getOperationName() { - return "checkout"; - } + @Override + protected String getOperationName() { + return "checkout"; + } - protected ILocalFileWriter createLocalFileWriter(String cvsRoot, - UpdatedFilesManager mergedFilesCollector, - CvsExecutionEnvironment cvsExecutionEnvironment) { - return DeafLocalFileWriter.INSTANCE; - } + @Override + protected ILocalFileWriter createLocalFileWriter(String cvsRoot, + UpdatedFilesManager mergedFilesCollector, + CvsExecutionEnvironment cvsExecutionEnvironment) { + return DeafLocalFileWriter.INSTANCE; + } - public void messageSent(String message, final byte[] byteMessage, boolean error, boolean tagged) { - super.messageSent(message, byteMessage, error, tagged); - myDirectoryContentListener.setModulePath(myAdminWriterStoringRepositoryPath.getModulePath()); - final Matcher matcher = UPDATING_PATTERN.matcher(message); - if (matcher.matches()) { - if (myModuleLocation != null && myModuleLocation.equals(matcher.group(1))) { + @Override + public void messageSent(String message, final byte[] byteMessage, boolean error, boolean tagged) { + super.messageSent(message, byteMessage, error, tagged); + myStreamingDirectoryContentListener.setModulePath(myAdminWriterStoringRepositoryPath.getModulePath()); + final Matcher matcher = UPDATING_PATTERN.matcher(message); + if (matcher.matches()) { + if (myModuleLocation != null && myModuleLocation.equals(matcher.group(1))) { + myIsInModule = true; + } + else { + myStreamingDirectoryContentListener.messageSent(message); + myIsInModule = false; + } + } + else if (DirectoryContentListener.moduleMessage_ver1(message)) { myIsInModule = true; } + + if (myIsInModule) { + myStreamingDirectoryContentListener.messageSent(message); + } + final DirectoryContent streamingDirectoryContent = myStreamingDirectoryContentListener.getDirectoryContent(); + if (myStreamingListener != null) { + final long timePassed = System.currentTimeMillis() - timeStamp; + if (streamingDirectoryContent.getTotalSize() > 0 && timePassed > 25L) { + myStreamingListener.consume(streamingDirectoryContent); + final DirectoryContentListener newListener = new DirectoryContentListener(); + newListener.setModuleName(myStreamingDirectoryContentListener.getModuleName()); + myStreamingDirectoryContentListener = newListener; + timeStamp = System.currentTimeMillis(); + } + } else { - myDirectoryContentListener.messageSent(message); - myIsInModule = false; + myDirectoryContentListener.getDirectoryContent().copyDataFrom(streamingDirectoryContent); } } - else if (DirectoryContentListener.moduleMessage_ver1(message)) { - myIsInModule = true; - } - if (myIsInModule) { - myDirectoryContentListener.messageSent(message); + @Override + public void modifyOptions(GlobalOptions options) { + super.modifyOptions(options); + options.setDoNoChanges(true); } + }; + operation.addFinishAction(new Runnable() { + @Override + public void run() { + myStreamingListener.consume(myStreamingDirectoryContentListener.getDirectoryContent()); } - - public void modifyOptions(GlobalOptions options) { - super.modifyOptions(options); - options.setDoNoChanges(true); - } - }; + }); + return operation; } private LocalPathIndifferentOperation createExpandingRepositoryPathOperation( AdminWriterStoringRepositoryPath adminWriter, CvsEnvironment environment, final String moduleName) { return new LocalPathIndifferentOperation(adminWriter, environment) { + @Override protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) { - CheckoutCommand result = new CheckoutCommand(null); + final CheckoutCommand result = new CheckoutCommand(null); result.addModule(moduleName); result.setRecursive(false); return result; } + @Override protected ILocalFileWriter createLocalFileWriter(String cvsRoot, UpdatedFilesManager mergedFilesCollector, CvsExecutionEnvironment cvsExecutionEnvironment) { return DeafLocalFileWriter.INSTANCE; } + @Override protected String getOperationName() { return "checkout"; } + @Override public void moduleExpanded(String module) { super.moduleExpanded(module); if (myModuleLocation == null) { myModuleLocation = module; - myDirectoryContentListener.setModuleName(myModuleLocation); + myStreamingDirectoryContentListener.setModuleName(myModuleLocation); } } }; } + @Override public DirectoryContent getDirectoryContent() { return myDirectoryContentListener.getDirectoryContent(); } + + @Override + public void setStreamingListener(Consumer streamingListener) { + myStreamingListener = streamingListener; + } } diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModulesListOperation.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModulesListOperation.java index 79b56f1fc496..9e07063fe7b7 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModulesListOperation.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsContent/GetModulesListOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -19,6 +19,7 @@ import com.intellij.cvsSupport2.connections.CvsEnvironment; import com.intellij.cvsSupport2.connections.CvsRootProvider; import com.intellij.cvsSupport2.cvsoperations.common.CvsExecutionEnvironment; import com.intellij.cvsSupport2.cvsoperations.common.LocalPathIndifferentOperation; +import com.intellij.util.Consumer; import org.netbeans.lib.cvsclient.command.Command; import org.netbeans.lib.cvsclient.command.checkout.ListModulesCommand; import org.netbeans.lib.cvsclient.command.checkout.Module; @@ -27,30 +28,61 @@ import java.util.Collection; public class GetModulesListOperation extends LocalPathIndifferentOperation implements DirectoryContentProvider{ private final ListModulesCommand myCommand = new ListModulesCommand(); - + private DirectoryContent myStreamingDirectoryContent = null; + private long timeStamp = System.currentTimeMillis(); + private Consumer myStreamingListener; public GetModulesListOperation(CvsEnvironment environment) { super(environment); + addFinishAction(new Runnable() { + @Override + public void run() { + if (myStreamingListener != null && myStreamingDirectoryContent.getTotalSize() > 0) { + myStreamingListener.consume(myStreamingDirectoryContent); + } + } + }); } + @Override protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) { return myCommand; } - public Collection getModulesInRepository() { + public Collection getModulesInRepository() { return myCommand.getModules(); } + @Override protected String getOperationName() { return "checkout"; } + @Override public DirectoryContent getDirectoryContent() { - DirectoryContent result = new DirectoryContent(); - Collection modules = myCommand.getModules(); + final DirectoryContent result = new DirectoryContent(); + final Collection modules = myCommand.getModules(); for (final Module module : modules) { result.addModule(module.getModuleName()); } return result; } + + @Override + public void setStreamingListener(final Consumer streamingListener) { + myStreamingListener = streamingListener; + myStreamingDirectoryContent = new DirectoryContent(); + myCommand.setModuleConsumer(new Consumer() { + @Override + public void consume(Module module) { + myStreamingDirectoryContent.addModule(module.getModuleName()); + final long timePassed = System.currentTimeMillis() - timeStamp; + if (timePassed > 25L) { + streamingListener.consume(myStreamingDirectoryContent); + myStreamingDirectoryContent = new DirectoryContent(); + timeStamp = System.currentTimeMillis(); + } + } + }); + } } diff --git a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ListModulesCommand.java b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ListModulesCommand.java index 95f2adde7a39..27be22a080dc 100644 --- a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ListModulesCommand.java +++ b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/command/checkout/ListModulesCommand.java @@ -1,11 +1,13 @@ package org.netbeans.lib.cvsclient.command.checkout; +import com.intellij.util.Consumer; +import org.jetbrains.annotations.Nullable; import org.netbeans.lib.cvsclient.IClientEnvironment; import org.netbeans.lib.cvsclient.IRequestProcessor; -import org.netbeans.lib.cvsclient.connection.AuthenticationException; import org.netbeans.lib.cvsclient.command.AbstractMessageParser; import org.netbeans.lib.cvsclient.command.Command; import org.netbeans.lib.cvsclient.command.CommandException; +import org.netbeans.lib.cvsclient.connection.AuthenticationException; import org.netbeans.lib.cvsclient.event.ICvsListener; import org.netbeans.lib.cvsclient.event.ICvsListenerRegistry; import org.netbeans.lib.cvsclient.event.IEventSender; @@ -14,7 +16,6 @@ import org.netbeans.lib.cvsclient.progress.IProgressViewer; import org.netbeans.lib.cvsclient.progress.sending.DummyRequestsProgressHandler; import org.netbeans.lib.cvsclient.request.CommandRequest; import org.netbeans.lib.cvsclient.request.Requests; -import org.jetbrains.annotations.Nullable; import java.util.HashSet; import java.util.Set; @@ -28,6 +29,7 @@ public class ListModulesCommand extends Command { private final Set modules = new HashSet(); private Module lastModule; + private Consumer myModuleConsumer; // Setup ================================================================== @@ -37,6 +39,7 @@ public class ListModulesCommand extends Command { // Implemented ============================================================ + @Override public boolean execute(IRequestProcessor requestProcessor, IEventSender eventManager, ICvsListenerRegistry listenerRegistry, IClientEnvironment clientEnvironment, @@ -58,6 +61,7 @@ public class ListModulesCommand extends Command { } } + @Override public String getCvsCommandLine() { return null; } @@ -76,7 +80,7 @@ public class ListModulesCommand extends Command { return null; } string = string.trim(); - if (string.length() == 0) { + if (string.isEmpty()) { return null; } return string; @@ -87,6 +91,7 @@ public class ListModulesCommand extends Command { private final class GetModulesParser extends AbstractMessageParser { private static final String MUTILINE_MODULE_PREFIX = " "; + @Override public void parseLine(String line, boolean errorMessage) { if (errorMessage) { return; @@ -116,18 +121,24 @@ public class ListModulesCommand extends Command { else { addNewModule(new Module(moduleName)); } - return; } private void addNewModule(Module module) { + if (myModuleConsumer != null) { + myModuleConsumer.consume(module); + } modules.add(module); lastModule = module; } - public void binaryMessageSent(final byte[] bytes) { - } + @Override + public void binaryMessageSent(final byte[] bytes) {} - public void outputDone() { - } + @Override + public void outputDone() {} + } + + public void setModuleConsumer(Consumer moduleConsumer) { + myModuleConsumer = moduleConsumer; } }