Configuring a Participant Picker in JCA
Objective
Participant Picker gives you the ability to search for participants using a variety of search criteria and gives the ability to pick selective participants.
Background
Participant Picker gives you the ability to search Participants of type User, Group, and Organization. It provides a wide variety of search scope criteria using which you can narrow down the search.
* 
This topic describes how to customize a JCA-based participant picker for use in JCA tables. In Windchill 11.0, a new participant picker based on AngularJS has been introduced and PTC recommends using it for standalone, single-page applications based on AngularJS, HTML, or Javascript. For more information, see Configuring a Participant Picker in AngularJS.
Scope/Applicability/Assumptions
Using in Windchill Client Architecture table: You should define a Windchill Client Architecture action, and point the action to a JSP page that has participant picker tag. Provide the required attributes “action Class” and “action Method “to the participant picker tag. Add the Windchill Client Architecture action you created to the desired Windchill Client Architecture table. When you click the action, it will launch the Participant Picker Wizard. Select desired participant and click OK. The Picker will invoke the action Method of the action Class that you have provided. In that method, you will consume or process the selected participant in a desired way.
Using Participant Picker in combination with Property Picker: The assumption is that you know how to use the Property Picker. The action attribute of your Property Picker should point to the JSP page that has participant picker tag. The required attribute “action Class” should “”(empty) and “action Method “ should be “JavaScript:${pickerCallback}()”. ${pickerCallback} is the pickerCallback JavaScript function that you supplied to Property Picker. After you select the desired participants and click OK in the wizard, your pickerCallback JavaScript function will be invoked with JSON object containing the picked participants.
Intended Outcome
The selected participants are either populated in Windchill Client Architecture table, or a populated in text box of Property Picker.
Solution
Use the Participant Picker to search for participants, and add the selected participants to a Windchill Client Architecture table or text box in a Property Picker.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
How to add Windchill Client Architecture actions to a Windchill Client Architecture table, how to dynamically update the table with selected participants.
How to configure a Property Picker, how to author JavaScript picker Callback functions.
Solution Elements
Element
Type
Description
actionClass
Tag Attribute
Name of the action class that needs to be invoked for processing the selected Participants.
actionMethod
Tag Attribute
Name of the action method that needs to be invoked for processing the selected Participants.
select
Tag Attribute
This will determine whether the picker allows multiple selections ("multi"), or just a single select ("single").
participantType
Tag Attribute
Use this to set the default to any Participant type. The class com.ptc.core.components.beans.PrincipalBean has four string constants defined, which one can be pass to this attribute. The constants are ALL_PARTICIPANT, USER, GROUP and ORG.
singleParticipantType
Tag Attribute
Use this to set the default Participant type specified in the tag attribute participantType as the only supported type. This takes value true/false. When set to true, it will restrict to single type specified as in the attribute participantType. When set to false or left unspecified, the picker supports participant types ALL_PARTICIPANT, USER, GROUP, ORG.
associationMap
Tag Attribute
This map contains key, value pairs of association to be displayed in association drop down list. Keys are Java String literals that are returned to the user upon selection of any association. Value is a localized string that is displayed in association drop down list.
defaultAssociation
Tag Attribute
The association you desire to be pre selected in the dropdown should be passed in this attribute.
associationLabel
Tag Attribute
The localized string for Display Label of the association.
emailAllowed
Tag Attribute
Set this to "true" to get email Textbox rendered. You can type any comma or space separated emails that you desire to invite.
contextMap
Tag Attribute
The List of Context in which you wants to perform Search In. This map contains key, value pairs of contexts to be displayed in Search In drop down list. Keys are Java String literals that represent oid of the Windchill object. Value is a localized string that is displayed in Search In drop down list.
filterEmail
Tag Attribute
If this attribute is set to “true” when searching for users, only users with email addresses are returned. Default is “false”.
recentAllowed
Tag Attribute
Set this to “false” to prevent the recent participants TextBox from being rendered. Default is “true”.
applicationContextSearch
Tag Attribute
If this attribute is set to “true” when searching for users, only users within a specified application context will be returned. Default is “false”.
defaultContext
Tag Attribute
The context you desire to be pre selected in the dropdown should be passed in this attribute.
serviceMap
Tag Attribute
Directory services list is passed, to perform search. Default this attribute is not supplied. This map contains key, value pairs of contexts to be displayed in Service drop down list. Keys are Java String literals that represent the Directory Server. Value is a localized string that is displayed in Service drop down list.
includeInternal
Tag Attribute
Set this to “true” to search for internal groups. Default is “false”.
disableRestrictedSearchScope
Tag Attribute
Set this to “true” to bypass the restricted search scope set on the organization. Default is “false”.
enforceRestrictedSearchScope
Tag Attribute
Set this to “true” to force the restricted search scope, despite how it is set on the organization. Default is “false”.
showRoles
Tag Attribute
Set this to “true” to add a filter on search to restrict search scope to the selected role. This option will only display when the type option is User.
When true, this will provide a dropdown list of available roles in the search criteria. The roles will come from the passed in context.
Default is “false”.
resourcePool
Tag Attribute
This will provide the pool of principals to search.
All access control rules will still apply.
searchProfileGroups
Tag Attribute
Set this to “true” to search only profile groups in the system.
Default is “false”.
searchDisconnectedPrincipals
Tag Attribute
Set this to “PrincipalBean.LDAP” to search only disconnected principals in Directory server.
Set this to “PrincipalBean.DB” to search only disconnected principals in the DB.
Default is “false”.
title
Tag Attribute
This will provide the title for the participant picker window.
Default is “Find Participant”.
showSearchIn
Tag Attribute
This will determine whether or not the "Search In:" field shows up in the participant picker. Default is "true" to preserve existing functionality.
helpSelectorKey
Tag Attribute
This will set the help link for the picker, if nothing is provided it will default to the service.properties value for ParticipantPickerHelp
enforceModifyPermission
Tag Attribute
This will filter the search results to only return objects that the current user has MODIFY permission on.
Procedure – Making Association available in Participant Picker
You want to include association in the Participant Picker. You will need to supply the tag attributes associationMap, defaultAssociation and associationLabel to the Participant Picker tag.
The second example in Sample Code below describes code sample of how association can be added to the Participant Picker.
Procedure – Participant Picker with Search in Context
You want to narrow down the search to different contexts. You will need to supply the tag attributes contextMap and defaultContext to the Participant Picker tag. The contexts can be Organization, Site, Product, Project, and Library.
Procedure – Search for Participants in different LDAP
You want to search for Participants in a different LDAP. You will need to supply the tag attribute serviceMap.
Configure your Windchill to support multiple LDAP servers. Each LDAP server will be identified by a name. The name of LDAP server has to be supplied as key, and a localized display label as value. When you supply the serviceMap, you will see a dropdown in the Participant Picker with label “Service”. The selected key is sent as service parameter to the Info*Engine tasks by the Participant Picker
Procedure – Search for Participants in different Directory Server
You want to search for Participants in a different Directory server. You will need to supply the tag attribute serviceMap.
Configure your Windchill to support multiple Directory servers. Each Directory server will be identified by a name. The name of Directory server has to be supplied as key, and a localized display label as value. When you supply the serviceMap, you will see a dropdown in the Participant Picker with label “Service”. The selected key is sent as service parameter to the Info*Engine tasks by the Participant Picker.
Procedure – Making Email invitation available in Participant Picker
You want to add email invitation text box to the Participant Picker. You will need to set the tag attribute emailAllowed="true".
The third example in the Sample Code section below describes code sample of how get email invitation textbox in the Participant Picker.
Procedure – Single select Participant Picker
You want to select only participant at a time. You will need to set the tag attribute select=”single”. This will render the Participant selection list as text box that can hold one value at a time.
Procedure – Restrict to single Participant type search
You want to restrict the type of Participants to be searched to one. You will need to set the tag attribute singleParticipantType="true".
Sample Code
Sample JSP that contains a Participant Picker tag
After making entry for action to launch the Participant Picker, write a JSP with the same name as in action tag (e.g. participantPickerSample.jsp).
<%@ page import="com.ptc.windchill.enterprise.picker.principal.PrincipalBean"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/components" prefix="jca"%>

