Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 327399 - Provide SVN operation tracking API
Summary: Provide SVN operation tracking API
Status: RESOLVED FIXED
Alias: None
Product: Subversive
Classification: Technology
Component: Core (show other bugs)
Version: 0.7   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Igor Burilo CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 306806 356023 356024 356025
Blocks:
  Show dependency tree
 
Reported: 2010-10-10 03:54 EDT by Alexander Gurov CLA
Modified: 2014-04-09 05:11 EDT (History)
4 users (show)

See Also:


Attachments
Call intercepting and commit UI API usage sample (5.39 KB, application/octet-stream)
2012-02-28 13:40 EST, Alexander Gurov CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Gurov CLA 2010-10-10 03:54:56 EDT
Hi,

I need for my project some additional information. I found that there exists some extension points, but the offered functionality seams to be not sufficient.
http:// www.eclipse.org/subversive/documentation/gettingStarted/abou tSubversive/extensions.php

Is there a way to get informed that the user has selected Team- > Update / Update to Revision / Revert.
I need to get informed about those actions. When the user executes once of these actions I want to execute additional user specific code.

Is this possible with Subversive?
Do you have any ideas how to reach that target?

Thank you
Adrian

Hi Adrian,

Currently there is no API that allows to solve such a tasks. What you really asking is API that allows to monitor user actions while using Subversive, right? If so, the task is pretty complex by itself: there is plenty of different actions, some of them pretty simple, but some of them have really complex workflows ("Share Project" action, for example).
On the other side they all were made in similar manner: gathering user input, composing action from several different but simple tasks and then running composed task as background or foreground work.
So, you could take it as the start point and try to figure out which areas is really interesting for you to be monitored. Then we can discuss the issue a little more deep in order to define what kind of API changes would be required to solve it.

-----------------------------------------------------------------------------
Hi Alexander,

you are right. I need an API that tells me the user actions while Subversive will be used.

Actually what I need is quit simple. I need only the information which files were {modified, deleted, created}.

What I also currently miss at the commit extension point is, that I can't get the information which files were be realy commited. The method performAfterCommitTasks(...) is not a real "after commit task" method.

I would also need a list of resources which were modified during an action. Interesting actions would be for me: {commit, update, update to revision, revert}.
A notification, that the user has shared now a new project will be also very interesting. And in respect also a notification that the user has disconnected from a project.

What do you think? Is there maybe already today a solution for me go gain those goals?
Comment 1 staudta CLA 2010-10-14 06:57:53 EDT
Hi Alexander,

you have written that there exists some way get information about "committed revisions". What do you mean with that the interface "org.eclipse.team.svn.ui.extension.factory.ICommitActionFactory"?

