It's all about the answers!

Ask a question

Prevent changes on certain folders - by certain users

VK L (8177141159) | asked Jun 21 '12, 11:39 a.m.
Hi All,
            I want to restrict access on certain folders to particular users alone. I am doing a server plugin for this. I need the below:
1. Stream name - to which deliver is happening
2. Folder name - Lowest-level and the parent folders involved + filename
3. contributor name 

How to get the path and stream details using server plugin? i tried using - but fails as its related to client plugin only...

Please advise and share any relevant codes or ideas that you have


David Olsen commented Jun 21 '12, 11:45 a.m.

Are you trying to limit read access or write access to those folders? I am guessing write access, that you want to prevent users from delivering changes to those folders. But your question isn't clear about that.

VK L commented Jun 22 '12, 1:50 a.m. | edited Jun 22 '12, 11:36 a.m.

Hi David,
                 I am trying to restrict write access to the folders.

VK L commented Jul 02 '12, 5:32 a.m. | edited Jul 02 '12, 10:00 a.m.

My requirement is that i should restrict add operations on a particular path for certain users.


3 answers

permanent link
Michele Pegoraro (1.8k12114101) | answered Jun 22 '12, 6:39 a.m.
I think you are talking about an advisor on the delivery operation.
In this case the operation.getOperationData() is an instance of DeliverOperationData. With this object you can retrieve the source and the target workspaces or streams (which are the same type of object) and the change-set.

Then, for every change-set, you can get the single change. The path is more difficult to be obtained, but you can get it using IScmService.configurationLocateAncestors method and then cycling through the tree path.


VK L commented Jun 22 '12, 7:04 a.m. | edited Jun 22 '12, 11:59 a.m.

Hi Michele,
                    My Code looks like this: - The problem that i have is FileItem - can be used only in clinet plugin i think and hence am unable to retrive the item details - folders and files here. Please suggest an alternative for server-side plugin