<jca:participantPicker
actionClass="com.ptc.netmarkets.principal.CustomPrincipalCommands"
actionMethod="addPrincipal"
participantType="<%= PrincipalBean.GROUP %>">
>
</jca:participantPicker>
-
This will render a basic participant picker as show below.
You perform a search based on search criteria. Move desired participants to Participant List and click OK. The component invokes actionClass and actionMethod provided as attributes to the participant picker tag. You need to write actionMethod in the actionClass. Example code is given below.
package com.ptc.core.components.rendering.guicomponents;
import java.util.List;

import com.ptc.core.components.forms.FormProcessingStatus;
import com.ptc.core.components.forms.FormResult;
import com.ptc.core.components.forms.FormResultAction;
import com.ptc.netmarkets.user.PrincipalPickerHelper;
import com.ptc.netmarkets.util.beans.NmCommandBean;
import com.ptc.windchill.enterprise.picker.principal.PrincipalBean;

import wt.util.WTException;

public class CustomPrincipalCommands {
public static FormResult addPrincipal(NmCommandBean cb) throws WTException {
FormResult result = new FormResult(FormProcessingStatus.SUCCESS);
result.setNextAction(FormResultAction.REFRESH_OPENER);
String principals = cb.getTextParameter(PrincipalBean.PARAM_SELECTED_PRINCIPALS);

if (principals == null) {
result.setStatus(FormProcessingStatus.FAILURE);
return result;
}

List<String> selectedPrincipals = PrincipalPickerHelper.retrievePrincipalListFromPickerPrincipals(principals);
// Now process selectedPrincipals
return result;
}
}
You should write a static method as actionMethod. It will take only one argument i.e., NmCommandBean. The selected participants are sent to this method as text parameters. With in the component these values are stored in hidden variable. The name of the hidden variable is defined as a static String in “com.ptc.windchill.enterprise.picker.principal.PrincipalBean”. To extract selected participants use PrincipalBean.PARAM_SELECTED_PRINCIPALS. This will return "##" separated principal entries. Each entry consists of principal type and DN (Distinguished Name) separated by "#".
Adding Association
To add association in the Participant picker, you need to provide three attributes as highlighted in the following sample. The attribute associationMap takes LinkedHashMap. You supply the key, value pairs to this map. Key’s are the java String literals. When user selects an association, this key String literal is passed back to the actionMethod as text Parameter. Values are localized string displayed in the dropdown list. Component uses LinkedHashMap to retain the order in which the key value pairs are added while displaying in the dropdown list.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/components" prefix="jca"%>
<%@ page import="java.util.LinkedHashMap"%>
<%@ page import = "com.ptc.windchill.enterprise.picker.principal. PrincipalBean" %>
<%
LinkedHashMap associationMap = new LinkedHashMap();
associationMap.put("GUEST", "Guest");
associationMap.put("MEMBERS", "Members");
associationMap.put("PROJECT MANAGER", "Project Manager");
%>

