From c5d4bfd21561645f4e4f4285982f561092e350e7 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 12 Dec 2011 13:52:44 +0100 Subject: [PATCH 1/5] plugins: do not suggest to enable dependencies when one of them was not installed for some reason (IDEA-78642) --- .../src/com/intellij/ide/plugins/PluginManager.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java index 10ba954a4e0f..3257425964e4 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java @@ -766,7 +766,16 @@ public class PluginManager { message.append("not loaded plugins"); } message.append(""); - message.append("
").append("Enable ").append(faultyDescriptors.size() == 1 ? disabledPluginNames.get(faultyDescriptors.iterator().next()) : " all necessary plugins").append(""); + boolean possibleToEnable = true; + for (String descriptor : faultyDescriptors) { + if (disabledPluginNames.get(descriptor) == null) { + possibleToEnable = false; + break; + } + } + if (possibleToEnable) { + message.append("
").append("Enable ").append(faultyDescriptors.size() == 1 ? disabledPluginNames.get(faultyDescriptors.iterator().next()) : " all necessary plugins").append(""); + } message.append("
").append("Open plugin manager"); } if (pluginsWithoutIdFound) { From a4468781101df749c94b275eb2828929232ba462 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 12 Dec 2011 13:59:11 +0100 Subject: [PATCH 2/5] SOE protection --- .../encoding/ChangeEncodingUpdateGroup.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeEncodingUpdateGroup.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeEncodingUpdateGroup.java index 49cac45a411b..53c64fa3965c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeEncodingUpdateGroup.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeEncodingUpdateGroup.java @@ -27,26 +27,38 @@ import com.intellij.pom.Navigatable; * @author cdr */ public class ChangeEncodingUpdateGroup extends DefaultActionGroup { + private boolean myUpdating; + @Override public void update(final AnActionEvent e) { + if (myUpdating) { + return; + } VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); if (files != null && files.length > 1) { virtualFile = null; } - if (virtualFile != null){ + if (virtualFile != null) { Navigatable navigatable = e.getData(PlatformDataKeys.NAVIGATABLE); if (navigatable instanceof OpenFileDescriptor) { // prefer source to the class file virtualFile = ((OpenFileDescriptor)navigatable).getFile(); } } - if(virtualFile != null && !virtualFile.isInLocalFileSystem()){ + if (virtualFile != null && !virtualFile.isInLocalFileSystem()) { virtualFile = null; } Pair result = ChooseFileEncodingAction.update(virtualFile); - e.getPresentation().setText(result.getFirst()); - e.getPresentation().setEnabled(result.getSecond()); + myUpdating = true; + try { + e.getPresentation().setText(result.getFirst()); + // updating the enabled state of the action can trigger the menuSelected handler, which updates the action group again + e.getPresentation().setEnabled(result.getSecond()); + } + finally { + myUpdating = false; + } } } From 810c16844ffb3f432fa729766d8af36c8a7d84a9 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 12 Dec 2011 16:29:30 +0300 Subject: [PATCH 3/5] Bug fix: Process doesn't stop on breakpoint. --- .../springloaded/SpringLoadedPositionManager.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java index dffc834d3c2a..34f0e7d303df 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java @@ -33,7 +33,7 @@ import java.util.regex.Pattern; */ public class SpringLoadedPositionManager implements PositionManager { - private static final Pattern GENERATED_CLASS_NAME = Pattern.compile(".*\\$\\$[A-Za-z0-9]{8}"); + private static final Pattern GENERATED_CLASS_NAME = Pattern.compile("\\$\\$[A-Za-z0-9]{8}"); private final DebugProcess myDebugProcess; @@ -158,6 +158,16 @@ public class SpringLoadedPositionManager implements PositionManager { return myDebugProcess.getRequestsManager().createClassPrepareRequest(requestor, className + "*"); } + private static boolean isSpringLoadedGeneratedClass(ReferenceType ownerClass, ReferenceType aClass) { + String name = aClass.name(); + String ownerClassName = ownerClass.name(); + + // return name == ownerClassName + "$$" + /[A-Za-z0-9]{8}/ + return name.length() == ownerClassName.length() + 2 + 8 + && name.startsWith(ownerClassName) + && GENERATED_CLASS_NAME.matcher(name.substring(ownerClassName.length())).matches(); + } + @Nullable private static List findNested(ReferenceType fromClass, SourcePosition classPosition) { if (!fromClass.isPrepared()) return null; @@ -169,7 +179,7 @@ public class SpringLoadedPositionManager implements PositionManager { for (ReferenceType nested : nestedTypes) { if (!nested.isPrepared()) continue; - if (GENERATED_CLASS_NAME.matcher(nested.name()).matches()) { + if (isSpringLoadedGeneratedClass(fromClass, nested)) { if (springLoadedGeneratedClasses.size() > 0 && !springLoadedGeneratedClasses.get(0).name().equals(nested.name())) { springLoadedGeneratedClasses.clear(); // Only latest generated classes should be used. } From 69ccf77b024bb2482e6007cb6ee88e27dac909d1 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 12 Dec 2011 16:48:26 +0300 Subject: [PATCH 4/5] Optimize DefaultPicoContainer for test. --- .../util/pico/DefaultPicoContainer.java | 107 +++++++++++------- 1 file changed, 68 insertions(+), 39 deletions(-) diff --git a/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java b/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java index 842cd469f4a4..c7dc592bb474 100644 --- a/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java +++ b/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java @@ -17,6 +17,7 @@ package com.intellij.util.pico; import com.intellij.util.ReflectionCache; import com.intellij.util.containers.ConcurrentHashMap; +import com.intellij.util.containers.FList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.picocontainer.*; @@ -24,7 +25,6 @@ import org.picocontainer.defaults.*; import java.io.Serializable; import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicReference; public class DefaultPicoContainer implements MutablePicoContainer, Serializable { @@ -34,11 +34,11 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable private final Set children = new HashSet(); private final Map componentKeyToAdapterCache = new ConcurrentHashMap(); - private final AtomicReference> componentAdapters = new AtomicReference>(new LinkedHashSet()); + private final LinkedHashSetWrapper componentAdapters = new LinkedHashSetWrapper(); // Keeps track of instantiation order. - private final AtomicReference> orderedComponentAdapters = new AtomicReference>(new LinkedHashSet()); + private final LinkedHashSetWrapper orderedComponentAdapters = new LinkedHashSetWrapper(); private final Map classNameToAdapter = new ConcurrentHashMap(); - private final CopyOnWriteArrayList nonAssignableComponentAdapters = new CopyOnWriteArrayList(); + private final AtomicReference> nonAssignableComponentAdapters = new AtomicReference>(FList.emptyList()); public DefaultPicoContainer(@NotNull ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) { this.componentAdapterFactory = componentAdapterFactory; @@ -50,7 +50,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable } public Collection getComponentAdapters() { - return Collections.unmodifiableCollection(componentAdapters.get()); + return componentAdapters.getImmutableSet(); } public Map getAssignablesCache() { @@ -59,7 +59,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable public Collection getNonAssignableAdapters() { - return nonAssignableComponentAdapters; + return nonAssignableComponentAdapters.get().getReversedList(); } @Nullable @@ -141,51 +141,34 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable classNameToAdapter.put(classKey, componentAdapter); } else { - nonAssignableComponentAdapters.add(componentAdapter); + do { + FList oldList = nonAssignableComponentAdapters.get(); + FList newList = oldList.prepend(componentAdapter); + if (nonAssignableComponentAdapters.compareAndSet(oldList, newList)) { + break; + } + } while (true); } - addElement(componentAdapters, componentAdapter); + componentAdapters.add(componentAdapter); componentKeyToAdapterCache.put(componentKey, componentAdapter); return componentAdapter; } - private static void addElement(AtomicReference> collectionHolder, T element) { - do { - LinkedHashSet oldCollection = collectionHolder.get(); - if (oldCollection.contains(element)) { - return; - } - - LinkedHashSet newCollection = new LinkedHashSet(oldCollection); - newCollection.add(element); - - if (collectionHolder.compareAndSet(oldCollection, newCollection)) break; - } while (true); - } - - private static void removeElement(AtomicReference> collectionHolder, T element) { - do { - LinkedHashSet oldCollection = collectionHolder.get(); - - LinkedHashSet newCollection = new LinkedHashSet(oldCollection); - newCollection.remove(element); - - if (collectionHolder.compareAndSet(oldCollection, newCollection)) break; - } while (true); - } - public ComponentAdapter unregisterComponent(Object componentKey) { ComponentAdapter adapter = componentKeyToAdapterCache.remove(componentKey); - removeElement(componentAdapters, adapter); - removeElement(orderedComponentAdapters, adapter); + componentAdapters.remove(adapter); + orderedComponentAdapters.remove(adapter); return adapter; } private void addOrderedComponentAdapter(ComponentAdapter componentAdapter) { - addElement(orderedComponentAdapters, componentAdapter); + if (!orderedComponentAdapters.contains(componentAdapter)) { + orderedComponentAdapters.add(componentAdapter); + } } public List getComponentInstances() throws PicoException { @@ -198,7 +181,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable } Map adapterToInstanceMap = new HashMap(); - for (final ComponentAdapter componentAdapter : componentAdapters.get()) { + for (final ComponentAdapter componentAdapter : componentAdapters.getImmutableSet()) { if (ReflectionCache.isAssignable(componentType, componentAdapter.getComponentImplementation())) { Object componentInstance = getInstance(componentAdapter); adapterToInstanceMap.put(componentAdapter, componentInstance); @@ -210,7 +193,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable } List result = new ArrayList(); - for (ComponentAdapter componentAdapter : orderedComponentAdapters.get()) { + for (ComponentAdapter componentAdapter : orderedComponentAdapters.getImmutableSet()) { final Object componentInstance = adapterToInstanceMap.get(componentAdapter); if (componentInstance != null) { // may be null in the case of the "implicit" adapter @@ -240,7 +223,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable @Nullable private Object getInstance(ComponentAdapter componentAdapter) { - final boolean isLocal = componentAdapters.get().contains(componentAdapter); + final boolean isLocal = componentAdapters.contains(componentAdapter); if (isLocal) { return getLocalInstance(componentAdapter); @@ -359,4 +342,50 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable public PicoContainer getParent() { return parent; } + + private static class LinkedHashSetWrapper { + + private volatile Set immutableSet; + + private final LinkedHashSet synchronizedSet = new LinkedHashSet(); + + private final ConcurrentHashMap concurrentSet = new ConcurrentHashMap(); + + public boolean contains(@Nullable T element) { + return element != null && concurrentSet.containsKey(element); + } + + public void add(@NotNull T element) { + synchronized (synchronizedSet) { + immutableSet = null; + synchronizedSet.add(element); + concurrentSet.put(element, element); + } + } + + public void remove(@Nullable T element) { + if (element == null) return; + synchronized (synchronizedSet) { + immutableSet = null; + synchronizedSet.remove(element); + concurrentSet.remove(element); + } + } + + @NotNull + public Set getImmutableSet() { + Set res = immutableSet; + if (res == null) { + synchronized (synchronizedSet) { + res = immutableSet; + if (res == null) { + res = Collections.unmodifiableSet((Set)synchronizedSet.clone()); + immutableSet = res; + } + } + } + + return res; + } + } } \ No newline at end of file From 30b1cd8e277c09d8218faa070019de35868a04a4 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 12 Dec 2011 14:06:42 +0100 Subject: [PATCH 5/5] copyright: provide default presentation for date format used for e.g. $today (IDEA-78731) --- .../src/com/maddyhome/idea/copyright/pattern/DateInfo.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/DateInfo.java b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/DateInfo.java index e17b81c163e6..8850438edf38 100644 --- a/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/DateInfo.java +++ b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/DateInfo.java @@ -70,4 +70,9 @@ public class DateInfo } private final Calendar calendar; + + @Override + public String toString() { + return new SimpleDateFormat().format(calendar.getTime()); + } } \ No newline at end of file