DeliverOperationData data = (DeliverOperationData) operationData;
        List<IChangeSetHandle> changeSetHandles = data.getChangeSetHandles();
        IRepositoryItemService itemService = getService(IRepositoryItemService.class);
        IScmService scmService = getService(IScmService.class);
        IItemServiceIterator changeSetIterator = ItemServiceIteratorFactory.INSTANCE.createFetchItemsIterator(itemService, changeSetHandles.toArray(new IItemHandle[changeSetHandles.size()]), IRepositoryItemService.COMPLETE);
        while (changeSetIterator.hasNext()) {
            IChangeSet changeSet = (IChangeSet);
            if (changeSet == null) {
            for (IChange change : (List<IChange>) changeSet.changes()) {
                if (change.kind() == IChange.ADD || change.kind() == IChange.MODIFY || change.kind() == IChange.DELETE)
                     IVersionableHandle versionableHandle = change.beforeState();
                    ServiceConfigurationProvider configProvider = ServiceConfigurationProvider.FACTORY.create(
                            data.getDestWorkspace(), changeSet.getComponent());
                    IVersionable item = (IVersionable) scmService.fetchState(versionableHandle, null, null);
                    if(item instanceof IFolder)
                        String path = "\"+((IFolder)item).getName();
                       IVersionableHandle parent  = ((IFolder)item).getParent();
                       System.out.println(" Folder names is" + path);
                       System.out.println(" Folder parent names is" + parent);
                    else if(item instanceof IFileItem)
                        String path = "\"+((IFileItem)item).getName();
                        IVersionableHandle parent = ((IFileItem)item).getParent();
                       System.out.println(" File names is" + path);
                       System.out.println(" File parent names is" + parent);

                    IAncestorReport reports[] = scmService.configurationLocateAncestors(
                            configProvider, new IVersionableHandle[] {versionableHandle}, null, null);
                    IAdvisorInfo info = collector.createProblemInfo(
                            "Deliver of deleted files is prohibited",
                            "The file " + toFullPath(item, reports[0].getNameItemPairs()) + " is not allowed to be deleted.",


    private String toFullPath(IVersionable versionable, List<INameItemPair> segments) {
        StringBuffer path = new StringBuffer();
        if(segments.isEmpty()) {
            return versionable.getName();
        for (INameItemPair nameItemPair : segments) {
            if(path.length() != 0) {
            // ignore the root folder which doesn't have a name
            if(nameItemPair.getName() != null)
        return path.toString();


Michele Pegoraro commented Jun 22 '12, 7:30 a.m. | edited Jun 22 '12, 11:59 a.m.

I use both and on my server side script. I don't know of any limitation between client and server in this case.

VK L commented Jun 22 '12, 7:35 a.m. | edited Jun 22 '12, 11:59 a.m.

Hi Michele,
                    Then could it be a problem with my pre-requisites? Because i got errors when using these methods in my server side plugin.

Could you put your associated plugin.xml code here?


Michele Pegoraro commented Jun 22 '12, 8:12 a.m. | edited Jun 22 '12, 12:00 p.m.

Where do you have the errors? And which exceptions do you have?

My plugin.xml is quite simple, for example:

            name="Check WAS Properties"
            Verifica che le properties versionate per il deploy automatico non contengano valori non ammessi.
            <requiredService interface=""/>
            <requiredService interface=""/>
            <requiredService interface=""/>
            <requiredService interface=""/>
            <requiredService interface=""/>
            <requiredService interface=""/>
            <requiredService interface=""/>

VK L commented Jun 22 '12, 8:58 a.m. | edited Jun 22 '12, 12:00 p.m.

Sorry, made it an advisor and i think thats the reason...I will modify it and check.

Do you have the code snippet for the Stream name, Filename and folder details retrieval?


Michele Pegoraro commented Jun 22 '12, 11:44 a.m. | edited Jun 22 '12, 12:00 p.m.

For stream name once you've the IWorkspaceHandle (from data.getDestWorkspace()) you can easily get the IWorkspace object (using IRepositoryItemService) and then use .getName() method.

FileName and path is quite complex but your snippet on previous answer seems correct at first view.

showing 5 of 6 show 1 more comments

permanent link
Evan Hughes (2.4k1218) | answered Jun 22 '12, 11:56 a.m.
edited Jun 22 '12, 11:58 a.m.
You shouldn't use the stream name to check if the stream is what you want. You should use the stream's UUID. You can get that using IWorkspace.getItemId(). This prevents your advisor from misbehaving when the stream's name changes or another stream is created with the same name. To set the UUID properly, you should create an aspect editor that allows clients to configure the advisor.

You should be running on the "" operation. That's "Deliver (phase 2)" which is more appropriate to what you're trying to do. You can walk over the changes by looking at the update report: 

<pre>public void run(AdvisableOperation operation, IProcessConfigurationElement advisorConfiguration, IAdvisorInfoCollector collector, IProgressMonitor monitor) throws TeamRepositoryException {
   IScmDeltaSource deltaSource = (IScmDeltaSource) operationData;
   IScmItemService scmItemService = getService(IScmItemService.class);

   for (IChangeHistoryModificationDelta mod : deltaSource.getDeltas(IChangeHistoryModificationDelta.class)) {
      IUpdateReport updateReport = mod.getUpdateReport();
         for (IComponentHandle comp : updateReport.getAffectedComponents()) {
            Collection<IItemUpdateReport> updatesForComponent = updateReport.getUpdatesForComponent(comp);

To check the location of the versionable in the hierarchy, you should query the IScmService.configurationLocateAncestors() for each of the changed items (listed in the IUpdateReport) to see if they are descendants of the versionables you care about. Note that new items won't exist in the configuration, and that items that have been moved may have been moved under newly created items.

permanent link
VK L (8177141159) | answered Jul 02 '12, 5:32 a.m.
Hi All,
            I have implemented this plugin and it works fine for modify/delete as there is a before and an after state. sample code that i used to get the path is as below:
for (IChange change : (List<IChange>) changeSet.changes()) {
                    ServiceConfigurationProvider configProvider = ServiceConfigurationProvider.FACTORY.create(data.getDestWorkspace(), changeSet.getComponent());
IVersionableHandle versionableHandle = change.beforeState();
IVersionable item =  (IVersionable) scmService.fetchState(versionableHandle, null, null);
                    IAncestorReport reports[] = scmService.configurationLocateAncestors(
                            configProvider, new IVersionableHandle[] {versionableHandle}, null, null);
                    String Path = toFullPath(item, reports[0].getNameItemPairs());

but in case of add operation, the value of versionableHandle is null and so the above code does not work. Could you please suggest how this can be achieved for an add operation?


Michele Pegoraro commented Jul 02 '12, 6:14 a.m.

The handle is null because of the configuration provider you've selected. In case of an add operation the element is not already present in the target stream so you have to use data.getSourceWorkspace() in order to have the object.

VK L commented Jul 02 '12, 6:29 a.m. | edited Jul 02 '12, 10:06 a.m.

Thanks Michelle. Could you please provide a sample code for the add operation?
Versionable handle looks to be retrieving a null value (or) is it the problem only because of config provider?

Michele Pegoraro commented Jul 02 '12, 8:42 a.m. | edited Jul 02 '12, 10:06 a.m.

Your snippet seems to be ok, in case of add operation (you can obtain change kind by IChange.getKind() and compare it with IChange.ADD) you have to select a different config provider.

VK L commented Jul 04 '12, 3:43 a.m. | edited Jul 04 '12, 9:50 a.m.

Hi Michele,
                    The plugin works fine now. But at times, it fails to run giving the following error:
 http-9443-Processor44]  WARN                             - Unhandled Exception Stream closed

And when i restart the system(local machine - where my JTS resides), it starts working again. there is no problem with plugin activation, but it fails at times - i can say after 2 or 3 runs.

Please advise.


Your answer

Register or to post your answer.