Jazz Forum Welcome to the Jazz Community Forum Connect and collaborate with IBM Engineering experts and users

precondition: restrict assigning roles for team members

 Hello 

I want to write a precondition that restrict assigning of some roles to specific roles. We want that e.g. only a team member with the role "Administrator" can assign the role "Administrator" to other team members. All other roles should not be restricted.

But how can I identify which change was done when the precondition for "SaveTeamArea" is run? If I use getActions() on the AdvisableOperation argument I got only the String "modify/members". And getOperationData returns "null".

Is there a way e.g. with the history to identify which roles has be added or removed?

Thanks and regards
Martin

0 votes

Comments

I don't believe there is history for team area changes.

I'm not aware of any before/after capabilty on anything other than workitems
altho the getprocessarea/getsecondaryprocessarea might be how to get it.

what does operation.getSecondaryActions(operation.getProcessArea()) return.


1 vote

 Unfortunately "operation.getSecondaryActions(operation.getProcessArea())" returns an empty String array. 


Do you see any other option to identify which changes was done for the "save team area" operation?

I do not know any more about this. I have never seen any history or change info team areas or project areas other than the process config source.


Accepted answer

Permanent link
this code works, shows the proposed new roles for members. I haven't figured out how to load the existing PA data.


in a participant (too far after the fact).. the getSaveditems()[0] has the new data. while getItems()[0] has the old data

        Object objData = operation;
        if (operation instanceof ProjectAreaSaveOperation)
        {   
            ProjectAreaSaveOperation data = (ProjectAreaSaveOperation) objData;          
            List<String> actions = Arrays.asList(data.getActions());
            if (actions.contains(ProjectAreaSaveOperation.ACTION_MODIFY_MEMBERS))
            {
                if(fcontributorService==null)
                {
                    IContributorService fcontributorService= getService(IContributorService.class);
                    fItemService = getService(IRepositoryItemService.class);
                }
                System.out.println("in modify members");
                IProjectArea pa = (IProjectArea) data.getItems()[0];
                IContributorHandle members[] = pa.getMembers();
                for(IContributorHandle member: members)
                {
                    IContributor user = (IContributor) fItemService.fetchItem(member, (new String[]{IContributor.NAME_PROPERTY,IContributor.DETAILS_PROPERTY}));
                    System.out.println("user name="+user.getName());
                    String[] roles = RolePersistence.getRoleIds(RolePersistence.getPersistentRoleData(pa.getTeamData(), user));
                    for(String role:roles)
                    {
                        System.out.println("\t role="+role);
                    }
                }
Martin Wassermann selected this answer as the correct answer

1 vote

Comments
in a participant (too far after the fact).. the getSaveditems()[0] has the new data. while getItems()[0] has the old data 

but data.getSavedItems()[0]; returns a 

java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0
So there with this solution there is the same problem as in my solution. I didn't get the new data. Or did it work for you with data.getSavedItems()[0]?

there are two different solutions..

in an Advisor, you get the NEW data, and have to LOAD the old data for the project area to compare against

in a Participant, you get BOTH the old and the new, least I do.

1 vote

Many thanks Sam for your support. Now it work's. 


Getting the old data can simply be done with 
IProcessArea oldProcess = (IProcessArea) repositoryService.fetchItem( newProcess.getItemHandle(), null);

had to post another 'answer' to hold the full sample. see my comment there about using the itemhandle


2 other answers

Permanent link
I have found a solution for the saveTeamArea operation. With
IProcessArea newProcess = operation.getProcessArea();
I can get the working copy of the user, and compare it the the actual process
IProcessArea oldProcess = (IProcessArea) repositoryService.fetchItem( newProcess.getItemHandle(), null);
After that I can compare the members of the oldProcess and the newProcess.

But If I try the same with the saveProjectArea operation I have a problem, because 
operation.getProcessArea();
returns not the working copy in the saveProjectArea operation but the original. Therefore I did not see the changes the user has made. 

Is there a way to get the working copy of the user that save the project area?

0 votes

Comments

get the contributor service ( add it as a pre-req to the plugin.xml)

    private static IContributorService fcontributorService = null;
            fcontributorService = getService(IContributorService.class);

then the extension is running in the context of the user making the change
            on the AbstractService class the  extension is part of

            getAuthenticatedContributor()

will get u the users handle, then use the service..

Some examples of the roles API also on my blog. E.g. https://rsjazz.wordpress.com/2013/06/26/attribute-customization-java-based-value-providers-conditions-and-validators/

Once you have the above, you could go deeper into the roles.

Sorry, I write my question unclear. I did not need the working copy of the user - I need the working copy of the project area that the authenticated user has changed. (and exactly the working copy that contains the changes of the authenticated user)


The operation getProcesssArea in the precondition did not return the working copy that the authenticated user has changed when he press save. Therefore I don'T know how I should get the changed the user has made to the project area. 

Did you know I can get this information?

ah.. because you are in a pre-condition no changes have been made yet.

but you should be able ot get the list of users in the teamarea/project area,
and get their role data

RolePersistence.getPersistentRoleData(teamarea_area.getTeamData(), user_handle);

my guess is that the old/new process data will point to different data.
I haven't done this is a plugin.
but you will have to loop thru each user, get their role data on both old/new process areas and compare lists.

Right, and this works perfect for the operation saveTeamArea


But if I want to use the same for saveProjectArea, oldProcess and newProcess points to the same data. So I can't get the "changed version" to compare with the original one.

So for the operation saveTeamArea my precondition works fine. But not for saveProjectArea because I can't fetch the changed version (the working copy)

don't you get a teamarea save for the project area, when you don't change the process config?

I don't see the save project area extension point in the default list.

Unfortunately it is a saveProjectArea operation if you change the members of the project area.

In Web the editor you dont see this operation for precondition but there is an operation for it (see https://jazz.net/wiki/bin/view/Main/CustomPreconditionsLandingSite)

I don't see that operation listed except in the 'data passed'  table.
"The following table gives the data types of the operation data"

you should not get the processarea (working copy), as you should HAVE the process area already.
and as u are not changing it (pre-conditions don't change), the other apis against it would work ok.

And that's the problem. I don't have the the process area that contains the changes. For  the operation saveTeamArea I get the process area that CONTAINS the changed by calling
    operation.getProcessArea();
But if I try the same with the operation saveProjectArea I receive the process area WITHOUT the changes. Therefore I can't check if the changes are correct.

ok, sorry, without debugging this myself, I don't have any other answer..

can u show me how you configured you advisor?  
(cut/paste the xml from eclipse project source view)
as I don't see it.

 The configuration is very similar to saveTeamArea, but inside the behavior of the project.configuration.

<project-configuration>
  .........
  <behavior>
    <role id="default">
    ...... 
      <project-operation id="com.ibm.team.process.server.saveProjectArea">
      <preconditions>
        <precondition
          id="com.company.jazz.extension.service.restrictassignofroles" 
          name="Restrict Assign of Roles"/>
        </preconditions>
      </project-operation>
   </role>
  </behavior>
</project-configuration>

thanks.. one more thing.. I am getting ''Save Project Area' failed. Preconditions have not been met: The advisor com.sd.tools.SaveProjectArea.advisor is not valid for the operation com.ibm.team.process.server.saveProjectArea.'

and my class def is
public class ProjectAreaSaveAdvisor extends AbstractService implements IOperationAdvisor

running on a 4.0.3 server. compiled against the 4.0.3 sdk.

showing 5 of 13 show 8 more comments

Permanent link
cool.. and sadly, in the SaveProjectArea operation data there is a field fPreviousItems
which holds the data you seek, but there is no method to get it.

I was concerned with using the projectArea handle provided in the advisor to load the pre-change data, as it was provided by the advisor..

so I did this

                URI srcuri = URI.create(pa.getName().replaceAll(" ", "%20"));
                IProcessArea projectArea = fProcessServerService.findProcessArea(srcuri.toString(), null);


full sample

package com.sd.tools;

import java.net.URI;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;

import com.ibm.team.process.common.IDevelopmentLine;
import com.ibm.team.process.common.IProcessArea;
import com.ibm.team.process.common.IProcessConfigurationElement;
import com.ibm.team.process.common.IProjectArea;
import com.ibm.team.process.common.advice.AdvisableOperation;
import com.ibm.team.process.common.advice.IAdvisorInfo;
import com.ibm.team.process.common.advice.IAdvisorInfoCollector;
import com.ibm.team.process.common.advice.runtime.IOperationAdvisor;
import com.ibm.team.process.common.advice.runtime.IOperationParticipant;
import com.ibm.team.process.common.advice.runtime.IParticipantInfoCollector;
import com.ibm.team.process.internal.common.RolePersistence;
import com.ibm.team.process.internal.service.ProjectAreaSaveOperation;
import com.ibm.team.process.service.IProcessServerService;
import com.ibm.team.repository.common.IContributor;
import com.ibm.team.repository.common.IContributorHandle;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.repository.common.service.IContributorService;
import com.ibm.team.repository.service.AbstractService;
import com.ibm.team.repository.service.IRepositoryItemService;

public class ProjectAreaSaveAdvisor extends AbstractService implements IOperationAdvisor
{
    IContributorService fcontributorService = null;
    IRepositoryItemService fItemService = null;
    IProcessServerService fProcessServerService = null;
    public ProjectAreaSaveAdvisor()   
    {
        System.out.println("in project save constructor");
    }

    @SuppressWarnings("restriction")
    public void run(AdvisableOperation operation,
            IProcessConfigurationElement participantConfig,
            IAdvisorInfoCollector collector, IProgressMonitor monitor)
            throws TeamRepositoryException   
    {
        Object objData = operation;
        if (operation instanceof ProjectAreaSaveOperation)
        {   
            ProjectAreaSaveOperation data = (ProjectAreaSaveOperation) objData;          
            List<String> actions = Arrays.asList(data.getActions());
            if (actions.contains(ProjectAreaSaveOperation.ACTION_MODIFY_MEMBERS))
            {
                if(fcontributorService==null)
                {
                    IContributorService fcontributorService= getService(IContributorService.class);
                    fItemService = getService(IRepositoryItemService.class);
                    fProcessServerService = getService(IProcessServerService.class);                   
                }
                System.out.println("in modify members");
                //
                IProjectArea pa = (IProjectArea) data.getItems()[0];
                IContributorHandle members[] = pa.getMembers();
                for(IContributorHandle member: members)
                {
                    IContributor user = (IContributor) fItemService.fetchItem(member, (new String[]{IContributor.NAME_PROPERTY,IContributor.DETAILS_PROPERTY}));
                    System.out.println("user name="+user.getName());
                    String[] roles = RolePersistence.getRoleIds(RolePersistence.getPersistentRoleData(pa.getTeamData(), user));
                    for(String role:roles)
                    {
                        System.out.println("\t role="+role);
                    }
                }
               
                // use this if in an Advisor                
                // get the old data           
                URI srcuri = URI.create(pa.getName().replaceAll(" ", "%20"));
                IProcessArea projectArea = fProcessServerService.findProcessArea(srcuri.toString(), null);
               
                // use this if in a participant               
                // gets the new data (post save)
                // projectArea = (IProjectArea) data.getSavedItems()[0];
               
                // get the list of members
                members = projectArea.getMembers();
                System.out.println(" old info");
                for(IContributorHandle member: members)
                {
                    IContributor user = (IContributor) fItemService.fetchItem(member, (new String[]{IContributor.NAME_PROPERTY,IContributor.DETAILS_PROPERTY}));
                    System.out.println("user name="+user.getName());
                    String[] roles = RolePersistence.getRoleIds(RolePersistence.getPersistentRoleData(projectArea.getTeamData(), user));
                    for(String role:roles)
                    {
                        System.out.println("\t role="+role);
                    }
                }                               
            }
        }           
    }
}


0 votes

Your answer

Register or log in to post your answer.

Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.

Search context
Follow this question

By Email: 

Once you sign in you will be able to subscribe for any updates here.

By RSS:

Answers
Answers and Comments
Question details
× 10,964

Question asked: Jun 24 '14, 9:58 a.m.

Question was seen: 6,226 times

Last updated: Jul 29 '14, 8:32 a.m.

Confirmation Cancel Confirm