Tell me if you need additional input from me.
Thank you for opening this bug.
Adrian
Comment 2 Eike Stepper CLA 2011-01-26 02:18:48 EST
(In reply to comment #0)
> I would also need a list of resources which were modified during an action.
> Interesting actions would be for me: {commit, update, update to revision,
> revert}.
> A notification, that the user has shared now a new project will be also very
> interesting. And in respect also a notification that the user has disconnected
> from a project.

I'd also need these particular hooks for a Subversive/Mylyn integration that creates Mylyn commit comments for successful SVN commits and links back from these comments to the Subversive HistoryPage.

I've contributed a working plugin to Mylyn in bug 306790 but it uses lower level connector events to gather the list of modifed resources and the committed revision number. I'd also like to get hold of the commit comment because it usually contains the bug ID. My code is very complicated and is partially based on assumptions (e.g. is -11 really the only event ID for successful commits??).

To foster cool tools on top of Subversive it would really be necessary to have better hooks in it.
Comment 3 Eike Stepper CLA 2011-01-26 02:23:25 EST
BTW. I wouldn't care if a particular operation that I'm interested in was triggered by a (human) user or not. I'm really interested in the effect on a repository and the set of parameters that influence it.
Comment 4 Alexander Gurov CLA 2011-05-15 16:34:20 EDT
Hello All, 

There is proposed API changes for an SVN actions monitoring:

public interface ISVNCallListener
{
	/**
	 * Allows to modify parameters before call (for exmple, you can wrap progress monitor in order to intercept progress notifications)
	 */
	public void asked(String methodName, Map parameters);
	public void succeeded(String methodName, Map parameters, Object returnValue);
	public void failed(String methodName, Map parameters, SVNConnectorException exception);
}

public interface ISVNConnector {
......
	public void addCallListener(ISVNCallListener listener);
	public void removeCallListener(ISVNCallListener listener);
......
}

public interface IRepositoryLocationStateListener
{
	public void changed(String field, Object oldValue, Object newValue);
	public void sslChanged(String field, Object oldValue, Object newValue);
	public void sshChanged(String field, Object oldValue, Object newValue);
	public void realmAdded(String realm, IRepositoryLocation location);
	public void realmRemoved(String realm);
	public function revisionLinkAdded(IRevisionLink link);
	public function revisionLinkRemoved(IRevisionLink link);
	public function proxyAcquired(ISVNConnector proxy);
	public function proxyDisposed(ISVNConnector proxy);
}

public interface IRepositoryLocation extends IRepositoryBase, IRepositoryResourceFactory {
......
	public void addStateListener(IRepositoryLocationStateListener listener);
	public void removeStateListener(IRepositoryLocationStateListener listener);
......
}


UI Commit monitor changes:

public interface ICommentDialogPanel extends IDialogPanel {
...........	
	
	/**
	 * Changes message in the commit panel
	 */
	public void setMessage(String message);

...........	
}

Anyone interested in those SVN API calls monitoring, please give us your opinion: is this API will provide sufficient abilities to cover all the required tasks for your case or not? Is there something to be improved?
Comment 5 Alexander Gurov CLA 2011-08-30 13:56:15 EDT
There will be a small difference in compare to the initial proposition regarding IRepository location state listener:

public interface ISSLSettingsStateListener
{
	public final String SSL_CERTIFICATE_PATH = "sslCertificatePath";
	public final String SSL_PASS_PHRASE = "sslPassPhrase";
	public final String SSL_PASS_PHRASE_SAVED = "sslPassPhraseSaved";
	public final String SSL_AUTHENTICATION_ENABLED = "sslAuthenticationEnabled";
	
	public void sslChanged(IRepositoryLocation where, String field, Object oldValue, Object newValue);
}

public interface ISSHSettingsStateListener
{
	public final String SSH_PASS_PHRASE = "sshPassPhrase";
	public final String SSH_PORT = "sshPort";
	public final String SSH_PRIVATE_KEY_PATH = "sshPrivateKeyPath";
	public final String SSH_USE_KEY_FILE = "sshUseKeyFile";
	public final String SSH_PASS_PHRASE_SAVED = "sshPassPhraseSaved";
	
	public void sshChanged(IRepositoryLocation where, String field, Object oldValue, Object newValue);
}

public interface IRepositoryLocationStateListener
	extends ISSHSettingsStateListener, ISSLSettingsStateListener
{
	public final String LABEL = "label";
	public final String URL = "url";
	public final String STRUCTURE_ENABLED = "structureEnabled";
	public final String TRUNK_LOCATION = "trunkLocation";
	public final String BRANCHES_LOCATION = "branchesLocation";
	public final String TAGS_LOCATION = "tagsLocation";
	public final String USERNAME = "username";
	public final String PASSWORD = "password";
	public final String PASSWORD_SAVED = "passwordSaved";
	public final String AUTHOR_NAME = "authorName";
	public final String AUTHOR_NAME_ENABLED = "authorNameEnabled";

	public void changed(IRepositoryLocation where, String field, Object oldValue, Object newValue);
	public void realmAdded(IRepositoryLocation where, String realm, IRepositoryLocation location);
	public void realmRemoved(IRepositoryLocation where, String realm);
	public void revisionLinkAdded(IRepositoryLocation where, IRevisionLink link);
	public void revisionLinkRemoved(IRepositoryLocation where, IRevisionLink link);
	public void proxyAcquired(IRepositoryLocation where, ISVNConnector proxy);
	public void proxyDisposed(IRepositoryLocation where, ISVNConnector proxy);
}

Also there will be the RepositoryLocationStateAdapter class which will provide default implementation of the IRepositoryLocationStateListener interface in order to simplfy its usage.
Comment 6 Alexander Gurov CLA 2011-09-25 05:37:51 EDT
Since there weren't any proposals regarding commit UI extensions it was implemented in the simplest way that will do regarding what was initially requested.
So, now there is the new interface:

public interface IModifiableCommentDialogPanel extends ICommentDialogPanel {
	/**
	 * Changes message in the commit panel
	 */
	public void setMessage(String message);

}

And when you implement your ICommitActionFactory you can handle it like this:

public class DefaultCommitActionFactory implements ICommitActionFactory {

	public ICommitDialog getCommitDialog(final Shell shell, Collection allFilesToCommit, final ICommentDialogPanel commentPanel) {
		return new ICommitDialog(){
			
			public String getMessage() {
				return commentPanel.getMessage();
			}
			
			public int open() {
				if (commentPanel instanceof IModifiableCommentDialogPanel) {
					((IModifiableCommentDialogPanel)commentPanel).setMessage("..."/*some commit message here*/);
				}
				DefaultDialog dialog = new DefaultDialog(shell, commentPanel);
				return dialog.open();
			}
			
		};
	}

This way it shouldn't break existing applications and should allow to set redefine initial comment when it is needed.
If there is a need for more complex solution please share your opinion. Thank you in advance, everyone!
Comment 7 Alexander Gurov CLA 2012-02-28 13:40:29 EST
Created attachment 211756 [details]
Call intercepting and commit UI API usage sample

To all who are interested in this. Please take a look at this sample.
Comment 8 Alexander Gurov CLA 2013-02-24 07:46:32 EST
Bug #306806 is closed now. All the requested API changes are completed.
Comment 9 Shwetha Telakula CLA 2013-07-29 16:42:55 EDT
Hi Alexander

I want to do some pre-commit actions like validating the files before commit.
I have been trying to use your sample plug in code to intercept commit call, but the documentation seems to be pretty thin on how to achieve. I would greatly appreciate some clarity on where I can fit my code (some kind of validation of files). I want to perform some actions just before commit action is performed. In your sample code I only see API to do after-perform tasks. Please provide your suggestions for this.

Thanks
Comment 10 Alexander Gurov CLA 2013-08-02 14:59:29 EDT
(In reply to comment #9)
> Hi Alexander
> 
> I want to do some pre-commit actions like validating the files before commit.
> I have been trying to use your sample plug in code to intercept commit call,
> but the documentation seems to be pretty thin on how to achieve. I would
> greatly appreciate some clarity on where I can fit my code (some kind of
> validation of files). I want to perform some actions just before commit
> action is performed. In your sample code I only see API to do after-perform
> tasks. Please provide your suggestions for this.
> 
> Thanks

Actually if you're using the sample that is attached to this task, there you can find the function:

public ICommitDialog getCommitDialog(final Shell shell, Collection allFilesToCommit, final ICommentDialogPanel panel) {
......
}

This function itself is the point where you could check the files (they're passed as the collection "allFilesToCommit"). 
If there is nothing more to do, then you could use the same code the DefaultCommitActionFactory class uses.
If you need to validate the files selected in the dialog itself - that should be done later. In order to check the actual files, passed to the commit function you may do it after the dialog is closed^

public ICommitDialog getCommitDialog(final Shell shell, Collection allFilesToCommit, final ICommentDialogPanel commentPanel) {
	return new ICommitDialog(){
		
		public String getMessage() {
			return commentPanel.getMessage();
		}
		
		public int open() {
			DefaultDialog dialog = new DefaultDialog(shell, commentPanel);
			int retVal = dialog.open();
			if (retVal == 0)
			{
				IResource []resourcesToCommit = ((CommitPanel)commentPanel).getSelectedResources();
			}
			return retVal;
		}
		
	};
}
Comment 11 Shwetha Telakula CLA 2013-08-02 18:12:46 EDT
Hi Alexander

Thanks so much for the suggestion. So my understanding is that I can return retVal = OK if my validation passes and I want to commit the files and I can return retval=CANCEL if my validation fails and I want to restrict the commit of the files. My question is how do I make changes in the dialog UI to show that 'Commit operation is not allowed because X, Y , Z files are invalid'. I want to be able to disable the 'OK' button that the developer can press to proceed to commit and display an error pop-up with the error message. But I am not able to make these changes on the UI because there is no extension point to edit the existing controls. Please provide your input on how this can be achieved using the extension factory. If not, is there an alternative way to achieve this. 

Thanks
Shwetha
Comment 12 Alexander Gurov CLA 2013-08-04 14:14:12 EDT
(In reply to comment #11)
There is no clear API exactly for the task you want to complete. On the other hand this could be done in not too complex way:

public ICommitDialog getCommitDialog(final Shell shell, Collection allFilesToCommit, final ICommentDialogPanel commentPanel) {
	return new ICommitDialog(){
		
		public String getMessage() {
			return commentPanel.getMessage();
		}
			
		public int open() {
			DefaultDialog dialog = new DefaultDialog(shell, commentPanel)
			{
				@Override
				public void setMessage(int level, String message) {
					if (level != IDialogManager.LEVEL_ERROR && true /* here is the condition for an outside error */) {
						level = IDialogManager.LEVEL_ERROR;
						message = "There is an error somewhere in files!";
					}
					super.setMessage(level, message);
				}
					
				@Override
				public void setButtonEnabled(int idx, boolean enabled) {
					if (true /* here is the condition for an outside error */) {
						enabled = false;
					}
					super.setButtonEnabled(idx, enabled);
				}
			};
			return dialog.open();
		}
			
	};
}

- Firstly we check if there is an error or not in the files to commit
- then we need to override 2 functions related to validation management in the DefaultDialog class
- then if there is an error and the status in dialog is not an error - we just override the status and prevent buttons enablement

Is this what you're looking for?
Comment 13 Shwetha Telakula CLA 2013-08-20 14:15:19 EDT
Thanks Alexander! That is pretty much what I am looking for. I am able to create a method with some validation and use its return value to make changes on the UI button.
Comment 14 Shwetha Telakula CLA 2014-04-07 13:29:59 EDT
Hi Alexander

I am able to successfully intercept the commit call to do some operation on the files before committing them using the commit extension point. But the problem occurs when I want to do a pretty large validation process before committing the files. My validation operation calls on to another project which takes around 2 mins to finish the validation process before returning the result. This large operation causes the Eclipse IDE to freeze as it is being done in the open() method as follows

public ICommitDialog getCommitDialog(final Shell shell,
			Collection allFilesToCommit, final ICommentDialogPanel commentPanel) {
		this.commentPanel = commentPanel;
		this.allFilesToCommit = allFilesToCommit;
		....
		return new ICommitDialog() {
			public String getMessage() {
				return commentPanel.getMessage();
			}

			public int open() {

				DefaultDialog dialog = new DefaultDialog(shell, commentPanel);
				int retVal = dialog.open();
				IResource[] resourcesToCommit = ((CommitPanel) commentPanel)
						.getSelectedResources();
				boolean commitStatus=false;
				if(retVal==0)
				commitStatus=validate(resourcesToCommit);
				if(commitStatus)
					return 0;
				else
				return 1;
			}
		};
	
	}

My validate() process spawns another thread where the processing is performed and is a large validation process. Do you have another API that can do this kind of large validation outside of the UI and return the validation result to the commit process? I want to be able to continue working on Eclipse IDE while my validation process is going on in the background. I would really appreciate your suggestion.

Thanks
Shwetha
Comment 15 Alexander Gurov CLA 2014-04-09 05:11:23 EDT
(In reply to Shwetha Telakula from comment #14)
Hi Shwetha,

The main problem is that the process of starting commit action itself was not supposed to be a long-running one. The preparatory work for the commit operation was expected to be done modal, while the commit operation itself (as a long-running one) - as a background process.

I see 2 possible solutions here:
1) the validation process should be performed as a background process, activated by some events, so that the commit dialog would not wait for it to be finished at all. It is probably the most desirable way, but not the simplest one.
2) you may try to imitate the behaviour of outside commit action's code. I.e. something around those lines:

public ICommitDialog getCommitDialog(final Shell shell,
			Collection allFilesToCommit, final ICommentDialogPanel commentPanel) {
		return new ICommitDialog() {
			public String getMessage() {
				return commentPanel.getMessage();
			}

			public int open() {
// 1) run background operation which includes validation then opening dialog and running a copy of the code from org.eclipse.team.svn.ui.action.local.CommitAction lines 55-59
// 2) return cancel button code (1) in order to cancel default processing in commit action
				return 1;
			}
		};
	
	}

The drawback of this way is that you would use an internal Subversive plug-in's specific in your code.