<c:set var="associationMap" value="<%= associationMap %>"/>
<c:set var="participantType" value="<%= PrincipalBean.USER %>"/>
<jca:participantPicker
actionClass="com.ptc.netmarkets.principal.CustomPrincipalCommands"
actionMethod="addPrincipal"
participantType="${participantType}"
emailAllowed="true"
defaultAssociation="GUEST"
associationMap="${associationMap}"
associationLabel="Add to Role"
>
</jca:participantPicker>
The above code will render association dropdown as shown in the following figure.
In the above example, you are trying to add a role to the participant. You move the desired participants to Participants List, select a role from the association list and click OK. The actionMethod code will now look like this.
package com.ptc.core.components.rendering.guicomponents;

import java.util.ArrayList;

import com.ptc.core.components.forms.FormProcessingStatus;
import com.ptc.core.components.forms.FormResult;
import com.ptc.core.components.forms.FormResultAction;
import com.ptc.netmarkets.role.NmRoleHelper;
import com.ptc.netmarkets.user.PrincipalPickerHelper;
import com.ptc.netmarkets.util.beans.NmCommandBean;
import com.ptc.windchill.enterprise.picker.principal.PrincipalBean;

import wt.util.WTException;

public class CustomPrincipalCommands {
public static FormResult addPrincipal(NmCommandBean cb) throws WTException {
FormResult result = new FormResult(FormProcessingStatus.SUCCESS);
result.setNextAction(FormResultAction.REFRESH_OPENER);
String principals = cb.getTextParameter(PrincipalBean.PARAM_SELECTED_PRINCIPALS);
if (principals == null) {
result.setStatus(FormProcessingStatus.FAILURE);
return result;
}

ArrayList<String> selectedPrincipals = (ArrayList) PrincipalPickerHelper
.retrievePrincipalListFromPickerPrincipals(principals);
String role = cb.getTextParameter(PrincipalBean.PARAM_ASSOCIATION);
NmRoleHelper.service.addUsersToRole(cb, role, selectedPrincipals);
return result;
}
}
You can extract the selected association from text parameter as highlighted in the above code.
Adding Email subscription
The code to get email subscription will look like this.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/components" prefix="jca"%>
<%@ page import="java.util.LinkedHashMap"%>
<%@ page import = "com.ptc.windchill.enterprise.picker.principal. PrincipalBean" %>
<%
LinkedHashMap associationMap = new LinkedHashMap();
associationMap.put("GUEST", "Guest");
associationMap.put("MEMBERS", "Members");
associationMap.put("PROJECT MANAGER", "Project Manager");
%>

