diff --git a/lib/commons-net-1.4.1.jar b/lib/commons-net-1.4.1.jar deleted file mode 100644 index 9666a92c8009..000000000000 Binary files a/lib/commons-net-1.4.1.jar and /dev/null differ diff --git a/lib/commons-net-2.0-patched.jar b/lib/commons-net-2.0-patched.jar new file mode 100644 index 000000000000..127306f10225 Binary files /dev/null and b/lib/commons-net-2.0-patched.jar differ diff --git a/lib/src/commons-net-1.4.1-src.zip b/lib/src/commons-net-1.4.1-src.zip deleted file mode 100644 index 14237a28d602..000000000000 Binary files a/lib/src/commons-net-1.4.1-src.zip and /dev/null differ diff --git a/lib/src/commons-net-2.0-patched-src.zip b/lib/src/commons-net-2.0-patched-src.zip new file mode 100644 index 000000000000..d9293b20b394 Binary files /dev/null and b/lib/src/commons-net-2.0-patched-src.zip differ diff --git a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java index 29d9f868295c..a855a6b4d4c4 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java @@ -43,6 +43,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -66,7 +68,17 @@ public class ChooseRunConfigurationAction extends AnAction { final Executor executor = getDefaultExecutor(); assert executor != null; - final RunListPopup popup = new RunListPopup(project, new ConfigurationListPopupStep(this, project, String.format("%s", executor.getActionName()))); + final RunListPopup popup = new RunListPopup(project, new ConfigurationListPopupStep(this, project, String.format("%s", executor.getActionName()))) { + @Override + protected void handleShiftClick(final boolean handleFinalChoices, final InputEvent inputEvent, final RunListPopup popup) { + try { + myCurrentExecutor = getAlternateExecutor(); + popup._handleSelect(handleFinalChoices, inputEvent); + } finally { + myCurrentExecutor = null; + } + } + }; registerActions(popup); final String adText = getAdText(getAlternateExecutor()); @@ -792,7 +804,7 @@ public class ChooseRunConfigurationAction extends AnAction { } } - private static class RunListPopup extends ListPopupImpl { + private static abstract class RunListPopup extends ListPopupImpl { private Project myProject_; public RunListPopup(final Project project, ListPopupStep step) { @@ -800,6 +812,28 @@ public class ChooseRunConfigurationAction extends AnAction { myProject_ = project; } + @Override + public void handleSelect(boolean handleFinalChoices, InputEvent e) { + if (e instanceof MouseEvent && e.isShiftDown()) { + handleShiftClick(handleFinalChoices, e, this); + return; + } + + _handleSelect(handleFinalChoices, e); + } + + protected void _handleSelect(boolean handleFinalChoices, InputEvent e) { + super.handleSelect(handleFinalChoices, e); + } + + protected abstract void handleShiftClick(boolean handleFinalChoices, final InputEvent inputEvent, final RunListPopup popup); + + @Override + protected boolean isActionClick(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON2 || e.isPopupTrigger() || e.getID() != MouseEvent.MOUSE_PRESSED) return false; + return e.getButton() == MouseEvent.BUTTON1; + } + @Override protected ListCellRenderer getListElementRenderer() { return new RunListElementRenderer(this); diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java index 330b51629090..884b6c418f9e 100644 --- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java +++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java @@ -62,6 +62,7 @@ import com.intellij.util.Icons; import com.intellij.util.Processor; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.Table; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -334,12 +335,7 @@ public class ShowUsagesAction extends AnAction { addUsageNodes(usageView.getRoot(), usageView, new ArrayList()); - final JTable table = new Table(){ - @Override - public boolean getScrollableTracksViewportWidth() { - return true; - } - }; + final JTable table = new MyTable(); TableScrollingUtil.installActions(table); final Vector data = new Vector(); setModel(table, usages, visibleNodes, usageView, data); @@ -411,6 +407,8 @@ public class ShowUsagesAction extends AnAction { } }; + + KeyboardShortcut shortcut = getSettingsShortcut(); if (shortcut != null) { builder.registerKeyboardAction(shortcut.getFirstKeyStroke(), editSettings); @@ -635,4 +633,30 @@ public class ShowUsagesAction extends AnAction { }); } } + + static class MyTable extends Table implements DataProvider { + @Override + public boolean getScrollableTracksViewportWidth() { + return true; + } + + public Object getData(@NonNls String dataId) { + if (LangDataKeys.PSI_ELEMENT.getName().equals(dataId)) { + final int[] selected = getSelectedRows(); + if (selected.length == 1) { + final Object at = getValueAt(selected[0], 0); + if (at instanceof UsageNode) { + final Usage usage = ((UsageNode)at).getUsage(); + if (usage instanceof UsageInfo2UsageAdapter) { + final PsiElement element = ((UsageInfo2UsageAdapter)usage).getElement(); + if (element != null) { + return element.getContainingFile(); + } + } + } + } + } + return null; + } + } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java index 465df0fb1a0c..9df8f6d20951 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java @@ -16,15 +16,16 @@ package com.intellij.openapi.roots.impl; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.containers.OrderedSet; -import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; + +import java.util.*; -import java.util.Collections; -import java.util.List; public class DirectoryInfo { public Module module; // module to which content it belongs or null @@ -36,11 +37,15 @@ public class DirectoryInfo { public VirtualFile sourceRoot; /** - * orderEntry to (classes of) which a directory belongs + * orderEntry to (classes of) which a directory belongs */ private List orderEntries = null; + @TestOnly + @SuppressWarnings({"unchecked"}) public boolean equals(Object o) { + assert ApplicationManager.getApplication().isUnitTestMode() : "DirectoryInfo.equals should only be used in tests"; + if (this == o) return true; if (!(o instanceof DirectoryInfo)) return false; @@ -50,7 +55,7 @@ public class DirectoryInfo { if (isInModuleSource != info.isInModuleSource) return false; if (isTestSource != info.isTestSource) return false; if (module != null ? !module.equals(info.module) : info.module != null) return false; - if (orderEntries != null ? !orderEntries.equals(info.orderEntries) : info.orderEntries != null) return false; + if (orderEntries != null ? !new HashSet(orderEntries).equals(new HashSet(info.orderEntries)) : info.orderEntries != null) return false; if (!Comparing.equal(libraryClassRoot, info.libraryClassRoot)) return false; if (!Comparing.equal(contentRoot, info.contentRoot)) return false; if (!Comparing.equal(sourceRoot, info.sourceRoot)) return false; @@ -80,20 +85,23 @@ public class DirectoryInfo { } @SuppressWarnings({"unchecked"}) - public void addOrderEntries(final List orderEntries, - final DirectoryInfo parentInfo, - final List oldParentEntries) { - if (this.orderEntries == null) { + public void addOrderEntries(List orderEntries, + @Nullable final DirectoryInfo parentInfo, + @Nullable final List oldParentEntries) { + if (orderEntries.isEmpty()) { + this.orderEntries = null; + } + else if (this.orderEntries == null) { this.orderEntries = orderEntries; } else if (parentInfo != null && oldParentEntries == this.orderEntries) { - this.orderEntries = parentInfo.getOrderEntries(); + this.orderEntries = parentInfo.orderEntries; } else { - List tmp = new OrderedSet(TObjectHashingStrategy.CANONICAL); + LinkedHashSet tmp = new LinkedHashSet(this.orderEntries.size() + orderEntries.size()); tmp.addAll(this.orderEntries); tmp.addAll(orderEntries); - this.orderEntries = tmp; + this.orderEntries = new ArrayList(tmp); } } } diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index cf80069f8176..4c7fec3ad206 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -229,7 +229,7 @@ public class AbstractTreeUi { private void initClearanceServiceIfNeeded() { if (ourClearanceService != null) return; - ourClearanceService = ConcurrencyUtil.newSingleScheduledThreadExecutor("AbstractTreeBuilder's janitor"); + ourClearanceService = ConcurrencyUtil.newSingleScheduledThreadExecutor("AbstractTreeBuilder's janitor", Thread.MIN_PRIORITY + 1); ourClearanceService.scheduleWithFixedDelay(new Runnable() { public void run() { cleanUpAll(); diff --git a/platform/platform-api/src/com/intellij/openapi/util/SimpleTimer.java b/platform/platform-api/src/com/intellij/openapi/util/SimpleTimer.java index e7498b040404..4e5e9d4bcd2c 100644 --- a/platform/platform-api/src/com/intellij/openapi/util/SimpleTimer.java +++ b/platform/platform-api/src/com/intellij/openapi/util/SimpleTimer.java @@ -21,7 +21,7 @@ import java.util.*; * Simple timer that keeps order of scheduled tasks */ public class SimpleTimer { - private final Timer ourTimer = new Timer(THREAD_NAME, true); + private final Timer ourTimer; private static final SimpleTimer ourInstance = new SimpleTimer(); private static final String THREAD_NAME = "SimpleTimer"; @@ -32,6 +32,16 @@ public class SimpleTimer { private final Map> myTime2Task = new TreeMap>(); private SimpleTimer() { + final Thread thread = Thread.currentThread(); + final int currentPrio = thread.getPriority(); + try { + // need this becase the timer's thread will inherit the priority on creation + thread.setPriority(Thread.MIN_PRIORITY + 1); + ourTimer = new Timer(THREAD_NAME, true); + } + finally { + thread.setPriority(currentPrio); + } } public static SimpleTimer getInstance() { @@ -47,7 +57,7 @@ public class SimpleTimer { ArrayList tasks = myTime2Task.get(targetTime); if (tasks == null) { - tasks = new ArrayList(2); + tasks = new ArrayList(2); myTime2Task.put(targetTime, tasks); } tasks.add(result); diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java index 8cdeae613f0f..cf7366205752 100644 --- a/platform/platform-api/src/com/intellij/util/Alarm.java +++ b/platform/platform-api/src/com/intellij/util/Alarm.java @@ -45,7 +45,7 @@ public class Alarm implements Disposable { private final ThreadPoolExecutor myExecutorService; - private static final ThreadPoolExecutor ourSharedExecutorService = ConcurrencyUtil.newSingleThreadExecutor("Alarm pool(shared)"); + private static final ThreadPoolExecutor ourSharedExecutorService = ConcurrencyUtil.newSingleThreadExecutor("Alarm pool(shared)", Thread.NORM_PRIORITY - 2); private final Object LOCK = new Object(); private final ThreadToUse myThreadToUse; @@ -84,7 +84,7 @@ public class Alarm implements Disposable { } public Alarm(@NotNull ThreadToUse threadToUse, Disposable parentDisposable) { myThreadToUse = threadToUse; - myExecutorService = threadToUse == ThreadToUse.OWN_THREAD ? ConcurrencyUtil.newSingleThreadExecutor("Alarm pool(own)") : ourSharedExecutorService; + myExecutorService = threadToUse == ThreadToUse.OWN_THREAD ? ConcurrencyUtil.newSingleThreadExecutor("Alarm pool(own)", Thread.NORM_PRIORITY - 2) : ourSharedExecutorService; if (parentDisposable != null) { Disposer.register(parentDisposable, this); diff --git a/platform/platform-impl/src/com/intellij/concurrency/JobSchedulerImpl.java b/platform/platform-impl/src/com/intellij/concurrency/JobSchedulerImpl.java index 80d781687df9..ad798b41baef 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/JobSchedulerImpl.java +++ b/platform/platform-impl/src/com/intellij/concurrency/JobSchedulerImpl.java @@ -23,7 +23,10 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.application.impl.ApplicationImpl; import org.jetbrains.annotations.NonNls; -import java.util.concurrent.*; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -34,7 +37,9 @@ public class JobSchedulerImpl extends JobScheduler implements Disposable { private static final ThreadFactory WORKERS_FACTORY = new ThreadFactory() { int i; public Thread newThread(final Runnable r) { - return new Thread(r, "JobScheduler pool "+i+++"/"+CORES_COUNT); + final Thread thread = new Thread(r, "JobScheduler pool " + i++ + "/" + CORES_COUNT); + thread.setPriority(Thread.NORM_PRIORITY); + return thread; } }; diff --git a/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java b/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java index 8445c049e4a7..2b7e35a5f261 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java @@ -106,6 +106,7 @@ public class PerformanceWatcher implements ApplicationComponent { checkEDTResponsiveness(); } }, "Performance watcher"); + myThread.setPriority(Thread.MIN_PRIORITY); myThread.start(); } diff --git a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java index 56ddc6e1e16c..69a9586f4ad4 100644 --- a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java @@ -15,9 +15,9 @@ */ package com.intellij.ide; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.application.ApplicationManager; import org.apache.xmlrpc.IdeaAwareWebServer; import org.apache.xmlrpc.IdeaAwareXmlRpcServer; import org.apache.xmlrpc.WebServer; @@ -46,8 +46,10 @@ public class XmlRpcServerImpl implements XmlRpcServer, ApplicationComponent { public void initComponent() { if (ApplicationManager.getApplication().isUnitTestMode() || !checkPort()) return; - + final Thread thread = Thread.currentThread(); + final int currentPrio = thread.getPriority(); try { + thread.setPriority(Thread.NORM_PRIORITY - 2); myWebServer = new IdeaAwareWebServer(getPortNumber(), null, new IdeaAwareXmlRpcServer()); myWebServer.start(); } @@ -55,6 +57,9 @@ public class XmlRpcServerImpl implements XmlRpcServer, ApplicationComponent { LOG.error(e); myWebServer = null; } + finally { + thread.setPriority(currentPrio); + } } public int getPortNumber() { diff --git a/platform/platform-impl/src/com/intellij/idea/SocketLock.java b/platform/platform-impl/src/com/intellij/idea/SocketLock.java index 54073deefed3..bd32dd33f8c1 100644 --- a/platform/platform-impl/src/com/intellij/idea/SocketLock.java +++ b/platform/platform-impl/src/com/intellij/idea/SocketLock.java @@ -162,7 +162,9 @@ public class SocketLock { } } - new Thread(new MyRunnable(), LOCK_THREAD_NAME).start(); + final Thread thread = new Thread(new MyRunnable(), LOCK_THREAD_NAME); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); return; } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 0e71eb79b4a3..22f605aac9e9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -25,7 +25,6 @@ import com.intellij.ide.IdeRepaintManager; import com.intellij.ide.impl.ProjectUtil; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManager; -import com.intellij.openapi.Disposable; import com.intellij.openapi.application.*; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.application.ex.ApplicationManagerEx; @@ -112,8 +111,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application new SynchronousQueue(), new ThreadFactory() { public Thread newThread(Runnable r) { - return new Thread(r, "ApplicationImpl pooled thread") - { + final Thread thread = new Thread(r, "ApplicationImpl pooled thread") { public void interrupt() { if (LOG.isDebugEnabled()) { LOG.debug("Interrupted worker, will remove from pool"); @@ -124,13 +122,16 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application public void run() { try { super.run(); - } catch(Throwable t) { + } + catch (Throwable t) { if (LOG.isDebugEnabled()) { LOG.debug("Worker exits due to exception", t); } } } }; + thread.setPriority(Thread.NORM_PRIORITY - 1); + return thread; } } ); diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java index e49a5b47e6ff..54fd5ed11639 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java @@ -54,7 +54,7 @@ public class ProgressManagerImpl extends ProgressManager { public ProgressManagerImpl(Application application) { if (!application.isUnitTestMode() && !DISABLED) { - new Thread(NAME) { + final Thread thread = new Thread(NAME) { public void run() { while (true) { try { @@ -65,7 +65,9 @@ public class ProgressManagerImpl extends ProgressManager { ourNeedToCheckCancel = true; } } - }.start(); + }; + thread.setPriority(Thread.MIN_PRIORITY + 1); + thread.start(); } } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java index ca27e6816cf3..67c907e66a1e 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/ListPopupImpl.java @@ -356,11 +356,15 @@ public class ListPopupImpl extends WizardPopup implements ListPopup { } } + protected boolean isActionClick(MouseEvent e) { + return UIUtil.isActionClick(e); + } + private class MyMouseListener extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { - if (!UIUtil.isActionClick(e)) return; + if (!isActionClick(e)) return; boolean handleFinalChoices = true; final Object selectedValue = myList.getSelectedValue(); diff --git a/platform/util/src/com/intellij/util/ConcurrencyUtil.java b/platform/util/src/com/intellij/util/ConcurrencyUtil.java index a21844ba5188..c24ada093846 100644 --- a/platform/util/src/com/intellij/util/ConcurrencyUtil.java +++ b/platform/util/src/com/intellij/util/ConcurrencyUtil.java @@ -16,8 +16,8 @@ package com.intellij.util; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; @@ -84,19 +84,33 @@ public class ConcurrencyUtil { V prev = map.putIfAbsent(key, defaultValue); return prev == null ? defaultValue : prev; } + public static ThreadPoolExecutor newSingleThreadExecutor(@NonNls final String threadFactoryName) { + return newSingleThreadExecutor(threadFactoryName, Thread.NORM_PRIORITY); + } + + public static ThreadPoolExecutor newSingleThreadExecutor(final String threadFactoryName, final int threadPriority) { return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new ThreadFactory() { public Thread newThread(final Runnable r) { - return new Thread(r, threadFactoryName); + final Thread thread = new Thread(r, threadFactoryName); + thread.setPriority(threadPriority); + return thread; } }); } + public static ScheduledThreadPoolExecutor newSingleScheduledThreadExecutor(@NonNls final String threadFactoryName) { + return newSingleScheduledThreadExecutor(threadFactoryName, Thread.NORM_PRIORITY); + } + + public static ScheduledThreadPoolExecutor newSingleScheduledThreadExecutor(final String threadFactoryName, final int threadPriority) { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, new ThreadFactory() { public Thread newThread(final Runnable r) { - return new Thread(r, threadFactoryName); + final Thread thread = new Thread(r, threadFactoryName); + thread.setPriority(threadPriority); + return thread; } }); executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false); diff --git a/platform/util/src/com/intellij/util/Timed.java b/platform/util/src/com/intellij/util/Timed.java index 0393ee9801df..92ccb64ce428 100644 --- a/platform/util/src/com/intellij/util/Timed.java +++ b/platform/util/src/com/intellij/util/Timed.java @@ -74,7 +74,7 @@ abstract class Timed implements Disposable { static { - ScheduledExecutorService service = ConcurrencyUtil.newSingleScheduledThreadExecutor("timed reference disposer"); + ScheduledExecutorService service = ConcurrencyUtil.newSingleScheduledThreadExecutor("timed reference disposer", Thread.MIN_PRIORITY + 1); service.scheduleWithFixedDelay(new Runnable() { public void run() { try { diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java index 8b3ada744ac6..0e35d68c1964 100644 --- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java +++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java @@ -123,6 +123,10 @@ public class ContainerUtil { return EmptyIterator.getInstance(); } + public static Iterable emptyIterable() { + return EmptyIterable.getInstance(); + } + @Nullable public static T find(T[] array, Condition condition) { for (T element : array) { @@ -297,6 +301,42 @@ public class ContainerUtil { }; } + public static Iterable iterate(final Collection collection, final Condition condition) { + if (collection.isEmpty()) return emptyIterable(); + return new Iterable() { + public Iterator iterator() { + return new Iterator() { + Iterator impl = collection.iterator(); + T next = findNext(); + + public boolean hasNext() { + return next != null; + } + + public T next() { + T result = next; + next = findNext(); + return result; + } + + private T findNext() { + while (impl.hasNext()) { + T each = impl.next(); + if (condition.value(each)) { + return each; + } + } + return null; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }; + } + public static void swapElements(final List list, final int index1, final int index2) { E e1 = list.get(index1); E e2 = list.get(index2); diff --git a/platform/util/src/com/intellij/util/containers/EmptyIterable.java b/platform/util/src/com/intellij/util/containers/EmptyIterable.java new file mode 100644 index 000000000000..a840976af1fe --- /dev/null +++ b/platform/util/src/com/intellij/util/containers/EmptyIterable.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2009 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.util.containers; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class EmptyIterable implements Iterable { + private static final EmptyIterable INSTANCE = new EmptyIterable(); + + public static EmptyIterable getInstance() { + return INSTANCE; + } + + public Iterator iterator() { + return EmptyIterator.getInstance(); + } +} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/containers/OrderedSet.java b/platform/util/src/com/intellij/util/containers/OrderedSet.java index e3f32d7fc8e6..450c9d5cba23 100644 --- a/platform/util/src/com/intellij/util/containers/OrderedSet.java +++ b/platform/util/src/com/intellij/util/containers/OrderedSet.java @@ -29,6 +29,11 @@ public class OrderedSet extends AbstractSet implements List { myElements = new ArrayList(); } + public OrderedSet(TObjectHashingStrategy hashingStrategy, int capacity) { + myHashSet = new THashSet(capacity, hashingStrategy); + myElements = new ArrayList(capacity); + } + public OrderedSet() { myHashSet = new THashSet(); myElements = new ArrayList(); diff --git a/platform/util/src/com/intellij/util/ui/Timer.java b/platform/util/src/com/intellij/util/ui/Timer.java index f86b6623f2ba..eedce6e35886 100644 --- a/platform/util/src/com/intellij/util/ui/Timer.java +++ b/platform/util/src/com/intellij/util/ui/Timer.java @@ -62,6 +62,7 @@ public abstract class Timer implements Disposable { myDisposed = true; } }; + myThread.setPriority(Thread.MIN_PRIORITY + 1); } public void setTakeInitialDelay(final boolean take) { diff --git a/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java b/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java index c5fdd5d20e72..5dff09c904da 100644 --- a/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java @@ -16,12 +16,15 @@ package com.intellij.util.containers; +import com.intellij.openapi.util.Condition; + import java.util.*; public class ContainerUtilTest extends junit.framework.TestCase { public void testFindInstanceOf() { Iterator iterator = Arrays.asList(new Object[]{new Integer(1), new ArrayList(), "1"}).iterator(); - String string = (String)com.intellij.util.containers.ContainerUtil.find(iterator, com.intellij.util.containers.FilteringIterator.instanceOf(String.class)); + String string = (String)com.intellij.util.containers.ContainerUtil + .find(iterator, com.intellij.util.containers.FilteringIterator.instanceOf(String.class)); junit.framework.Assert.assertEquals("1", string); } @@ -32,17 +35,41 @@ public class ContainerUtilTest extends junit.framework.TestCase { assertEquals(2, l.get(1)); assertEquals(3, l.get(2)); assertEquals(4, l.get(3)); - + try { l.get(-1); fail(); - } catch(IndexOutOfBoundsException ignore) { + } + catch (IndexOutOfBoundsException ignore) { } try { l.get(4); fail(); - } catch(IndexOutOfBoundsException ignore) { + } + catch (IndexOutOfBoundsException ignore) { } } + + public void testIterateWithCondition() throws Exception { + Condition cond = new Condition() { + public boolean value(Integer integer) { + return integer > 2; + } + }; + + asserIterating(Arrays.asList(1, 4, 2, 5), cond, 4, 5); + asserIterating(Arrays.asList(1, 2), cond); + asserIterating(Collections.emptyList(), cond); + asserIterating(Arrays.asList(4), cond, 4); + } + + private void asserIterating(List collection, Condition condition, Integer... expected) { + Iterable it = ContainerUtil.iterate(collection, condition); + List actual = new ArrayList(); + for (Integer each : it) { + actual.add(each); + } + assertEquals(Arrays.asList(expected), actual); + } } diff --git a/platform/vcs-impl/src/com/intellij/lifecycle/SlowlyClosingAlarm.java b/platform/vcs-impl/src/com/intellij/lifecycle/SlowlyClosingAlarm.java index 7ef8eb6bac1e..e15cab7c6fd9 100644 --- a/platform/vcs-impl/src/com/intellij/lifecycle/SlowlyClosingAlarm.java +++ b/platform/vcs-impl/src/com/intellij/lifecycle/SlowlyClosingAlarm.java @@ -50,7 +50,9 @@ public class SlowlyClosingAlarm implements AtomicSectionsAware, Disposable { private static ThreadFactory threadFactory(@NonNls final String threadsName) { return new ThreadFactory() { public Thread newThread(final Runnable r) { - return new Thread(r, threadsName); + final Thread thread = new Thread(r, threadsName); + thread.setPriority(Thread.MIN_PRIORITY); + return thread; } }; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index 64988d952cb0..8cffe3fcb4f2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -34,8 +34,8 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.*; -import com.intellij.openapi.vcs.changes.ui.CommitHelper; import com.intellij.openapi.vcs.changes.conflicts.ChangelistConflictTracker; +import com.intellij.openapi.vcs.changes.ui.CommitHelper; import com.intellij.openapi.vcs.checkin.CheckinEnvironment; import com.intellij.openapi.vcs.checkin.CheckinHandler; import com.intellij.openapi.vcs.readOnlyHandler.ReadonlyStatusHandlerImpl; @@ -69,7 +69,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec private final UpdateRequestsQueue myUpdater; @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) - private static final ScheduledExecutorService ourUpdateAlarm = ConcurrencyUtil.newSingleScheduledThreadExecutor("Change List Updater"); + private static final ScheduledExecutorService ourUpdateAlarm = ConcurrencyUtil.newSingleScheduledThreadExecutor("Change List Updater", Thread.MIN_PRIORITY + 1); private final Modifier myModifier; diff --git a/plugins/git4idea/src/git4idea/history/GitCopyHistoryRevisionNumberAction.java b/plugins/git4idea/src/git4idea/history/GitCopyHistoryRevisionNumberAction.java new file mode 100644 index 000000000000..135c158d4b99 --- /dev/null +++ b/plugins/git4idea/src/git4idea/history/GitCopyHistoryRevisionNumberAction.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2009 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 git4idea.history; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.vcs.VcsDataKeys; +import com.intellij.openapi.vcs.history.VcsFileRevision; +import git4idea.i18n.GitBundle; + +import java.awt.datatransfer.StringSelection; + +/** + * The action that copies a revision number text to clipboard + */ +public class GitCopyHistoryRevisionNumberAction extends AnAction implements DumbAware { + + /** + * The constructor + */ + public GitCopyHistoryRevisionNumberAction() { + super(GitBundle.getString("history.copy.revsion.number")); + } + + /** + * {@inheritDoc} + */ + @Override + public void actionPerformed(AnActionEvent e) { + VcsFileRevision revision = e.getData(VcsDataKeys.VCS_FILE_REVISION); + if (revision != null) { + CopyPasteManager.getInstance().setContents(new StringSelection(revision.getRevisionNumber().asString())); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled((e.getData(VcsDataKeys.VCS_FILE_REVISION) != null)); + } +} diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java b/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java index 5209cd82599c..7e3a2ae519e9 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java @@ -62,7 +62,7 @@ public class GitHistoryProvider implements VcsHistoryProvider { * {@inheritDoc} */ public AnAction[] getAdditionalActions(FileHistoryPanel panel) { - return new AnAction[]{new GitShowAllSubmittedFilesAction()}; + return new AnAction[]{new GitShowAllSubmittedFilesAction(), new GitCopyHistoryRevisionNumberAction()}; } /** diff --git a/plugins/git4idea/src/git4idea/i18n/GitBundle.properties b/plugins/git4idea/src/git4idea/i18n/GitBundle.properties index dcfac82f50e7..0475ecc2d966 100644 --- a/plugins/git4idea/src/git4idea/i18n/GitBundle.properties +++ b/plugins/git4idea/src/git4idea/i18n/GitBundle.properties @@ -138,6 +138,7 @@ git.vcs.config.ssh.mode.tooltip=Specify which version of SSH to be used wi git.vcs.config.ssh.mode=&SSH executable: git.vcs.config.test.label=Test git.vcs.config.test=&Test +history.copy.revsion.number=Copy Revision Number index.file.error=Updating file in the index failed init.add.root.message=Do you want to add this directory as vcs root? init.add.root.title=Git Init diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index 42f6fe361e85..e743e6052466 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -218,7 +218,7 @@ public class GroovyAnnotator implements Annotator { private static void checkLabeledStatement(GrLabeledStatement statement, AnnotationHolder holder) { final String name = statement.getLabelName(); if (ResolveUtil.resolveLabeledStatement(name, statement, true) != null) { - holder.createErrorAnnotation(statement.getLabel(), GroovyBundle.message("label.already.used", name)); + holder.createWarningAnnotation(statement.getLabel(), GroovyBundle.message("label.already.used", name)); } } @@ -232,20 +232,18 @@ public class GroovyAnnotator implements Annotator { } } - final PsiElement targetStatement = statement.findTargetStatement(); + final GrStatement targetStatement = statement.findTargetStatement(); if (targetStatement == null) { if (statement instanceof GrContinueStatement && label == null) { holder.createErrorAnnotation(statement, GroovyBundle.message("continue.outside.loop")); } - else if (statement instanceof GrBreakStatement) { - if (label == null) { - holder.createErrorAnnotation(statement, GroovyBundle.message("break.outside.loop.or.switch")); - } - else if (findFirstLoop(statement) == null) { - holder.createErrorAnnotation(statement, GroovyBundle.message("break.outside.loop")); - } + else if (statement instanceof GrBreakStatement && label == null) { + holder.createErrorAnnotation(statement, GroovyBundle.message("break.outside.loop.or.switch")); } } + if (statement instanceof GrBreakStatement && label != null && findFirstLoop(statement) == null) { + holder.createErrorAnnotation(statement, GroovyBundle.message("break.outside.loop")); + } } @Nullable diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index c0e3be47076a..a0af3e28198a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -241,8 +241,8 @@ public class ResolveUtil { do { PsiElement last = element; element = element.getParent(); - if (element == null || element instanceof GrMember || element instanceof GrClosableBlock || element instanceof GroovyFile) break; - if (element instanceof GrStatement) { + if (element == null || element instanceof GrMember || element instanceof GroovyFile) break; + if (element instanceof GrStatement && !(element instanceof GrClosableBlock)) { statement = (GrStatement)element; } PsiElement sibling = element; @@ -253,6 +253,7 @@ public class ResolveUtil { } sibling = sibling.getPrevSibling(); } + if (element instanceof GrClosableBlock) break; } while (true); return new Pair(null, null); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenModulePsiReference.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenModulePsiReference.java index c1e6fa2be120..d05745434751 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenModulePsiReference.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenModulePsiReference.java @@ -19,9 +19,6 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.LocalQuickFixProvider; import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.notification.Notifications; -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.io.FileUtil; @@ -134,7 +131,7 @@ public class MavenModulePsiReference extends MavenPsiReference implements LocalQ myWithParent ? id : null); } catch (IOException e) { - Notifications.Bus.notify(new Notification("Maven", "Cannot create a module", e.getMessage(), NotificationType.ERROR), project); + MavenUtil.showError(project, "Cannot create a module", e); } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfiguration.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfiguration.java index 7034dee12962..a3a8c37a685e 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfiguration.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfiguration.java @@ -18,6 +18,9 @@ package org.jetbrains.idea.maven.execution; import com.intellij.execution.ExecutionException; import com.intellij.execution.Executor; import com.intellij.execution.configurations.*; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; import com.intellij.openapi.module.Module; @@ -69,6 +72,18 @@ public class MavenRunConfiguration extends RunConfigurationBase implements Locat return MavenExternalParameters .createJavaParameters(mySettings.myRunnerParameters, mySettings.myGeneralSettings, mySettings.myRunnerSettings); } + + @Override + protected OSProcessHandler startProcess() throws ExecutionException { + OSProcessHandler result = super.startProcess(); + result.addProcessListener(new ProcessAdapter() { + @Override + public void processTerminated(ProcessEvent event) { + updateProjectsFolders(); + } + }); + return result; + } }; state.setConsoleBuilder(MavenConsoleImpl.createConsoleBuilder(getProject())); return state; @@ -81,6 +96,10 @@ public class MavenRunConfiguration extends RunConfigurationBase implements Locat } } + private void updateProjectsFolders() { + MavenProjectsManager.getInstance(getProject()).updateProjectTargetFolders(); + } + @NotNull public Module[] getModules() { return Module.EMPTY_ARRAY; @@ -125,7 +144,7 @@ public class MavenRunConfiguration extends RunConfigurationBase implements Locat if (mySettings.myGeneralSettings == null) mySettings.myGeneralSettings = new MavenGeneralSettings(); if (mySettings.myRunnerSettings == null) mySettings.myRunnerSettings = new MavenRunnerSettings(); - if (mySettings.myRunnerParameters == null) mySettings.myRunnerParameters = new MavenRunnerParameters(); + if (mySettings.myRunnerParameters == null) mySettings.myRunnerParameters = new MavenRunnerParameters(); } } @@ -158,8 +177,7 @@ public class MavenRunConfiguration extends RunConfigurationBase implements Locat } public MavenSettings(Project project) { - this(MavenProjectsManager.getInstance(project).getGeneralSettings(), - MavenRunner.getInstance(project).getState(), + this(MavenProjectsManager.getInstance(project).getGeneralSettings(), MavenRunner.getInstance(project).getState(), new MavenRunnerParameters()); } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfigurationType.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfigurationType.java index bb2dad4387f8..e894b1feaace 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfigurationType.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfigurationType.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.maven.execution; +import com.intellij.compiler.options.CompileStepBeforeRun; import com.intellij.execution.*; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.ConfigurationTypeUtil; @@ -31,12 +32,13 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; -import com.intellij.compiler.options.CompileStepBeforeRun; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.project.MavenGeneralSettings; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; +import org.jetbrains.idea.maven.utils.MavenUtil; import javax.swing.*; import java.util.List; @@ -143,7 +145,7 @@ public class MavenRunConfigurationType implements LocatableConfigurationType { public RunnerAndConfigurationSettings createConfigurationByLocation(Location l) { final MavenRunnerParameters params = createBuildParameters(l); if (params == null) return null; - return createRunnerAndConfigurationSettings(null, null, params, l.getProject(), false); + return createRunnerAndConfigurationSettings(null, null, params, l.getProject()); } public boolean isConfigurationByLocation(RunConfiguration configuration, Location location) { @@ -161,24 +163,42 @@ public class MavenRunConfigurationType implements LocatableConfigurationType { return new MavenRunnerParameters(true, f.getParent().getPath(), goals, profiles); } - public static void runConfiguration(Project project, MavenRunnerParameters params, DataContext dataContext) throws ExecutionException { - doRunConfiguration(dataContext, createRunnerAndConfigurationSettings(MavenProjectsManager.getInstance(project).getGeneralSettings(), - MavenRunner.getInstance(project).getState(), - params, - project, - true)); + public static void runConfiguration(Project project, + MavenRunnerParameters params, + DataContext dataContext, + @Nullable ProgramRunner.Callback callback) { + MavenGeneralSettings settings = MavenProjectsManager.getInstance(project).getGeneralSettings(); + MavenRunnerSettings runnerSettings = MavenRunner.getInstance(project).getState(); + runConfiguration(project, params, settings, runnerSettings, dataContext, callback); } - private static void doRunConfiguration(DataContext dataContext, RunnerAndConfigurationSettings settings) throws ExecutionException { + public static void runConfiguration(Project project, + MavenRunnerParameters params, + MavenGeneralSettings settings, + MavenRunnerSettings runnerSettings, + DataContext context, + @Nullable ProgramRunner.Callback callback) { + RunnerAndConfigurationSettings configSettings = createRunnerAndConfigurationSettings(settings, + runnerSettings, + params, + project); + ProgramRunner runner = RunnerRegistry.getInstance().findRunnerById(DefaultRunExecutor.EXECUTOR_ID); - runner.execute(DefaultRunExecutor.getRunExecutorInstance(), new ExecutionEnvironment(runner, settings, dataContext)); + ExecutionEnvironment env = new ExecutionEnvironment(runner, configSettings, context); + Executor executor = DefaultRunExecutor.getRunExecutorInstance(); + + try { + runner.execute(executor, env, callback); + } + catch (ExecutionException e) { + MavenUtil.showError(project, "Failed to execute Maven goal", e); + } } private static RunnerAndConfigurationSettings createRunnerAndConfigurationSettings(MavenGeneralSettings generalSettings, MavenRunnerSettings runnerSettings, MavenRunnerParameters params, - Project project, - boolean diableMakeBeforeRun) { + Project project) { MavenRunConfigurationType type = ConfigurationTypeUtil.findConfigurationType(MavenRunConfigurationType.class); final RunnerAndConfigurationSettingsImpl settings = RunManagerEx.getInstanceEx(project) @@ -188,12 +208,6 @@ public class MavenRunConfigurationType implements LocatableConfigurationType { if (generalSettings != null) runConfiguration.setGeneralSettings(generalSettings); if (runnerSettings != null) runConfiguration.setRunnerSettings(runnerSettings); - if (diableMakeBeforeRun) disableMakeBeforeRun(RunManager.getInstance(project), runConfiguration); - return settings; } - - private static void disableMakeBeforeRun(RunManager runManager, MavenRunConfiguration runConfiguration) { - //((RunManagerEx)runManager).getBeforeRunTask(runConfiguration, CompileStepBeforeRun.ID).setEnabled(false); - } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunner.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunner.java index aaabb9b6c231..94b9de4e86ba 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunner.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunner.java @@ -62,10 +62,6 @@ public class MavenRunner extends SimpleProjectComponent implements PersistentSta mySettings = settings; } - public void run(MavenRunnerParameters parameters, MavenRunnerSettings settings) { - run(parameters, settings, null); - } - public void run(final MavenRunnerParameters parameters, final MavenRunnerSettings settings, final Runnable onComplete) { FileDocumentManager.getInstance().saveAllDocuments(); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java index 27b72e0e5c7c..6e78c91bcf3a 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenFoldersImporter.java @@ -21,7 +21,6 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ProjectRootManager; -import org.jetbrains.idea.maven.importing.MavenImporter; import org.jetbrains.idea.maven.project.MavenImportingSettings; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/MavenOpenOrCreateFilesAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/MavenOpenOrCreateFilesAction.java index 84d31dd4715e..1f452f214bd5 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/MavenOpenOrCreateFilesAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/MavenOpenOrCreateFilesAction.java @@ -15,9 +15,6 @@ */ package org.jetbrains.idea.maven.project.actions; -import com.intellij.notification.Notifications; -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationType; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.application.Result; @@ -84,7 +81,7 @@ public abstract class MavenOpenOrCreateFilesAction extends MavenAction { MavenUtil.runFileTemplate(project, newFile, getFileTemplate()); } catch (IOException ex) { - Notifications.Bus.notify(new Notification("Maven", "Cannot create " + file.getName(), ex.getMessage(), NotificationType.ERROR), project); + MavenUtil.showError(project, "Cannot create " + file.getName(), ex); } } }.execute(); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RunBuildAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RunBuildAction.java index 8bbbd4185570..435d031902e7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RunBuildAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/RunBuildAction.java @@ -15,15 +15,13 @@ */ package org.jetbrains.idea.maven.project.actions; -import com.intellij.execution.ExecutionException; import com.intellij.openapi.actionSystem.AnActionEvent; import org.jetbrains.idea.maven.execution.MavenRunConfigurationType; import org.jetbrains.idea.maven.execution.MavenRunnerParameters; +import org.jetbrains.idea.maven.project.MavenProject; +import org.jetbrains.idea.maven.utils.MavenDataKeys; import org.jetbrains.idea.maven.utils.actions.MavenAction; import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; -import org.jetbrains.idea.maven.utils.MavenDataKeys; -import org.jetbrains.idea.maven.utils.MavenLog; -import org.jetbrains.idea.maven.project.MavenProject; import java.util.List; @@ -47,14 +45,9 @@ public class RunBuildAction extends MavenAction { if (!perform) return true; - try { - MavenRunnerParameters params = new MavenRunnerParameters( - true, project.getDirectory(), goals, MavenActionUtil.getProjectsManager(e).getActiveProfiles()); - MavenRunConfigurationType.runConfiguration(MavenActionUtil.getProject(e), params, e.getDataContext()); - } - catch (ExecutionException ex) { - MavenLog.LOG.warn(ex); - } + MavenRunnerParameters params = new MavenRunnerParameters( + true, project.getDirectory(), goals, MavenActionUtil.getProjectsManager(e).getActiveProfiles()); + MavenRunConfigurationType.runConfiguration(MavenActionUtil.getProject(e), params, e.getDataContext(), null); return true; } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenKeymapExtension.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenKeymapExtension.java index 9b95aebd93d0..976701255163 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenKeymapExtension.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenKeymapExtension.java @@ -15,7 +15,6 @@ */ package org.jetbrains.idea.maven.tasks; -import com.intellij.execution.ExecutionException; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -28,17 +27,16 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.TestOnly; import org.jetbrains.idea.maven.embedder.MavenEmbedderFactory; +import org.jetbrains.idea.maven.execution.MavenRunConfigurationType; +import org.jetbrains.idea.maven.execution.MavenRunnerParameters; import org.jetbrains.idea.maven.project.MavenPlugin; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; -import org.jetbrains.idea.maven.execution.MavenRunConfigurationType; -import org.jetbrains.idea.maven.execution.MavenRunnerParameters; +import org.jetbrains.idea.maven.utils.MavenArtifactUtil; +import org.jetbrains.idea.maven.utils.MavenIcons; +import org.jetbrains.idea.maven.utils.MavenPluginInfo; import org.jetbrains.idea.maven.utils.actions.MavenAction; import org.jetbrains.idea.maven.utils.actions.MavenActionUtil; -import org.jetbrains.idea.maven.utils.MavenArtifactUtil; -import org.jetbrains.idea.maven.utils.MavenLog; -import org.jetbrains.idea.maven.utils.MavenPluginInfo; -import org.jetbrains.idea.maven.utils.MavenIcons; import java.io.File; import java.util.*; @@ -184,16 +182,11 @@ public class MavenKeymapExtension implements KeymapExtension { } public void actionPerformed(AnActionEvent e) { - try { - MavenRunnerParameters params = new MavenRunnerParameters(true, - myMavenProject.getDirectory(), - Arrays.asList(myGoal), - MavenActionUtil.getProjectsManager(e).getActiveProfiles()); - MavenRunConfigurationType.runConfiguration(MavenActionUtil.getProject(e), params, e.getDataContext()); - } - catch (ExecutionException ex) { - MavenLog.LOG.warn(ex); - } + MavenRunnerParameters params = new MavenRunnerParameters(true, + myMavenProject.getDirectory(), + Arrays.asList(myGoal), + MavenActionUtil.getProjectsManager(e).getActiveProfiles()); + MavenRunConfigurationType.runConfiguration(MavenActionUtil.getProject(e), params, e.getDataContext(), null); } public MavenProject getMavenProject() { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java index 0f2ebbb8ff1c..6f5c94b39337 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java @@ -19,6 +19,9 @@ import com.intellij.codeInsight.template.TemplateManager; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathManager; @@ -150,6 +153,11 @@ public class MavenUtil { return LaterInvocator.isInModalContext(); } + public static void showError(Project project, String title, Throwable e) { + MavenLog.LOG.error(e); + Notifications.Bus.notify(new Notification("Maven", title, e.getMessage(), NotificationType.ERROR), project); + } + public static Properties getSystemProperties() { Properties result = (Properties)System.getProperties().clone(); for (String each : new THashSet((Set)result.keySet())) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java index e36f4d5180ec..1b9f244c69f3 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilder.java @@ -15,14 +15,16 @@ */ package org.jetbrains.idea.maven.wizards; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.ide.DataManager; import com.intellij.ide.util.EditorHelper; import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.ModuleWizardStep; import com.intellij.ide.util.projectWizard.SourcePathsBuilder; import com.intellij.ide.util.projectWizard.WizardContext; -import com.intellij.notification.Notifications; -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationType; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; @@ -46,6 +48,7 @@ import com.intellij.psi.xml.XmlElement; import org.jetbrains.idea.maven.dom.MavenDomUtil; import org.jetbrains.idea.maven.dom.model.MavenDomModule; import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel; +import org.jetbrains.idea.maven.execution.MavenRunConfigurationType; import org.jetbrains.idea.maven.execution.MavenRunner; import org.jetbrains.idea.maven.execution.MavenRunnerParameters; import org.jetbrains.idea.maven.execution.MavenRunnerSettings; @@ -107,9 +110,7 @@ public class MavenModuleBuilder extends ModuleBuilder implements SourcePathsBuil result.setResult(file); } catch (IOException e) { - MavenLog.LOG.warn(e); - Notifications.Bus.notify(new Notification("Maven", "Cannot create " + MavenConstants.POM_XML + " " + root.getPath(), - e.getMessage(), NotificationType.ERROR), project); + showError(project, e); return; } @@ -185,7 +186,7 @@ public class MavenModuleBuilder extends ModuleBuilder implements SourcePathsBuil workingDir.deleteOnExit(); } catch (IOException e) { - MavenLog.LOG.warn("Cannot generate archetype", e); + showError(project, e); return; } @@ -208,24 +209,32 @@ public class MavenModuleBuilder extends ModuleBuilder implements SourcePathsBuil runner.run(params, settings, new Runnable() { public void run() { - try { - FileUtil.copyDir(new File(workingDir, myProjectId.getArtifactId()), new File(myContentRootPath)); - } - catch (IOException e) { - MavenLog.LOG.warn("Cannot generate archetype", e); - return; - } - - FileUtil.delete(workingDir); - - pom.refresh(false, false); - updateProjectPom(project, pom); - - LocalFileSystem.getInstance().refreshWithoutFileWatcher(true); + copyGeneratedFiles(workingDir, pom, project); } }); } + private void copyGeneratedFiles(File workingDir, VirtualFile pom, Project project) { + try { + FileUtil.copyDir(new File(workingDir, myProjectId.getArtifactId()), new File(myContentRootPath)); + } + catch (IOException e) { + showError(project, e); + return; + } + + FileUtil.delete(workingDir); + + pom.refresh(false, false); + updateProjectPom(project, pom); + + LocalFileSystem.getInstance().refreshWithoutFileWatcher(true); + } + + private void showError(Project project, Throwable e) { + MavenUtil.showError(project, "Failed to create a Maven project", e); + } + @Override public String getBuilderId() { return getClass().getName(); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java index 227cc81c5aee..3e226792f5bc 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java @@ -77,11 +77,15 @@ public abstract class MavenTestCase extends UsefulTestCase { MavenWorkspaceSettingsComponent.getInstance(myProject).loadState(new MavenWorkspaceSettings()); + String home = getTestMavenHome(); + if (home != null) { + getMavenGeneralSettings().setMavenHome(home); + } + restoreSettingsFile(); ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { - try { setUpInWriteAction(); } @@ -153,11 +157,20 @@ public abstract class MavenTestCase extends UsefulTestCase { @Override protected void runTest() throws Throwable { - new WriteAction() { - protected void run(Result result) throws Throwable { - MavenTestCase.super.runTest(); - } - }.executeSilently().throwException(); + if (runInWriteAction()) { + new WriteAction() { + protected void run(Result result) throws Throwable { + MavenTestCase.super.runTest(); + } + }.executeSilently().throwException(); + } + else { + MavenTestCase.super.runTest(); + } + } + + protected boolean runInWriteAction() { + return true; } protected MavenGeneralSettings getMavenGeneralSettings() { @@ -409,8 +422,12 @@ public abstract class MavenTestCase extends UsefulTestCase { } protected boolean hasMavenInstallation() { - boolean result = "true".equals(System.getProperty("idea.maven.test.has.installation")); + boolean result = getTestMavenHome() != null; if (!result) System.out.println("Ignored, because Maven installation not found: " + getClass().getSimpleName() + "." + getName()); return result; } + + private String getTestMavenHome() { + return System.getProperty("idea.maven.test.home"); + } } diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java new file mode 100644 index 000000000000..61ad7353937e --- /dev/null +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutionTest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2000-2009 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 org.jetbrains.idea.maven.execution; + +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.testFramework.MapDataContext; +import com.intellij.util.concurrency.Semaphore; +import org.jetbrains.idea.maven.MavenImportingTestCase; + +import java.io.File; +import java.util.Arrays; + +@SuppressWarnings({"ConstantConditions"}) +public class MavenExecutionTest extends MavenImportingTestCase { + @Override + protected boolean runInWriteAction() { + return false; + } + + public void testExternalExecutor() throws Exception { + if (!hasMavenInstallation()) return; + + VfsUtil.saveText(createProjectSubFile("src/main/java/A.java"), "public class A {}"); + + new WriteAction() { + @Override + protected void run(Result objectResult) throws Throwable { + createProjectPom("test" + + "project" + + "1"); + } + }.execute(); + + assertFalse(new File(getProjectPath(), "target").exists()); + + execute(new MavenRunnerParameters(true, getProjectPath(), Arrays.asList("compile"), null)); + + assertTrue(new File(getProjectPath(), "target").exists()); + } + + public void testUpdatingExcludedFoldersAfterExecution() throws Exception { + if (!hasMavenInstallation()) return; + + new WriteAction() { + @Override + protected void run(Result objectResult) throws Throwable { + createStdProjectFolders(); + + importProject("test" + + "project" + + "1"); + + createProjectSubDirs("target/generated-sources/foo", + "target/bar"); + } + }.execute(); + + assertModules("project"); + assertExcludes("project", "target"); + + MavenRunnerParameters params = new MavenRunnerParameters(true, getProjectPath(), Arrays.asList("compile"), null); + execute(params); + + assertSources("project", + "src/main/java", + "src/main/resources", + "target/generated-sources/foo"); + + assertExcludes("project", + "target/bar", + "target/classes", + "target/classes"); // output dirs are collected twice for exclusion and for compiler output + } + + private void execute(MavenRunnerParameters params) { + final Semaphore sema = new Semaphore(); + sema.down(); + MapDataContext context = new MapDataContext(); + context.put(PlatformDataKeys.PROJECT, myProject); + MavenRunConfigurationType.runConfiguration(myProject, params, getMavenGeneralSettings(), + new MavenRunnerSettings(), + context, new ProgramRunner.Callback() { + public void processStarted(final RunContentDescriptor descriptor) { + descriptor.getProcessHandler().addProcessListener(new ProcessAdapter() { + @Override + public void processTerminated(ProcessEvent event) { + sema.up(); + descriptor.dispose(); + } + }); + } + }); + sema.waitFor(); + } + +} diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutorsTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutorsTest.java deleted file mode 100644 index ea464ba9499c..000000000000 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenExecutorsTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2000-2009 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 org.jetbrains.idea.maven.execution; - -import com.intellij.openapi.progress.EmptyProgressIndicator; -import com.intellij.openapi.vfs.VfsUtil; -import org.jetbrains.idea.maven.MavenTestCase; - -import java.io.File; -import java.util.Arrays; - -public class MavenExecutorsTest extends MavenTestCase { - public void testExternalExecutor() throws Exception { - if (!hasMavenInstallation()) return; - - VfsUtil.saveText(createProjectSubFile("src/main/java/A.java"), "public class A {}"); - - createProjectPom("test" + - "project" + - "1"); - - assertFalse(new File(getProjectPath(), "target").exists()); - - MavenRunnerParameters params = new MavenRunnerParameters(true, getProjectPath(), Arrays.asList("compile"), null); - MavenRunnerSettings settings = new MavenRunnerSettings(); - - MavenExecutor e; - settings.setJreName(MavenRunnerSettings.USE_INTERNAL_JAVA); - e = new MavenExternalExecutor(params, getMavenGeneralSettings(), settings, NULL_MAVEN_CONSOLE); - - assertTrue(e.execute(new EmptyProgressIndicator())); - - assertTrue(new File(getProjectPath(), "target").exists()); - } -} diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenRunnerTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenRunnerTest.java deleted file mode 100644 index 8390c21210b8..000000000000 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/execution/MavenRunnerTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2000-2009 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 org.jetbrains.idea.maven.execution; - -import org.jetbrains.idea.maven.MavenImportingTestCase; - -import java.util.Arrays; - -public class MavenRunnerTest extends MavenImportingTestCase { - public void testUpdatingExcludedFoldersAfterRun() throws Exception { - if (!hasMavenInstallation()) return; - - createStdProjectFolders(); - - importProject("test" + - "project" + - "1"); - - assertModules("project"); - assertExcludes("project", "target"); - - createProjectSubDirs("target/generated-sources/foo", - "target/bar"); - - MavenRunner runner = new MavenRunner(myProject); - MavenRunnerParameters params = new MavenRunnerParameters(true, getProjectPath(), Arrays.asList("compile"), null); - MavenRunnerSettings settings = new MavenRunnerSettings(); - runner.run(params, settings); - - assertSources("project", - "src/main/java", - "src/main/resources", - "target/generated-sources/foo"); - - assertExcludes("project", - "target/bar", - "target/classes", - "target/classes"); // output dirs are collected twice for exclusion and for compiler output - } -}