diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java b/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java new file mode 100644 index 000000000000..142bbfc399b2 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java @@ -0,0 +1,323 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.execution; + +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentFactory; +import com.intellij.ui.content.MessageView; +import com.intellij.util.Function; +import com.intellij.util.NotNullFunction; +import com.intellij.util.concurrency.Semaphore; +import com.intellij.util.ui.ErrorTreeView; +import com.intellij.util.ui.MessageCategory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * + * @author: Roman Chernyatchik + * @date: Oct 4, 2007 + */ +public class ExecutionHelper { + private static final Logger LOG = Logger.getInstance(ExecutionHelper.class.getName()); + + private ExecutionHelper() { + } + + public static void showErrors(@NotNull final Project myProject, + @NotNull final List exceptionList, + @NotNull final String tabDisplayName, + @Nullable final VirtualFile file) { + if (ApplicationManager.getApplication().isUnitTestMode() && !exceptionList.isEmpty()) { + throw new RuntimeException(exceptionList.get(0)); + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myProject.isDisposed()) return; + if (exceptionList.isEmpty()) { + removeContents(null, myProject, tabDisplayName); + return; + } + + final RailsErrorViewPanel errorTreeView = new RailsErrorViewPanel(myProject); + try { + openMessagesView(errorTreeView, myProject, tabDisplayName); + } + catch (NullPointerException e) { + final StringBuilder builder = new StringBuilder(); + builder.append("Exceptions occured:"); + for (final Exception exception : exceptionList) { + builder.append("\n"); + builder.append(exception.getMessage()); + } + Messages.showErrorDialog(builder.toString(), "Execution Error"); + return; + } + for (final Exception exception : exceptionList) { + String[] messages = new String[]{exception.getMessage()}; + if (messages.length == 0) messages = new String[]{"Unknown Error"}; + errorTreeView.addMessage(MessageCategory.ERROR, messages, file, -1, -1, null); + } + + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW).activate(null); + } + }); + } + + private static void openMessagesView(@NotNull final RailsErrorViewPanel errorTreeView, + @NotNull final Project myProject, + @NotNull final String tabDisplayName) { + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + final MessageView messageView = ServiceManager.getService(myProject, MessageView.class); + final Content content = ContentFactory.SERVICE.getInstance().createContent(errorTreeView, tabDisplayName, true); + messageView.getContentManager().addContent(content); + Disposer.register(content, errorTreeView); + messageView.getContentManager().setSelectedContent(content); + removeContents(content, myProject, tabDisplayName); + } + }, "Open message view", null); + } + + private static void removeContents(@Nullable final Content notToRemove, + @NotNull final Project myProject, + @NotNull final String tabDisplayName) { + MessageView messageView = ServiceManager.getService(myProject, MessageView.class); + Content[] contents = messageView.getContentManager().getContents(); + for (Content content : contents) { + LOG.assertTrue(content != null); + if (content.isPinned()) continue; + if (tabDisplayName.equals(content.getDisplayName()) && content != notToRemove) { + ErrorTreeView listErrorView = (ErrorTreeView)content.getComponent(); + if (listErrorView != null) { + if (messageView.getContentManager().removeContent(content, true)) { + content.release(); + } + } + } + } + } + + @Nullable + public static ProcessHandler findRunningConsole(final Project project, + @NotNull final NotNullFunction cmdLineMatcher) { + final ProcessHandler[] processes = ExecutionManager.getInstance(project).getRunningProcesses(); + for (ProcessHandler process : processes) { + if (process instanceof OSProcessHandler && !process.isProcessTerminated()) { + final String commandLine = ((OSProcessHandler)process).getCommandLine(); + if (cmdLineMatcher.fun(commandLine).booleanValue()) { + return process; + } + } + } + return null; + } + + public static class RailsErrorViewPanel extends NewErrorTreeViewPanel { + public RailsErrorViewPanel(final Project project) { + super(project, null); + } + + protected boolean canHideWarnings() { + return false; + } + } + + + public static void executeExternalProcess(@Nullable final Project myProject, + @NotNull final OSProcessHandler processHandler, + @NotNull final ExecutionMode mode) { + final String title = mode.getTitle() != null ? mode.getTitle() : "Running. Please wait..."; + assert title != null; + + final Runnable process; + if (mode.cancelable()) { + process = createCancelableExecutionProcess(processHandler, mode.shouldCancelFun()); + } + else { + if (mode.getTimeout() <= 0) { + process = new Runnable() { + public void run() { + processHandler.waitFor(); + } + }; + } else { + process = createTimelimitedExecutionProcess(processHandler, mode.getTimeout()); + } + } + if (mode.withModalProgress()) { + ProgressManager.getInstance().runProcessWithProgressSynchronously(process, title, mode.cancelable(), myProject, + mode.getProgressParentComponent()); + } + else if (mode.inBackGround()) { + final Task task = new Task.Backgroundable(myProject, title, mode.cancelable()) { + public void run(@NotNull final ProgressIndicator indicator) { + process.run(); + } + }; + ProgressManager.getInstance().run(task); + } + else { + final String title2 = mode.getTitle2(); + final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null && title2 != null) { + indicator.setText2(title2); + } + process.run(); + } + } + + private static Runnable createCancelableExecutionProcess(final ProcessHandler processHandler, + final Function cancelableFun) { + return new Runnable() { + private ProgressIndicator myProgressIndicator; + private final Semaphore mySemaphore = new Semaphore(); + + private final Runnable myWaitThread = new Runnable() { + public void run() { + try { + processHandler.waitFor(); + } + finally { + mySemaphore.up(); + } + } + }; + + private final Runnable myCancelListener = new Runnable() { + public void run() { + for (; ;) { + if ((myProgressIndicator != null && (myProgressIndicator.isCanceled() + || !myProgressIndicator.isRunning())) + || (cancelableFun != null && cancelableFun.fun(null).booleanValue()) + || processHandler.isProcessTerminated()) { + + if (!processHandler.isProcessTerminated()) { + try { + processHandler.destroyProcess(); + } + finally { + mySemaphore.up(); + } + } + break; + } + try { + synchronized (this) { + wait(1000); + } + } + catch (InterruptedException e) { + //Do nothing + } + } + } + }; + + public void run() { + myProgressIndicator = ProgressManager.getInstance().getProgressIndicator(); + if (myProgressIndicator != null && StringUtil.isEmpty(myProgressIndicator.getText())) { + myProgressIndicator.setText("Please wait"); + } + + LOG.assertTrue(myProgressIndicator != null || cancelableFun != null, + "Cancelable process must have an opportunity to be canceled!"); + mySemaphore.down(); + ApplicationManager.getApplication().executeOnPooledThread(myWaitThread); + ApplicationManager.getApplication().executeOnPooledThread(myCancelListener); + + mySemaphore.waitFor(); + } + }; + } + + private static Runnable createTimelimitedExecutionProcess(final OSProcessHandler processHandler, + final int timeout) { + return new Runnable() { + private final Semaphore mySemaphore = new Semaphore(); + private final Object LOCK = new Object(); + private Boolean processedFinished = Boolean.FALSE; + + private final Runnable myProcessThread = new Runnable() { + public void run() { + try { + processHandler.waitFor(); + synchronized (LOCK) { + processedFinished = Boolean.TRUE; + } + } + finally { + mySemaphore.up(); + } + } + }; + + private final Runnable myTimeoutListener = new Runnable() { + public void run() { + try { + synchronized (this) { + try { + wait(1000 * timeout); + synchronized (LOCK) { + if (!processedFinished) { + LOG.error("Timeout (" + timeout + " sec) on executing: " + processHandler.getCommandLine()); + processHandler.destroyProcess(); + } + } + } + finally { + mySemaphore.up(); + } + } + } + catch (InterruptedException e) { + //Do nothing + } + } + }; + + public void run() { + mySemaphore.down(); + ApplicationManager.getApplication().executeOnPooledThread(myProcessThread); + ApplicationManager.getApplication().executeOnPooledThread(myTimeoutListener); + + mySemaphore.waitFor(); + } + }; + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutionMode.java b/platform/lang-impl/src/com/intellij/execution/ExecutionMode.java new file mode 100644 index 000000000000..81e8677fcac8 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/ExecutionMode.java @@ -0,0 +1,97 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution; + +import com.intellij.util.Function; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** +* @author Roman.Chernyatchik +*/ +public abstract class ExecutionMode { + private final boolean myCancelable; + private final String myTitle; + private final String myTitle2; + private final boolean myRunWithModal; + private final boolean myRunInBG; + private final JComponent myProgressParentComponent; + private Function myShouldCancelFun; + private final Object CANCEL_FUN_LOCK = new Object(); + + public ExecutionMode(final boolean cancelable, + @Nullable final String title, + @Nullable final String title2, + final boolean runInBG, + final boolean runWithModal, + JComponent progressParentComponent) { + myCancelable = cancelable; + myTitle = title; + myTitle2 = title2; + myRunInBG = runInBG; + myRunWithModal = runWithModal; + myProgressParentComponent = progressParentComponent; + } + + public int getTimeout() { + // it is ignored + return -1; + } + + @Nullable + public String getTitle() { + return myTitle; + } + + @Nullable + public String getTitle2() { + return myTitle2; + } + + public boolean cancelable() { + return myCancelable; + } + + public boolean inBackGround() { + return myRunInBG; + } + + public boolean withModalProgress() { + return myRunWithModal; + } + + public JComponent getProgressParentComponent() { + return myProgressParentComponent; + } + + /** + * Runner checks this fun during process running, if returns true, process will be canceled. + */ + @Nullable + public Function shouldCancelFun() { + synchronized (CANCEL_FUN_LOCK) { + return myShouldCancelFun; + } + } + + public void setShouldCancelFun(final Function shouldCancelFun) { + synchronized (CANCEL_FUN_LOCK) { + myShouldCancelFun = shouldCancelFun; + } + } + +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutionModes.java b/platform/lang-impl/src/com/intellij/execution/ExecutionModes.java new file mode 100644 index 000000000000..a03ac3ec6ef5 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/ExecutionModes.java @@ -0,0 +1,97 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution; + +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author oleg + */ +public class ExecutionModes { + /** + * Process will be run in back ground mode + */ + public static class BackGroundMode extends ExecutionMode { + + public BackGroundMode(final boolean cancelable, @Nullable final String title) { + super(cancelable, title, null, true, false, null); + } + + public BackGroundMode(@Nullable final String title) { + this(true, title); + } + } + + /** + * Process will be run in modal dialog + */ + public static class ModalProgressMode extends ExecutionMode { + + public ModalProgressMode(final boolean cancelable, @Nullable final String title, JComponent progressParentComponent) { + super(cancelable, title, null, false, true, progressParentComponent); + } + + public ModalProgressMode(@Nullable final String title) { + this(true, title, null); + } + + public ModalProgressMode(@Nullable final String title, JComponent progressParentComponent) { + this(true, title, progressParentComponent); + } + } + + /** + * Process will be run in the same thread. + */ + public static class SameThreadMode extends ExecutionMode { + private final int myTimeout; + + public SameThreadMode(final boolean cancelable, + @Nullable final String title2, + final int timeout) { + super(cancelable, null, title2, false, false, null); + myTimeout = timeout; + } + + public SameThreadMode(@Nullable final String title2) { + this(true, title2, -1); + } + + /** + * @param cancelable + */ + public SameThreadMode(final boolean cancelable) { + this(cancelable, null, -1); + } + + /** + * @param timeout If less than zero it will be ignored + */ + public SameThreadMode(final int timeout) { + this(false, null, timeout); + } + + public SameThreadMode() { + this(true); + } + + public int getTimeout() { + return myTimeout; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/Output.java b/platform/lang-impl/src/com/intellij/execution/Output.java new file mode 100644 index 000000000000..267046ce7464 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/Output.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2008 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.execution; + +/** + * Created by IntelliJ IDEA. + * + * @author: oleg + * @date: 24.08.2006 + */ +public class Output { + private final String stdout; + private final String stderr; + + public Output(String stdout, String stderr) { + this.stdout = stdout; + this.stderr = stderr; + } + + public String getStdout() { + return stdout; + } + + public String getStderr() { + return stderr; + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/OutputListener.java b/platform/lang-impl/src/com/intellij/execution/OutputListener.java new file mode 100644 index 000000000000..cba904e34f8e --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/OutputListener.java @@ -0,0 +1,29 @@ +package com.intellij.execution; + +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; + +/** +* @author oleg +*/ +public class OutputListener extends ProcessAdapter { + private final StringBuilder out; + private final StringBuilder err; + + public OutputListener(@NotNull final StringBuilder out, @NotNull final StringBuilder err) { + this.out = out; + this.err = err; + } + + public void onTextAvailable(ProcessEvent event, Key outputType) { + if (outputType == ProcessOutputTypes.STDOUT) { + out.append(event.getText()); + } + if (outputType == ProcessOutputTypes.STDERR) { + err.append(event.getText()); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java index 88686b89ac7f..c22f0d9dbac3 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +29,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; -import com.intellij.openapi.updateSettings.impl.PluginDownloader; -import com.intellij.openapi.updateSettings.impl.UpdateChannel; -import com.intellij.openapi.updateSettings.impl.UpdateChecker; +import com.intellij.openapi.updateSettings.impl.*; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.SystemInfo; @@ -196,22 +194,21 @@ public class IdeaApplication { } }, ModalityState.NON_MODAL); + app.addApplicationListener(new ApplicationAdapter() { + @Override + public boolean canExitApplication() { + if (UpdateSettings.getInstance().isUpdateOnExit()) { + updatePlugins(false); + } + return true; + } + }); + app.invokeLater(new Runnable() { public void run() { if (UpdateChecker.isMyVeryFirstOpening() && UpdateChecker.checkNeeded()) { - try { - UpdateChecker.setMyVeryFirstOpening(false); - final UpdateChannel newVersion = UpdateChecker.checkForUpdates(); - final List updatedPlugins = UpdateChecker.updatePlugins(false); - if (newVersion != null) { - UpdateChecker.showUpdateInfoDialog(true, newVersion, updatedPlugins); - } else if (updatedPlugins != null) { - UpdateChecker.showNoUpdatesDialog(true, updatedPlugins); - } - } - catch (ConnectionException e) { - // It's not a problem on automatic check - } + UpdateChecker.setMyVeryFirstOpening(false); + updatePlugins(true); } if (myPerformProjectLoad) { @@ -226,6 +223,21 @@ public class IdeaApplication { } }, ModalityState.NON_MODAL); } + + private void updatePlugins(boolean showConfirmation) { + try { + final UpdateChannel newVersion = UpdateChecker.checkForUpdates(); + final List updatedPlugins = UpdateChecker.updatePlugins(false); + if (newVersion != null) { + UpdateChecker.showUpdateInfoDialog(true, newVersion, updatedPlugins); + } else if (updatedPlugins != null) { + UpdateChecker.showNoUpdatesDialog(true, updatedPlugins, showConfirmation); + } + } + catch (ConnectionException e) { + // It's not a problem on automatic check + } + } } private void loadProject() { diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java index 00212be88d89..0b47eda982ac 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,7 @@ import java.util.List; public abstract class AbstractUpdateDialog extends DialogWrapper { private final boolean myEnableLink; protected final List myUploadedPlugins; + protected boolean myShowConfirmation = true; protected AbstractUpdateDialog(boolean canBeParent, boolean enableLink, final List updatePlugins) { super(canBeParent); @@ -95,7 +96,7 @@ public abstract class AbstractUpdateDialog extends DialogWrapper { } protected void doOKAction() { - if (doDownloadAndPrepare()) { + if (doDownloadAndPrepare() && isShowConfirmation()) { final ApplicationEx app = ApplicationManagerEx.getApplicationEx(); if (app.isRestartCapable()) { app.restart(); @@ -116,9 +117,11 @@ public abstract class AbstractUpdateDialog extends DialogWrapper { return false; } - public void doCancelAction() { - UpdateChecker.saveDisabledToUpdatePlugins(); - if (myUploadedPlugins != null) UpdateChecker.install(myUploadedPlugins); //update on restart - super.doCancelAction(); + public void setShowConfirmation(boolean showConfirmation) { + myShowConfirmation = showConfirmation; + } + + public boolean isShowConfirmation() { + return myShowConfirmation; } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java index 7ce314b11cdd..0d131f1ef3ed 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ public class CheckForUpdateAction extends AnAction implements DumbAware { UpdateChecker.showUpdateInfoDialog(enableLink, newVersion, updatedPlugins); } else { - UpdateChecker.showNoUpdatesDialog(enableLink, updatedPlugins); + UpdateChecker.showNoUpdatesDialog(enableLink, updatedPlugins, true); } } catch (ConnectionException e) { diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesDialog.java index b7ba16704a85..85a714e5a375 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import java.util.List; * @author pti */ class NoUpdatesDialog extends AbstractUpdateDialog { - protected NoUpdatesDialog(final boolean canBeParent, final List updatePlugins, boolean enableLink) { super(canBeParent, enableLink, updatePlugins); setTitle(IdeBundle.message("updates.info.dialog.title")); @@ -54,14 +53,14 @@ class NoUpdatesDialog extends AbstractUpdateDialog { @Override protected boolean doDownloadAndPrepare() { boolean hasSmthToUpdate = super.doDownloadAndPrepare(); - if (hasSmthToUpdate && + if (hasSmthToUpdate && isShowConfirmation() && Messages.showYesNoDialog(IdeBundle.message("message.idea.restart.required", ApplicationNamesInfo.getInstance().getProductName()), IdeBundle.message("title.plugins"), Messages.getQuestionIcon()) != 0) { hasSmthToUpdate = false; } return hasSmthToUpdate; } - + private class NoUpdatesPanel { private JPanel myPanel; private JPanel myPluginsPanel; diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index e3f39d7b317b..048b9a60a07c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,6 +83,9 @@ public final class UpdateChecker { public static String ADDITIONAL_REQUEST_OPTIONS = ""; + private UpdateChecker() { + } + public static enum DownloadPatchResult { SUCCESS, FAILED, CANCELED } @@ -117,11 +120,13 @@ public final class UpdateChecker { } public static boolean checkNeeded() { - final UpdateSettings settings = UpdateSettings.getInstance(); if (settings == null || getUpdateUrl() == null) return false; final String checkPeriod = settings.CHECK_PERIOD; + if (checkPeriod.equals(UpdateSettingsConfigurable.ON_EXIT)) { + return false; + } if (checkPeriod.equals(UpdateSettingsConfigurable.ON_START_UP)) { checkInterval = 0; } @@ -375,8 +380,9 @@ public final class UpdateChecker { return document[0]; } - public static void showNoUpdatesDialog(boolean enableLink, final List updatePlugins) { + public static void showNoUpdatesDialog(boolean enableLink, final List updatePlugins, boolean showConfirmation) { NoUpdatesDialog dialog = new NoUpdatesDialog(true, updatePlugins, enableLink); + dialog.setShowConfirmation(showConfirmation); dialog.show(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java index 06d96d2d9f3b..df6fd65e158a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,4 +73,8 @@ public class UpdateSettings implements PersistentStateComponent { LOG.info(e); } } + + public boolean isUpdateOnExit() { + return UpdateSettingsConfigurable.ON_EXIT.equals(CHECK_PERIOD); + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java index e6aaf219f12d..876b9c19f9ff 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,7 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear @NonNls public static final String DAILY = "Daily"; @NonNls public static final String WEEKLY = "Weekly"; @NonNls public static final String MONTHLY = "Monthly"; + @NonNls public static final String ON_EXIT = "On every exit"; private static final Map PERIOD_VALUE_MAP = new HashMap(); static { @@ -59,6 +60,7 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear PERIOD_VALUE_MAP.put(DAILY, IdeBundle.message("updates.check.period.daily")); PERIOD_VALUE_MAP.put(WEEKLY, IdeBundle.message("updates.check.period.weekly")); PERIOD_VALUE_MAP.put(MONTHLY, IdeBundle.message("updates.check.period.monthly")); + PERIOD_VALUE_MAP.put(ON_EXIT, IdeBundle.message("updates.check.period.on.exit")); } public JComponent createComponent() { @@ -150,6 +152,7 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear myPeriodCombo.addItem(DAILY); myPeriodCombo.addItem(WEEKLY); myPeriodCombo.addItem(MONTHLY); + myPeriodCombo.addItem(ON_EXIT); myPeriodCombo.setRenderer(new MappingListCellRenderer(PERIOD_VALUE_MAP)); diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 893fe5e91a2f..0a8e3f8fade9 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -1059,4 +1059,5 @@ FileChooser.listViewActionLabelText=List FileChooser.detailsViewActionLabelText=Details FileChooser.refreshActionLabelText=Refresh browsers.settings=Web Browsers +updates.check.period.on.exit=On every exit diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java index c0dff80e1804..402041792a47 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java @@ -37,21 +37,26 @@ public class MavenDomProjectProcessorUtils { } @NotNull - public static List collectChildrenProjects(@NotNull final MavenDomProjectModel model) { + public static Set getChildrenProjects(@NotNull final MavenDomProjectModel model) { + Set models = new HashSet(); + collectChildrenProjects(model, models); + + return models; + } + + private static void collectChildrenProjects(@NotNull final MavenDomProjectModel model, @NotNull Set models) { MavenProject mavenProject = MavenDomUtil.findProject(model); if (mavenProject != null) { final Project project = model.getManager().getProject(); - Set inheritors = MavenProjectsManager.getInstance(project).findInheritors(mavenProject); - - - return ContainerUtil.mapNotNull(inheritors, new Function() { - public MavenDomProjectModel fun(MavenProject childProject) { - return MavenDomUtil.getMavenDomProjectModel(project, childProject.getFile()); + for (MavenProject inheritor : MavenProjectsManager.getInstance(project).findInheritors(mavenProject)) { + MavenDomProjectModel inheritorProjectModel = MavenDomUtil.getMavenDomProjectModel(project, inheritor.getFile()); + if (inheritorProjectModel != null && !models.contains(inheritorProjectModel)) { + models.add(inheritorProjectModel); + collectChildrenProjects(inheritorProjectModel, models); } - }); + } } - return Collections.emptyList(); } @NotNull public static Set collectParentProjects(@NotNull final MavenDomProjectModel projectDom, diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java index 0ffde5494d59..2c9d5bb47319 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java @@ -183,15 +183,8 @@ public class MavenDomGutterAnnotator implements Annotator { private static void annotateMavenDomProjectChildren(MavenDomProjectModel model, AnnotationHolder holder) { MavenProject mavenProject = MavenDomUtil.findProject(model); if (mavenProject != null) { - final Project project = model.getManager().getProject(); - Set inheritors = MavenProjectsManager.getInstance(project).findInheritors(mavenProject); + Set children = MavenDomProjectProcessorUtils.getChildrenProjects(model); - - List children = ContainerUtil.mapNotNull(inheritors, new Function() { - public MavenDomProjectModel fun(MavenProject childProject) { - return MavenDomUtil.getMavenDomProjectModel(project, childProject.getFile()); - } - }); if (children.size() > 0) { NavigationGutterIconBuilder.create(MavenIcons.CHILDREN_PROJECTS, MAVEN_PROJECT_CONVERTER). setTargets(children). diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyAction.java index db21b39bc8cd..c4acd1de60ca 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyAction.java @@ -205,16 +205,16 @@ public class IntroducePropertyAction extends BaseRefactoringAction { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { collectUsages(myModel); - for (MavenDomProjectModel model : MavenDomProjectProcessorUtils.collectChildrenProjects(myModel)) { + for (MavenDomProjectModel model : MavenDomProjectProcessorUtils.getChildrenProjects(myModel)) { collectUsages(model); } } private void collectUsages(@NotNull MavenDomProjectModel model) { if (model.isValid()) { - XmlElement root = model.getXmlElement(); + final XmlElement root = model.getXmlElement(); if (root != null) { - root.accept(new XmlElementVisitor() { + root.acceptChildren(new XmlElementVisitor() { @Override public void visitXmlText(XmlText text) { @@ -226,7 +226,10 @@ public class IntroducePropertyAction extends BaseRefactoringAction { @Override public void visitXmlAttributeValue(XmlAttributeValue value) { - usages.addAll(getUsages(value)); + XmlTag xmlTag = PsiTreeUtil.getParentOfType(value, XmlTag.class); + if (xmlTag != null && !xmlTag.equals(root)) { + usages.addAll(getUsages(value)); + } } @Override diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java index d4e25f376c30..7d09fe904eff 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java @@ -26,7 +26,6 @@ import com.intellij.refactoring.introduceVariable.IntroduceVariableHandler; import com.intellij.refactoring.ui.NameSuggestionsField; import com.intellij.util.Function; import com.intellij.util.containers.OrderedSet; -import com.intellij.util.xml.DomBundle; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.dom.MavenDomBundle; import org.jetbrains.idea.maven.dom.MavenDomProjectProcessorUtils; @@ -197,14 +196,7 @@ public class IntroducePropertyDialog extends DialogWrapper { } private static boolean isContainWrongSymbols(@NotNull String text) { - return text.length() == 0 || - text.contains("\"") || - text.contains("'") || - text.contains(">") || - text.contains("<") || - text.contains("/") || - text.contains("\\") || - Character.isDigit(text.charAt(0)); + return text.length() == 0 || StringUtil.containsAnyChar(text, "\t ;*'\"\\/,()^&<>={}[]") ; } private boolean isPropertyExist(@NotNull String text) { @@ -212,7 +204,7 @@ public class IntroducePropertyDialog extends DialogWrapper { if (isPropertyExist(text, project)) return true; - for (MavenDomProjectModel child : MavenDomProjectProcessorUtils.collectChildrenProjects(project)) { + for (MavenDomProjectModel child : MavenDomProjectProcessorUtils.getChildrenProjects(project)) { if (isPropertyExist(text, child)) return true; }