<c:set var="associationMap" value="<%= associationMap %>"/>
<c:set var="participantType" value="<%= PrincipalBean.USER %>"/>
<jca:participantPicker
actionClass="com.ptc.netmarkets.principal.CustomPrincipalCommands"
actionMethod="addPrincipal"
participantType="${participantType}"
emailAllowed="true"
defaultAssociation="GUEST"
associationMap="${associationMap}"
associationLabel="Add to Role"
>
</jca:participantPicker>
The above code will render the email subscription field as shown in the following figure.
Validation is done for the values entered for Email Invitation input box located at Recent Products > Teams > Add Participants to team > Find Participant:
Click Add — E-mail format is validated. Error message is seen if the e-mail format is incorrect. If the e-mail format is correct, user is added successfully to the Participant List panel on the right.
Click Ok — E-mail is validated for user record entry in the Atlas. If the e-mail exists in Atlas, the user is added to particular role in the Team. If e-mail does not exist, error message is seen at the banner level. Message is displayed when:
All the e-mails are successfully added to the team.
If none of the e-mails are added.
If only few are added and others are not added to the team.
Sample JSP to launch the Picker and send back the picker values to a Textbox.
You can use Property Picker tag to render a Textbox and Find button to launch Participant Picker. The Find button has to declared in actions.xml as described in the above sections. The Property Picker by default provides a JavaScript call back function that will be invoked by the picker to send back the picked values from any picker. Property Picker also has an ability to define custom JavaScript function that can be invoked by pickers. For example:
<p:propertyPicker label="${label}" field="${textbox}" action="participantPickerSample2" type="participantpicker">
<p:populate from="${displayAttribute}" to="${displayFieldId}"/>
<p:populate from="oid" to="${id}" />
<p:pickerParam name="pickerId" value="${id}" />
<p:pickerParam name="objectType" value="wt.org.WTGroup"/>
<p:pickerParam name="componentId" value="${componentId}"/>
<p:pickerParam name="pickedDataFetcher" value="${pickedDataFetcher}" />
<p:pickerParam name="pickerCallback" value="${pickerCallBack}" />
<p:pickerParam name="containerRef" value="${containerRef}"/>
<p:pickerParam name="baseWhereClause" value="${baseWhereClause}" />
<p:pickerParam name="pickerTitle" value="${pickerTitle}"/>
<p:pickerParam name="multiSelect" value="${multiSelect}"/>
</p:propertyPicker>
Coming back to the Participant Picker, one can get the pickerCallback JavaScript function name as request parameter, when Participant Picker is launched from Property Picker.
<c:set var="pickerCallback" value="<%=request.getParameter(\"pickerCallback\")%>"/>
<jca:participantPicker
actionClass=""
actionMethod="JavaScript:${pickerCallback}()"
participantType="<%= PrincipalBean.GROUP %>"

>
</jca:participantPicker>
We pass a blank string to the actionClass attribute of Participant Picker. The JavaScript call back function name that we got from the request parameter is appended to the string “JavaScript:” and passed as value to actionMethod. This string “JavaScript:” is used internally in the picker to identify, as PickerCallBack mechanism is needed. When user selects the desired participants and clicks OK, the values are sent back to the JavaScript function as JSON object (as defined in Property Picker).
Examples of Usage in Windchill Code
All locations are within \<WT_HOME>\codebase\netmarkets\jsp:
\roleAccess\profile_addMembers.jsp
\subscription\subscrPrincipalPicker.jsp
\team\addUsersToRole.jsp
\object\findParticipant.jsp
\work\addUsersToRole.jsp (resourcePool)
\principal\find_disconnected.jsp (searchDisconnectedPrincipals)
\group\addProfileToList.jsp (enforceModifyPermission & searchProfileGroups)
\user\addToAdmin.jsp (enforceRestrictedSearchScope)
\agreements\findParticipant.jsp (disableRestrictedSearchScope)
這是否有幫助?