diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml
index 926c4b8e2b99..af758032d20b 100644
--- a/.idea/inspectionProfiles/idea_default.xml
+++ b/.idea/inspectionProfiles/idea_default.xml
@@ -258,7 +258,7 @@
-
+
diff --git a/bin/scripts/unix/idea.sh b/bin/scripts/unix/idea.sh
index b8f92069856c..934b38612f70 100755
--- a/bin/scripts/unix/idea.sh
+++ b/bin/scripts/unix/idea.sh
@@ -194,7 +194,7 @@ LD_LIBRARY_PATH="$IDE_BIN_HOME:$LD_LIBRARY_PATH" "$JAVA_BIN" \
EC=$?
test $EC -ne 88 && exit $EC
if [ -x "$HOME/.@@system_selector@@/restart/restarter.sh" ]; then
- $HOME/.@@system_selector@@/restart/restarter.sh
+ "$HOME/.@@system_selector@@/restart/restarter.sh"
"$RM" -f "$HOME/.@@system_selector@@/restart/restarter.sh"
fi
exec "$0" "$@"
diff --git a/build.xml b/build.xml
index ab62c1eb1932..dd8c90d39069 100644
--- a/build.xml
+++ b/build.xml
@@ -16,8 +16,7 @@
-
+
@@ -42,15 +41,15 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
index 6e861e88b7ae..d78a9a07cf1b 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
@@ -158,7 +158,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
myDebugProcessDispatcher.addListener(new DebugProcessAdapter() {
@Override
public void paused(SuspendContext suspendContext) {
- myThreadBlockedMonitor.stopWatching(suspendContext.getThread());
+ myThreadBlockedMonitor.stopWatching(
+ suspendContext.getSuspendPolicy() != EventRequest.SUSPEND_ALL ? suspendContext.getThread() : null);
}
});
}
@@ -2143,6 +2144,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
// }
//}
+ @NotNull
public DebuggerContextImpl getDebuggerContext() {
return mySession.getContextManager().getContext();
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/ThreadBlockedMonitor.java b/java/debugger/impl/src/com/intellij/debugger/engine/ThreadBlockedMonitor.java
index 7475e3bbd6da..43b0dd2cfc20 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/ThreadBlockedMonitor.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/ThreadBlockedMonitor.java
@@ -24,6 +24,7 @@ import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.Alarm;
import com.intellij.util.SingleAlarm;
@@ -42,6 +43,8 @@ import java.util.HashSet;
* @author egor
*/
public class ThreadBlockedMonitor {
+ private static final Logger LOG = Logger.getInstance(ThreadBlockedMonitor.class);
+
private final Collection myWatchedThreads = new HashSet();
private final SingleAlarm myAlarm;
@@ -71,14 +74,17 @@ public class ThreadBlockedMonitor {
if (thread != null) {
myWatchedThreads.remove(thread);
}
+ else {
+ myWatchedThreads.clear();
+ }
if (myWatchedThreads.isEmpty()) {
myAlarm.cancel();
}
}
- private void onThreadBlocked(@NotNull final ThreadReference blockedThread,
- @NotNull final ThreadReference blockingThread,
- final DebugProcessImpl process) {
+ private static void onThreadBlocked(@NotNull final ThreadReference blockedThread,
+ @NotNull final ThreadReference blockingThread,
+ final DebugProcessImpl process) {
XDebugSessionImpl.NOTIFICATION_GROUP.createNotification(
DebuggerBundle.message("status.thread.blocked.by", blockedThread.name(), blockingThread.name()),
DebuggerBundle.message("status.thread.blocked.by.resume", blockingThread.name()),
@@ -101,6 +107,11 @@ public class ThreadBlockedMonitor {
}).notify(process.getProject());
}
+ private ThreadReference getCurrentThread() {
+ ThreadReferenceProxyImpl threadProxy = myProcess.getDebuggerContext().getThreadProxy();
+ return threadProxy != null ? threadProxy.getThreadReference() : null;
+ }
+
private void checkBlockingThread() {
myProcess.getManagerThread().schedule(new DebuggerCommandImpl() {
@Override
@@ -115,14 +126,16 @@ public class ThreadBlockedMonitor {
vmProxy.canGetCurrentContendedMonitor() ? thread.getThreadReference().currentContendedMonitor() : null;
if (waitedMonitor != null && vmProxy.canGetMonitorInfo()) {
ThreadReference blockingThread = waitedMonitor.owningThread();
- if (blockingThread != null) {
+ if (blockingThread != null
+ && blockingThread.suspendCount() > 1
+ && getCurrentThread() != blockingThread) {
onThreadBlocked(thread.getThreadReference(), blockingThread, myProcess);
}
}
}
}
catch (IncompatibleThreadStateException e) {
- e.printStackTrace();
+ LOG.info(e);
}
finally {
vmProxy.getVirtualMachine().resume();
diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java
index c75a41f1f613..81000f4b7eb8 100644
--- a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java
@@ -306,7 +306,14 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
InvalidStackFrameException error = null;
for (int attempt = 0; attempt < 2; attempt++) {
try {
- return getAllValues().get(localVariable.getVariable());
+ Map values = getAllValues();
+ LocalVariable variable = localVariable.getVariable();
+ if (values.containsKey(variable)) {
+ return values.get(variable);
+ }
+ else { // try direct get
+ return getStackFrame().getValue(variable);
+ }
}
catch (InvalidStackFrameException e) {
error = e;
@@ -359,6 +366,14 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
catch (AbsentInformationException e) {
throw EvaluateExceptionUtil.createEvaluateException(e);
}
+ catch (InternalException e) {
+ // extra logging for IDEA-141270
+ if (e.errorCode() == 35 || e.errorCode() == 101) {
+ LOG.info(e);
+ myAllValues = Collections.emptyMap();
+ }
+ else throw e;
+ }
}
return myAllValues;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/GraphicsObjectRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/GraphicsObjectRenderer.java
index 1676cf2736c3..b3b257a5824f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/GraphicsObjectRenderer.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/GraphicsObjectRenderer.java
@@ -45,9 +45,15 @@ public class GraphicsObjectRenderer extends ToStringBasedRenderer implements Ful
Field surfaceField = ((ClassType)value.type()).fieldByName("surfaceData");
if (surfaceField == null) return null;
ObjectReference surfaceDataValue = (ObjectReference)value.getValue(surfaceField);
- final Field bufImgField = ((ClassType)surfaceDataValue.type()).fieldByName("bufImg");
- if (bufImgField == null) return null;
- final Value bufImgValue = surfaceDataValue.getValue(bufImgField);
+ if (surfaceDataValue == null) return null;
+
+ Field imgField = ((ReferenceType)surfaceDataValue.type()).fieldByName("bufImg"); // BufImgSurfaceData
+ if (imgField == null) {
+ imgField = ((ReferenceType)surfaceDataValue.type()).fieldByName("offscreenImage"); // CGLSurfaceData
+ }
+ if (imgField == null) return null;
+
+ final Value bufImgValue = surfaceDataValue.getValue(imgField);
Type type = bufImgValue.type();
if (!(type instanceof ReferenceType) || !DebuggerUtils.instanceOf(type, "java.awt.Image")) {
return null;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/IconObjectRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/IconObjectRenderer.java
index 51cb8b3c0fe7..c5be60cf00a2 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/IconObjectRenderer.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/IconObjectRenderer.java
@@ -16,10 +16,12 @@
package com.intellij.debugger.ui.tree.render;
import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.FullValueEvaluatorProvider;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
+import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.impl.DebuggerUtilsImpl;
import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
@@ -42,15 +44,27 @@ class IconObjectRenderer extends ToStringBasedRenderer implements FullValueEvalu
}
@Override
- public Icon calcValueIcon(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener listener)
+ public Icon calcValueIcon(final ValueDescriptor descriptor, final EvaluationContext evaluationContext, final DescriptorLabelListener listener)
throws EvaluateException {
- String getterName = AllIcons.Debugger.Value.getIconHeight() <= 16 ? "iconToBytesPreviewNormal" : "iconToBytesPreviewRetina";
- if (!Registry.is("debugger.auto.fetch.icons") || DebuggerUtilsImpl.isRemote(evaluationContext.getDebugProcess())) {
- return null; // do not auto load icon for remote
- }
- else {
- return ImageObjectRenderer.getIcon(evaluationContext, descriptor.getValue(), getterName);
- }
+ EvaluationContextImpl evalContext = ((EvaluationContextImpl)evaluationContext);
+ DebugProcessImpl debugProcess = evalContext.getDebugProcess();
+
+ if (!Registry.is("debugger.auto.fetch.icons") || DebuggerUtilsImpl.isRemote(debugProcess)) return null;
+
+ debugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(evalContext.getSuspendContext()) {
+ @Override
+ public Priority getPriority() {
+ return Priority.LOW;
+ }
+
+ @Override
+ public void contextAction() throws Exception {
+ String getterName = AllIcons.Debugger.Value.getIconHeight() <= 16 ? "iconToBytesPreviewNormal" : "iconToBytesPreviewRetina";
+ descriptor.setValueIcon(ImageObjectRenderer.getIcon(evaluationContext, descriptor.getValue(), getterName));
+ listener.labelChanged();
+ }
+ });
+ return null;
}
@Nullable
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ChangeLibraryLevelAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ChangeLibraryLevelAction.java
index 9cd1fa67c5b4..979b9db7ded1 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ChangeLibraryLevelAction.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ChangeLibraryLevelAction.java
@@ -17,6 +17,8 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.DumbModePermission;
+import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
@@ -56,18 +58,24 @@ public class ChangeLibraryLevelAction extends ChangeLibraryLevelActionBase {
final LibraryProjectStructureElement libraryElement = (LibraryProjectStructureElement)selectedElement;
final LibraryEx oldLibrary = (LibraryEx)context.getLibrary(libraryElement.getLibrary().getName(), mySourceConfigurable.getLevel());
LOG.assertTrue(oldLibrary != null);
- final Library newLibrary = doCopy(oldLibrary);
- if (newLibrary == null) return;
- final Collection usages = context.getDaemonAnalyzer().getUsages(libraryElement);
- for (ProjectStructureElementUsage usage : usages) {
- usage.replaceElement(new LibraryProjectStructureElement(context, newLibrary));
- }
+ DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
+ @Override
+ public void run() {
+ final Library newLibrary = doCopy(oldLibrary);
+ if (newLibrary == null) return;
- if (!myCopy) {
- mySourceConfigurable.removeLibrary(libraryElement);
- }
- ProjectStructureConfigurable.getInstance(myProject).selectProjectOrGlobalLibrary(newLibrary, true);
+ final Collection usages = context.getDaemonAnalyzer().getUsages(libraryElement);
+ for (ProjectStructureElementUsage usage : usages) {
+ usage.replaceElement(new LibraryProjectStructureElement(context, newLibrary));
+ }
+
+ if (!myCopy) {
+ mySourceConfigurable.removeLibrary(libraryElement);
+ }
+ ProjectStructureConfigurable.getInstance(myProject).selectProjectOrGlobalLibrary(newLibrary, true);
+ }
+ });
}
@Override
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
index ff96f4025ca5..140f672f1a30 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
@@ -26,6 +26,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -413,8 +414,15 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
}
final PsiType qualifierExpressionType = qualifierExpression.getType();
- return qualifierExpressionType != null && !TypeConversionUtil.containsWildcards(qualifierExpressionType)
- ? qualifierExpressionType.getCanonicalText() : getClassReferenceName(containingClass);
+ if (qualifierExpressionType != null && !TypeConversionUtil.containsWildcards(qualifierExpressionType)) {
+ try {
+ final String canonicalText = qualifierExpressionType.getCanonicalText();
+ JavaPsiFacade.getElementFactory(containingClass.getProject()).createExpressionFromText(canonicalText + "::foo", qualifierExpression);
+ return canonicalText;
+ }
+ catch (IncorrectOperationException ignore){}
+ }
+ return getClassReferenceName(containingClass);
}
private static String getClassReferenceName(PsiClass containingClass) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index 2559f4e9f3a5..439d23ccaf1b 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -1513,12 +1513,12 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
static List getMethodContracts(@NotNull final PsiMethod method) {
- final PsiAnnotation contractAnno = findContractAnnotation(method);
- if (contractAnno != null) {
- return CachedValuesManager.getCachedValue(contractAnno, new CachedValueProvider>() {
- @Nullable
- @Override
- public Result> compute() {
+ return CachedValuesManager.getCachedValue(method, new CachedValueProvider>() {
+ @Nullable
+ @Override
+ public Result> compute() {
+ final PsiAnnotation contractAnno = findContractAnnotation(method);
+ if (contractAnno != null) {
String text = AnnotationUtil.getStringAttributeValue(contractAnno, null);
if (text != null) {
try {
@@ -1534,12 +1534,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
catch (Exception ignored) {
}
}
- return Result.create(Collections.emptyList(), contractAnno, method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
}
- });
- }
-
- return Collections.emptyList();
+ return Result.create(Collections.emptyList(), method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
+ }
+ });
}
@Nullable
diff --git a/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java b/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java
index 015c9efab8bc..e5660c288fa9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java
+++ b/java/java-impl/src/com/intellij/codeInsight/JavaTargetElementEvaluator.java
@@ -315,7 +315,7 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
if (referenceExpression != null && element instanceof PsiMethod) {
final PsiClass[] memberClass = getMemberClass(referenceExpression, element);
if (memberClass != null && memberClass.length == 1) {
- return CachedValuesManager.getCachedValue(referenceExpression, new CachedValueProvider() {
+ return CachedValuesManager.getCachedValue(memberClass[0], new CachedValueProvider() {
@Nullable
@Override
public Result compute() {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java
index 544925856a52..b770f5839835 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -139,11 +139,8 @@ public class ClassInnerStuffCache {
@Nullable
@Override
public Result compute() {
- PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
String text = "public static " + myClass.getName() + "[] values() { }";
- PsiMethod physicalMethod = factory.createMethodFromText(text, myClass);
- PsiMethod method = new LightMethod(myClass.getManager(), physicalMethod, myClass);
- return new Result(method, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
+ return new Result(getSyntheticMethod(text), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
}
});
}
@@ -154,11 +151,8 @@ public class ClassInnerStuffCache {
@Nullable
@Override
public Result compute() {
- PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
String text = "public static " + myClass.getName() + " valueOf(java.lang.String name) throws java.lang.IllegalArgumentException { }";
- PsiMethod physicalMethod = factory.createMethodFromText(text, myClass);
- PsiMethod method = new LightMethod(myClass.getManager(), physicalMethod, myClass);
- return new Result(method, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
+ return new Result(getSyntheticMethod(text), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
}
});
}
@@ -236,6 +230,12 @@ public class ClassInnerStuffCache {
return cachedInners;
}
+ private PsiMethod getSyntheticMethod(String text) {
+ PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
+ PsiMethod method = factory.createMethodFromText(text, myClass);
+ return new LightMethod(myClass.getManager(), method, myClass);
+ }
+
public void dropCaches() {
myTracker.incModificationCount();
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java
new file mode 100644
index 000000000000..d4db9714b032
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java
@@ -0,0 +1,15 @@
+// "Replace lambda with method reference" "true"
+
+import java.util.function.Function;
+
+class Test {
+
+
+ class Bar {
+ void f( ){
+ Function.Bar, String> r = Bar::foo;
+ }
+
+ private String foo() {}
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java
new file mode 100644
index 000000000000..04df9584ad1a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeLambdaWithFormalParametersWithParameterizedContainerClassToReceiverMethodRef.java
@@ -0,0 +1,15 @@
+// "Replace lambda with method reference" "true"
+
+import java.util.function.Function;
+
+class Test {
+
+
+ class Bar {
+ void f( ){
+ Function.Bar, String> r = (Test.Bar t) -> t.foo();
+ }
+
+ private String foo() {}
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java b/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java
index 65d04a22dfb1..a8c4f255248b 100644
--- a/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java
+++ b/java/java-tests/testSrc/com/intellij/find/FindInEditorMultiCaretTest.java
@@ -148,11 +148,11 @@ public class FindInEditorMultiCaretTest extends LightPlatformCodeInsightFixtureT
}
private void nextOccurrence() {
- executeHeaderAction(EditorSearchSession.createNextOccurrenceAction());
+ executeHeaderAction(new NextOccurrenceAction());
}
private void prevOccurrence() {
- executeHeaderAction(EditorSearchSession.createPrevOccurrenceAction());
+ executeHeaderAction(new PrevOccurrenceAction());
}
private void addOccurrence() {
diff --git a/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java b/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java
index 65b49bcd2aac..cfcf716c13e0 100644
--- a/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java
+++ b/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java
@@ -22,8 +22,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.WriteExternalException;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
import com.intellij.util.ArrayUtil;
@@ -104,12 +102,7 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
final Profile projectProfile = myProfiles.get(profile);
if (projectProfile != null) {
Element profileElement = new Element(PROFILE);
- try {
- projectProfile.writeExternal(profileElement);
- }
- catch (WriteExternalException e) {
- LOG.error(e);
- }
+ projectProfile.writeExternal(profileElement);
boolean hasSmthToSave = sortedProfiles.length > 1 || isCustomProfileUsed();
if (!hasSmthToSave) {
for (Element child : profileElement.getChildren()) {
@@ -141,16 +134,12 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
for (Element o : state.getChildren(PROFILE)) {
Profile profile = myApplicationProfileManager.createProfile();
profile.setProfileManager(this);
- try {
- profile.readExternal(o);
- }
- catch (InvalidDataException e) {
- LOG.error(e);
- }
+ profile.readExternal(o);
profile.setProjectLevel(true);
if (profileKeys.contains(profile.getName())) {
updateProfile(profile);
- } else {
+ }
+ else {
myProfiles.put(profile.getName(), profile);
}
}
@@ -252,10 +241,6 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
});
}
- public void removeProfilesListener(@NotNull ProfileChangeAdapter profilesListener) {
- myProfilesListener.remove(profilesListener);
- }
-
public static class ProfileStateSplitter extends MainConfigurationStateSplitter {
@NotNull
@Override
diff --git a/platform/analysis-api/src/com/intellij/profile/Profile.java b/platform/analysis-api/src/com/intellij/profile/Profile.java
index 64150f91fbad..7aa2370836b5 100644
--- a/platform/analysis-api/src/com/intellij/profile/Profile.java
+++ b/platform/analysis-api/src/com/intellij/profile/Profile.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -16,14 +16,14 @@
package com.intellij.profile;
import com.intellij.openapi.options.Scheme;
-import com.intellij.openapi.util.JDOMExternalizable;
+import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
/**
* User: anna
* Date: 20-Nov-2005
*/
-public interface Profile extends JDOMExternalizable, Comparable, Scheme {
+public interface Profile extends Comparable, Scheme {
void copyFrom(@NotNull Profile profile);
void setLocal(boolean isLocal);
@@ -48,4 +48,8 @@ public interface Profile extends JDOMExternalizable, Comparable, Scheme {
@NotNull
ProfileManager getProfileManager();
+
+ void readExternal(Element element);
+
+ void writeExternal(Element element);
}
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java
index 263ba488e5e0..f3295fcd50e6 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.intellij.codeInspection.ex;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
@@ -27,7 +26,6 @@ import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.options.ExternalInfo;
import com.intellij.openapi.options.ExternalizableScheme;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
@@ -253,7 +251,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
}
@Override
- public void readExternal(@NotNull Element element) throws InvalidDataException {
+ public void readExternal(@NotNull Element element) {
super.readExternal(element);
final String version = element.getAttributeValue(VERSION_TAG);
@@ -868,12 +866,6 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
}
}
- @Override
- @Nullable
- public ExternalInfo getExternalInfo() {
- return null;
- }
-
@NotNull
public List getAllTools(Project project) {
initInspectionTools(project);
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
index d5b60c4b88a4..5f7e9014cf99 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
@@ -142,7 +142,7 @@ public class ToolsImpl implements Tools {
return result;
}
- public void writeExternal(Element inspectionElement) throws WriteExternalException {
+ public void writeExternal(@NotNull Element inspectionElement) throws WriteExternalException {
if (myTools != null) {
for (ScopeToolState state : myTools) {
final Element scopeElement = new Element("scope");
diff --git a/platform/analysis-impl/src/com/intellij/profile/ProfileEx.java b/platform/analysis-impl/src/com/intellij/profile/ProfileEx.java
index dc7040e868c3..388a3c8eac12 100644
--- a/platform/analysis-impl/src/com/intellij/profile/ProfileEx.java
+++ b/platform/analysis-impl/src/com/intellij/profile/ProfileEx.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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,10 +15,7 @@
*/
package com.intellij.profile;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.WriteExternalException;
import com.intellij.util.xmlb.SmartSerializer;
import com.intellij.util.xmlb.annotations.OptionTag;
import com.intellij.util.xmlb.annotations.Transient;
@@ -30,8 +27,6 @@ import org.jetbrains.annotations.NotNull;
* Date: 01-Dec-2005
*/
public abstract class ProfileEx implements Profile {
- private static final Logger LOG = Logger.getInstance(ProfileEx.class);
-
public static final String SCOPE = "scope";
public static final String NAME = "name";
@@ -68,17 +63,9 @@ public abstract class ProfileEx implements Profile {
@Override
public void copyFrom(@NotNull Profile profile) {
- try {
- Element config = new Element("config");
- profile.writeExternal(config);
- readExternal(config);
- }
- catch (WriteExternalException e) {
- LOG.error(e);
- }
- catch (InvalidDataException e) {
- LOG.error(e);
- }
+ Element config = new Element("config");
+ profile.writeExternal(config);
+ readExternal(config);
}
@Override
@@ -121,7 +108,7 @@ public abstract class ProfileEx implements Profile {
}
@Override
- public void readExternal(Element element) throws InvalidDataException {
+ public void readExternal(Element element) {
mySerializer.readExternal(this, element);
}
@@ -130,7 +117,7 @@ public abstract class ProfileEx implements Profile {
}
@Override
- public void writeExternal(Element element) throws WriteExternalException {
+ public void writeExternal(Element element) {
serializeInto(element, true);
}
diff --git a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt
index 27ac1dbc5e2e..3e8a1fc3e03f 100644
--- a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt
+++ b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt
@@ -15,6 +15,8 @@
*/
package com.intellij.configurationStore
+import com.intellij.ide.actions.ExportableItem
+import com.intellij.ide.actions.getExportableComponentsMap
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.*
import com.intellij.openapi.vfs.CharsetToolkit
@@ -33,6 +35,7 @@ import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import java.io.ByteArrayInputStream
+import java.io.File
import java.io.InputStream
import java.nio.file.Path
import java.nio.file.Paths
@@ -109,6 +112,17 @@ internal class ApplicationStoreTest {
assertThat(oldFile).doesNotExist()
}
+ @Test fun `export settings`() {
+ val storageManager = ApplicationManager.getApplication().stateStore.stateStorageManager
+ val optionsPath = storageManager.expandMacros(StoragePathMacros.APP_CONFIG)
+ val rootConfigPath = storageManager.expandMacros(ROOT_CONFIG)
+ val map = getExportableComponentsMap(false, true, storageManager)
+ assertThat(map.size()).isNotEqualTo(0)
+
+ val key = File(optionsPath, "filetypes.xml")
+ assertThat(map.get(key)).containsExactly(ExportableItem(listOf(key, File(rootConfigPath, "filetypes")), "File types", RoamingType.DEFAULT))
+ }
+
private fun createComponentData(foo: String) = """"""
@Test fun `remove data from deprecated storage if another component data exists`() {
diff --git a/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt b/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt
index 27663ecbc040..75d15662fe08 100644
--- a/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt
+++ b/platform/configuration-store-impl/testSrc/DirectoryBasedStorageTest.kt
@@ -40,7 +40,7 @@ private fun StateStorage.ExternalizationSession.save() {
private fun StateStorageBase<*>.setStateAndSave(componentName: String, state: String?) {
var externalizationSession = startExternalization()!!
- externalizationSession.setState(null, componentName, if (state == null) Element("state") else JDOMUtil.load(state.reader))
+ externalizationSession.setState(null, componentName, if (state == null) Element("state") else JDOMUtil.load(state.reader()))
externalizationSession.save()
}
diff --git a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt
index 2082a7ceea56..d48f33c9210f 100644
--- a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt
+++ b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt
@@ -39,7 +39,7 @@ class ModuleStoreTest {
}
}
- private fun VirtualFile.loadModule() = runWriteAction { ModuleManager.getInstance(projectRule.project).loadModule(getPath()) }
+ private fun VirtualFile.loadModule() = runWriteAction { ModuleManager.getInstance(projectRule.project).loadModule(path) }
fun Path.createModule() = projectRule.createModule(this)
}
@@ -51,8 +51,7 @@ class ModuleStoreTest {
@Test fun `set option`() {
val moduleFile = runWriteAction {
- VfsTestUtil.createFile(tempDirManager.newVirtualDirectory("module"), "test.iml", "\n" +
- "")
+ VfsTestUtil.createFile(tempDirManager.newVirtualDirectory("module"), "test.iml", "\n")
}
moduleFile.loadModule().useAndDispose {
@@ -117,7 +116,7 @@ class ModuleStoreTest {
assertThat(moduleFile).isRegularFile()
val virtualFile = LocalFileSystem.getInstance().findFileByPath(modulePath)!!
- val newData = moduleFile.readText().replace("\n", "").toByteArray()
+ val newData = moduleFile.readText().replace("\n", "").toByteArray()
runWriteAction {
virtualFile.setBinaryContent(newData)
}
diff --git a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt
index 1e66ba93b924..8eab00a7b829 100644
--- a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt
+++ b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.impl.ProjectManagerImpl
import com.intellij.openapi.util.io.systemIndependentPath
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.*
+import com.intellij.util.PathUtil
import org.assertj.core.api.Assertions.assertThat
import org.intellij.lang.annotations.Language
import org.junit.ClassRule
@@ -64,7 +65,7 @@ private fun createOrLoadProject(tempDirManager: TemporaryDirectory, task: (Proje
}
}
-class ProjectStoreTest {
+internal class ProjectStoreTest {
companion object {
@ClassRule val projectRule = ProjectRule()
}
@@ -76,12 +77,7 @@ class ProjectStoreTest {
@Language("XML")
private val iprFileContent =
- "\n" +
- "\n" +
- " \n" +
- " \n" +
- " \n" +
- ""
+ "\n\n \n \n \n"
@State(name = "AATestComponent", storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE)))
private class TestComponent : PersistentStateComponent {
@@ -103,6 +99,8 @@ class ProjectStoreTest {
}) { project ->
val testComponent = test(project)
+ assertThat(project.basePath).isEqualTo(PathUtil.getParentPath((PathUtil.getParentPath(project.projectFilePath!!))))
+
// test reload on external change
val file = File(project.stateStore.stateStorageManager.expandMacros(StoragePathMacros.PROJECT_FILE))
file.writeText(file.readText().replace("""""", """"""))
@@ -117,6 +115,8 @@ class ProjectStoreTest {
@Test fun fileBasedStorage() {
loadAndUseProject(tempDirManager, { it.writeChild("test${ProjectFileType.DOT_DEFAULT_EXTENSION}", iprFileContent).path }) { project ->
test(project)
+
+ assertThat(project.basePath).isEqualTo(PathUtil.getParentPath(project.projectFilePath!!))
}
}
diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt
index eec50f3c5811..af887d26a771 100644
--- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt
+++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt
@@ -375,9 +375,6 @@ data class TestScheme(@field:Attribute private var name: String = "", @field:Att
override @Transient fun setName(newName: String) {
name = newName
}
-
- @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
- override fun getExternalInfo() = null
}
open class TestSchemesProcessor : BaseSchemeProcessor() {
diff --git a/platform/core-api/src/com/intellij/openapi/options/ExternalizableScheme.java b/platform/core-api/src/com/intellij/openapi/options/ExternalizableScheme.java
index 25ef647ba133..59fb7f043335 100644
--- a/platform/core-api/src/com/intellij/openapi/options/ExternalizableScheme.java
+++ b/platform/core-api/src/com/intellij/openapi/options/ExternalizableScheme.java
@@ -16,13 +16,7 @@
package com.intellij.openapi.options;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
public interface ExternalizableScheme extends Scheme {
- @SuppressWarnings({"unused", "deprecation"})
- @Nullable
- @Deprecated
- ExternalInfo getExternalInfo();
-
void setName(@NotNull String newName);
}
diff --git a/platform/core-api/src/com/intellij/openapi/options/ExternalizableSchemeAdapter.java b/platform/core-api/src/com/intellij/openapi/options/ExternalizableSchemeAdapter.java
index 43caad945b52..d53eb269c504 100644
--- a/platform/core-api/src/com/intellij/openapi/options/ExternalizableSchemeAdapter.java
+++ b/platform/core-api/src/com/intellij/openapi/options/ExternalizableSchemeAdapter.java
@@ -16,17 +16,10 @@
package com.intellij.openapi.options;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
public abstract class ExternalizableSchemeAdapter implements ExternalizableScheme {
protected String myName;
- @Override
- @Nullable
- public final ExternalInfo getExternalInfo() {
- return null;
- }
-
@Override
@NotNull
public final String getName() {
diff --git a/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java b/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java
index 61904cf83ae7..5d4599feb32d 100644
--- a/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java
+++ b/platform/core-api/src/com/intellij/patterns/PsiElementPattern.java
@@ -339,6 +339,19 @@ public abstract class PsiElementPattern("withLastChildSkipping") {
+ @Override
+ public boolean accepts(@NotNull T t, ProcessingContext context) {
+ PsiElement last = t.getLastChild();
+ while (last != null && skip.accepts(last)) {
+ last = last.getPrevSibling();
+ }
+ return pattern.accepts(last);
+ }
+ });
+ }
+
public static class Capture extends PsiElementPattern> {
protected Capture(final Class aClass) {
diff --git a/platform/diff-impl/src/com/intellij/diff/actions/ProxyUndoRedoAction.java b/platform/diff-impl/src/com/intellij/diff/actions/ProxyUndoRedoAction.java
new file mode 100644
index 000000000000..1e7a30f62c59
--- /dev/null
+++ b/platform/diff-impl/src/com/intellij/diff/actions/ProxyUndoRedoAction.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000-2015 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.diff.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.EmptyAction;
+import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.command.undo.UndoManager;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class ProxyUndoRedoAction extends DumbAwareAction {
+ @NotNull private final UndoManager myUndoManager;
+ @NotNull private final TextEditor myEditor;
+ private final boolean myUndo;
+
+ private ProxyUndoRedoAction(@NotNull UndoManager manager, @NotNull TextEditor editor, boolean undo) {
+ myUndoManager = manager;
+ myEditor = editor;
+ myUndo = undo;
+ }
+
+ public static void register(@Nullable Project project, @NotNull Editor editor, @NotNull JComponent component) {
+ UndoManager undoManager = project != null ? UndoManager.getInstance(project) : UndoManager.getGlobalInstance();
+ TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(editor);
+ if (undoManager != null) {
+ EmptyAction.setupAction(new ProxyUndoRedoAction(undoManager, textEditor, true), IdeActions.ACTION_UNDO, component);
+ EmptyAction.setupAction(new ProxyUndoRedoAction(undoManager, textEditor, false), IdeActions.ACTION_REDO, component);
+ }
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ e.getPresentation().setEnabled(myUndo ? myUndoManager.isUndoAvailable(myEditor) : myUndoManager.isRedoAvailable(myEditor));
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ if (myUndo) {
+ myUndoManager.undo(myEditor);
+ }
+ else {
+ myUndoManager.redo(myEditor);
+ }
+ }
+}
diff --git a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java
index b9a812426e9c..38b3e8e85389 100644
--- a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java
+++ b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeTool.java
@@ -17,6 +17,7 @@ package com.intellij.diff.merge;
import com.intellij.diff.DiffContext;
import com.intellij.diff.FrameDiffTool;
+import com.intellij.diff.actions.ProxyUndoRedoAction;
import com.intellij.diff.comparison.ByLine;
import com.intellij.diff.comparison.ComparisonMergeUtil;
import com.intellij.diff.comparison.ComparisonPolicy;
@@ -44,8 +45,6 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.EditorEx;
-import com.intellij.openapi.fileEditor.TextEditor;
-import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
@@ -225,10 +224,7 @@ public class TextMergeTool implements MergeTool {
DiffUtil.registerAction(new IgnoreSelectedChangesAction(Side.LEFT, true), myPanel);
DiffUtil.registerAction(new IgnoreSelectedChangesAction(Side.RIGHT, true), myPanel);
- if (myUndoManager != null) {
- new UndoRedoAction(true).register();
- new UndoRedoAction(false).register();
- }
+ ProxyUndoRedoAction.register(getProject(), getEditor(ThreeSide.BASE), myContentPanel);
}
@Override
@@ -1161,43 +1157,6 @@ public class TextMergeTool implements MergeTool {
// Helpers
//
- private class UndoRedoAction extends DumbAwareAction {
- private final boolean myUndo;
-
- public UndoRedoAction(boolean undo) {
- myUndo = undo;
- }
-
- public void register() {
- EmptyAction.setupAction(this, myUndo ? IdeActions.ACTION_UNDO : IdeActions.ACTION_REDO, myContentPanel);
- }
-
- @Override
- public void update(AnActionEvent e) {
- assert myUndoManager != null;
- TextEditor textEditor = getTextEditor();
- e.getPresentation().setEnabled(myUndo ? myUndoManager.isUndoAvailable(textEditor) : myUndoManager.isRedoAvailable(textEditor));
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- assert myUndoManager != null;
- TextEditor textEditor = getTextEditor();
- if (myUndo) {
- myUndoManager.undo(textEditor);
- }
- else {
- myUndoManager.redo(textEditor);
- }
- }
-
- @NotNull
- private TextEditor getTextEditor() {
- EditorEx editor = getEditor(ThreeSide.BASE);
- return TextEditorProvider.getInstance().getTextEditor(editor);
- }
- }
-
private class MyDividerPaintable implements DiffDividerDrawUtil.DividerPaintable {
@NotNull private final Side mySide;
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java
index 066d2710ff58..ff6e13e39a3f 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java
@@ -16,6 +16,7 @@
package com.intellij.diff.tools.util.side;
import com.intellij.diff.DiffContext;
+import com.intellij.diff.actions.ProxyUndoRedoAction;
import com.intellij.diff.actions.impl.FocusOppositePaneAction;
import com.intellij.diff.actions.impl.OpenInEditorWithMouseAction;
import com.intellij.diff.actions.impl.SetEditorSettingsAction;
@@ -80,6 +81,12 @@ public abstract class TwosideTextDiffViewer extends TwosideDiffViewer COMPONENT_KEY = DataKey.create("search-replace-component");
- public static final DataKey STATUS_TEXT_KEY = DataKey.create("search-replace-status-text");
-
private final EventDispatcher myEventDispatcher = EventDispatcher.create(Listener.class);
private final MyTextComponentWrapper mySearchFieldWrapper;
@@ -90,7 +87,7 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat
private final DataProvider myDataProviderDelegate;
private boolean myMultilineMode;
- private String myStatusText;
+ private String myStatusText = "";
@NotNull
public static Builder buildFor(@Nullable Project project, @NotNull JComponent component) {
@@ -225,6 +222,11 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat
myStatusText = status;
}
+ @NotNull
+ public String getStatusText() {
+ return myStatusText;
+ }
+
public void replace() {
if (myReplaceAction != null) {
myReplaceAction.run();
@@ -258,12 +260,6 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat
@Nullable
@Override
public Object getData(@NonNls String dataId) {
- if (STATUS_TEXT_KEY.is(dataId)) {
- return myStatusText;
- }
- if (COMPONENT_KEY.is(dataId)) {
- return this;
- }
if (SpeedSearchSupply.SPEED_SEARCH_CURRENT_QUERY.is(dataId)) {
return mySearchTextComponent.getText();
}
diff --git a/platform/lang-impl/src/com/intellij/find/SearchSession.java b/platform/lang-impl/src/com/intellij/find/SearchSession.java
new file mode 100644
index 000000000000..2f10e7767d3b
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/find/SearchSession.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2015 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.find;
+
+import com.intellij.openapi.actionSystem.DataKey;
+import org.jetbrains.annotations.NotNull;
+
+public interface SearchSession {
+ DataKey KEY = DataKey.create("search.replace.session");
+ String INCORRECT_REGEX_MESSAGE = "Incorrect regular expression";
+
+ @NotNull
+ FindModel getFindModel();
+
+ @NotNull
+ SearchReplaceComponent getComponent();
+
+ boolean hasMatches();
+
+ void searchForward();
+
+ void searchBackward();
+
+ void close();
+}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderSetSearchContextAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderSetSearchContextAction.java
index e8f185a1ad93..022e82599a7b 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderSetSearchContextAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderSetSearchContextAction.java
@@ -15,8 +15,8 @@
*/
package com.intellij.find.editorHeaderActions;
-import com.intellij.find.EditorSearchSession;
import com.intellij.find.FindModel;
+import com.intellij.find.SearchSession;
import org.jetbrains.annotations.NotNull;
public class EditorHeaderSetSearchContextAction extends EditorHeaderToggleAction {
@@ -29,12 +29,12 @@ public class EditorHeaderSetSearchContextAction extends EditorHeaderToggleAction
}
@Override
- protected boolean isSelected(@NotNull EditorSearchSession session) {
+ protected boolean isSelected(@NotNull SearchSession session) {
return session.getFindModel().getSearchContext() == myContext;
}
@Override
- protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
+ protected void setSelected(@NotNull SearchSession session, boolean selected) {
session.getFindModel().setSearchContext(selected ? myContext : FindModel.SearchContext.ANY);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderToggleAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderToggleAction.java
index aea1f7b9a968..1d9af865a8fc 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderToggleAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/EditorHeaderToggleAction.java
@@ -1,6 +1,6 @@
package com.intellij.find.editorHeaderActions;
-import com.intellij.find.EditorSearchSession;
+import com.intellij.find.SearchSession;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.ex.CheckboxAction;
@@ -34,19 +34,19 @@ public abstract class EditorHeaderToggleAction extends CheckboxAction implements
@Override
public boolean isSelected(AnActionEvent e) {
- EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
+ SearchSession search = e.getData(SearchSession.KEY);
return search != null && isSelected(search);
}
@Override
public void setSelected(AnActionEvent e, boolean selected) {
- EditorSearchSession search = e.getData(EditorSearchSession.SESSION_KEY);
+ SearchSession search = e.getData(SearchSession.KEY);
if (search != null) {
setSelected(search, selected);
}
}
- protected abstract boolean isSelected(@NotNull EditorSearchSession session);
+ protected abstract boolean isSelected(@NotNull SearchSession session);
- protected abstract void setSelected(@NotNull EditorSearchSession session, boolean selected);
+ protected abstract void setSelected(@NotNull SearchSession session, boolean selected);
}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/NextOccurrenceAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/NextOccurrenceAction.java
index 3d393b71ac06..6b97875e1bb8 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/NextOccurrenceAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/NextOccurrenceAction.java
@@ -15,6 +15,8 @@
*/
package com.intellij.find.editorHeaderActions;
+import com.intellij.find.SearchSession;
+import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.Shortcut;
@@ -24,8 +26,13 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
public final class NextOccurrenceAction extends PrevNextOccurrenceAction {
- public NextOccurrenceAction(@NotNull Handler handler) {
- super(IdeActions.ACTION_NEXT_OCCURENCE, handler);
+ public NextOccurrenceAction() {
+ super(IdeActions.ACTION_NEXT_OCCURENCE);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ e.getRequiredData(SearchSession.KEY).searchForward();
}
@NotNull
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevNextOccurrenceAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevNextOccurrenceAction.java
index 0848c7ec728f..2ca45259c1ae 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevNextOccurrenceAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevNextOccurrenceAction.java
@@ -15,7 +15,7 @@
*/
package com.intellij.find.editorHeaderActions;
-import com.intellij.find.SearchReplaceComponent;
+import com.intellij.find.SearchSession;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.util.containers.ContainerUtil;
@@ -25,28 +25,21 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public abstract class PrevNextOccurrenceAction extends DumbAwareAction implements ContextAwareShortcutProvider {
- private final Handler myHandler;
-
- PrevNextOccurrenceAction(@NotNull String templateActionId, @NotNull Handler handler) {
+ PrevNextOccurrenceAction(@NotNull String templateActionId) {
copyFrom(ActionManager.getInstance().getAction(templateActionId));
- myHandler = handler;
}
@Override
public final void update(AnActionEvent e) {
- myHandler.update(e);
- }
-
- @Override
- public final void actionPerformed(AnActionEvent e) {
- myHandler.actionPerformed(e);
+ SearchSession search = e.getData(SearchSession.KEY);
+ e.getPresentation().setEnabled(search != null && search.hasMatches());
}
@Nullable
@Override
public final ShortcutSet getShortcut(@NotNull DataContext context) {
- SearchReplaceComponent searchComponent = SearchReplaceComponent.COMPONENT_KEY.getData(context);
- boolean singleLine = searchComponent != null && !searchComponent.isMultiline();
+ SearchSession search = SearchSession.KEY.getData(context);
+ boolean singleLine = search != null && !search.getFindModel().isMultiline();
return Utils.shortcutSetOf(singleLine ? ContainerUtil.concat(getDefaultShortcuts(), getSingleLineShortcuts()) : getDefaultShortcuts());
}
@@ -55,11 +48,4 @@ public abstract class PrevNextOccurrenceAction extends DumbAwareAction implement
@NotNull
protected abstract List getSingleLineShortcuts();
-
-
- public interface Handler {
- void update(AnActionEvent e);
-
- void actionPerformed(AnActionEvent e);
- }
}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevOccurrenceAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevOccurrenceAction.java
index 69fdb153005a..fd2b8264c3ae 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevOccurrenceAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/PrevOccurrenceAction.java
@@ -15,6 +15,8 @@
*/
package com.intellij.find.editorHeaderActions;
+import com.intellij.find.SearchSession;
+import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.actionSystem.Shortcut;
@@ -27,8 +29,13 @@ import java.awt.event.KeyEvent;
import java.util.List;
public final class PrevOccurrenceAction extends PrevNextOccurrenceAction {
- public PrevOccurrenceAction(@NotNull Handler handler) {
- super(IdeActions.ACTION_PREVIOUS_OCCURENCE, handler);
+ public PrevOccurrenceAction() {
+ super(IdeActions.ACTION_PREVIOUS_OCCURENCE);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ e.getRequiredData(SearchSession.KEY).searchBackward();
}
@NotNull
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/StatusTextAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/StatusTextAction.java
index 0e0141c9384e..98d440856b2c 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/StatusTextAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/StatusTextAction.java
@@ -15,7 +15,7 @@
*/
package com.intellij.find.editorHeaderActions;
-import com.intellij.find.SearchReplaceComponent;
+import com.intellij.find.SearchSession;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
@@ -29,10 +29,11 @@ import java.awt.*;
public class StatusTextAction extends DumbAwareAction implements CustomComponentAction {
@Override
public void update(AnActionEvent e) {
- String statusText = e.getData(SearchReplaceComponent.STATUS_TEXT_KEY);
+ SearchSession search = e.getData(SearchSession.KEY);
+ String statusText = search == null ? "" : search.getComponent().getStatusText();
JLabel label = (JLabel)e.getPresentation().getClientProperty(CUSTOM_COMPONENT_PROPERTY);
if (label != null) {
- label.setText(StringUtil.notNullize(statusText));
+ label.setText(statusText);
label.setVisible(StringUtil.isNotEmpty(statusText));
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleMatchCase.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleMatchCase.java
index 62ef6a42803a..69e9bdf9a411 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleMatchCase.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleMatchCase.java
@@ -15,8 +15,8 @@
*/
package com.intellij.find.editorHeaderActions;
-import com.intellij.find.EditorSearchSession;
import com.intellij.find.FindSettings;
+import com.intellij.find.SearchSession;
import org.jetbrains.annotations.NotNull;
public class ToggleMatchCase extends EditorHeaderToggleAction {
@@ -25,12 +25,12 @@ public class ToggleMatchCase extends EditorHeaderToggleAction {
}
@Override
- protected boolean isSelected(@NotNull EditorSearchSession session) {
+ protected boolean isSelected(@NotNull SearchSession session) {
return session.getFindModel().isCaseSensitive();
}
@Override
- protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
+ protected void setSelected(@NotNull SearchSession session, boolean selected) {
session.getFindModel().setCaseSensitive(selected);
FindSettings.getInstance().setLocalCaseSensitive(selected);
}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java
index 60b4df84521b..9412d6380966 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/TogglePreserveCaseAction.java
@@ -17,6 +17,7 @@ package com.intellij.find.editorHeaderActions;
import com.intellij.find.EditorSearchSession;
import com.intellij.find.FindModel;
+import com.intellij.find.SearchSession;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
@@ -35,12 +36,12 @@ public class TogglePreserveCaseAction extends EditorHeaderToggleAction {
}
@Override
- protected boolean isSelected(@NotNull EditorSearchSession session) {
+ protected boolean isSelected(@NotNull SearchSession session) {
return session.getFindModel().isPreserveCase();
}
@Override
- protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
+ protected void setSelected(@NotNull SearchSession session, boolean selected) {
session.getFindModel().setPreserveCase(selected);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleRegex.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleRegex.java
index adbfb1678173..8eae08363699 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleRegex.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleRegex.java
@@ -15,9 +15,9 @@
*/
package com.intellij.find.editorHeaderActions;
-import com.intellij.find.EditorSearchSession;
import com.intellij.find.FindModel;
import com.intellij.find.FindSettings;
+import com.intellij.find.SearchSession;
import org.jetbrains.annotations.NotNull;
public class ToggleRegex extends EditorHeaderToggleAction {
@@ -26,12 +26,12 @@ public class ToggleRegex extends EditorHeaderToggleAction {
}
@Override
- protected boolean isSelected(@NotNull EditorSearchSession session) {
+ protected boolean isSelected(@NotNull SearchSession session) {
return session.getFindModel().isRegularExpressions();
}
@Override
- protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
+ protected void setSelected(@NotNull SearchSession session, boolean selected) {
FindModel findModel = session.getFindModel();
findModel.setRegularExpressions(selected);
if (selected) {
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleSelectionOnlyAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleSelectionOnlyAction.java
index a07dca65159e..098efd68238a 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleSelectionOnlyAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleSelectionOnlyAction.java
@@ -1,6 +1,7 @@
package com.intellij.find.editorHeaderActions;
import com.intellij.find.EditorSearchSession;
+import com.intellij.find.SearchSession;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
@@ -18,12 +19,12 @@ public class ToggleSelectionOnlyAction extends EditorHeaderToggleAction {
}
@Override
- protected boolean isSelected(@NotNull EditorSearchSession session) {
+ protected boolean isSelected(@NotNull SearchSession session) {
return !session.getFindModel().isGlobal();
}
@Override
- protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
+ protected void setSelected(@NotNull SearchSession session, boolean selected) {
session.getFindModel().setGlobal(!selected);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleWholeWordsOnlyAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleWholeWordsOnlyAction.java
index 266ec757a895..32dedf0ccef4 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleWholeWordsOnlyAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleWholeWordsOnlyAction.java
@@ -1,7 +1,7 @@
package com.intellij.find.editorHeaderActions;
-import com.intellij.find.EditorSearchSession;
import com.intellij.find.FindSettings;
+import com.intellij.find.SearchSession;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
@@ -14,18 +14,18 @@ public class ToggleWholeWordsOnlyAction extends EditorHeaderToggleAction {
public void update(AnActionEvent e) {
super.update(e);
- EditorSearchSession session = e.getData(EditorSearchSession.SESSION_KEY);
+ SearchSession session = e.getData(SearchSession.KEY);
e.getPresentation().setEnabled(session != null && !session.getFindModel().isRegularExpressions());
e.getPresentation().setVisible(session != null && !session.getFindModel().isMultiline());
}
@Override
- protected boolean isSelected(@NotNull EditorSearchSession session) {
+ protected boolean isSelected(@NotNull SearchSession session) {
return session.getFindModel().isWholeWordsOnly();
}
@Override
- protected void setSelected(@NotNull EditorSearchSession session, boolean selected) {
+ protected void setSelected(@NotNull SearchSession session, boolean selected) {
FindSettings.getInstance().setLocalWholeWordsOnly(selected);
session.getFindModel().setWholeWordsOnly(selected);
}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java
index b5193eddcedf..105b63dba306 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java
@@ -360,9 +360,6 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable
}
JDOMUtil.writeDocument(new Document(element), filePath, SystemProperties.getLineSeparator());
}
- catch (WriteExternalException e1) {
- LOG.error(e1);
- }
catch (IOException e1) {
LOG.error(e1);
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java b/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java
index 686c20b4f0b9..cf83ac0e14ad 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java
@@ -19,7 +19,6 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.components.ExportableComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
@@ -32,6 +31,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.FieldPanel;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.containers.MultiMap;
import gnu.trove.THashSet;
@@ -57,14 +57,14 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
private final boolean myShowFilePath;
private final String myDescription;
- public ChooseComponentsToExportDialog(@NotNull MultiMap fileToComponents,
+ public ChooseComponentsToExportDialog(@NotNull MultiMap fileToComponents,
boolean showFilePath, final String title, String description) {
super(false);
myDescription = description;
myShowFilePath = showFilePath;
- Map componentToContainingListElement = new LinkedHashMap();
- for (ExportableComponent component : fileToComponents.values()) {
+ Map componentToContainingListElement = new LinkedHashMap();
+ for (ExportableItem component : fileToComponents.values()) {
if (!addToExistingListElement(component, componentToContainingListElement, fileToComponents)) {
ComponentElementProperties componentElementProperties = new ComponentElementProperties();
componentElementProperties.addComponent(component);
@@ -147,12 +147,12 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
super.doOKAction();
}
- private static boolean addToExistingListElement(@NotNull ExportableComponent component,
- @NotNull Map componentToContainingListElement,
- @NotNull MultiMap fileToComponents) {
+ private static boolean addToExistingListElement(@NotNull ExportableItem component,
+ @NotNull Map componentToContainingListElement,
+ @NotNull MultiMap fileToComponents) {
File file = null;
- for (File exportFile : component.getExportFiles()) {
- for (ExportableComponent tiedComponent : fileToComponents.get(exportFile)) {
+ for (File exportFile : component.getFiles()) {
+ for (ExportableItem tiedComponent : fileToComponents.get(exportFile)) {
if (tiedComponent == component) {
continue;
}
@@ -234,8 +234,8 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
return panel;
}
- Set getExportableComponents() {
- Set components = new THashSet();
+ Set getExportableComponents() {
+ Set components = new THashSet();
for (ComponentElementProperties elementProperties : myChooser.getMarkedElements()) {
components.addAll(elementProperties.myComponents);
}
@@ -243,9 +243,9 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
}
private static class ComponentElementProperties implements ElementsChooser.ElementProperties {
- private final Set myComponents = new HashSet();
+ private final Set myComponents = new HashSet();
- private boolean addComponent(ExportableComponent component) {
+ private boolean addComponent(ExportableItem component) {
return myComponents.add(component);
}
@@ -263,10 +263,10 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
public String toString() {
Set names = new LinkedHashSet();
- for (ExportableComponent component : myComponents) {
+ for (ExportableItem component : myComponents) {
names.add(component.getPresentableName());
}
- return StringUtil.join(names.toArray(new String[names.size()]), ", ");
+ return StringUtil.join(ArrayUtil.toStringArray(names), ", ");
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
deleted file mode 100644
index f657aa4c95af..000000000000
--- a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright 2000-2015 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.
- */
-
-/**
- * @author cdr
- */
-package com.intellij.ide.actions;
-
-import com.intellij.AbstractBundle;
-import com.intellij.CommonBundle;
-import com.intellij.ide.IdeBundle;
-import com.intellij.ide.plugins.IdeaPluginDescriptor;
-import com.intellij.ide.plugins.PluginManager;
-import com.intellij.ide.plugins.PluginManagerCore;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.application.impl.ApplicationImpl;
-import com.intellij.openapi.components.*;
-import com.intellij.openapi.components.impl.ServiceManagerImpl;
-import com.intellij.openapi.components.impl.stores.StateStorageManager;
-import com.intellij.openapi.components.impl.stores.StoreUtil;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.extensions.PluginDescriptor;
-import com.intellij.openapi.options.OptionsBundle;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.io.FileUtilRt;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.CharsetToolkit;
-import com.intellij.util.PairProcessor;
-import com.intellij.util.PlatformUtils;
-import com.intellij.util.ReflectionUtil;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.MultiMap;
-import com.intellij.util.io.ZipUtil;
-import gnu.trove.THashSet;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.*;
-import java.util.*;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-public class ExportSettingsAction extends AnAction implements DumbAware {
- private static final Logger LOG = Logger.getInstance(ExportSettingsAction.class);
-
- @Override
- public void actionPerformed(@Nullable AnActionEvent e) {
- ApplicationManager.getApplication().saveSettings();
-
- ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(getExportableComponentsMap(true, true), true,
- IdeBundle.message("title.select.components.to.export"),
- IdeBundle.message(
- "prompt.please.check.all.components.to.export"));
- if (!dialog.showAndGet()) {
- return;
- }
-
- Set markedComponents = dialog.getExportableComponents();
- if (markedComponents.isEmpty()) {
- return;
- }
-
- Set exportFiles = new THashSet(FileUtil.FILE_HASHING_STRATEGY);
- for (ExportableComponent markedComponent : markedComponents) {
- ContainerUtil.addAll(exportFiles, markedComponent.getExportFiles());
- }
-
- final File saveFile = dialog.getExportFile();
- try {
- if (saveFile.exists() && Messages.showOkCancelDialog(
- IdeBundle.message("prompt.overwrite.settings.file", FileUtil.toSystemDependentName(saveFile.getPath())),
- IdeBundle.message("title.file.already.exists"), Messages.getWarningIcon()) != Messages.OK) {
- return;
- }
-
- MyZipOutputStream zipOut = new MyZipOutputStream(new BufferedOutputStream(new FileOutputStream(saveFile)));
- try {
- Set writtenItemRelativePaths = new THashSet();
- String configRoot = FileUtilRt.toSystemIndependentName(PathManager.getConfigPath());
- for (File file : exportFiles) {
- if (file.exists()) {
- String relativePath = FileUtilRt.getRelativePath(configRoot, FileUtilRt.toSystemIndependentName(file.getAbsolutePath()), '/');
- assert relativePath != null;
- ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths);
- }
- }
-
- exportInstalledPlugins(zipOut);
-
- ZipEntry zipEntry = new ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER);
- zipOut.putNextEntry(zipEntry);
- zipOut.closeEntry();
- }
- finally {
- zipOut.doClose();
- }
- ShowFilePathAction.showDialog(getEventProject(e), IdeBundle.message("message.settings.exported.successfully"),
- IdeBundle.message("title.export.successful"), saveFile, null);
- }
- catch (IOException e1) {
- Messages.showErrorDialog(IdeBundle.message("error.writing.settings", e1.toString()), IdeBundle.message("title.error.writing.file"));
- }
- }
-
- private static void exportInstalledPlugins(@NotNull MyZipOutputStream zipOut) throws IOException {
- List plugins = new ArrayList();
- for (IdeaPluginDescriptor descriptor : PluginManagerCore.getPlugins()) {
- if (!descriptor.isBundled() && descriptor.isEnabled()) {
- plugins.add(descriptor.getPluginId().getIdString());
- }
- }
- if (plugins.isEmpty()) {
- return;
- }
-
- ZipEntry e = new ZipEntry(PluginManager.INSTALLED_TXT);
- zipOut.putNextEntry(e);
- try {
- PluginManagerCore.writePluginsList(plugins, new OutputStreamWriter(zipOut, CharsetToolkit.UTF8_CHARSET));
- }
- finally {
- zipOut.closeEntry();
- }
- }
-
- private static class MyZipOutputStream extends ZipOutputStream {
- private boolean ignoreClose = true;
-
- public MyZipOutputStream(@NotNull OutputStream out) {
- super(out);
- }
-
- @Override
- public void close() throws IOException {
- if (!ignoreClose) {
- doClose();
- }
- }
-
- public void doClose() throws IOException {
- super.close();
- }
- }
-
- @NotNull
- public static MultiMap getExportableComponentsMap(boolean onlyExisting, boolean computePresentableNames) {
- ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication();
- StateStorageManager storageManager = ComponentsPackage.getStateStore(application).getStateStorageManager();
- return getExportableComponentsMap(onlyExisting, computePresentableNames, storageManager);
- }
-
- @NotNull
- public static MultiMap getExportableComponentsMap(final boolean onlyExisting, final boolean computePresentableNames, final @NotNull StateStorageManager storageManager) {
- @SuppressWarnings("deprecation")
- List components1 = ComponentsPackage.getComponents(ApplicationManager.getApplication(), ExportableApplicationComponent.class);
- List components2 = ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent.class);
- final MultiMap result = MultiMap.createLinkedSet();
- for (ExportableComponent component : ContainerUtil.concat(components1, components2)) {
- for (File exportFile : component.getExportFiles()) {
- result.putValue(exportFile, component);
- }
- }
-
- if (onlyExisting) {
- for (Iterator it = result.keySet().iterator(); it.hasNext(); ) {
- if (!it.next().exists()) {
- it.remove();
- }
- }
- }
-
- ServiceManagerImpl.processAllImplementationClasses((ApplicationImpl)ApplicationManager.getApplication(), new PairProcessor, PluginDescriptor>() {
- @Override
- public boolean process(@NotNull Class> aClass, @Nullable PluginDescriptor pluginDescriptor) {
- State stateAnnotation = StoreUtil.getStateSpec(aClass);
- if (stateAnnotation != null && !StringUtil.isEmpty(stateAnnotation.name())) {
- if (ExportableComponent.class.isAssignableFrom(aClass)) {
- return true;
- }
-
- int storageIndex;
- Storage[] storages = stateAnnotation.storages();
- if (storages.length == 1) {
- storageIndex = 0;
- }
- else {
- return true;
- }
-
- Storage storage = storages[storageIndex];
- if (storage.roamingType() != RoamingType.DISABLED &&
- storage.storageClass().equals(StateStorage.class) &&
- storage.scheme() == StorageScheme.DEFAULT &&
- !StringUtil.isEmpty(storage.file()) &&
- storage.file().startsWith(StoragePathMacros.APP_CONFIG)) {
-
- File additionalExportFile = null;
- if (!StringUtil.isEmpty(stateAnnotation.additionalExportFile())) {
- String expandedPath = storageManager.expandMacros(stateAnnotation.additionalExportFile());
- additionalExportFile = new File(expandedPath);
- if (!additionalExportFile.exists()) {
- //noinspection deprecation
- additionalExportFile = new File(storageManager.expandMacros(StoragePathMacros.ROOT_CONFIG) + '/' + expandedPath);
- }
-
- if (onlyExisting && !additionalExportFile.exists()) {
- additionalExportFile = null;
- }
- }
-
- File file = new File(storageManager.expandMacros(storage.file()));
- boolean fileExists = !onlyExisting || file.exists();
- if (fileExists || additionalExportFile != null) {
- File[] files;
- if (additionalExportFile == null) {
- files = new File[]{file};
- }
- else {
- files = fileExists ? new File[]{file, additionalExportFile} : new File[]{additionalExportFile};
- }
- ExportableComponentItem item = new ExportableComponentItem(files,
- computePresentableNames
- ? getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor)
- : "",
- storage.roamingType());
- result.putValue(file, item);
- if (additionalExportFile != null) {
- result.putValue(additionalExportFile, item);
- }
- }
- }
- }
- return true;
- }
- });
- return result;
- }
-
- @NotNull
- private static String getComponentPresentableName(@NotNull State state, @NotNull Class> aClass, @Nullable PluginDescriptor pluginDescriptor) {
- if (state.presentableName() != State.NameGetter.class) {
- try {
- return ReflectionUtil.newInstance(state.presentableName()).get();
- }
- catch (Exception e) {
- LOG.error(e);
- }
- }
-
- String defaultName = state.name();
- String resourceBundleName;
- if (pluginDescriptor != null && pluginDescriptor instanceof IdeaPluginDescriptor && !"com.intellij".equals(pluginDescriptor.getPluginId().getIdString())) {
- resourceBundleName = ((IdeaPluginDescriptor)pluginDescriptor).getResourceBundleBaseName();
- }
- else {
- resourceBundleName = OptionsBundle.PATH_TO_BUNDLE;
- }
-
- if (resourceBundleName == null) {
- return defaultName;
- }
-
- ClassLoader classLoader = pluginDescriptor == null ? null : pluginDescriptor.getPluginClassLoader();
- classLoader = classLoader == null ? aClass.getClassLoader() : classLoader;
- if (classLoader != null) {
- String message = messageOrDefault(classLoader, resourceBundleName, defaultName);
- if (message != defaultName) {
- return message;
- }
-
- if (PlatformUtils.isRubyMine()) {
- // ruby plugin in RubyMine has id "com.intellij", so, we cannot set "resource-bundle" in plugin.xml
- return messageOrDefault(classLoader, "org.jetbrains.plugins.ruby.RBundle", defaultName);
- }
- }
- return defaultName;
- }
-
- @NotNull
- private static String messageOrDefault(@NotNull ClassLoader classLoader, @NotNull String bundleName, @NotNull String defaultName) {
- ResourceBundle bundle = AbstractBundle.getResourceBundle(bundleName, classLoader);
- return bundle == null ? defaultName : CommonBundle.messageOrDefault(bundle, "exportable." + defaultName + ".presentable.name", defaultName);
- }
-
- public static final class ExportableComponentItem implements ExportableComponent {
- private final File[] files;
- private final String name;
- private final RoamingType roamingType;
-
- public ExportableComponentItem(@NotNull File[] files, @NotNull String name, @NotNull RoamingType roamingType) {
- this.files = files;
- this.name = name;
- this.roamingType = roamingType;
- }
-
- @NotNull
- @Override
- public File[] getExportFiles() {
- return files;
- }
-
- @NotNull
- @Override
- public String getPresentableName() {
- return name;
- }
-
- @NotNull
- public RoamingType getRoamingType() {
- return roamingType;
- }
- }
-}
-
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.kt b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.kt
new file mode 100644
index 000000000000..d547d67d234e
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.kt
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2000-2015 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.ide.actions
+
+import com.intellij.AbstractBundle
+import com.intellij.CommonBundle
+import com.intellij.ide.IdeBundle
+import com.intellij.ide.plugins.IdeaPluginDescriptor
+import com.intellij.ide.plugins.PluginManager
+import com.intellij.ide.plugins.PluginManagerCore
+import com.intellij.openapi.actionSystem.AnAction
+import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.application.PathManager
+import com.intellij.openapi.application.impl.ApplicationImpl
+import com.intellij.openapi.components.*
+import com.intellij.openapi.components.impl.ServiceManagerImpl
+import com.intellij.openapi.components.impl.stores.StateStorageManager
+import com.intellij.openapi.components.impl.stores.StoreUtil
+import com.intellij.openapi.diagnostic.Logger
+import com.intellij.openapi.extensions.PluginDescriptor
+import com.intellij.openapi.options.OptionsBundle
+import com.intellij.openapi.project.DumbAware
+import com.intellij.openapi.ui.Messages
+import com.intellij.openapi.util.io.FileUtil
+import com.intellij.openapi.util.io.FileUtilRt
+import com.intellij.openapi.util.text.StringUtil
+import com.intellij.openapi.vfs.CharsetToolkit
+import com.intellij.util.PairProcessor
+import com.intellij.util.PlatformUtils
+import com.intellij.util.ReflectionUtil
+import com.intellij.util.containers.MultiMap
+import com.intellij.util.io.ZipUtil
+import gnu.trove.THashSet
+import java.io.*
+import java.util.*
+import java.util.zip.ZipEntry
+import java.util.zip.ZipOutputStream
+
+private class ExportSettingsAction : AnAction(), DumbAware {
+ override fun actionPerformed(e: AnActionEvent?) {
+ ApplicationManager.getApplication().saveSettings()
+
+ val dialog = ChooseComponentsToExportDialog(getExportableComponentsMap(true, true), true,
+ IdeBundle.message("title.select.components.to.export"),
+ IdeBundle.message(
+ "prompt.please.check.all.components.to.export"))
+ if (!dialog.showAndGet()) {
+ return
+ }
+
+ val markedComponents = dialog.exportableComponents
+ if (markedComponents.isEmpty()) {
+ return
+ }
+
+ val exportFiles = THashSet(FileUtil.FILE_HASHING_STRATEGY)
+ for (markedComponent in markedComponents) {
+ exportFiles.addAll(markedComponent.files)
+ }
+
+ val saveFile = dialog.exportFile
+ try {
+ if (saveFile.exists() && Messages.showOkCancelDialog(
+ IdeBundle.message("prompt.overwrite.settings.file", FileUtil.toSystemDependentName(saveFile.path)),
+ IdeBundle.message("title.file.already.exists"), Messages.getWarningIcon()) != Messages.OK) {
+ return
+ }
+
+ val zipOut = MyZipOutputStream(BufferedOutputStream(FileOutputStream(saveFile)))
+ try {
+ val writtenItemRelativePaths = THashSet()
+ val configRoot = FileUtilRt.toSystemIndependentName(PathManager.getConfigPath())
+ for (file in exportFiles) {
+ if (file.exists()) {
+ val relativePath = FileUtilRt.getRelativePath(configRoot, FileUtilRt.toSystemIndependentName(file.absolutePath), '/')!!
+ ZipUtil.addFileOrDirRecursively(zipOut, null, file, relativePath, null, writtenItemRelativePaths)
+ }
+ }
+
+ exportInstalledPlugins(zipOut)
+
+ val zipEntry = ZipEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER)
+ zipOut.putNextEntry(zipEntry)
+ zipOut.closeEntry()
+ }
+ finally {
+ zipOut.doClose()
+ }
+ ShowFilePathAction.showDialog(AnAction.getEventProject(e), IdeBundle.message("message.settings.exported.successfully"),
+ IdeBundle.message("title.export.successful"), saveFile, null)
+ }
+ catch (e1: IOException) {
+ Messages.showErrorDialog(IdeBundle.message("error.writing.settings", e1.toString()), IdeBundle.message("title.error.writing.file"))
+ }
+ }
+}
+
+private class MyZipOutputStream(out: OutputStream) : ZipOutputStream(out) {
+ override fun close() {
+ }
+
+ fun doClose() {
+ super.close()
+ }
+}
+
+data class ExportableItem(val files: List, val presentableName: String, val roamingType: RoamingType)
+
+private val LOG = Logger.getInstance(ExportSettingsAction::class.java)
+
+private fun exportInstalledPlugins(zipOut: MyZipOutputStream) {
+ val plugins = ArrayList()
+ for (descriptor in PluginManagerCore.getPlugins()) {
+ if (!descriptor.isBundled && descriptor.isEnabled) {
+ plugins.add(descriptor.pluginId.idString)
+ }
+ }
+ if (plugins.isEmpty()) {
+ return
+ }
+
+ val e = ZipEntry(PluginManager.INSTALLED_TXT)
+ zipOut.putNextEntry(e)
+ try {
+ PluginManagerCore.writePluginsList(plugins, OutputStreamWriter(zipOut, CharsetToolkit.UTF8_CHARSET))
+ }
+ finally {
+ zipOut.closeEntry()
+ }
+}
+
+fun getExportableComponentsMap(onlyExisting: Boolean, computePresentableNames: Boolean, storageManager: StateStorageManager = ApplicationManager.getApplication().stateStore.stateStorageManager): MultiMap {
+ val result = MultiMap.createLinkedSet()
+ val processor = { component: ExportableComponent ->
+ val item = ExportableItem(component.exportFiles.toList(), component.presentableName, RoamingType.DEFAULT)
+ for (exportFile in item.files) {
+ result.putValue(exportFile, item)
+ }
+ }
+
+ @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
+ ApplicationManager.getApplication().getComponents(ExportableApplicationComponent::class.java).forEach(processor)
+ ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent::class.java).forEach(processor)
+
+ if (onlyExisting) {
+ val it = result.keySet().iterator()
+ while (it.hasNext()) {
+ if (!it.next().exists()) {
+ it.remove()
+ }
+ }
+ }
+
+ ServiceManagerImpl.processAllImplementationClasses(ApplicationManager.getApplication() as ApplicationImpl, object : PairProcessor, PluginDescriptor> {
+ override fun process(aClass: Class<*>, pluginDescriptor: PluginDescriptor?): Boolean {
+ val stateAnnotation = StoreUtil.getStateSpec(aClass)
+ if (stateAnnotation != null && !StringUtil.isEmpty(stateAnnotation.name)) {
+ if (ExportableComponent::class.java.isAssignableFrom(aClass)) {
+ return true
+ }
+
+ val storageIndex: Int
+ val storages = stateAnnotation.storages
+ if (storages.size() == 1) {
+ storageIndex = 0
+ }
+ else {
+ return true
+ }
+
+ val storage = storages[storageIndex]
+ if (storage.roamingType != RoamingType.DISABLED && storage.storageClass == StateStorage::class && storage.scheme == StorageScheme.DEFAULT && !storage.file.isNullOrEmpty()) {
+ var additionalExportFile: File? = null
+ var additionalExportPath = stateAnnotation.additionalExportFile
+ if (additionalExportPath.isNotEmpty()) {
+ // backward compatibility - path can contain macro
+ @Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
+ if (additionalExportPath[0] != '$') {
+ additionalExportPath = StoragePathMacros.ROOT_CONFIG + "/" + additionalExportPath
+ }
+ additionalExportFile = File(storageManager.expandMacros(additionalExportPath))
+ if (onlyExisting && !additionalExportFile.exists()) {
+ additionalExportFile = null
+ }
+ }
+
+ val file = File(storageManager.expandMacros(storage.file))
+ val fileExists = !onlyExisting || file.exists()
+ if (fileExists || additionalExportFile != null) {
+ val files = if (additionalExportFile == null) listOf(file) else if (fileExists) listOf(file, additionalExportFile) else listOf(additionalExportFile)
+ val item = ExportableItem(files, if (computePresentableNames) getComponentPresentableName(stateAnnotation, aClass, pluginDescriptor) else "", storage.roamingType)
+ result.putValue(file, item)
+ if (additionalExportFile != null) {
+ result.putValue(additionalExportFile, item)
+ }
+ }
+ }
+ }
+ return true
+ }
+ })
+ return result
+}
+
+private fun getComponentPresentableName(state: State, aClass: Class<*>, pluginDescriptor: PluginDescriptor?): String {
+ val presentableName = state.presentableName.java
+ if (presentableName != State.NameGetter::class.java) {
+ try {
+ return ReflectionUtil.newInstance(presentableName).get()
+ }
+ catch (e: Exception) {
+ LOG.error(e)
+ }
+ }
+
+ val defaultName = state.name
+ val resourceBundleName = (if (pluginDescriptor is IdeaPluginDescriptor && "com.intellij" != pluginDescriptor.pluginId.idString) {
+ pluginDescriptor.resourceBundleBaseName
+ }
+ else {
+ OptionsBundle.PATH_TO_BUNDLE
+ }) ?: return defaultName
+
+ var classLoader = pluginDescriptor?.pluginClassLoader ?: aClass.classLoader
+ if (classLoader != null) {
+ val message = messageOrDefault(classLoader, resourceBundleName, defaultName)
+ if (message !== defaultName) {
+ return message
+ }
+
+ if (PlatformUtils.isRubyMine()) {
+ // ruby plugin in RubyMine has id "com.intellij", so, we cannot set "resource-bundle" in plugin.xml
+ return messageOrDefault(classLoader, "org.jetbrains.plugins.ruby.RBundle", defaultName)
+ }
+ }
+ return defaultName
+}
+
+private fun messageOrDefault(classLoader: ClassLoader, bundleName: String, defaultName: String): String {
+ val bundle = AbstractBundle.getResourceBundle(bundleName, classLoader) ?: return defaultName
+ return CommonBundle.messageOrDefault(bundle, "exportable.$defaultName.presentable.name", defaultName)
+}
+
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java
deleted file mode 100644
index db61dbc06aaa..000000000000
--- a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright 2000-2015 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.
- */
-
-/**
- * @author cdr
- */
-package com.intellij.ide.actions;
-
-import com.intellij.ide.IdeBundle;
-import com.intellij.ide.plugins.PluginManager;
-import com.intellij.ide.startup.StartupActionScriptManager;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ApplicationNamesInfo;
-import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.application.ex.ApplicationEx;
-import com.intellij.openapi.components.ExportableComponent;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.updateSettings.impl.UpdateSettings;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.io.FileUtilRt;
-import com.intellij.util.Consumer;
-import com.intellij.util.containers.MultiMap;
-import gnu.trove.THashSet;
-import org.jetbrains.annotations.NotNull;
-
-import java.awt.*;
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
-
-public class ImportSettingsAction extends AnAction implements DumbAware {
- @Override
- public void actionPerformed(@NotNull AnActionEvent e) {
- final DataContext dataContext = e.getDataContext();
- final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);
- ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, IdeBundle.message("title.import.file.location"), IdeBundle.message("prompt.choose.import.file.path")).doWhenDone(new Consumer() {
- @Override
- public void consume(String path) {
- File saveFile = new File(path);
- try {
- doImport(saveFile);
- }
- catch (ZipException e1) {
- Messages.showErrorDialog(
- IdeBundle.message("error.reading.settings.file", presentableFileName(saveFile), e1.getMessage(), promptLocationMessage()),
- IdeBundle.message("title.invalid.file"));
- }
- catch (IOException e1) {
- Messages.showErrorDialog(IdeBundle.message("error.reading.settings.file.2", presentableFileName(saveFile), e1.getMessage()),
- IdeBundle.message("title.error.reading.file"));
- }
- }
- });
- }
-
- private static void doImport(@NotNull File saveFile) throws IOException {
- if (!saveFile.exists()) {
- Messages.showErrorDialog(IdeBundle.message("error.cannot.find.file", presentableFileName(saveFile)),
- IdeBundle.message("title.file.not.found"));
- return;
- }
-
- @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
- final ZipEntry magicEntry = new ZipFile(saveFile).getEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER);
- if (magicEntry == null) {
- Messages.showErrorDialog(
- IdeBundle.message("error.file.contains.no.settings.to.import", presentableFileName(saveFile), promptLocationMessage()),
- IdeBundle.message("title.invalid.file"));
- return;
- }
-
- MultiMap fileToComponents = ExportSettingsAction.getExportableComponentsMap(false, true);
- List components = getComponentsStored(saveFile, fileToComponents.values());
- fileToComponents.values().retainAll(components);
- final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(fileToComponents, false,
- IdeBundle.message("title.select.components.to.import"),
- IdeBundle.message("prompt.check.components.to.import"));
- if (!dialog.showAndGet()) {
- return;
- }
-
- final Set chosenComponents = dialog.getExportableComponents();
- Set relativeNamesToExtract = new THashSet();
- for (ExportableComponent chosenComponent : chosenComponents) {
- for (File exportFile : chosenComponent.getExportFiles()) {
- String rPath = FileUtilRt.getRelativePath(new File(PathManager.getConfigPath()), exportFile);
- assert rPath != null;
- relativeNamesToExtract.add(FileUtil.toSystemIndependentName(rPath));
- }
- }
-
- relativeNamesToExtract.add(PluginManager.INSTALLED_TXT);
-
- final File tempFile = new File(PathManager.getPluginTempPath() + "/" + saveFile.getName());
- FileUtil.copy(saveFile, tempFile);
- File outDir = new File(PathManager.getConfigPath());
- final ImportSettingsFilenameFilter filenameFilter = new ImportSettingsFilenameFilter(relativeNamesToExtract);
- StartupActionScriptManager.addActionCommand(new StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter));
- // remove temp file
- StartupActionScriptManager.addActionCommand(new StartupActionScriptManager.DeleteCommand(tempFile));
-
- UpdateSettings.getInstance().forceCheckForUpdateAfterRestart();
-
- String key = ApplicationManager.getApplication().isRestartCapable()
- ? "message.settings.imported.successfully.restart"
- : "message.settings.imported.successfully";
- if (Messages.showOkCancelDialog(IdeBundle.message(key,
- ApplicationNamesInfo.getInstance().getProductName(),
- ApplicationNamesInfo.getInstance().getFullProductName()),
- IdeBundle.message("title.restart.needed"), Messages.getQuestionIcon()) == Messages.OK) {
- ((ApplicationEx)ApplicationManager.getApplication()).restart(true);
- }
- }
-
- private static String presentableFileName(@NotNull File file) {
- return "'" + FileUtil.toSystemDependentName(file.getPath()) + "'";
- }
-
- private static String promptLocationMessage() {
- return IdeBundle.message("message.please.ensure.correct.settings");
- }
-
- @NotNull
- private static List getComponentsStored(@NotNull File settings,
- @NotNull Collection extends ExportableComponent> registeredComponents) throws IOException {
- THashSet zipEntries = new THashSet();
- ZipFile zip = new ZipFile(settings);
- try {
- Enumeration enumeration = zip.entries();
- while (enumeration.hasMoreElements()) {
- ZipEntry zipEntry = (ZipEntry)enumeration.nextElement();
- zipEntries.add(zipEntry.getName());
- }
- }
- finally {
- zip.close();
- }
-
- File configPath = new File(PathManager.getConfigPath());
- List components = new ArrayList();
-
- for (ExportableComponent component : registeredComponents) {
- for (File exportFile : component.getExportFiles()) {
- String relativePath = FileUtilRt.getRelativePath(configPath, exportFile);
- assert relativePath != null;
- relativePath = FileUtilRt.toSystemIndependentName(relativePath);
- if (exportFile.getName().indexOf('.') == -1 && !exportFile.isFile()) {
- relativePath += '/';
- }
- if (zipEntries.contains(relativePath)) {
- components.add(component);
- break;
- }
- }
- }
- return components;
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt
new file mode 100644
index 000000000000..44e4d5c57f8e
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.kt
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2000-2015 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.ide.actions
+
+import com.intellij.ide.IdeBundle
+import com.intellij.ide.plugins.PluginManager
+import com.intellij.ide.startup.StartupActionScriptManager
+import com.intellij.openapi.actionSystem.AnAction
+import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.actionSystem.PlatformDataKeys
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.application.ApplicationNamesInfo
+import com.intellij.openapi.application.PathManager
+import com.intellij.openapi.application.ex.ApplicationEx
+import com.intellij.openapi.project.DumbAware
+import com.intellij.openapi.ui.Messages
+import com.intellij.openapi.updateSettings.impl.UpdateSettings
+import com.intellij.openapi.util.io.FileUtil
+import com.intellij.openapi.util.io.FileUtilRt
+import com.intellij.util.Consumer
+import gnu.trove.THashSet
+import java.io.File
+import java.io.IOException
+import java.util.*
+import java.util.zip.ZipException
+import java.util.zip.ZipFile
+
+private class ImportSettingsAction : AnAction(), DumbAware {
+ override fun actionPerformed(e: AnActionEvent) {
+ val dataContext = e.dataContext
+ val component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext)
+ ChooseComponentsToExportDialog.chooseSettingsFile(PathManager.getConfigPath(), component, IdeBundle.message("title.import.file.location"), IdeBundle.message("prompt.choose.import.file.path")).doWhenDone(object : Consumer {
+ override fun consume(path: String) {
+ val saveFile = File(path)
+ try {
+ doImport(saveFile)
+ }
+ catch (e1: ZipException) {
+ Messages.showErrorDialog(
+ IdeBundle.message("error.reading.settings.file", presentableFileName(saveFile), e1.getMessage(), promptLocationMessage()),
+ IdeBundle.message("title.invalid.file"))
+ }
+ catch (e1: IOException) {
+ Messages.showErrorDialog(IdeBundle.message("error.reading.settings.file.2", presentableFileName(saveFile), e1.getMessage()),
+ IdeBundle.message("title.error.reading.file"))
+ }
+ }
+ })
+ }
+
+ private fun doImport(saveFile: File) {
+ if (!saveFile.exists()) {
+ Messages.showErrorDialog(IdeBundle.message("error.cannot.find.file", presentableFileName(saveFile)),
+ IdeBundle.message("title.file.not.found"))
+ return
+ }
+
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
+ val magicEntry = ZipFile(saveFile).getEntry(ImportSettingsFilenameFilter.SETTINGS_JAR_MARKER)
+ if (magicEntry == null) {
+ Messages.showErrorDialog(
+ IdeBundle.message("error.file.contains.no.settings.to.import", presentableFileName(saveFile), promptLocationMessage()),
+ IdeBundle.message("title.invalid.file"))
+ return
+ }
+
+ val fileToComponents = getExportableComponentsMap(false, true)
+ val components = getComponentsStored(saveFile, fileToComponents.values())
+ fileToComponents.values().retainAll(components)
+ val dialog = ChooseComponentsToExportDialog(fileToComponents, false,
+ IdeBundle.message("title.select.components.to.import"),
+ IdeBundle.message("prompt.check.components.to.import"))
+ if (!dialog.showAndGet()) {
+ return
+ }
+
+ val chosenComponents = dialog.exportableComponents
+ val relativeNamesToExtract = THashSet()
+ for (chosenComponent in chosenComponents) {
+ for (exportFile in chosenComponent.files) {
+ relativeNamesToExtract.add(FileUtil.toSystemIndependentName(FileUtilRt.getRelativePath(File(PathManager.getConfigPath()), exportFile)!!))
+ }
+ }
+
+ relativeNamesToExtract.add(PluginManager.INSTALLED_TXT)
+
+ val tempFile = File(PathManager.getPluginTempPath(), saveFile.name)
+ FileUtil.copy(saveFile, tempFile)
+ val outDir = File(PathManager.getConfigPath())
+ val filenameFilter = ImportSettingsFilenameFilter(relativeNamesToExtract)
+ StartupActionScriptManager.addActionCommand(StartupActionScriptManager.UnzipCommand(tempFile, outDir, filenameFilter))
+ // remove temp file
+ StartupActionScriptManager.addActionCommand(StartupActionScriptManager.DeleteCommand(tempFile))
+
+ UpdateSettings.getInstance().forceCheckForUpdateAfterRestart()
+
+ val key = if (ApplicationManager.getApplication().isRestartCapable)
+ "message.settings.imported.successfully.restart"
+ else
+ "message.settings.imported.successfully"
+ if (Messages.showOkCancelDialog(IdeBundle.message(key,
+ ApplicationNamesInfo.getInstance().productName,
+ ApplicationNamesInfo.getInstance().fullProductName),
+ IdeBundle.message("title.restart.needed"), Messages.getQuestionIcon()) == Messages.OK) {
+ (ApplicationManager.getApplication() as ApplicationEx).restart(true)
+ }
+ }
+
+ private fun presentableFileName(file: File) = "'" + FileUtil.toSystemDependentName(file.path) + "'"
+
+ private fun promptLocationMessage() = IdeBundle.message("message.please.ensure.correct.settings")
+
+ private fun getComponentsStored(settings: File, registeredComponents: Collection): List {
+ val zipEntries = THashSet()
+ val zipFile = ZipFile(settings)
+ try {
+ val enumeration = zipFile.entries()
+ while (enumeration.hasMoreElements()) {
+ zipEntries.add(enumeration.nextElement().name)
+ }
+ }
+ finally {
+ zipFile.close()
+ }
+
+ val configPath = File(PathManager.getConfigPath())
+ val components = ArrayList()
+ for (component in registeredComponents) {
+ for (exportFile in component.files) {
+ var relativePath = FileUtilRt.getRelativePath(configPath, exportFile)!!
+ relativePath = FileUtilRt.toSystemIndependentName(relativePath)
+ if (exportFile.name.indexOf('.') == -1 && !exportFile.isFile) {
+ relativePath += '/'
+ }
+ if (zipEntries.contains(relativePath)) {
+ components.add(component)
+ break
+ }
+ }
+ }
+ return components
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/idea/SocketLock.java b/platform/platform-impl/src/com/intellij/idea/SocketLock.java
index 9c39bbe7db15..58d19c847974 100644
--- a/platform/platform-impl/src/com/intellij/idea/SocketLock.java
+++ b/platform/platform-impl/src/com/intellij/idea/SocketLock.java
@@ -15,10 +15,6 @@
*/
package com.intellij.idea;
-import com.intellij.CommonBundle;
-import com.intellij.openapi.application.ApplicationNamesInfo;
-import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.diagnostic.DefaultLogger;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
@@ -34,91 +30,134 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.io.BuiltInServer;
import org.jetbrains.io.MessageDecoder;
-import javax.swing.*;
import java.io.*;
import java.net.Socket;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
/**
* @author mike
*/
public final class SocketLock {
- private static final Logger LOG = Logger.getInstance(SocketLock.class);
-
- @NonNls private static final String ACTIVATE_COMMAND = "activate ";
-
- private final String configPath;
- private final String systemPath;
-
public enum ActivateStatus {ACTIVATED, NO_INSTANCE, CANNOT_ACTIVATE}
- private final AtomicReference>> activateListener = new AtomicReference>>();
+ private static final String PORT_FILE = "port";
+ private static final String ACTIVATE_COMMAND = "activate ";
+ private static final String PORT_LOCK_FILE = "port.lock";
- private BuiltInServer server;
+ private final String myConfigPath;
+ private final String mySystemPath;
+ private final AtomicReference>> myActivateListener = new AtomicReference>>();
+ private BuiltInServer myServer;
public SocketLock(@NotNull String configPath, @NotNull String systemPath) {
- this.configPath = canonicalPath(configPath);
- this.systemPath = canonicalPath(systemPath);
+ myConfigPath = canonicalPath(configPath);
+ mySystemPath = canonicalPath(systemPath);
}
public void setExternalInstanceListener(@Nullable Consumer> consumer) {
- activateListener.set(consumer);
+ myActivateListener.set(consumer);
}
public void dispose() {
- if (LOG.isDebugEnabled()) {
- LOG.debug("enter: destroyProcess()");
- }
+ log("enter: dispose()");
+
+ BuiltInServer server = myServer;
+ if (server == null) return;
- BuiltInServer server = this.server;
- boolean doRemovePortMarker = server != null;
try {
- if (server != null) {
- Disposer.dispose(server);
- }
+ Disposer.dispose(server);
}
finally {
- if (doRemovePortMarker) {
- try {
- executeAndClose(new Executor() {
- @Override
- public Void execute(@NotNull List closeables) throws IOException {
- File config = new File(configPath);
- File system = new File(systemPath);
- lockPortMarker(config, closeables);
- lockPortMarker(system, closeables);
- FileUtil.delete(new File(config, "port"));
- FileUtil.delete(new File(system, "port"));
- return null;
- }
- });
- }
- catch (Throwable e) {
- logError(e);
- }
+ try {
+ underLocks(new Callable() {
+ @Override
+ public Void call() throws Exception {
+ FileUtil.delete(new File(myConfigPath, PORT_FILE));
+ FileUtil.delete(new File(mySystemPath, PORT_FILE));
+ return null;
+ }
+ });
+ }
+ catch (Exception e) {
+ Logger.getInstance(SocketLock.class).warn(e);
}
}
}
@Nullable
public BuiltInServer getServer() {
- return server;
+ return myServer;
}
- private static void lockPortMarker(@NotNull File parent, @NotNull List list) throws IOException {
- FileUtilRt.createDirectory(parent);
- FileOutputStream stream = new FileOutputStream(new File(parent, "port.lock"), true);
- list.add(stream);
+ @NotNull
+ public ActivateStatus lock() throws Exception {
+ return lock(ArrayUtil.EMPTY_STRING_ARRAY);
+ }
+
+ @NotNull
+ public ActivateStatus lock(@NotNull final String[] args) throws Exception {
+ log("enter: lock(config=%s system=%s)", myConfigPath, mySystemPath);
+
+ return underLocks(new Callable() {
+ @Override
+ public ActivateStatus call() throws Exception {
+ File portMarkerC = new File(myConfigPath, PORT_FILE);
+ File portMarkerS = new File(mySystemPath, PORT_FILE);
+
+ MultiMap portToPath = MultiMap.createSmart();
+ addExistingPort(portMarkerC, myConfigPath, portToPath);
+ addExistingPort(portMarkerS, mySystemPath, portToPath);
+ if (!portToPath.isEmpty()) {
+ for (Map.Entry> entry : portToPath.entrySet()) {
+ ActivateStatus status = tryActivate(entry.getKey(), entry.getValue(), args);
+ if (status != ActivateStatus.NO_INSTANCE) {
+ return status;
+ }
+ }
+ }
+
+ final String[] lockedPaths = {myConfigPath, mySystemPath};
+ myServer = BuiltInServer.start(1, 6942, 50, false, new NotNullProducer() {
+ @NotNull
+ @Override
+ public ChannelHandler produce() {
+ return new MyChannelInboundHandler(lockedPaths, myActivateListener);
+ }
+ });
+
+ byte[] portBytes = Integer.toString(myServer.getPort()).getBytes(CharsetToolkit.UTF8_CHARSET);
+ FileUtil.writeToFile(portMarkerC, portBytes);
+ FileUtil.writeToFile(portMarkerS, portBytes);
+ return ActivateStatus.NO_INSTANCE;
+ }
+ });
+ }
+
+ private V underLocks(@NotNull Callable action) throws Exception {
+ FileUtilRt.createDirectory(new File(myConfigPath));
+ FileOutputStream lock1 = new FileOutputStream(new File(myConfigPath, PORT_LOCK_FILE), true);
+ try {
+ FileUtilRt.createDirectory(new File(mySystemPath));
+ FileOutputStream lock2 = new FileOutputStream(new File(mySystemPath, PORT_LOCK_FILE), true);
+ try {
+ return action.call();
+ }
+ finally {
+ lock2.close();
+ }
+ }
+ finally {
+ lock1.close();
+ }
}
private static void addExistingPort(@NotNull File portMarker, @NotNull String path, @NotNull MultiMap portToPath) {
@@ -126,189 +165,81 @@ public final class SocketLock {
try {
portToPath.putValue(Integer.parseInt(FileUtilRt.loadFile(portMarker)), path);
}
- catch (Throwable e) {
- LOG.debug(e);
+ catch (Exception e) {
+ log(e);
// don't delete - we overwrite it on write in any case
}
}
}
- @Nullable
- public ActivateStatus lock() {
- return lock(ArrayUtil.EMPTY_STRING_ARRAY);
- }
-
- @Nullable
- public ActivateStatus lock(@NotNull final String[] args) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("enter: lock(configPath='" + configPath + "', systemPath='" + systemPath + "')");
- }
-
- try {
- final File config = new File(configPath);
- final File system = new File(systemPath);
- final File portMarkerC = new File(config, "port");
- final File portMarkerS = new File(system, "port");
- return executeAndClose(new Executor() {
- @Override
- public ActivateStatus execute(@NotNull List closeables) throws Throwable {
- lockPortMarker(config, closeables);
- lockPortMarker(system, closeables);
- MultiMap portToPath = MultiMap.createSmart();
- addExistingPort(portMarkerC, configPath, portToPath);
- addExistingPort(portMarkerS, systemPath, portToPath);
- if (!portToPath.isEmpty()) {
- for (Map.Entry> entry : portToPath.entrySet()) {
- ActivateStatus status = tryActivate(entry.getKey(), entry.getValue(), args);
- if (status != ActivateStatus.NO_INSTANCE) {
- return status;
- }
- }
- }
-
- final String[] lockedPaths = {configPath, systemPath};
- server = BuiltInServer.start(1, 6942, 50, false, new NotNullProducer() {
- @NotNull
- @Override
- public ChannelHandler produce() {
- return new MyChannelInboundHandler(lockedPaths, activateListener);
- }
- });
-
- byte[] portBytes = Integer.toString(server.getPort()).getBytes(CharsetToolkit.UTF8_CHARSET);
- FileUtil.writeToFile(portMarkerC, portBytes);
- FileUtil.writeToFile(portMarkerS, portBytes);
- return ActivateStatus.NO_INSTANCE;
- }
- });
- }
- catch (Throwable e) {
- logError(e);
-
- if (Main.isHeadless()) {
- Main.showMessage("Cannot lock system folders", e);
- }
- else {
- String pathToLogFile = PathManager.getLogPath() + "/idea.log file".replace('/', File.separatorChar);
- JOptionPane.showMessageDialog(
- JOptionPane.getRootFrame(),
- CommonBundle.message("cannot.start.other.instance.is.running.error.message", ApplicationNamesInfo.getInstance().getProductName(),
- pathToLogFile),
- CommonBundle.message("title.warning"),
- JOptionPane.WARNING_MESSAGE
- );
- }
- return null;
- }
- }
-
- private interface Executor {
- T execute(@NotNull List closeables) throws Throwable;
- }
-
- private static T executeAndClose(@NotNull Executor executor) throws Throwable {
- List closeables = new ArrayList();
- try {
- return executor.execute(closeables);
- }
- finally {
- for (Closeable closeable : closeables) {
- try {
- closeable.close();
- }
- catch (Throwable e) {
- logError(e);
- }
- }
- }
- }
-
- private static void logError(@NotNull Throwable e) {
- // default logger throws AssertionError and it leads to startup failure without error message dialog
- if (LOG instanceof DefaultLogger) {
- LOG.warn(e);
- }
- else {
- LOG.error(e);
- }
- }
-
- @SuppressWarnings({"SocketOpenedButNotSafelyClosed", "IOResourceOpenedButNotSafelyClosed"})
@NotNull
private static ActivateStatus tryActivate(int portNumber, @NotNull Collection paths, @NotNull String[] args) {
- Socket socket = null;
try {
- socket = new Socket(NetUtils.getLoopbackAddress(), portNumber);
- socket.setSoTimeout(300);
+ Socket socket = new Socket(NetUtils.getLoopbackAddress(), portNumber);
+ try {
+ socket.setSoTimeout(300);
- boolean result = false;
- DataInputStream in = new DataInputStream(socket.getInputStream());
- while (true) {
- try {
- String path = in.readUTF();
- if (paths.contains(path)) {
- result = true;
- // don't break - read all input
+ boolean result = false;
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") DataInputStream in = new DataInputStream(socket.getInputStream());
+ while (true) {
+ try {
+ String path = in.readUTF();
+ if (paths.contains(path)) {
+ result = true; // don't break - read all input
+ }
+ }
+ catch (IOException ignored) {
+ break;
}
}
- catch (IOException ignored) {
- break;
+
+ if (result) {
+ try {
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") DataOutputStream out = new DataOutputStream(socket.getOutputStream());
+ out.writeUTF(ACTIVATE_COMMAND + new File(".").getAbsolutePath() + "\0" + StringUtil.join(args, "\0"));
+ out.flush();
+ String response = in.readUTF();
+ if (response.equals("ok")) {
+ return ActivateStatus.ACTIVATED;
+ }
+ }
+ catch (IOException e) {
+ log(e);
+ }
+
+ return ActivateStatus.CANNOT_ACTIVATE;
}
}
-
- if (result) {
- try {
- DataOutputStream out = new DataOutputStream(socket.getOutputStream());
- out.writeUTF(ACTIVATE_COMMAND + new File(".").getAbsolutePath() + "\0" + StringUtil.join(args, "\0"));
- out.flush();
- String response = in.readUTF();
- if (response.equals("ok")) {
- return ActivateStatus.ACTIVATED;
- }
- }
- catch (IOException e) {
- LOG.info(e);
- }
- return ActivateStatus.CANNOT_ACTIVATE;
+ finally {
+ socket.close();
}
}
catch (IOException e) {
- LOG.debug(e);
- }
- finally {
- if (socket != null) {
- try {
- socket.close();
- }
- catch (IOException e) {
- LOG.debug(e);
- }
- }
+ log(e);
}
return ActivateStatus.NO_INSTANCE;
}
private static class MyChannelInboundHandler extends MessageDecoder {
- private final String[] lockedPaths;
- private State state = State.HEADER;
- private final AtomicReference>> activateListener;
-
- public MyChannelInboundHandler(@NotNull String[] lockedPaths, @NotNull AtomicReference>> activateListener) {
- this.lockedPaths = lockedPaths;
- this.activateListener = activateListener;
- }
-
private enum State {HEADER, CONTENT}
- @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
+ private final String[] myLockedPaths;
+ private final AtomicReference>> myActivateListener;
+ private State myState = State.HEADER;
+
+ public MyChannelInboundHandler(@NotNull String[] lockedPaths, @NotNull AtomicReference>> activateListener) {
+ myLockedPaths = lockedPaths;
+ myActivateListener = activateListener;
+ }
+
@Override
public void channelActive(ChannelHandlerContext context) throws Exception {
ByteBuf buffer = context.alloc().ioBuffer(1024);
boolean success = false;
try {
ByteBufOutputStream out = new ByteBufOutputStream(buffer);
- for (String path : lockedPaths) {
+ for (String path : myLockedPaths) {
if (path != null) {
out.writeUTF(path);
}
@@ -324,11 +255,10 @@ public final class SocketLock {
context.writeAndFlush(buffer);
}
- @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
@Override
protected void messageReceived(@NotNull ChannelHandlerContext context, @NotNull ByteBuf input) throws Exception {
while (true) {
- switch (state) {
+ switch (myState) {
case HEADER: {
ByteBuf buffer = getBufferIfSufficient(input, 2, context);
if (buffer == null) {
@@ -336,7 +266,7 @@ public final class SocketLock {
}
contentLength = buffer.readUnsignedShort();
- state = State.CONTENT;
+ myState = State.CONTENT;
}
break;
@@ -348,7 +278,7 @@ public final class SocketLock {
if (StringUtil.startsWith(command, ACTIVATE_COMMAND)) {
List args = StringUtil.split(command.subSequence(ACTIVATE_COMMAND.length(), command.length()).toString(), "\0");
- Consumer> listener = activateListener.get();
+ Consumer> listener = myActivateListener.get();
if (listener != null) {
listener.consume(args);
}
@@ -371,8 +301,20 @@ public final class SocketLock {
private static String canonicalPath(@NotNull String configPath) {
try {
return new File(configPath).getCanonicalPath();
- } catch (IOException ignore) {
+ }
+ catch (IOException ignore) {
return configPath;
}
}
+
+ private static void log(Exception e) {
+ Logger.getInstance(SocketLock.class).debug(e);
+ }
+
+ private static void log(String format, Object... args) {
+ Logger logger = Logger.getInstance(SocketLock.class);
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format(format, args));
+ }
+ }
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
index a87d02672d12..24ead9495020 100644
--- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
+++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java
@@ -244,6 +244,7 @@ public class StartupUtil {
finally { writer.close(); }
}
+ @SuppressWarnings("SSBasedInspection")
private static void delete(File ideTempFile) {
if (!FileUtilRt.delete(ideTempFile)) {
ideTempFile.deleteOnExit();
@@ -251,25 +252,36 @@ public class StartupUtil {
}
private synchronized static boolean lockSystemFolders(String[] args) {
- assert ourLock == null;
+ if (ourLock != null) {
+ throw new AssertionError();
+ }
+
ourLock = new SocketLock(PathManager.getConfigPath(), PathManager.getSystemPath());
- SocketLock.ActivateStatus activateStatus = ourLock.lock(args);
- if (activateStatus != SocketLock.ActivateStatus.NO_INSTANCE) {
- if (activateStatus != null && (Main.isHeadless() || activateStatus == SocketLock.ActivateStatus.CANNOT_ACTIVATE)) {
- String message = "Only one instance of " + ApplicationNamesInfo.getInstance().getFullProductName() + " can be run at a time.";
- Main.showMessage("Too Many Instances", message, true);
- }
+ SocketLock.ActivateStatus status;
+ try {
+ status = ourLock.lock(args);
+ }
+ catch (Exception e) {
+ Main.showMessage("Cannot Lock System Folders", e);
return false;
}
- ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
- @Override
- public void run() {
- ourLock.dispose();
- }
- });
- return true;
+ if (status == SocketLock.ActivateStatus.NO_INSTANCE) {
+ ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
+ @Override
+ public void run() {
+ ourLock.dispose();
+ }
+ });
+ return true;
+ }
+ else if (Main.isHeadless() || status == SocketLock.ActivateStatus.CANNOT_ACTIVATE) {
+ String message = "Only one instance of " + ApplicationNamesInfo.getInstance().getFullProductName() + " can be run at a time.";
+ Main.showMessage("Too Many Instances", message, true);
+ }
+
+ return false;
}
private static void fixProcessEnvironment(Logger log) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java
index 25b5963dd3b4..2bd5e6a6773c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/AbstractFileType.java
@@ -22,7 +22,6 @@ import com.intellij.lang.Commenter;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.fileTypes.ex.ExternalizableFileType;
-import com.intellij.openapi.options.ExternalInfo;
import com.intellij.openapi.options.ExternalizableScheme;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.util.*;
@@ -415,10 +414,4 @@ public class AbstractFileType extends UserFileType implements
public void setCommenter(final Commenter commenter) {
myCommenter = commenter;
}
-
- @Override
- @Nullable
- public ExternalInfo getExternalInfo() {
- return null;
- }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
index 04dda45f891d..6bca569c45ac 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
@@ -71,7 +71,7 @@ import java.util.concurrent.atomic.AtomicLong;
@State(
name = "FileTypeManager",
- storages = @Storage(file = StoragePathMacros.APP_CONFIG + "/filetypes.xml"),
+ storages = @Storage(file = "filetypes.xml"),
additionalExportFile = FileTypeManagerImpl.FILE_SPEC
)
public class FileTypeManagerImpl extends FileTypeManagerEx implements PersistentStateComponent, ApplicationComponent, Disposable {
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java
index 616d3ec0014b..562c9c60d80a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java
@@ -15,12 +15,15 @@
*/
package com.intellij.openapi.progress.util;
+import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
+import com.intellij.util.NotNullProducer;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -36,8 +39,26 @@ import java.awt.geom.Rectangle2D;
public class ColorProgressBar extends JComponent {
private static final Dimension PREFERRED_SIZE = new Dimension(146, 17);
- public static final Color GREEN = new JBColor(new Color(0x6cad74), new Color(0x4a8c53));
- public static final Color RED = new JBColor(new Color(0xd67b76), new Color(0xe55757));
+ public static final Color GREEN = new JBColor(new NotNullProducer() {
+ @NotNull
+ @Override
+ public Color produce() {
+ UISettings settings = UISettings.getInstance();
+ return settings == null || null == settings.COLOR_BLINDNESS
+ ? new JBColor(new Color(0x6cad74), new Color(0x4a8c53))
+ : new JBColor(new Color(0x6ca69c), new Color(0x639990));
+ }
+ });
+ public static final Color RED = new JBColor(new NotNullProducer() {
+ @NotNull
+ @Override
+ public Color produce() {
+ UISettings settings = UISettings.getInstance();
+ return settings == null || null == settings.COLOR_BLINDNESS
+ ? new JBColor(new Color(0xd67b76), new Color(0xe55757))
+ : new JBColor(new Color(0xcc7447), new Color(0xcc7447));
+ }
+ });
public static final Color RED_TEXT = new JBColor(new Color(0xb81708), new Color(0xdb5c5c));
public static final Color BLUE = new JBColor(new Color(1, 68, 208), JBColor.blue);
public static final Color YELLOW = new JBColor(new Color(0xa67a21), new Color(0x91703a));
diff --git a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
index b75ea7f93f64..dd650794f018 100644
--- a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
+++ b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
@@ -17,6 +17,8 @@ package org.jetbrains.io;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.ExceptionUtil;
import com.intellij.util.NotNullProducer;
import com.intellij.util.net.NetUtils;
import io.netty.bootstrap.ServerBootstrap;
@@ -52,16 +54,25 @@ public class BuiltInServer implements Disposable {
}
@NotNull
- public static BuiltInServer start(int workerCount, int firstPort, int portsCount, boolean tryAnyPort, @Nullable NotNullProducer channelHandler) throws Throwable {
- return start(new NioEventLoopGroup(workerCount, PooledThreadExecutor.INSTANCE), true, firstPort, portsCount, tryAnyPort, channelHandler);
+ public static BuiltInServer start(int workerCount,
+ int firstPort,
+ int portsCount,
+ boolean tryAnyPort,
+ @Nullable NotNullProducer handler) throws Exception {
+ return start(new NioEventLoopGroup(workerCount, PooledThreadExecutor.INSTANCE), true, firstPort, portsCount, tryAnyPort, handler);
}
@NotNull
- public static BuiltInServer start(@NotNull EventLoopGroup eventLoopGroup, boolean isOwnerOfEventLoopGroup, int firstPort, int portsCount, boolean tryAnyPort, @Nullable NotNullProducer channelHandler) throws Throwable {
+ public static BuiltInServer start(@NotNull EventLoopGroup eventLoopGroup,
+ boolean isEventLoopGroupOwner,
+ int firstPort,
+ int portsCount,
+ boolean tryAnyPort,
+ @Nullable NotNullProducer handler) throws Exception {
ChannelRegistrar channelRegistrar = new ChannelRegistrar();
ServerBootstrap bootstrap = NettyUtil.nioServerBootstrap(eventLoopGroup);
- configureChildHandler(bootstrap, channelRegistrar, channelHandler);
- return new BuiltInServer(eventLoopGroup, bind(firstPort, portsCount, tryAnyPort, bootstrap, channelRegistrar), isOwnerOfEventLoopGroup);
+ configureChildHandler(bootstrap, channelRegistrar, handler);
+ return new BuiltInServer(eventLoopGroup, bind(firstPort, portsCount, tryAnyPort, bootstrap, channelRegistrar), isEventLoopGroupOwner);
}
public int getPort() {
@@ -73,7 +84,9 @@ public class BuiltInServer implements Disposable {
return eventLoopGroup;
}
- static void configureChildHandler(@NotNull ServerBootstrap bootstrap, @NotNull final ChannelRegistrar channelRegistrar, final @Nullable NotNullProducer channelHandler) {
+ static void configureChildHandler(@NotNull ServerBootstrap bootstrap,
+ @NotNull final ChannelRegistrar channelRegistrar,
+ final @Nullable NotNullProducer channelHandler) {
final PortUnificationServerHandler portUnificationServerHandler = channelHandler == null ? new PortUnificationServerHandler() : null;
bootstrap.childHandler(new ChannelInitializer() {
@Override
@@ -83,41 +96,41 @@ public class BuiltInServer implements Disposable {
});
}
- public static boolean isPortForbidden(int port) {
- for (int forbiddenPort : FORBIDDEN_PORTS) {
- if (port == forbiddenPort) return true;
- }
- return false;
- }
+ private static int bind(int firstPort,
+ int portsCount,
+ boolean tryAnyPort,
+ @NotNull ServerBootstrap bootstrap,
+ @NotNull ChannelRegistrar channelRegistrar) throws Exception {
+ InetAddress address = NetUtils.getLoopbackAddress();
- private static int bind(int firstPort, int portsCount, boolean tryAnyPort, @NotNull ServerBootstrap bootstrap, @NotNull ChannelRegistrar channelRegistrar) throws Throwable {
- InetAddress loopbackAddress = NetUtils.getLoopbackAddress();
for (int i = 0; i < portsCount; i++) {
int port = firstPort + i;
- if (isPortForbidden(i)) {
+ if (ArrayUtil.indexOf(FORBIDDEN_PORTS, i) >= 0) {
continue;
}
- ChannelFuture future = bootstrap.bind(loopbackAddress, port).awaitUninterruptibly();
+ ChannelFuture future = bootstrap.bind(address, port).awaitUninterruptibly();
if (future.isSuccess()) {
channelRegistrar.add(future.channel());
return port;
}
else if (!tryAnyPort && i == (portsCount - 1)) {
- throw future.cause();
+ ExceptionUtil.rethrowAll(future.cause());
}
}
LOG.info("We cannot bind to our default range, so, try to bind to any free port");
- ChannelFuture future = bootstrap.bind(loopbackAddress, 0).awaitUninterruptibly();
+ ChannelFuture future = bootstrap.bind(address, 0).awaitUninterruptibly();
if (future.isSuccess()) {
channelRegistrar.add(future.channel());
return ((InetSocketAddress)future.channel().localAddress()).getPort();
}
else {
- throw future.cause();
+ ExceptionUtil.rethrowAll(future.cause());
}
+
+ return -1; // unreachable
}
@Override
diff --git a/platform/platform-resources-en/src/messages/CommonBundle.properties b/platform/platform-resources-en/src/messages/CommonBundle.properties
index 683703be061e..bf8d5dbabedd 100644
--- a/platform/platform-resources-en/src/messages/CommonBundle.properties
+++ b/platform/platform-resources-en/src/messages/CommonBundle.properties
@@ -141,10 +141,7 @@ local.vcs.action.name.undo.command=Undo {0}
local.vcs.action.name.redo.command=Redo {0}
error.reading.color.scheme.from.file.error.message=Error reading color scheme from {0}
-corrupted.scheme.file.message.title=Corrupted File
button.background=&Background
-vcs.configurable.general.tab.title=General
-cannot.start.other.instance.is.running.error.message={0} was unable to create a local connection in order to check whether\nother instance of {0} is currently running on the same machine.\nRunning multiple instances of {0} on the same machine may cause unpredictable\nresults because of sharing system folders.\nPlease troubleshoot your TCP/IP configuration and/or local firewall settings.\nand attach the {1}
button.load.file=Load File
date.frequency=Once {0}
name.label.text=Na&me:
diff --git a/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java b/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java
index 134f4ddcf8b4..15d6b2d0164f 100644
--- a/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/idea/LockSupportTest.java
@@ -50,7 +50,7 @@ public class LockSupportTest {
}
@Test(timeout = 30000)
- public void testUseCanonicalPathLock() {
+ public void testUseCanonicalPathLock() throws Exception {
assumeThat(SystemInfo.isFileSystemCaseSensitive, is(false));
String path1 = myTempDir.getPath();
@@ -69,7 +69,7 @@ public class LockSupportTest {
}
@Test(timeout = 30000)
- public void testLock() {
+ public void testLock() throws Exception {
SocketLock lock = new SocketLock(myTempDir.getPath() + "/c", myTempDir.getPath() + "/s");
try {
assertThat(lock.lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE));
@@ -80,8 +80,8 @@ public class LockSupportTest {
}
@Test(timeout = 30000)
- public void testTwoLocks() {
- List toClose = new ArrayList();
+ public void testTwoLocks() throws Exception {
+ List toClose = new ArrayList<>();
try {
assertThat(createLock(toClose, myTempDir, "1", "1-").lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE));
assertThat(createLock(toClose, myTempDir, "1.1", "1-1").lock(), equalTo(SocketLock.ActivateStatus.NO_INSTANCE));
@@ -92,9 +92,7 @@ public class LockSupportTest {
assertThat(createLock(toClose, myTempDir, "1.1", "1-1").lock(), equalTo(SocketLock.ActivateStatus.ACTIVATED));
}
finally {
- for (SocketLock lock : toClose) {
- lock.dispose();
- }
+ toClose.forEach(SocketLock::dispose);
}
}
@@ -106,7 +104,7 @@ public class LockSupportTest {
}
@Test(timeout = 30000)
- public void testDispose() {
+ public void testDispose() throws Exception {
SocketLock lock1 = new SocketLock(myTempDir.getPath() + "/1", myTempDir.getPath() + "/1-");
SocketLock lock2 = new SocketLock(myTempDir.getPath() + "/1", myTempDir.getPath() + "/1-");
diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/State.java b/platform/projectModel-api/src/com/intellij/openapi/components/State.java
index 1f76209076bb..3dc82b321ec6 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/components/State.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/components/State.java
@@ -36,6 +36,9 @@ public @interface State {
*/
boolean defaultStateAsResource() default false;
+ /**
+ * Additional export path (relative to application-level configuration root directory).
+ */
String additionalExportFile() default "";
Class extends NameGetter> presentableName() default NameGetter.class;
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java
index 6c133cc28eb1..d5eb4c6e6070 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/deployment/DeployToServerRunConfiguration.java
@@ -17,10 +17,7 @@ package com.intellij.remoteServer.impl.configuration.deployment;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
-import com.intellij.execution.configurations.ConfigurationFactory;
-import com.intellij.execution.configurations.RunConfigurationBase;
-import com.intellij.execution.configurations.RunProfileState;
-import com.intellij.execution.configurations.RuntimeConfigurationException;
+import com.intellij.execution.configurations.*;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
@@ -218,6 +215,27 @@ public class DeployToServerRunConfiguration attributes = testFailed.getAttributes();
- assert testFailed.getFailureMessage() != null : "No failure message for: " + myTestFrameworkName;
+ LOG.assertTrue(testFailed.getFailureMessage() != null, "No failure message for: " + myTestFrameworkName);
final boolean testError = attributes.get(ATTR_KEY_TEST_ERROR) != null;
TestFailedEvent testFailedEvent = new TestFailedEvent(testFailed, testError,
attributes.get(ATTR_KEY_EXPECTED_FILE_PATH),
diff --git a/platform/testFramework/src/com/intellij/TestCaseLoader.java b/platform/testFramework/src/com/intellij/TestCaseLoader.java
index 376a08b8bc63..505f3320b739 100644
--- a/platform/testFramework/src/com/intellij/TestCaseLoader.java
+++ b/platform/testFramework/src/com/intellij/TestCaseLoader.java
@@ -65,7 +65,7 @@ public class TestCaseLoader {
public TestCaseLoader(String classFilterName, boolean forceLoadPerformanceTests) {
myForceLoadPerformanceTests = forceLoadPerformanceTests;
String patterns = System.getProperty(TARGET_TEST_PATTERNS);
- if (patterns != null) {
+ if (!StringUtil.isEmpty(patterns)) {
myTestClassesFilter = new PatternListTestClassFilter(StringUtil.split(patterns, ";"));
System.out.println("Using patterns: [" + patterns +"]");
}
diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties
index 4313874d6b86..723472a0bd68 100644
--- a/platform/util/resources/misc/registry.properties
+++ b/platform/util/resources/misc/registry.properties
@@ -199,7 +199,7 @@ debugger.close.dialog.on.navigate=true
debugger.close.dialog.on.navigate.description=Close evaluate dialog on Jump to (type) source action
debugger.async.smart.step.into=true
debugger.async.smart.step.into.description=Smart step into anonymous class methods in any thread
-debugger.monitor.blocked.threads=false
+debugger.monitor.blocked.threads=true
debugger.monitor.blocked.threads.description=Watch if a thread we do stepping in is blocked by another suspended thread
analyze.exceptions.on.the.fly=false
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java
index a2bbf3618d7c..51a47d5b51d4 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelvedChangeList.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -24,7 +24,6 @@ package com.intellij.openapi.vcs.changes.shelf;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.impl.patch.FilePatch;
-import com.intellij.openapi.options.ExternalInfo;
import com.intellij.openapi.options.ExternalizableScheme;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
@@ -36,7 +35,6 @@ import com.intellij.openapi.vcs.FileStatus;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
@@ -90,7 +88,7 @@ public class ShelvedChangeList implements JDOMExternalizable, ExternalizableSche
DATE = new Date(Long.parseLong(element.getAttributeValue(ATTRIBUTE_DATE)));
myRecycled = Boolean.parseBoolean(element.getAttributeValue(ATTRIBUTE_RECYCLED_CHANGELIST));
//noinspection unchecked
- final List children = (List)element.getChildren(ELEMENT_BINARY);
+ final List children = element.getChildren(ELEMENT_BINARY);
myBinaryFiles = new ArrayList(children.size());
for (Element child : children) {
ShelvedBinaryFile binaryFile = new ShelvedBinaryFile();
@@ -161,12 +159,6 @@ public class ShelvedChangeList implements JDOMExternalizable, ExternalizableSche
return mySchemeName;
}
- @Nullable
- @Override
- public ExternalInfo getExternalInfo() {
- return null;
- }
-
@Override
public void setName(@NotNull String newName) {
mySchemeName = newName;
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/PermanentGraphImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/PermanentGraphImpl.java
index 21cc23e82249..5a1bb3e77f1f 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/PermanentGraphImpl.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/PermanentGraphImpl.java
@@ -17,6 +17,8 @@
package com.intellij.vcs.log.graph.impl.facade;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
import com.intellij.openapi.util.Condition;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
@@ -78,7 +80,7 @@ public class PermanentGraphImpl implements PermanentGraph, P
@NotNull private final Set myBranchesCommitId;
@NotNull private final Set myBranchNodeIds;
@NotNull private final ReachableNodes myReachableNodes;
- @NotNull private final BekIntMap myBekIntMap;
+ @NotNull private final Supplier myBekIntMap;
public PermanentGraphImpl(@NotNull PermanentLinearGraphImpl permanentLinearGraph,
@NotNull GraphLayoutImpl permanentGraphLayout,
@@ -92,7 +94,12 @@ public class PermanentGraphImpl implements PermanentGraph, P
myBranchesCommitId = branchesCommitId;
myBranchNodeIds = permanentCommitsInfo.convertToNodeIds(branchesCommitId);
myReachableNodes = new ReachableNodes(LinearGraphUtils.asLiteLinearGraph(permanentLinearGraph));
- myBekIntMap = BekSorter.createBekMap(myPermanentLinearGraph, myPermanentGraphLayout, myPermanentCommitsInfo.getTimestampGetter());
+ myBekIntMap = Suppliers.memoize(new Supplier() {
+ @Override
+ public BekIntMap get() {
+ return BekSorter.createBekMap(myPermanentLinearGraph, myPermanentGraphLayout, myPermanentCommitsInfo.getTimestampGetter());
+ }
+ });
}
@NotNull
@@ -105,10 +112,10 @@ public class PermanentGraphImpl implements PermanentGraph, P
baseController = new BaseController(this);
}
else if (sortType == SortType.LinearBek) {
- baseController = new LinearBekController(new BekBaseController(this, myBekIntMap), this);
+ baseController = new LinearBekController(new BekBaseController(this, myBekIntMap.get()), this);
}
else {
- baseController = new BekBaseController(this, myBekIntMap);
+ baseController = new BekBaseController(this, myBekIntMap.get());
}
LinearGraphController controller;
diff --git a/platform/vcs-log/graph/vcs-log-graph.iml b/platform/vcs-log/graph/vcs-log-graph.iml
index d342ddf28976..4416b93a59fc 100644
--- a/platform/vcs-log/graph/vcs-log-graph.iml
+++ b/platform/vcs-log/graph/vcs-log-graph.iml
@@ -14,6 +14,6 @@
+
-
-
+
\ No newline at end of file
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java
index f7708d4b7a99..e654a83a65ab 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java
@@ -194,7 +194,7 @@ public class GroovyScriptClass extends LightElement implements PsiClass, Synthet
return RecursionManager.doPreventingRecursion(this, false, new Computable() {
@Override
public PsiClassType compute() {
- return CachedValuesManager.getCachedValue(myFile, new CachedValueProvider() {
+ return CachedValuesManager.getCachedValue(GroovyScriptClass.this, new CachedValueProvider() {
@Nullable
@Override
public Result compute() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
index c094dbd512ff..8bd5e1723fd6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
@@ -276,7 +276,7 @@ public class MvcModuleStructureSynchronizer extends AbstractProjectComponent {
@Override
public void computeInReadAction(@NotNull ProgressIndicator indicator) {
if (!isUpToDate()) {
- indicator.cancel();
+ scheduleRunActions();
return;
}
diff --git a/plugins/junit/src/com/intellij/execution/junit/TestMethod.java b/plugins/junit/src/com/intellij/execution/junit/TestMethod.java
index 013c0e908bf2..3b68c8fb60f8 100644
--- a/plugins/junit/src/com/intellij/execution/junit/TestMethod.java
+++ b/plugins/junit/src/com/intellij/execution/junit/TestMethod.java
@@ -51,8 +51,7 @@ class TestMethod extends TestObject {
protected void addJUnit3Parameter(JavaParameters javaParameters, final JUnitConfiguration.Data data, Project project) throws ExecutionException {
final PsiClass psiClass = JavaExecutionUtil.findMainClass(project, data.getMainClassName(), GlobalSearchScope.allScope(project));
- LOG.assertTrue(psiClass != null);
- if (JUnitUtil.isJUnit4TestClass(psiClass)) {
+ if (psiClass == null || JUnitUtil.isJUnit4TestClass(psiClass)) {
return;
}
final String methodName = data.getMethodName();
diff --git a/plugins/settings-repository/src/copyAppSettingsToRepository.kt b/plugins/settings-repository/src/copyAppSettingsToRepository.kt
index d638b61f4303..435a9116a2dc 100644
--- a/plugins/settings-repository/src/copyAppSettingsToRepository.kt
+++ b/plugins/settings-repository/src/copyAppSettingsToRepository.kt
@@ -17,9 +17,11 @@ package org.jetbrains.settingsRepository
import com.intellij.configurationStore.ROOT_CONFIG
import com.intellij.configurationStore.StateStorageManagerImpl
-import com.intellij.ide.actions.ExportSettingsAction
+import com.intellij.ide.actions.ExportableItem
+import com.intellij.ide.actions.getExportableComponentsMap
import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.components.*
+import com.intellij.openapi.components.RoamingType
+import com.intellij.openapi.components.stateStore
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.io.FileUtilRt
import java.io.File
@@ -27,7 +29,7 @@ import java.io.File
fun copyLocalConfig(storageManager: StateStorageManagerImpl = ApplicationManager.getApplication()!!.stateStore.stateStorageManager as StateStorageManagerImpl) {
val streamProvider = storageManager.streamProvider!! as IcsManager.IcsStreamProvider
- val fileToComponents = ExportSettingsAction.getExportableComponentsMap(true, false, storageManager)
+ val fileToComponents = getExportableComponentsMap(true, false, storageManager)
for (file in fileToComponents.keySet()) {
val absolutePath = FileUtilRt.toSystemIndependentName(file.absolutePath)
var fileSpec = storageManager.collapseMacros(absolutePath)
@@ -67,20 +69,20 @@ private fun saveDirectory(parent: File, parentFileSpec: String, roamingType: Roa
}
}
-private fun getRoamingType(components: Collection): RoamingType {
+private fun getRoamingType(components: Collection): RoamingType {
for (component in components) {
- if (component is ExportSettingsAction.ExportableComponentItem) {
+ if (component is ExportableItem) {
return component.roamingType
}
- else if (component is PersistentStateComponent<*>) {
- val stateAnnotation = component.javaClass.getAnnotation(State::class.java)
- if (stateAnnotation != null) {
- val storages = stateAnnotation.storages
- if (!storages.isEmpty()) {
- return storages[0].roamingType
- }
- }
- }
+// else if (component is PersistentStateComponent<*>) {
+// val stateAnnotation = component.javaClass.getAnnotation(State::class.java)
+// if (stateAnnotation != null) {
+// val storages = stateAnnotation.storages
+// if (!storages.isEmpty()) {
+// return storages[0].roamingType
+// }
+// }
+// }
}
return RoamingType.DEFAULT
}
\ No newline at end of file
diff --git a/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java b/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java
index 5664908788bf..6232db10a13a 100644
--- a/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java
+++ b/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java
@@ -31,39 +31,45 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener
public synchronized void onStart(final ISuite suite) {
if (suite != null) {
- final List allMethods = suite.getAllMethods();
- if (allMethods != null) {
- int count = 0;
- for (ITestNGMethod method : allMethods) {
- if (method.isTest()) count += method.getInvocationCount();
+ try {
+ final List allMethods = suite.getAllMethods();
+ if (allMethods != null) {
+ int count = 0;
+ for (ITestNGMethod method : allMethods) {
+ if (method.isTest()) count += method.getInvocationCount();
+ }
+ myPrintStream.println("##teamcity[testCount count = \'" + count + "\']");
}
- myPrintStream.println("##teamcity[testCount count = \'" + count + "\']");
}
+ catch (NoSuchMethodError ignore) {}
myPrintStream.println("##teamcity[rootName name = '" + suite.getName() + "' location = 'file://" + suite.getXmlSuite().getFileName() + "']");
}
}
public synchronized void onFinish(ISuite suite) {
- if (suite != null && suite.getAllInvokedMethods().size() < suite.getAllMethods().size()) {
- for (ITestNGMethod method : suite.getAllMethods()) {
- if (method.isTest()) {
- boolean found = false;
- for (IInvokedMethod invokedMethod : suite.getAllInvokedMethods()) {
- if (invokedMethod.getTestMethod() == method) {
- found = true;
+ try {
+ if (suite != null && suite.getAllInvokedMethods().size() < suite.getAllMethods().size()) {
+ for (ITestNGMethod method : suite.getAllMethods()) {
+ if (method.isTest()) {
+ boolean found = false;
+ for (IInvokedMethod invokedMethod : suite.getAllInvokedMethods()) {
+ if (invokedMethod.getTestMethod() == method) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ final String fullEscapedMethodName = escapeName(getShortName(method.getTestClass().getName()) + "." + method.getMethodName());
+ myPrintStream.println("##teamcity[testStarted name=\'" + fullEscapedMethodName + "\']");
+ myPrintStream.println("##teamcity[testIgnored name=\'" + fullEscapedMethodName + "\']");
+ myPrintStream.println("##teamcity[testFinished name=\'" + fullEscapedMethodName + "\']");
break;
}
}
- if (!found) {
- final String fullEscapedMethodName = escapeName(getShortName(method.getTestClass().getName()) + "." + method.getMethodName());
- myPrintStream.println("##teamcity[testStarted name=\'" + fullEscapedMethodName + "\']");
- myPrintStream.println("##teamcity[testIgnored name=\'" + fullEscapedMethodName + "\']");
- myPrintStream.println("##teamcity[testFinished name=\'" + fullEscapedMethodName + "\']");
- break;
- }
}
}
}
+ catch (NoSuchMethodError ignored) {}
for (int i = myCurrentSuites.size() - 1; i >= 0; i--) {
onSuiteFinish(myCurrentSuites.remove(i));
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java
index 60f12b2489b6..dfdd6db8fa13 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/BoundIconRenderer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -68,6 +68,7 @@ public class BoundIconRenderer extends GutterIconRenderer {
}
}
+ @Override
@NotNull
public Icon getIcon() {
if (myIcon != null) {
@@ -76,13 +77,16 @@ public class BoundIconRenderer extends GutterIconRenderer {
return PlatformIcons.UI_FORM_ICON;
}
+ @Override
public boolean isNavigateAction() {
return true;
}
+ @Override
@Nullable
public AnAction getClickAction() {
return new AnAction() {
+ @Override
public void actionPerformed(AnActionEvent e) {
List formFiles = getBoundFormFiles();
if (formFiles.size() > 0) {
@@ -104,6 +108,7 @@ public class BoundIconRenderer extends GutterIconRenderer {
};
}
+ @Override
@Nullable
public String getTooltipText() {
List formFiles = getBoundFormFiles();
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java
index 05c1bcb1b912..da243250d8ec 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormClassAnnotator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -37,6 +37,7 @@ import java.util.List;
public class FormClassAnnotator implements Annotator {
private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.binding.FormClassAnnotator");
+ @Override
public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) {
if (psiElement instanceof PsiField) {
PsiField field = (PsiField) psiElement;
@@ -76,20 +77,24 @@ public class FormClassAnnotator implements Annotator {
final String message = UIDesignerBundle.message("field.is.overwritten.by.generated.code", field.getName());
Annotation annotation = holder.createWarningAnnotation(field.getInitializer(), message);
annotation.registerFix(new IntentionAction() {
+ @Override
@NotNull
public String getText() {
return message;
}
+ @Override
@NotNull
public String getFamilyName() {
return UIBundle.message("remove.field.initializer.quick.fix");
}
+ @Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return field.getInitializer() != null;
}
+ @Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!FileModificationService.getInstance().preparePsiElementForWrite(field)) return;
final PsiExpression initializer = field.getInitializer();
@@ -97,6 +102,7 @@ public class FormClassAnnotator implements Annotator {
initializer.delete();
}
+ @Override
public boolean startInWriteAction() {
return true;
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddGroupAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddGroupAction.java
index 2d388652188f..4047d7e58b74 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddGroupAction.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/AddGroupAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -20,17 +20,18 @@ import com.intellij.CommonBundle;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.uiDesigner.UIDesignerBundle;
import java.util.ArrayList;
+import java.util.List;
/**
* @author yole
*/
public class AddGroupAction extends AnAction {
+ @Override
public void actionPerformed(AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
if (project == null) return;
@@ -41,15 +42,15 @@ public class AddGroupAction extends AnAction {
UIDesignerBundle.message("title.add.group"),
Messages.getQuestionIcon()
);
- if(groupName == null){
+ if (groupName == null) {
return;
}
Palette palette = Palette.getInstance(project);
// Check that name of the group is unique
- final ArrayList groups = palette.getGroups();
- for(int i = groups.size() - 1; i >= 0; i--){
- if(groupName.equals(groups.get(i).getName())){
+ List groups = palette.getGroups();
+ for (int i = groups.size() - 1; i >= 0; i--) {
+ if (groupName.equals(groups.get(i).getName())) {
Messages.showErrorDialog(project,
UIDesignerBundle.message("error.group.name.unique"),
CommonBundle.getErrorTitle());
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java
index a3d66a914304..cbf5cccf19b1 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/ComponentItemDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -53,7 +53,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
-import java.util.ArrayList;
+import java.util.List;
/**
* @author Vladimir Kondratyev
@@ -114,6 +114,7 @@ public final class ComponentItemDialog extends DialogWrapper {
updateEnabledTextField();
myTfClassName.getChildComponent().addDocumentListener(new com.intellij.openapi.editor.event.DocumentAdapter() {
+ @Override
public void documentChanged(com.intellij.openapi.editor.event.DocumentEvent e) {
updateOKAction();
}
@@ -128,12 +129,14 @@ public final class ComponentItemDialog extends DialogWrapper {
UIDesignerBundle.message("add.component.choose.icon")));
myTfNestedForm.addActionListener(new MyChooseFileActionListener(project, new TreeFileChooser.PsiFileFilter() {
+ @Override
public boolean accept(PsiFile file) {
return file.getFileType().equals(StdFileTypes.GUI_DESIGNER_FORM);
}
}, myTfNestedForm, UIDesignerBundle.message("add.component.choose.form")));
myTfNestedForm.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+ @Override
protected void textChanged(DocumentEvent e) {
updateOKAction();
}
@@ -181,10 +184,11 @@ public final class ComponentItemDialog extends DialogWrapper {
void showGroupChooser(GroupItem defaultGroup) {
myGroupLabel.setVisible(true);
myGroupComboBox.setVisible(true);
- final ArrayList groups = Palette.getInstance(myProject).getGroups();
+ List groups = Palette.getInstance(myProject).getGroups();
myGroupComboBox.setModel(new DefaultComboBoxModel(groups.toArray()));
myGroupComboBox.setSelectedItem(defaultGroup);
myGroupComboBox.addItemListener(new ItemListener() {
+ @Override
public void itemStateChanged(ItemEvent e) {
updateOKAction();
}
@@ -205,15 +209,18 @@ public final class ComponentItemDialog extends DialogWrapper {
updateOKAction();
}
+ @Override
@NotNull
protected Action[] createActions() {
return new Action[]{getOKAction(), getCancelAction(), getHelpAction()};
}
+ @Override
protected void doHelpAction() {
HelpManager.getInstance().invokeHelp("reference.dialogs.addEditPaletteComponent");
}
+ @Override
protected void doOKAction() {
// TODO[vova] implement validation
if (myClassRadioButton.isSelected()) {
@@ -294,6 +301,7 @@ public final class ComponentItemDialog extends DialogWrapper {
return true;
}
+ @Override
protected String getDimensionServiceKey() {
if (myOneOff) {
return "#com.intellij.uiDesigner.palette.ComponentItemDialog.OneOff";
@@ -301,10 +309,12 @@ public final class ComponentItemDialog extends DialogWrapper {
return "#com.intellij.uiDesigner.palette.ComponentItemDialog";
}
+ @Override
public JComponent getPreferredFocusedComponent() {
return myTfClassName.getChildComponent();
}
+ @Override
protected JComponent createCenterPanel() {
return myPanel;
}
@@ -365,6 +375,7 @@ public final class ComponentItemDialog extends DialogWrapper {
myProject = project;
}
+ @Override
public void actionPerformed(final ActionEvent e) {
final TreeClassChooserFactory factory = TreeClassChooserFactory.getInstance(myProject);
final TreeClassChooser chooser = factory.createInheritanceClassChooser(UIDesignerBundle.message("title.choose.component.class"),
@@ -394,6 +405,7 @@ public final class ComponentItemDialog extends DialogWrapper {
myTitle = title;
}
+ @Override
public void actionPerformed(ActionEvent e) {
final TreeClassChooserFactory factory = TreeClassChooserFactory.getInstance(myProject);
PsiFile formFile = null;
@@ -413,6 +425,7 @@ public final class ComponentItemDialog extends DialogWrapper {
}
private class MyRadioChangeListener implements ChangeListener {
+ @Override
public void stateChanged(ChangeEvent e) {
updateEnabledTextField();
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java
index 3bedd33a745a..d69437c7b204 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/EditGroupAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -20,17 +20,17 @@ import com.intellij.CommonBundle;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.uiDesigner.UIDesignerBundle;
-import java.util.ArrayList;
+import java.util.List;
/**
* @author yole
*/
public class EditGroupAction extends AnAction {
+ @Override
public void actionPerformed(AnActionEvent e) {
Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
GroupItem groupToBeEdited = GroupItem.DATA_KEY.getData(e.getDataContext());
@@ -45,14 +45,14 @@ public class EditGroupAction extends AnAction {
groupToBeEdited.getName(),
null
);
- if(groupName == null || groupName.equals(groupToBeEdited.getName())){
+ if (groupName == null || groupName.equals(groupToBeEdited.getName())) {
return;
}
Palette palette = Palette.getInstance(project);
- final ArrayList groups = palette.getGroups();
- for(int i = groups.size() - 1; i >= 0; i--){
- if(groupName.equals(groups.get(i).getName())){
+ List groups = palette.getGroups();
+ for (int i = groups.size() - 1; i >= 0; i--) {
+ if (groupName.equals(groups.get(i).getName())) {
Messages.showErrorDialog(project, UIDesignerBundle.message("error.group.name.unique"),
CommonBundle.getErrorTitle());
return;
@@ -63,7 +63,8 @@ public class EditGroupAction extends AnAction {
palette.fireGroupsChanged();
}
- @Override public void update(AnActionEvent e) {
+ @Override
+ public void update(AnActionEvent e) {
Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
GroupItem groupItem = GroupItem.DATA_KEY.getData(e.getDataContext());
e.getPresentation().setEnabled(project != null && groupItem != null && !groupItem.isReadOnly());
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java
index 4627efd195f0..2fe60e396578 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/palette/Palette.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2015 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,7 +18,6 @@ package com.intellij.uiDesigner.palette;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.LafManagerListener;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
@@ -78,7 +77,7 @@ public final class Palette implements Disposable, PersistentStateComponent myClass2Properties;
private final Map myClassName2Item;
/*All groups in the palette*/
- private final ArrayList myGroups;
+ private final List myGroups;
/*Listeners, etc*/
private final List myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final Project myProject;
@@ -118,7 +117,9 @@ public final class Palette implements Disposable, PersistentStateComponentDO NOT MODIFY OR CACHE THIS LIST.
*/
- public ArrayList getGroups(){
+ public List getGroups() {
return myGroups;
}
public GroupItem[] getToolWindowGroups() {
- GroupItem[] groups = new GroupItem[myGroups.size()+1];
- for(int i=0; i groups){
+ public void setGroups(@NotNull final ArrayList groups) {
myGroups.clear();
myGroups.addAll(groups);
@@ -288,9 +274,10 @@ public final class Palette implements Disposable, PersistentStateComponentitem to the palette.
+ *
* @param item item to be added
- * @exception java.lang.IllegalArgumentException if an item for the same class
- * is already exists in the palette
+ * @throws IllegalArgumentException if an item for the same class
+ * is already exists in the palette
*/
public void addItem(@NotNull final GroupItem group, @NotNull final ComponentItem item) {
// class -> item
@@ -309,7 +296,7 @@ public final class Palette implements Disposable, PersistentStateComponent propertyName2initialValue = new HashMap();
{
final Element initialValues = itemElement.getChild(ELEMENT_INITIAL_VALUES);
- if (initialValues != null){
- for(final Object o : initialValues.getChildren(ELEMENT_PROPERTY)) {
+ if (initialValues != null) {
+ for (final Object o : initialValues.getChildren(ELEMENT_PROPERTY)) {
final Element e = (Element)o;
final String name = LwXmlReader.getRequiredString(e, ATTRIBUTE_NAME);
// TODO[all] currently all initial values are strings
@@ -430,14 +417,11 @@ public final class Palette implements Disposable, PersistentStateComponent groupElements) {
+ for (Element groupElement : groupElements) {
+ GroupItem group = new GroupItem(LwXmlReader.getRequiredString(groupElement, ATTRIBUTE_NAME));
myGroups.add(group);
- for (final Object o : groupElement.getChildren(ELEMENT_ITEM)) {
- final Element itemElement = (Element)o;
+ for (Element itemElement : groupElement.getChildren(ELEMENT_ITEM)) {
try {
processItemElement(itemElement, group, false);
}
@@ -448,8 +432,10 @@ public final class Palette implements Disposable, PersistentStateComponent name2value
- ){
+ ) {
LOG.assertTrue(ELEMENT_ITEM.equals(itemElement.getName()));
- if(name2value.size() == 0){ // do not append 'initial-values' subtag
+ if (name2value.size() == 0) { // do not append 'initial-values' subtag
return;
}
@@ -516,8 +504,10 @@ public final class Palette implements Disposable, PersistentStateComponent filter = null;
if (name.equals(SwingProperties.LABEL_FOR)) {
filter = new Condition() {
+ @Override
public boolean value(final RadComponent t) {
ComponentItem item = getItem(t.getComponentClassName());
return item != null && item.isCanAttachLabel();
@@ -756,9 +744,9 @@ public final class Palette implements Disposable, PersistentStateComponentDO NOT USE THIS METHOD DIRECTLY. Use {@link com.intellij.uiDesigner.radComponents.RadComponent#getInplaceProperty(int, int) }
+ * DO NOT USE THIS METHOD DIRECTLY. Use {@link RadComponent#getInplaceProperty(int, int) }
* instead.
*/
@Nullable
@@ -777,17 +765,17 @@ public final class Palette implements Disposable, PersistentStateComponent= 0; i--) {
final IntrospectedProperty property = properties[i];
- if(property.getName().equals(inplaceProperty)){
+ if (property.getName().equals(inplaceProperty)) {
return property;
}
}
return null;
}
- public static boolean isRemovable(@NotNull final GroupItem group){
+ public static boolean isRemovable(@NotNull final GroupItem group) {
final ComponentItem[] items = group.getItems();
- for(int i = items.length - 1; i >=0; i--){
- if(!items [i].isRemovable()){
+ for (int i = items.length - 1; i >= 0; i--) {
+ if (!items[i].isRemovable()) {
return false;
}
}
@@ -797,12 +785,12 @@ public final class Palette implements Disposable, PersistentStateComponent arguments) throws ExecutionException {
- final String condaExecutable = findCondaExecutable(mySdk);
+ final String condaExecutable = PyCondaPackageService.getCondaExecutable();
final String path = getCondaDirectory();
if (path == null) throw new PyExecutionException("Empty conda name for " + mySdk, command, arguments);
@@ -109,6 +109,7 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
private String getCondaDirectory() {
final VirtualFile homeDirectory = mySdk.getHomeDirectory();
if (homeDirectory == null) return null;
+ if (SystemInfo.isWindows) return homeDirectory.getParent().getPath();
return homeDirectory.getParent().getParent().getPath();
}
@@ -147,7 +148,6 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
}
final String name = fields.get(0);
final String version = fields.get(1);
- final String location = fields.get(2);
final List requirements = new ArrayList();
if (fields.size() >= 4) {
final String requiresLine = fields.get(3);
@@ -155,25 +155,24 @@ public class PyCondaPackageManagerImpl extends PyPackageManagerImpl {
requirements.addAll(PyRequirement.parse(requiresSpec));
}
if (!"Python".equals(name)) {
- packages.add(new PyPackage(name, version, location, requirements));
+ packages.add(new PyPackage(name, version, "", requirements));
}
}
return packages;
}
- @Nullable
- public static String findCondaExecutable(Sdk sdk) {
- final String condaName = SystemInfo.isWindows ? "conda.exe" : "conda";
+ public static boolean isCondaVEnv(Sdk sdk) {
+ final String condaName = "conda-meta";
final VirtualFile homeDirectory = sdk.getHomeDirectory();
- if (homeDirectory == null) return null;
- final VirtualFile condaExecutable = homeDirectory.getParent().findChild(condaName);
- return condaExecutable != null ? condaExecutable.getPath() : null;
+ if (homeDirectory == null) return false;
+ final VirtualFile condaExecutable = SystemInfo.isWindows ? homeDirectory.getParent().findChild(condaName) :
+ homeDirectory.getParent().getParent().findChild(condaName);
+ return condaExecutable != null;
}
@NotNull
public static String createVirtualEnv(@NotNull String destinationDir, String version) throws ExecutionException {
- final String condaName = SystemInfo.isWindows ? "conda.exe" : "conda";
- final String condaExecutable = PyCondaPackageService.getCondaExecutable(condaName);
+ final String condaExecutable = PyCondaPackageService.getCondaExecutable();
if (condaExecutable == null) throw new PyExecutionException("Cannot find conda", "Conda", Collections.emptyList(), new ProcessOutput());
final ArrayList parameters = Lists.newArrayList(condaExecutable, "create", "-p", destinationDir,
diff --git a/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java b/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java
index ae79f64e5e5c..c3355fa4c0d0 100644
--- a/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java
+++ b/python/src/com/jetbrains/python/packaging/PyCondaPackageService.java
@@ -79,12 +79,28 @@ public class PyCondaPackageService implements PersistentStateComponent parameters = Lists.newArrayList(conda, "config", "--add", "channels", repositoryUrl, "--force");
+ final GeneralCommandLine commandLine = new GeneralCommandLine(parameters);
+
+ try {
+ final Process process = commandLine.createProcess();
+ final CapturingProcessHandler handler = new CapturingProcessHandler(process);
+ final ProcessOutput result = handler.runProcess();
+ final int exitCode = result.getExitCode();
+ if (exitCode != 0) {
+ final String message = StringUtil.isEmptyOrSpaces(result.getStdout()) && StringUtil.isEmptyOrSpaces(result.getStderr()) ?
+ "Permission denied" : "Non-zero exit code";
+ LOG.warn("Failed to add repository " + message);
+ }
+ PyCondaPackageService.getInstance().addChannel(repositoryUrl);
+ }
+ catch (ExecutionException e) {
+ LOG.warn("Failed to add repository");
+ }
+
+ }
+
+ @Override
+ public void removeRepository(String repositoryUrl) {
+ final String conda = PyCondaPackageService.getCondaExecutable();
+ final ArrayList parameters = Lists.newArrayList(conda, "config", "--remove", "channels", repositoryUrl, "--force");
+ final GeneralCommandLine commandLine = new GeneralCommandLine(parameters);
+
+ try {
+ final Process process = commandLine.createProcess();
+ final CapturingProcessHandler handler = new CapturingProcessHandler(process);
+ final ProcessOutput result = handler.runProcess();
+ final int exitCode = result.getExitCode();
+ if (exitCode != 0) {
+ final String message = StringUtil.isEmptyOrSpaces(result.getStdout()) && StringUtil.isEmptyOrSpaces(result.getStderr()) ?
+ "Permission denied" : "Non-zero exit code";
+ LOG.warn("Failed to remove repository " + message);
+ }
+ PyCondaPackageService.getInstance().removeChannel(repositoryUrl);
+ }
+ catch (ExecutionException e) {
+ LOG.warn("Failed to remove repository");
+ }
+ }
+
@Override
public boolean canInstallToUser() {
return false;
@@ -71,8 +124,4 @@ public class PyCondaManagementService extends PyPackageManagementService {
consumer.consume(versions);
}
- @Override
- public void uninstallPackages(List installedPackages, Listener listener) {
- super.uninstallPackages(installedPackages, listener);
- }
}
diff --git a/python/src/com/jetbrains/python/sdk/AbstractCreateVirtualEnvDialog.java b/python/src/com/jetbrains/python/sdk/AbstractCreateVirtualEnvDialog.java
index ec069ff17c47..fe0d9e50fc71 100644
--- a/python/src/com/jetbrains/python/sdk/AbstractCreateVirtualEnvDialog.java
+++ b/python/src/com/jetbrains/python/sdk/AbstractCreateVirtualEnvDialog.java
@@ -128,7 +128,7 @@ public abstract class AbstractCreateVirtualEnvDialog extends IdeaDialog {
new LocationNameFieldsBinding(project, myDestination, myName, myInitialPath, "Select Location for Virtual Environment");
}
- private void setInitialDestination() {
+ protected void setInitialDestination() {
myInitialPath = "";
final VirtualFile file = VirtualEnvSdkFlavor.getDefaultLocation();
diff --git a/python/src/com/jetbrains/python/sdk/CreateCondaEnvDialog.java b/python/src/com/jetbrains/python/sdk/CreateCondaEnvDialog.java
index e1f74649d843..37c9620424ab 100644
--- a/python/src/com/jetbrains/python/sdk/CreateCondaEnvDialog.java
+++ b/python/src/com/jetbrains/python/sdk/CreateCondaEnvDialog.java
@@ -20,9 +20,11 @@ import com.intellij.facet.ui.FacetValidatorsManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.ui.components.JBLabel;
import com.jetbrains.python.packaging.PyCondaPackageManagerImpl;
+import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor;
import com.jetbrains.python.validation.UnsupportedFeaturesUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,6 +57,14 @@ public class CreateCondaEnvDialog extends AbstractCreateVirtualEnvDialog {
checkValid();
}
+ @Override
+ protected void setInitialDestination() {
+ final List locations = VirtualEnvSdkFlavor.getCondaDefaultLocations();
+ if (!locations.isEmpty()) {
+ myInitialPath = locations.get(0).getPath();
+ }
+ }
+
protected void layoutPanel(final List allSdks) {
final GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java
index bf16c4ee37bb..c66d491f6a7f 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java
@@ -37,7 +37,6 @@ import com.intellij.openapi.ui.popup.ListSeparator;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.NullableConsumer;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.packaging.PyCondaPackageService;
@@ -110,8 +109,7 @@ public class PythonSdkDetailsStep extends BaseListPopupStep {
options.add(REMOTE);
}
options.add(VIRTUALENV);
- final String condaName = SystemInfo.isWindows ? "conda.exe" : "conda";
- if (PyCondaPackageService.getCondaExecutable(condaName) != null) {
+ if (PyCondaPackageService.getCondaExecutable() != null) {
options.add(CONDA);
}
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java
index 5e9fc647fe06..c08e908d8cb0 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java
@@ -316,7 +316,7 @@ public class PythonSdkType extends SdkType {
public static boolean isCondaVirtualEnv(Sdk sdk) {
final String path = sdk.getHomePath();
- return path != null && PyCondaPackageManagerImpl.findCondaExecutable(sdk) != null;
+ return path != null && PyCondaPackageManagerImpl.isCondaVEnv(sdk);
}
@Nullable