mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
git4idea: Refactored GitHandler to extract OSProcessHandler to GitTextHandler in order to support binary data handler
This commit is contained in:
@@ -16,12 +16,8 @@
|
||||
package git4idea.commands;
|
||||
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.process.OSProcessHandler;
|
||||
import com.intellij.execution.process.ProcessEvent;
|
||||
import com.intellij.execution.process.ProcessListener;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
@@ -61,16 +57,11 @@ public abstract class GitHandler {
|
||||
/**
|
||||
* a command line
|
||||
*/
|
||||
private final GeneralCommandLine myCommandLine;
|
||||
/**
|
||||
* wrapped process handler
|
||||
*/
|
||||
// note that access is safe because it accessed in unsynchronized block only after process is started, and it does not change after that
|
||||
@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private OSProcessHandler myHandler;
|
||||
final GeneralCommandLine myCommandLine;
|
||||
/**
|
||||
* process
|
||||
*/
|
||||
private Process myProcess;
|
||||
@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) Process myProcess;
|
||||
/**
|
||||
* If true, the standard output is not copied to version control console
|
||||
*/
|
||||
@@ -193,6 +184,13 @@ public abstract class GitHandler {
|
||||
this(project, VfsUtil.virtualToIoFile(vcsRoot), command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return multicaster for listeners
|
||||
*/
|
||||
protected GitHandlerListener listeners() {
|
||||
return myListeners.getMulticaster();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add error code to ignored list
|
||||
*
|
||||
@@ -433,34 +431,7 @@ public abstract class GitHandler {
|
||||
myCommandLine.setEnvParams(myEnv);
|
||||
// start process
|
||||
myProcess = myCommandLine.createProcess();
|
||||
myHandler = new OSProcessHandler(myProcess, myCommandLine.getCommandLineString()) {
|
||||
@Override
|
||||
public Charset getCharset() {
|
||||
return myCharset == null ? super.getCharset() : myCharset;
|
||||
}
|
||||
};
|
||||
myHandler.addProcessListener(new ProcessListener() {
|
||||
public void startNotified(final ProcessEvent event) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void processTerminated(final ProcessEvent event) {
|
||||
final int exitCode = event.getExitCode();
|
||||
setExitCode(exitCode);
|
||||
cleanupEnv();
|
||||
GitHandler.this.processTerminated(exitCode);
|
||||
myListeners.getMulticaster().processTerminated(exitCode);
|
||||
}
|
||||
|
||||
public void processWillTerminate(final ProcessEvent event, final boolean willBeDestroyed) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void onTextAvailable(final ProcessEvent event, final Key outputType) {
|
||||
GitHandler.this.onTextAvailable(event.getText(), outputType);
|
||||
}
|
||||
});
|
||||
myHandler.startNotify();
|
||||
startHandlingStreams();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
cleanupEnv();
|
||||
@@ -468,6 +439,11 @@ public abstract class GitHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start handling streams for the handler
|
||||
*/
|
||||
protected abstract void startHandlingStreams();
|
||||
|
||||
/**
|
||||
* Notification for handler to handle process exit event
|
||||
*
|
||||
@@ -484,14 +460,6 @@ public abstract class GitHandler {
|
||||
return line.getCommandLineString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked when some text is available
|
||||
*
|
||||
* @param text an available text
|
||||
* @param outputType output type
|
||||
*/
|
||||
protected abstract void onTextAvailable(final String text, final Key outputType);
|
||||
|
||||
/**
|
||||
* Cancel activity
|
||||
*/
|
||||
@@ -500,14 +468,14 @@ public abstract class GitHandler {
|
||||
if (!myIsCancellable) {
|
||||
throw new IllegalStateException("The process is not cancellable.");
|
||||
}
|
||||
try {
|
||||
myHandler.destroyProcess();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Exception during cancel", e);
|
||||
}
|
||||
destroyProcess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy process
|
||||
*/
|
||||
protected abstract void destroyProcess();
|
||||
|
||||
/**
|
||||
* @return exit code for process if it is available
|
||||
*/
|
||||
@@ -521,14 +489,14 @@ public abstract class GitHandler {
|
||||
/**
|
||||
* @param exitCode a exit code for process
|
||||
*/
|
||||
private synchronized void setExitCode(int exitCode) {
|
||||
protected synchronized void setExitCode(int exitCode) {
|
||||
myExitCode = exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup environment
|
||||
*/
|
||||
private synchronized void cleanupEnv() {
|
||||
protected synchronized void cleanupEnv() {
|
||||
if (!myNoSSHFlag && !myEnvironmentCleanedUp) {
|
||||
GitSSHService ssh = GitSSHIdeaService.getInstance();
|
||||
myEnvironmentCleanedUp = true;
|
||||
@@ -543,14 +511,19 @@ public abstract class GitHandler {
|
||||
checkStarted();
|
||||
try {
|
||||
if (myInputProcessor != null) {
|
||||
myInputProcessor.process(myHandler.getProcessInput());
|
||||
myInputProcessor.process(myProcess.getOutputStream());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myHandler.waitFor();
|
||||
waitForProcess();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for process
|
||||
*/
|
||||
protected abstract void waitForProcess();
|
||||
|
||||
/**
|
||||
* Set silent mode. When handler is silent, it does not logs command in version control console.
|
||||
* Note that this option also suppresses stderr and stdout copying.
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.List;
|
||||
/**
|
||||
* The handler that is based on per-line processing of the text.
|
||||
*/
|
||||
public class GitLineHandler extends GitHandler {
|
||||
public class GitLineHandler extends GitTextHandler {
|
||||
/**
|
||||
* the partial line from stdout stream
|
||||
*/
|
||||
@@ -112,7 +112,7 @@ public class GitLineHandler extends GitHandler {
|
||||
* @param lineBuilder a line builder
|
||||
*/
|
||||
private void notifyLines(final Key outputType, final Iterator<String> lines, final StringBuilder lineBuilder) {
|
||||
if (! lines.hasNext()) return;
|
||||
if (!lines.hasNext()) return;
|
||||
if (lineBuilder.length() > 0) {
|
||||
lineBuilder.append(lines.next());
|
||||
if (lines.hasNext()) {
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.concurrent.Semaphore;
|
||||
* The class also includes a number of static utility methods that represent some
|
||||
* simple commands.
|
||||
*/
|
||||
public class GitSimpleHandler extends GitHandler {
|
||||
public class GitSimpleHandler extends GitTextHandler {
|
||||
/**
|
||||
* Stderr output
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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 git4idea.commands;
|
||||
|
||||
import com.intellij.execution.process.OSProcessHandler;
|
||||
import com.intellij.execution.process.ProcessEvent;
|
||||
import com.intellij.execution.process.ProcessListener;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* The handler for git commands with text outputs
|
||||
*/
|
||||
public abstract class GitTextHandler extends GitHandler {
|
||||
/**
|
||||
* the logger
|
||||
*/
|
||||
private static final Logger log = Logger.getInstance(GitTextHandler.class.getName());
|
||||
|
||||
/**
|
||||
* wrapped process handler
|
||||
*/
|
||||
// note that access is safe because it accessed in unsynchronized block only after process is started, and it does not change after that
|
||||
@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private OSProcessHandler myHandler;
|
||||
|
||||
/**
|
||||
* The constructor from super
|
||||
*
|
||||
* @param project the project
|
||||
* @param directory the command directory
|
||||
* @param command the command
|
||||
*/
|
||||
protected GitTextHandler(@NotNull Project project, @NotNull File directory, @NotNull GitCommand command) {
|
||||
super(project, directory, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @param project the project
|
||||
* @param vcsRoot the vcs root
|
||||
* @param command the command to run
|
||||
*/
|
||||
protected GitTextHandler(final Project project, final VirtualFile vcsRoot, final GitCommand command) {
|
||||
super(project, vcsRoot, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void startHandlingStreams() {
|
||||
myHandler = new OSProcessHandler(myProcess, myCommandLine.getCommandLineString()) {
|
||||
@Override
|
||||
public Charset getCharset() {
|
||||
Charset charset = GitTextHandler.this.getCharset();
|
||||
return charset == null ? super.getCharset() : charset;
|
||||
}
|
||||
};
|
||||
myHandler.addProcessListener(new ProcessListener() {
|
||||
public void startNotified(final ProcessEvent event) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void processTerminated(final ProcessEvent event) {
|
||||
final int exitCode = event.getExitCode();
|
||||
setExitCode(exitCode);
|
||||
cleanupEnv();
|
||||
GitTextHandler.this.processTerminated(exitCode);
|
||||
listeners().processTerminated(exitCode);
|
||||
}
|
||||
|
||||
public void processWillTerminate(final ProcessEvent event, final boolean willBeDestroyed) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void onTextAvailable(final ProcessEvent event, final Key outputType) {
|
||||
GitTextHandler.this.onTextAvailable(event.getText(), outputType);
|
||||
}
|
||||
});
|
||||
myHandler.startNotify();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked when some text is available
|
||||
*
|
||||
* @param text an available text
|
||||
* @param outputType output type
|
||||
*/
|
||||
protected abstract void onTextAvailable(final String text, final Key outputType);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void destroyProcess() {
|
||||
try {
|
||||
myHandler.destroyProcess();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Exception during cancel", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void waitForProcess() {
|
||||
myHandler.waitFor();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user