mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
git4idea: refactored rebase editor service to support other types of rebase editors
This commit is contained in:
@@ -21,9 +21,9 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import git4idea.commands.GitHandler;
|
||||
import git4idea.commands.GitLineHandler;
|
||||
import git4idea.i18n.GitBundle;
|
||||
import git4idea.rebase.GitInteractiveRebaseEditorHandler;
|
||||
import git4idea.rebase.GitRebaseActionDialog;
|
||||
import git4idea.rebase.GitRebaseUtils;
|
||||
import git4idea.rebase.GitRebaseEditorHandler;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.Iterator;
|
||||
@@ -70,7 +70,7 @@ public abstract class GitAbstractRebaseResumeAction extends GitRebaseActionBase
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void configureEditor(GitRebaseEditorHandler editor) {
|
||||
protected void configureEditor(GitInteractiveRebaseEditorHandler editor) {
|
||||
editor.setRebaseEditorShown();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,10 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import git4idea.commands.GitHandler;
|
||||
import git4idea.commands.GitHandlerUtil;
|
||||
import git4idea.commands.GitLineHandler;
|
||||
import git4idea.i18n.GitBundle;
|
||||
import git4idea.rebase.GitRebaseEditorHandler;
|
||||
import git4idea.rebase.GitRebaseEditorMain;
|
||||
import git4idea.rebase.GitInteractiveRebaseEditorHandler;
|
||||
import git4idea.rebase.GitRebaseEditorService;
|
||||
import git4idea.rebase.GitRebaseLineListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -51,14 +49,13 @@ public abstract class GitRebaseActionBase extends GitRepositoryAction {
|
||||
}
|
||||
final VirtualFile root = h.workingDirectoryFile();
|
||||
GitRebaseEditorService service = GitRebaseEditorService.getInstance();
|
||||
GitRebaseEditorHandler editor = service.getHandler(project, root);
|
||||
GitInteractiveRebaseEditorHandler editor = new GitInteractiveRebaseEditorHandler(service, project, root);
|
||||
GitRebaseLineListener resultListener = new GitRebaseLineListener();
|
||||
h.addLineListener(resultListener);
|
||||
configureEditor(editor);
|
||||
affectedRoots.add(root);
|
||||
try {
|
||||
h.setEnvironment(GitHandler.GIT_EDITOR_ENV, service.getEditorCommand());
|
||||
h.setEnvironment(GitRebaseEditorMain.IDEA_REBASE_HANDER_NO, Integer.toString(editor.getHandlerNo()));
|
||||
service.configureHandler(h, editor.getHandlerNo());
|
||||
GitHandlerUtil.doSynchronously(h, GitBundle.getString("rebasing.title"), h.printableCommandLine());
|
||||
}
|
||||
finally {
|
||||
@@ -105,7 +102,7 @@ public abstract class GitRebaseActionBase extends GitRepositoryAction {
|
||||
*
|
||||
* @param editor the editor to configure
|
||||
*/
|
||||
protected void configureEditor(GitRebaseEditorHandler editor) {
|
||||
protected void configureEditor(GitInteractiveRebaseEditorHandler editor) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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.rebase;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
/**
|
||||
* The handler for rebase editor request. The handler shows {@link git4idea.rebase.GitRebaseEditor}
|
||||
* dialog with the specified file. If user accepts the changes, it saves file and returns 0,
|
||||
* otherwise it just returns error code.
|
||||
*/
|
||||
public class GitInteractiveRebaseEditorHandler implements Closeable, GitRebaseEditorHandler {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private final static Logger LOG = Logger.getInstance(GitInteractiveRebaseEditorHandler.class.getName());
|
||||
/**
|
||||
* The service object that has created this handler
|
||||
*/
|
||||
private final GitRebaseEditorService myService;
|
||||
/**
|
||||
* The context project
|
||||
*/
|
||||
private final Project myProject;
|
||||
/**
|
||||
* The git repository root
|
||||
*/
|
||||
private final VirtualFile myRoot;
|
||||
/**
|
||||
* The handler number
|
||||
*/
|
||||
private int myHandlerNo;
|
||||
/**
|
||||
* If true, the handler has been closed
|
||||
*/
|
||||
private boolean myIsClosed;
|
||||
/**
|
||||
* Set to true after rebase editor was shown
|
||||
*/
|
||||
protected boolean myRebaseEditorShown = false;
|
||||
|
||||
/**
|
||||
* The constructor from fields that is expected to be
|
||||
* accessed only from {@link git4idea.rebase.GitRebaseEditorService}.
|
||||
*
|
||||
* @param service the service object that has created this handler
|
||||
* @param project the context project
|
||||
* @param root the git repository root
|
||||
*/
|
||||
public GitInteractiveRebaseEditorHandler(final GitRebaseEditorService service, final Project project, final VirtualFile root) {
|
||||
myService = service;
|
||||
myProject = project;
|
||||
myRoot = root;
|
||||
myHandlerNo = service.registerHandler(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit commits request
|
||||
*
|
||||
* @param path the path to editing
|
||||
* @return the exit code to be returned from editor
|
||||
*/
|
||||
public int editCommits(final String path) {
|
||||
ensureOpen();
|
||||
final Ref<Boolean> isSuccess = new Ref<Boolean>();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
if (myRebaseEditorShown) {
|
||||
GitRebaseUnstructuredEditor editor = new GitRebaseUnstructuredEditor(myProject, myRoot, path);
|
||||
editor.show();
|
||||
if (editor.isOK()) {
|
||||
editor.save();
|
||||
isSuccess.set(true);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
isSuccess.set(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setRebaseEditorShown();
|
||||
GitRebaseEditor editor = new GitRebaseEditor(myProject, myRoot, path);
|
||||
editor.show();
|
||||
if (editor.isOK()) {
|
||||
editor.save();
|
||||
isSuccess.set(true);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
editor.cancel();
|
||||
isSuccess.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error("Failed to edit the git rebase file: " + path, e);
|
||||
}
|
||||
isSuccess.set(false);
|
||||
}
|
||||
});
|
||||
return (isSuccess.isNull() || !isSuccess.get().booleanValue()) ? GitRebaseEditorMain.ERROR_EXIT_CODE : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked to indicate that this editor will be invoked in the rebase continuation action.
|
||||
*/
|
||||
public void setRebaseEditorShown() {
|
||||
myRebaseEditorShown = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that handler has not yet been closed
|
||||
*/
|
||||
private void ensureOpen() {
|
||||
if (myIsClosed) {
|
||||
throw new IllegalStateException("The handler was already closed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop using the handler
|
||||
*/
|
||||
public void close() {
|
||||
ensureOpen();
|
||||
myIsClosed = true;
|
||||
myService.unregisterHandler(myHandlerNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the handler number
|
||||
*/
|
||||
public int getHandlerNo() {
|
||||
return myHandlerNo;
|
||||
}
|
||||
}
|
||||
@@ -15,142 +15,15 @@
|
||||
*/
|
||||
package git4idea.rebase;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
/**
|
||||
* The handler for rebase editor request. The handler shows {@link git4idea.rebase.GitRebaseEditor}
|
||||
* dialog with the specified file. If user accepts the changes, it saves file and returns 0,
|
||||
* otherwise it just returns error code.
|
||||
* The interface
|
||||
*/
|
||||
public class GitRebaseEditorHandler implements Closeable {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private final static Logger LOG = Logger.getInstance(GitRebaseEditorHandler.class.getName());
|
||||
/**
|
||||
* The service object that has created this handler
|
||||
*/
|
||||
private final GitRebaseEditorService myService;
|
||||
/**
|
||||
* The context project
|
||||
*/
|
||||
private final Project myProject;
|
||||
/**
|
||||
* The git repository root
|
||||
*/
|
||||
private final VirtualFile myRoot;
|
||||
/**
|
||||
* The handler number
|
||||
*/
|
||||
private final int myHandlerNo;
|
||||
/**
|
||||
* If true, the handler has been closed
|
||||
*/
|
||||
private boolean myIsClosed;
|
||||
/**
|
||||
* Set to true after rebase edior was shown
|
||||
*/
|
||||
private boolean myRebaseEditorShown = false;
|
||||
|
||||
/**
|
||||
* The constructor from fields that is expected to be
|
||||
* accessed only from {@link git4idea.rebase.GitRebaseEditorService}.
|
||||
*
|
||||
* @param service the service object that has created this handler
|
||||
* @param project the context project
|
||||
* @param root the git repository root
|
||||
* @param handlerNo the handler no for this editor
|
||||
*/
|
||||
GitRebaseEditorHandler(final GitRebaseEditorService service, final Project project, final VirtualFile root, final int handlerNo) {
|
||||
myService = service;
|
||||
myProject = project;
|
||||
myRoot = root;
|
||||
myHandlerNo = handlerNo;
|
||||
}
|
||||
|
||||
public interface GitRebaseEditorHandler {
|
||||
/**
|
||||
* Edit commits request
|
||||
*
|
||||
* @param path the path to eding
|
||||
* @param path the path to editing
|
||||
* @return the exit code to be returned from editor
|
||||
*/
|
||||
public int editCommits(final String path) {
|
||||
ensureOpen();
|
||||
final Ref<Boolean> isSuccess = new Ref<Boolean>();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
if (myRebaseEditorShown) {
|
||||
GitRebaseUnstructuredEditor editor = new GitRebaseUnstructuredEditor(myProject, myRoot, path);
|
||||
editor.show();
|
||||
if (editor.isOK()) {
|
||||
editor.save();
|
||||
isSuccess.set(true);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
isSuccess.set(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setRebaseEditorShown();
|
||||
GitRebaseEditor editor = new GitRebaseEditor(myProject, myRoot, path);
|
||||
editor.show();
|
||||
if (editor.isOK()) {
|
||||
editor.save();
|
||||
isSuccess.set(true);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
editor.cancel();
|
||||
isSuccess.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error("Failed to edit the git rebase file: " + path, e);
|
||||
}
|
||||
isSuccess.set(false);
|
||||
}
|
||||
});
|
||||
return (isSuccess.isNull() || !isSuccess.get().booleanValue()) ? GitRebaseEditorMain.ERROR_EXIT_CODE : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked to indicate that this editor will be invoked in the rebase continuation action.
|
||||
*/
|
||||
public void setRebaseEditorShown() {
|
||||
myRebaseEditorShown = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that handler has not yet been closed
|
||||
*/
|
||||
private void ensureOpen() {
|
||||
if (myIsClosed) {
|
||||
throw new IllegalStateException("The handler was already closed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop using the handler
|
||||
*/
|
||||
public void close() {
|
||||
ensureOpen();
|
||||
myIsClosed = true;
|
||||
myService.unregisterHandler(myHandlerNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the handler number
|
||||
*/
|
||||
public int getHandlerNo() {
|
||||
return myHandlerNo;
|
||||
}
|
||||
int editCommits(String path);
|
||||
}
|
||||
|
||||
@@ -18,9 +18,8 @@ package git4idea.rebase;
|
||||
import com.intellij.ide.XmlRpcServer;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import git4idea.commands.GitHandler;
|
||||
import git4idea.commands.GitLineHandler;
|
||||
import git4idea.commands.ScriptGenerator;
|
||||
import gnu.trove.THashMap;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
@@ -35,11 +34,6 @@ import java.util.Random;
|
||||
* The service that generates editor script for
|
||||
*/
|
||||
public class GitRebaseEditorService implements ApplicationComponent {
|
||||
/**
|
||||
* the logger
|
||||
*/
|
||||
private static final Logger LOG = Logger.getInstance(GitRebaseEditorService.class.getName());
|
||||
|
||||
/**
|
||||
* The editor command that is set to env variable
|
||||
*/
|
||||
@@ -65,7 +59,7 @@ public class GitRebaseEditorService implements ApplicationComponent {
|
||||
*/
|
||||
private final static Random oursRandom = new Random();
|
||||
/**
|
||||
* If true, the component has been intialized
|
||||
* If true, the component has been initialized
|
||||
*/
|
||||
private boolean myInitialized = false;
|
||||
/**
|
||||
@@ -138,24 +132,27 @@ public class GitRebaseEditorService implements ApplicationComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the handler instance
|
||||
* Register the handler in the service
|
||||
*
|
||||
* @param handler the handler to register
|
||||
* @return the handler identifier
|
||||
*/
|
||||
public GitRebaseEditorHandler getHandler(Project project, VirtualFile root) {
|
||||
public int registerHandler(GitRebaseEditorHandler handler) {
|
||||
initComponent();
|
||||
GitRebaseEditorHandler rc = null;
|
||||
Integer rc = null;
|
||||
synchronized (myHandlersLock) {
|
||||
for (int i = Integer.MAX_VALUE; i > 0; i--) {
|
||||
int code = Math.abs(oursRandom.nextInt());
|
||||
// note that code might still be negative at this point if it is Integer.MIN_VALUE.
|
||||
if (code > 0 && !myHandlers.containsKey(code)) {
|
||||
rc = new GitRebaseEditorHandler(this, project, root, code);
|
||||
rc = code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rc == null) {
|
||||
throw new IllegalStateException("There is a problem with random number allocation");
|
||||
}
|
||||
myHandlers.put(rc.getHandlerNo(), rc);
|
||||
myHandlers.put(rc, handler);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -166,7 +163,7 @@ public class GitRebaseEditorService implements ApplicationComponent {
|
||||
*
|
||||
* @param handlerNo the handler number.
|
||||
*/
|
||||
void unregisterHandler(final int handlerNo) {
|
||||
public void unregisterHandler(final int handlerNo) {
|
||||
synchronized (myHandlersLock) {
|
||||
if (myHandlers.remove(handlerNo) == null) {
|
||||
throw new IllegalStateException("The handler " + handlerNo + " has been already remoted");
|
||||
@@ -175,7 +172,7 @@ public class GitRebaseEditorService implements ApplicationComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister handler
|
||||
* Get handler
|
||||
*
|
||||
* @param handlerNo the handler number.
|
||||
*/
|
||||
@@ -184,12 +181,23 @@ public class GitRebaseEditorService implements ApplicationComponent {
|
||||
synchronized (myHandlersLock) {
|
||||
GitRebaseEditorHandler h = myHandlers.get(handlerNo);
|
||||
if (h == null) {
|
||||
throw new IllegalStateException("The handler " + handlerNo + " has been already remoted");
|
||||
throw new IllegalStateException("The handler " + handlerNo + " is not registered");
|
||||
}
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure handler with editor
|
||||
*
|
||||
* @param h the handler to configure
|
||||
* @param editorNo the editor number
|
||||
*/
|
||||
public void configureHandler(GitLineHandler h, int editorNo) {
|
||||
h.setEnvironment(GitHandler.GIT_EDITOR_ENV, getEditorCommand());
|
||||
h.setEnvironment(GitRebaseEditorMain.IDEA_REBASE_HANDER_NO, Integer.toString(editorNo));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The internal xml rcp handler
|
||||
@@ -202,6 +210,7 @@ public class GitRebaseEditorService implements ApplicationComponent {
|
||||
* @param path the path to edit
|
||||
* @return exit code
|
||||
*/
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public int editCommits(int handlerNo, String path) {
|
||||
return getHandler(handlerNo).editCommits(path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user