From cb16f0746159563935ec1cac9f85c710b22aef35 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 15 May 2017 14:32:40 +0200 Subject: [PATCH] IDEA-168525 Possibility to listen to ant build events --- .../execution/AntBeforeExecutionEvent.java | 31 ++++++++++++ .../config/execution/AntExecutionEvent.java | 31 ++++++++++++ .../execution/AntExecutionListener.java | 26 ++++++++++ .../execution/AntFinishedExecutionEvent.java | 41 ++++++++++++++++ .../config/execution/ExecutionHandler.java | 49 ++++++++++++++++--- 5 files changed, 170 insertions(+), 8 deletions(-) create mode 100644 plugins/ant/src/com/intellij/lang/ant/config/execution/AntBeforeExecutionEvent.java create mode 100644 plugins/ant/src/com/intellij/lang/ant/config/execution/AntExecutionEvent.java create mode 100644 plugins/ant/src/com/intellij/lang/ant/config/execution/AntExecutionListener.java create mode 100644 plugins/ant/src/com/intellij/lang/ant/config/execution/AntFinishedExecutionEvent.java diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBeforeExecutionEvent.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBeforeExecutionEvent.java new file mode 100644 index 000000000000..5122415d09e4 --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntBeforeExecutionEvent.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2017 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.lang.ant.config.execution; + +import com.intellij.lang.ant.config.AntBuildFile; + +public class AntBeforeExecutionEvent extends AntExecutionEvent{ + private final AntBuildMessageView myMessageView; + + AntBeforeExecutionEvent(AntBuildFile buildFile, AntBuildMessageView messageView) { + super(buildFile); + myMessageView = messageView; + } + + public AntBuildMessageView getMessageView() { + return myMessageView; + } +} diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntExecutionEvent.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntExecutionEvent.java new file mode 100644 index 000000000000..c63909963bee --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntExecutionEvent.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2017 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.lang.ant.config.execution; + +import com.intellij.lang.ant.config.AntBuildFile; + +class AntExecutionEvent { + + private final AntBuildFile myBuildFile; + + protected AntExecutionEvent(AntBuildFile buildFile) { + myBuildFile = buildFile; + } + + public AntBuildFile getBuildFile() { + return myBuildFile; + } +} diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntExecutionListener.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntExecutionListener.java new file mode 100644 index 000000000000..bdf9b5f265a2 --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntExecutionListener.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2017 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.lang.ant.config.execution; + +import com.intellij.util.messages.Topic; + +public interface AntExecutionListener { + Topic TOPIC = Topic.create("AntExecutionListener", AntExecutionListener.class); + + void beforeExecution(AntBeforeExecutionEvent event); + + void buildFinished(AntFinishedExecutionEvent event); +} diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntFinishedExecutionEvent.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntFinishedExecutionEvent.java new file mode 100644 index 000000000000..447f145af066 --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntFinishedExecutionEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2017 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.lang.ant.config.execution; + +import com.intellij.lang.ant.config.AntBuildFile; + +public class AntFinishedExecutionEvent extends AntExecutionEvent{ + private final Status myStatus; + private final int myErrorCount; + + public enum Status { + SUCCESS, CANCELED, FAILURE; + } + + AntFinishedExecutionEvent(AntBuildFile buildFile, Status status, int errorCount) { + super(buildFile); + myStatus = status; + myErrorCount = errorCount; + } + + public Status getStatus() { + return myStatus; + } + + public int getErrorCount() { + return myErrorCount; + } +} diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/ExecutionHandler.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/ExecutionHandler.java index 721b4874e525..276b66c58ed2 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/execution/ExecutionHandler.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/ExecutionHandler.java @@ -26,6 +26,7 @@ import com.intellij.execution.util.ExecutionErrorDialog; import com.intellij.history.LocalHistory; import com.intellij.ide.macro.Macro; import com.intellij.lang.ant.AntBundle; +import com.intellij.lang.ant.config.AntBuildFile; import com.intellij.lang.ant.config.AntBuildFileBase; import com.intellij.lang.ant.config.AntBuildListener; import com.intellij.lang.ant.config.AntBuildTarget; @@ -66,7 +67,9 @@ public final class ExecutionHandler { List additionalProperties, @NotNull final AntBuildListener antBuildListener) { AntBuildTarget target = antRunConfiguration.getTarget(); - if (target == null) return null; + if (target == null) { + return null; + } FutureResult result = runBuildImpl((AntBuildFileBase)target.getModel().getBuildFile(), new String[]{target.getName()}, null, @@ -106,6 +109,7 @@ public final class ExecutionHandler { @NotNull final AntBuildListener antBuildListener, final boolean waitFor) { final AntBuildMessageView messageView; final GeneralCommandLine commandLine; + final AntBuildListenerWrapper listenerWrapper = new AntBuildListenerWrapper(buildFile, antBuildListener); final Project project = buildFile.getProject(); try { FileDocumentManager.getInstance().saveAllDocuments(); @@ -120,23 +124,25 @@ public final class ExecutionHandler { messageView = prepareMessageView(buildMessageViewToReuse, buildFile, targets, additionalProperties); commandLine = builder.getCommandLine().toCommandLine(); messageView.setBuildCommandLine(commandLine.getCommandLineString()); + + project.getMessageBus().syncPublisher(AntExecutionListener.TOPIC).beforeExecution(new AntBeforeExecutionEvent(buildFile, messageView)); } catch (RunCanceledException e) { e.showMessage(project, AntBundle.message("run.ant.error.dialog.title")); - antBuildListener.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); + listenerWrapper.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); return null; } catch (CantRunException e) { ExecutionErrorDialog.show(e, AntBundle.message("cant.run.ant.error.dialog.title"), project); - antBuildListener.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); + listenerWrapper.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); return null; } catch (Macro.ExecutionCancelledException e) { - antBuildListener.buildFinished(AntBuildListener.ABORTED, 0); + listenerWrapper.buildFinished(AntBuildListener.ABORTED, 0); return null; } catch (Throwable e) { - antBuildListener.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); + listenerWrapper.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); LOG.error(e); return null; } @@ -148,12 +154,12 @@ public final class ExecutionHandler { } public void onCancel() { - antBuildListener.buildFinished(AntBuildListener.ABORTED, 0); + listenerWrapper.buildFinished(AntBuildListener.ABORTED, 0); } public void run(@NotNull final ProgressIndicator indicator) { try { - ProcessHandler handler = runBuild(indicator, messageView, buildFile, antBuildListener, commandLine); + ProcessHandler handler = runBuild(indicator, messageView, buildFile, listenerWrapper, commandLine); future.set(handler); if (waitFor && handler != null) { handler.waitFor(); @@ -161,7 +167,7 @@ public final class ExecutionHandler { } catch (Throwable e) { LOG.error(e); - antBuildListener.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); + listenerWrapper.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); } } }.queue(); @@ -306,4 +312,31 @@ public final class ExecutionHandler { } return messageView; } + + private static class AntBuildListenerWrapper implements AntBuildListener { + @NotNull + private final AntBuildFile myBuildFile; + @NotNull + private final AntBuildListener myDelegate; + + AntBuildListenerWrapper(@NotNull AntBuildFile buildFile, @NotNull AntBuildListener delegate) { + myBuildFile = buildFile; + myDelegate = delegate; + } + + @Override + public void buildFinished(int state, int errorCount) { + try { + final AntFinishedExecutionEvent.Status status = state == AntBuildListener.ABORTED? AntFinishedExecutionEvent.Status.CANCELED : + state == AntBuildListener.FAILED_TO_RUN? AntFinishedExecutionEvent.Status.FAILURE : + AntFinishedExecutionEvent.Status.SUCCESS; + myBuildFile.getProject().getMessageBus().syncPublisher(AntExecutionListener.TOPIC).buildFinished( + new AntFinishedExecutionEvent(myBuildFile, status, errorCount) + ); + } + finally { + myDelegate.buildFinished(state, errorCount); + } + } + } }