{"id":76781,"date":"2021-01-18T15:32:00","date_gmt":"2021-01-18T06:32:00","guid":{"rendered":"https:\/\/support.questetra.com\/developer-blog\/synchronize-users-chapter3\/"},"modified":"2026-04-14T15:51:31","modified_gmt":"2026-04-14T06:51:31","slug":"synchronize-users-chapter3","status":"publish","type":"post","link":"https:\/\/support.questetra.com\/en\/developer-blog\/synchronize-users-chapter3\/","title":{"rendered":"Synchronizing User Information in QBPMS with Local Data (Organizational Affiliation Chapter)"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"58\" data-attachment-id=\"113212\" data-permalink=\"https:\/\/support.questetra.com\/en\/developer-blog\/message-start-event-http-browser\/attachment\/professional-banner-new-en\/\" data-orig-file=\"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2018\/12\/professional-banner-new-en.png?fit=1200%2C68&amp;ssl=1\" data-orig-size=\"1200,68\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"professional-banner-new-en\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2018\/12\/professional-banner-new-en.png?fit=1024%2C58&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2018\/12\/professional-banner-new-en-1024x58.png?resize=1024%2C58&#038;ssl=1\" alt=\"\" class=\"wp-image-113212\" srcset=\"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2018\/12\/professional-banner-new-en.png?resize=1024%2C58&amp;ssl=1 1024w, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2018\/12\/professional-banner-new-en.png?resize=600%2C34&amp;ssl=1 600w, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2018\/12\/professional-banner-new-en.png?resize=768%2C44&amp;ssl=1 768w, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2018\/12\/professional-banner-new-en.png?w=1200&amp;ssl=1 1200w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/support.questetra.com\/en\/developer-blog\/synchronize-users-chapter2\/\"><i class=\"fas fa-arrow-left\"><\/i> Previous: Synchronizing User Information with Local Data (User Information Chapter)<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/support.questetra.com\/en\/developer-blog\/synchronize-users-chapter1\/\">Preparatory Chapter<\/a><\/li><li><a href=\"https:\/\/support.questetra.com\/en\/developer-blog\/synchronize-users-chapter2\/\">User Information Chapter<\/a><\/li><li><strong>Organizational Affiliation Chapter<\/strong>\n<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In the &#8220;User Information Chapter&#8221;, we manipulated User information which was only enough to log in to an account, using the System Setting API of Questetra BPM Suite. In this post, I will introduce an example program for manipulating the information of the User&#8217;s affiliation to Organizations registered in Questetra BPM Suite. As with User information, prepare a TSV file that indicates which Organization each User belongs to, and synchronizes the registered User information on Questetra BPM Suite accordingly. In this example, the following data is assumed in a TSV file.<\/p>\n\n\n<div class=\"su-note\"  style=\"border-color:#bcd3e5;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\"><div class=\"su-note-inner su-u-clearfix su-u-trim\" style=\"background-color:#d6edff;border-color:#ffffff;color:#333333;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\">\n<table style=\"border: none !important\">\n<tbody>\n<tr>\n<td style=\"width: 17em;border: none !important;padding: 0\">questetra@gmail.com<\/td>\n<td style=\"border: none !important;padding: 0\">00 Questetra Inc.!<\/td>\n<\/tr>\n<tr>\n<td style=\"border: none !important;padding: 0\">questetra+Galapagos@gmail.com<\/td>\n<td style=\"border: none !important;padding: 0\">20 Sales Department!<\/td>\n<\/tr>\n<tr>\n<td style=\"border: none !important;padding: 0\">questetra+Oahu@gmail.com<\/td>\n<td style=\"border: none !important;padding: 0\">20 Sales Department<\/td>\n<\/tr>\n<tr>\n<td style=\"border: none !important;padding: 0\">questetra+Sumatera@gmail.com<\/td>\n<td style=\"border: none !important;padding: 0\">10 Management Department!<\/td>\n<\/tr>\n<tr>\n<td style=\"border: none !important;padding: 0\">questetra+Canarias@gmail.com<\/td>\n<td style=\"border: none !important;padding: 0\">10 Management Department 30 Development Department<\/td>\n<\/tr>\n<tr>\n<td style=\"border: none !important;padding: 0\">&#8230;<\/td>\n<td style=\"border: none !important;padding: 0\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">First, the user&#8217;s registered email address, and then the organization to which the user belongs are listed in tab-separated format. In the above example, it shows that the user with the email address &#8220;questetra+Canarias@gmail.com&#8221; belongs to both &#8220;10 Management Department&#8221; and &#8220;30 Development Department&#8221;. In addition, as you can see with &#8220;20 Sales Department!&#8221; for questetra+Galapagos@gmail.com, an &#8220;!&#8221; attached at the end of an Organization name indicates that the user is the leader of the Organization. The goal of this article is to match the contents of a TSV file in such a format with the user information registered in Questetra.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As with user information, you need a class for comparing the TSV file with the registered information on Questetra BPM Suite to identify the difference, and a class for manipulating the information of the User&#8217;s affiliation to Organizations on Questetra BPM Suite using its API. Let&#8217;s implement the former as <em>SyncMembershipWithTSV<\/em> class and the latter as the <em>MembershipDataManager<\/em> class.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>MembershipDataManager<\/em> class<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To manipulate the information of User&#8217;s affiliation to Organizations, we will use the <em>MembershipApi<\/em> class (a class that manipulates information of User&#8217;s affiliation to Organizations) and <em>QgroupApi<\/em> class (a class that manipulates Organization information) in the <em>com.questetra.bpms.client.swagger<\/em>, the library of Questetra. Also, we will use the <em>UserDataManager<\/em> class which we implemented in the &#8220;User Information Chapter&#8221; to check the user ID.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Authentication (Constructor)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>import com.questetra.bpms.client.swagger.model.*;\nimport com.questetra.bpms.client.swagger.ApiClient;\nimport com.questetra.bpms.client.swagger.ApiException;\nimport com.questetra.bpms.client.swagger.Configuration;\nimport com.questetra.bpms.client.swagger.auth.*;\nimport com.questetra.bpms.client.swagger.api.MembershipApi;\nimport com.questetra.bpms.client.swagger.api.QgroupApi;\n\nimport java.util.HashMap;\n\n\n\/**\n * List and manipulate the affiliation of Users.\n *\/\nclass MembershipDataManager {\n    private final MembershipApi apiInstance;\n    private final HashMap&lt;String, QuserWithPrimaryQgroup&gt; userMap = new HashMap&lt;&gt;();\n    private final HashMap&lt;String, Qgroup&gt; groupMap = new HashMap&lt;&gt;();\n\n    public MembershipDataManager() {\n        ApiClient defaultClient = Configuration.getDefaultApiClient();\n        \/\/ Set URL\n        defaultClient.setBasePath(\"https:\/\/example.questetra.net\/\");\n\n        \/\/ Basic Authentication\n        HttpBasicAuth basic \n                = (HttpBasicAuth) defaultClient.getAuthentication(\"basic\");\n        basic.setUsername(\"{EMAIL ADDRESS}\");\n        basic.setPassword(\"{PASSWORD for Basic Authentication}\");\n\n        this.apiInstance = new MembershipApi();\n    }\n\n...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The codes for Basic authentication by constructor are the same as the <em>UserDataManager<\/em> class. Note that we are importing <em>MembershipApi<\/em> and <em>QgroupApi<\/em> since we will deal with Organizational information this time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also, as we will implement a method for acquiring user objects and organization objects from Questetra BPM Suite in the next section, make a declaration of member variables, <em>userMap<\/em> and <em>groupMap<\/em> to be used there. These are HashMap objects for storing information on users and organizations once searched.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Methods for searching Users\/Organizations<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>     ...\n\n    \/**\n     * Search for Organizations (Qgroup) by Organization name\n     * Throw ApiException if the Organization specified by the name doesn't exist on Questetra BPM Suite\n     * @param name: Organization name\n     * @return Qgroup: Organization object that has found by search\n     *\/\n    private Qgroup findGroup(String name) throws ApiException {\n        \/\/ Organizations that have already been found are added to HashMap\n        if (this.groupMap.containsKey(name)) {\n            return this.groupMap.get(name);\n        }\n        QgroupApi groupApiInstance = new QgroupApi();\n        Qgroup result = groupApiInstance.findQgroup(null, name).getQgroup();\n        \/\/ HashMap\u306b\u8ffd\u52a0\n        this.groupMap.put(name, result);\n        return result;\n    }\n\n    \/**\n     * Search for a User (QuserWithPrimaryQgroup) by email address.\n     * Throw ApiException if the User with specified email address doesn't exist on Questetra BPM Suite\n     * @param email: Email address\n     * @return QuserWithPrimaryQgroup: Found User object\n     *\/\n    private QuserWithPrimaryQgroup findUser(String email) throws ApiException {\n        \/\/ Users that have already been found are added to HashMap\n        if (this.userMap.containsKey(email)) {\n            return this.userMap.get(email);\n        }\n        UserDataManager userManager = new UserDataManager();\n        QuserWithPrimaryQgroup result = userManager.find(null, email).getQuser();\n        \/\/ Add to HashMap\n        this.userMap.put(email, result);\n        return result;\n    }\n\n    ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To use the methods of MembershipApi class, specification of Users or Organizations must be done with IDs. Therefore, you need to implement a method for searching User objects by email address written in the TSV file, and a method for searching Organizations by Organization names beforehand. By invoking <em>getId<\/em>, an instance method, from these objects, User Id\/Organization ID can be retrieved.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the <em>findUser<\/em> method, the <em>UserDataManager.find<\/em> which we have implemented in &#8220;User Information Chapter&#8221; is used. The <em>findUser<\/em> method searches for User objects registered on Questetra BPM Suite by the email addresses passed to the argument and returns. Also, save the user object once retrieved in <em>userMap<\/em>, the member variable, of <em>HashMap<\/em> class. By using HashMap, you can retrieve the user object from here at the second and subsequent searches.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the <em>findGroup<\/em> method, <em>QgroupApi<\/em> class which has been imported from API library is used. The <em>QgroupApi<\/em> class is a class for manipulating Organization information, and the <em>QgroupApi.findQgroup<\/em> method is a method that searches Organization objects. The arguments are <em>id<\/em>: an organization ID and <em>name<\/em>: an organization name, and only one of them is sufficient. In this example, pass <em>null<\/em> to the argument <em>id<\/em> since Organization ID is unknown. Save the organization object in <em>HashMap<\/em> class as with the user object.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Method to list the Users affiliation to Organizations<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>    ...\n\n    \/**\n     * Listing the User's affiliation to organization.\n     * @param email: Email address of the User.\n     * @return MembershipList: List of affiliated Organization.\n     *\/\n    public MembershipList findMemberships(String email) throws ApiException {\n        \/\/ Search User ID of the specified email address\n        Long userId = this.findUser(email).getId();\n        MembershipList result = this.apiInstance.listMembershipsByQuser(userId);\n        return result;\n    }\n\n    ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is a method that returns the list of Organizations to which the specified user belongs. We will implement this to compare Organizational affiliations in TSV files and registration information on Questetra BPM Suite.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the <em>MembershipApi<\/em> class, the <em>listMembershipsByQuser<\/em> method which searches the list of affiliated organizations by user IDs is implemented. The argument of the <em>MembershipApi.listMembershipsByQuser<\/em> method is <em>id<\/em>: user ID. User IDs are retrieved by searching for User objects using the aforementioned <em>findUser<\/em> method.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Method to add organizations to information of User&#8217;s affiliation to Organizations<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>    ...\n\n    \/**\n     * Adding organization to information of User's affiliation to Organizations\n     * @param email: Email address of User.\n     * @param group: Organization name\n     * @param isLeader: true for a leader, false for a staff\n     * @return MembershipWrapper\n     *\/\n    public MembershipWrapper add(String email, String group,\n                                 boolean isLeader) throws ApiException {\n        \/\/ Search User ID by the specified email address\n        Long userId = this.findUser(email).getId();\n        \/\/ Search Organization ID by the specified Organization name\n        Long groupId = this.findGroup(group).getId();\n\n        MembershipWrapper result;\n\n        if (isLeader) {\n            result = this.apiInstance.addMembership(userId, groupId, \"_leader\");\n            System.out.printf(\"Add: %s \/ %s, %s\\n\", email, group, \"leader\");\n        } else {\n            result = this.apiInstance.addMembership(userId, groupId, null);\n            System.out.printf(\"Add: %s \/ %s, %s\\n\", email, group, \"staff\");\n        }\n\n        return result;\n    }\n\n    ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is a method for adding organization to information of User&#8217;s affiliation to Organizations. When <em>email<\/em>: email address of the user, <em>groups<\/em>: organization name, and <em>isLeader<\/em>: a leader or not, are passed to arguments, Organizations will be added to affiliation of the target User. The argument, <em>isLeader<\/em>, is a boolean and if true indicates that the user is the leader of the organization.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <em>addMembership<\/em> method of <em>MembershipApi<\/em> class is used for the addition of organizations to User&#8217;s affiliation. There are three arguments which are, <em>quserId<\/em>: User ID, <em>qgroupId<\/em>: Organization ID, and <em>role<\/em>: status in the organization. Also, to retrieve the User ID and Organization ID we use the methods <em>findUser<\/em> and <em>findGroup<\/em>, which we implemented earlier.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Method to delete Organizations from information of User&#8217;s affiliation to Organizations<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>    ...\n\n    \/**\n     * Deleting organizations from information of User's affiliation to Organizations\n     * @param email: Email address of User.\n     * @param group: Organization name.\n     *\/\n    public void delete(String email, String group) throws ApiException {\n        \/\/ Search User ID by the specified email address\n        Long userId = this.findUser(email).getId();\n        \/\/ Search Organization ID by the specified Organization name\n        Long groupId = this.findGroup(group).getId();\n\n        this.apiInstance.deleteMembership(userId, groupId);\n        System.out.printf(\"Deleted: %s \/ %s\\n\", email, group);\n    }\n\n    ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is a method for deleting Organizations from information of User&#8217;s affiliation to Organizations. When the <em>email<\/em>: user&#8217;s email address and <em>group<\/em>: Organization name, are passed to the argument, those Organizations will be deleted from the affiliation of the user.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <em>deleteMembership<\/em> method of <em>MembershipApi<\/em> class is used for the deletion of organization from information of User&#8217;s affiliation to Organizations. There are two arguments which are, <em>quserId<\/em>: User ID, and <em>qgroupId<\/em>: Organization ID. As with the <em>addMembreship<\/em> method, User ID and Organization ID are retrieved using <em>findUser<\/em> and <em>findGroup<\/em> methods.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Method for updating information of User&#8217;s affiliation to Organizations<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>    ...\n\n    \/**\n     * Updating information of User's affiliation to Organizations\n     * @param email: Email address of User.\n     * @param group: Organizational name\n     * @param isLeader: true for a leader, false for a staff\n     * @return MembershipWrapper\n     *\/\n    public MembershipWrapper update(String email, String group,\n                                    boolean isLeader) throws ApiException {\n        \/\/ Search User ID by the specified email address\n        Long userId = this.findUser(email).getId();\n        \/\/ Search Organization ID by the specified Organization name\n        Long groupId = this.findGroup(group).getId();\n\n        MembershipWrapper result;\n\n        \/\/ Change to Leader\n        if (isLeader) {\n            result = this.apiInstance.updateMembership(userId, groupId, \"_leader\");\n            System.out.printf(\"Changed the role: %s \/ %s, \u2192 %s\\n\",\n                              email, group, \"leader\");\n        }\n        \/\/ Change to Staff\n        else {\n            result = this.apiInstance.updateMembership(userId, groupId, null);\n            System.out.printf(\"Changed the role: %s \/ %s, \u2192 %s\\n\",\n                              email, group, \"staff\");\n        }\n\n        return result;\n    }\n\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is a method for updating the status of Users in the Organization. When the <em>email<\/em>: user&#8217;s email address and <em>group<\/em>: Organization name and <em>isLeader<\/em>: a leader or not, are passed to the argument, the status of the target User will be updated. As with the <en> add method, the <em>isLeader<\/em> indicates the User is a leader of the Organization if it is true.<\/en><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <em>updateMembership<\/em> method of <em>MembershipApi<\/em> class is used for the updating of information of User&#8217;s affiliation to Organizations. There are three arguments which are <em>quserId<\/em>: User ID, <em>qgroupId<\/em>: Organization ID, and <em>role<\/em>: status in the organization. The way of usage is almost the same as the <em>addMembership<\/em> method. You can use the <em>MembershipApi.updateMembership<\/em> method, for example, to change a user who was &#8220;Staff&#8221; to a &#8220;Leader&#8221; in an Organization.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>SyncMembershipWithTSV<\/em> class<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I am going to describe processing for matching the difference in comparison of TSV file with registered information on Questetra BPM Suite. It will realize synchronization of information of User&#8217;s affiliation to Organizations between a local data and Questetra BPM Suite, by reading the information from a TSV file and Questetra BPM Suite respectively, determining which data to update, and executing the update via Web API.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><em>main<\/em> method<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>import com.questetra.bpms.client.swagger.ApiException;\nimport com.questetra.bpms.client.swagger.model.Membership;\n\nimport java.io.IOException;\nimport java.util.*;\n\nimport static java.util.stream.Collectors.toSet;\n\nclass SyncMembershipWithTSV {\n    public static void main(String&#091;] args) throws IOException, ApiException {\n        \/\/ Reading TSV data\n        List&lt;String&#091;]&gt; data = TSVReader.readLines(\"{PATH OF TSV FILE}\");\n        \/\/ Processing one line by one.\n        for (String&#091;] user : data) {\n            sync(user);\n        }\n    }\n    ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The basic operation is &#8220;Read TSV file -&gt; Synchronize one line (one User) at a time&#8221;. <em>TSVReader<\/em> class is used for reading the TSV file as with the &#8220;User Information Chapter&#8221;. The imported data forms a List of String [], such as [Email Address, Organization 0, Organization 1, &#8230;]. Synchronization processing for one user is collected in the <em>sync<\/em> method.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><em>sync (String[] user)<\/em> method<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">With this method, synchronization of organizational affiliation information for one User is processed. The argument <em>user<\/em> is one line of data of the TSV file that has been read by <em>TSVReader.readLines ()<\/em>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Retrieving information of affiliation to Organizations of each User on Questetra BPM Suite<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>    ...\n\n    \/**\n     * Synchronizing the information of affiliation to Organization of one User\n     * @param user: One line of data read from TSV\n     * @throws ApiException\n     *\/\n    private static void sync(String&#091;] user) throws ApiException {\n        MembershipDataManager manager = new MembershipDataManager();\n\n        \/\/ Retrieve the organization to which the user currently belongs on Questetra BPM Suite\n        Set&lt;Membership&gt; currentMembershipSet = new HashSet&lt;&gt;(\n                            manager.findMemberships(user&#091;0]).getMemberships());\n        \/\/ Create a Set of \"organizations to which the user belongs as a leader\"\n        Set&lt;Membership&gt; currentLeaderSet =\n                            currentMembershipSet.stream()\n                                      .filter(m -&gt; Objects.equals(\n                                              m.getRole(),\"_leader\"))\n                                      .collect(toSet());\n\n        Set&lt;String&gt; currentGroupSet = currentMembershipSet.stream()\n                                                      .map(Membership::getQgroupName)\n                                                      .collect(toSet());\n        Set&lt;String&gt; currentLeaderGroupSet = currentLeaderSet.stream()\n                                                      .map(Membership::getQgroupName)\n                                                      .collect(toSet());\n\n    ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">First, use the <em>MembershipDataManager.findMemberships<\/em> method to find out which organization the user belongs to on Questetra BPM Suite. Information on the organization to which the user currently belongs on Questetra BPM Suite can be obtained from a set of <em>Membership<\/em> objects. Create <em>Set&lt;String&gt;<\/em> type <em>currentGroupSet<\/em> by retrieving Organization names from <em>Membership<\/em> object, since where to change will be determined by comparing between <em>Set&lt;String&gt;<\/em> types later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We will also prepare a set of organizations on Questetra BPM Suite to which the User belongs as a leader, to check if there is a change in the status of the User in an Organization. Create a <em>CurrentLeaderGroupSet<\/em> of <em>Set&lt;String&gt;<\/em> type by filtering the retrieved set of <em>Membership<\/em> object with &#8220;extract only organizations to which the User belongs as a leader&#8221; using Stream API, and retrieve Organization names from the remaining <em>Membership<\/em> object.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Retrieve information of Organizations to which each User belongs from TSV file<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>    ...\n\n        \/\/ Retrieve information of Organizations to which a User belongs from TSV file\n        Set&lt;String&gt; nextMembershipSet = new HashSet&lt;&gt;(Arrays.asList(user)\n                                                            .subList(1, user.length));\n        \/\/ Create a Set of \"Organization to which the User belongs as a leader\"\n        Set&lt;String&gt; nextLeaderGroupSet =\n                nextMembershipSet.stream()\n                                 .filter(m -&gt; m.endsWith(\"!\"))\n                                 .map(m -&gt; m.substring(0, m.length()-1))\n                                 .collect(toSet());\n        Set&lt;String&gt; nextGroupSet = nextMembershipSet.stream()\n                                    .map(m -&gt; {\n                                        if (m.endsWith(\"!\"))\n                                            return m.substring(0, m.length()-1);\n                                        else return m;}).collect(toSet());\n\n        sync(user&#091;0], currentGroupSet, nextGroupSet,\n                      currentLeaderGroupSet, nextLeaderGroupSet);\n    }\n\n    ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In the same way, organizational affiliation information written in the TSV file is also collected. In this example, if an<strong> &#8220;!&#8221; is appended at the end of the Organization name<\/strong> in the TSV file, the user is considered to be a leader of that Organization.<\/p>\n\n\n<div class=\"su-note\"  style=\"border-color:#dbdbdb;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\"><div class=\"su-note-inner su-u-clearfix su-u-trim\" style=\"background-color:#f5f5f5;border-color:#ffffff;color:#333333;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\">\nIf an email address of a user or an Organization name which does not exist on Questetra BPM Suite is written in the TSV file, an ApiException exception will be thrown from the <em>findUser<\/em> method or <em>findGroup<\/em> method.<br \/>\n<\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, pass the created organization set to the <em>sync<\/em> (String email, Set &lt;String&gt; currentGroupSet, &#8230;) method to manipulate the registered information via the Web API.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><em>sync<\/em> (String email, Set &lt;String&gt; currentGroupSet, &#8230;) method<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">With this method, the data to be changed in the organizational affiliation information are specified, and the information actually registered on Questetra BPM Suite through Web API is changed.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Finding &#8220;Organizations to add\/delete affiliation&#8221;<\/h4>\n\n\n\n<pre><code class=\"java\">    ...\n\n    \/**\n     * Comparing registered information of User's affiliation to Organizations on Questetra BPM Suite and on TSV,\n     *  manipulate the registered information via Web API.\n     * @param email: Email address of the User\n     * @param currentGroupSet: Set of Organizations which the User currently belongs to\n     *                         of the information registered on Questetra BPM Suite\n     * @param nextGroupSet: Set of Organizations of User's affiliation instructed in TSV\n     * @param currentLeaderGroupSet Set of Organizations to which the User is affiliated as a \n     *                              leader, in the information currently registered on Questetra BPM Suite.\n     * @param nextLeaderGroupSet: Set of Organizations of User's affiliation as a leader instructed in TSV\n     * @throws ApiException\n     *\/\n    private static void sync(String email,\n                             Set&lt;String&gt; currentGroupSet,\n                             Set&lt;String&gt; nextGroupSet,\n                             Set&lt;String&gt; currentLeaderGroupSet,\n                             Set&lt;String&gt; nextLeaderGroupSet) throws ApiException {\n        MembershipDataManager manager = new MembershipDataManager();\n\n        \/\/ Create Sets which are \"Organization names that exist only on TSV (to be added)\" and \n        \/\/  \"Organization names that exist only on Questetra BPM Suite (to be deleted)\n\n        \/\/ Set of Organization names to be deleted\n        Set&lt;String&gt; willDelete = subtract(currentGroupSet, nextGroupSet);\n        \/\/ Set of Organization names to be added\n        Set&lt;String&gt; willAdd = subtract(nextGroupSet, currentGroupSet);\n\n        for (String group : willDelete) { \/\/ Delete from affiliation\n            manager.delete(email, group);\n        }\n\n        for (String group : willAdd) { \/\/ Add to affiliation\n            if (nextLeaderGroupSet.contains(group))\n                 manager.add(email, group, true);\n            else manager.add(email, group, false);\n        }\n  \n    ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">As with the way we found the difference in User information in &#8220;User Information Chapter&#8221;, we will also use Set operations to find out this time. First, we will make it check whether there is a change in affiliation information, and determine the Organizations to add and delete from the User&#8217;s affiliation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, I will implement and use the subtract method that will return the difference between sets when passing two sets as arguments. Among the information of affiliation to Organization currently registered on Questetra BPM Suite, a set of organizations that do not overlap with the contents of the TSV file is stored in <em>willDelete<\/em> of the Set &lt;String&gt; type and is targeted for deletion. Similarly, create <em>willAdd<\/em>, a set of organizations that are only included in the TSV file and must be added to affiliation to organizations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, update the information on Questetra BPM Suite for each organization stored in <em>willDelete<\/em>, <em>willAdd<\/em> using the <em>delete<\/em>, <em>add<\/em> method of <em>MembershipDataManager<\/em> class. With this, the information of User&#8217;s affiliation to Organizations on Questetra BPM Suite and onTSV will be matched.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Finding out &#8220;Organizations in which status of the User has changed&#8221;<\/h4>\n\n\n\n<pre><code class=\"java\">    ...\n\n        \/\/ Finding Organizations to which the User is affiliated as a leader on Questetra but not on TSV,\n        \/\/ remain Organizations to which continue to affiliate.\n        \/\/ \"Was a leader before, but is not now\" = \"Changed from leader to staff\"\n        \/\/                                          or \"Got out of members of the Organization (willDelete)\"\n        Set&lt;String&gt; wasLeader = subtract(currentLeaderGroupSet, nextLeaderGroupSet);\n        Set&lt;String&gt; toStaff = subtract(wasLeader, willDelete);\n\n        \/\/ Finding Organizations to which the User is affiliated as a leader on TSV but not on Questetra,\n        \/\/ remain Organizations to which continue to affiliate.\n        \/\/ \"Become a new leader\" = \"Changed from staff to leader\"\n        \/\/                          or \"Newly added to the organization as a leader (willAdd)\"\n        Set&lt;String&gt; willLeader = subtract(nextLeaderGroupSet, currentLeaderGroupSet);\n        Set&lt;String&gt; toLeader = subtract(willLeader, willAdd);\n\n        for (String group : toStaff) { \/\/ Changed to a staff\n            manager.update(email, group, false);\n        }\n\n        for (String group : toLeader) { \/\/ Changed to a leader\n            manager.update(email, group, true);\n        }\n    }\n\n    ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next, check if there is a case where &#8220;a User continues to belong to the same Organization but his\/her status is changed&#8221;. Organizations to which the User&#8217;s affiliation to be changed in the synchronization has been retrieved as <em>willDelete<\/em> and <em>willAdd<\/em> in the previous section. Find out whether there is an Organization which is not included in those sets and the user&#8217;s status is changed in it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Again, the organization that has changed in the User&#8217;s status information can be retrieved by taking the difference between two sets, which are currentLeaderGroupSet, the information on Questetra BPM Suite, and the nextLeaderGroupSet, the information on the TSV file. However, when &#8220;an Organization name to which the User is affiliated as a leader disappears&#8221;, for example, there are possible causes, either &#8220;the User&#8217;s status has been changed from a leader to a staff&#8221; or &#8220;no longer being affiliated to the Organization.&#8221; In this case, it is possible to narrow down to the former by finding a difference between <em>willDelete<\/em> which is &#8220;a set of Organizations names to which the User is no longer affiliated&#8221;. This can be applied when finding a set of Organizations in which the User&#8217;s status is changed from staff to leader.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When the organization set toStaff to be changed to the staff and the organization set toLeader to be changed to the leader are requested, update the registered information on Questetra BPM Suite using the <em>update<\/em> method of <em>MembershipDataManager<\/em> class. With this, the status information of the User in affiliated Organizations will be synchronized.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><em>subtract<\/em> method<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>    \/**\n     * Returns the difference between two sets (set1 - set2)\n     * @param: set1 Minuend set\n     * @param: set2 Subtrahend set\n     * @param: &lt;T&gt;\n     * @return: Difference set\n     *\/\n    private static &lt;T&gt; Set&lt;T&gt; subtract(Set&lt;T&gt; set1, Set&lt;T&gt; set2) {\n        Set&lt;T&gt; subtraction = new HashSet&lt;&gt;(set1);\n        subtraction.removeAll(set2);\n        return subtraction;\n    }<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is a method used for set operations. It returns the difference set between given two sets.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Together with &#8220;User Information Chapter&#8221;, now you are able to synchronize basic User information on Questetra BPM Suite with an external file. In the User detail page it corresponds to the part enclosed in the screenshot below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"821\" height=\"577\" data-attachment-id=\"76782\" data-permalink=\"https:\/\/support.questetra.com\/en\/bpmn-icons\/onedrive-file-upload\/attachment\/screen-shot-2019-04-17-at-17-59-20-en\/\" data-orig-file=\"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/05\/Screen-Shot-2019-04-17-at-17.59.20-en.png?fit=821%2C577&amp;ssl=1\" data-orig-size=\"821,577\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Screen-Shot-2019-04-17-at-17.59.20-en\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/05\/Screen-Shot-2019-04-17-at-17.59.20-en.png?fit=821%2C577&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/05\/Screen-Shot-2019-04-17-at-17.59.20-en.png?resize=821%2C577&#038;ssl=1\" alt=\"\" class=\"wp-image-76782\" srcset=\"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/05\/Screen-Shot-2019-04-17-at-17.59.20-en.png?w=821&amp;ssl=1 821w, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/05\/Screen-Shot-2019-04-17-at-17.59.20-en.png?resize=448%2C315&amp;ssl=1 448w, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/05\/Screen-Shot-2019-04-17-at-17.59.20-en.png?resize=768%2C540&amp;ssl=1 768w\" sizes=\"auto, (max-width: 821px) 100vw, 821px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This is the end of the series of articles regarding the manipulation of User information using Web API. Questetra BPM Suite provides various API endpoints other than the one introduced here. The documentation for <em>com.questetra.bpms.client.swagger<\/em> is available at the following link, so please refer to it.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/Questetra\/qbpms-client-swagger\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub &#8211; Questetra\/qbpms-client-swagger: Questetra BPM Suite API Client Library for Java<\/a><\/li><\/ul>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Appendix: The entire body of codes that used<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">SyncMembershipWithTSV.java<\/h3>\n\n\n\n<pre><code class=\"java\">import com.questetra.bpms.client.swagger.ApiException;\nimport com.questetra.bpms.client.swagger.model.Membership;\n\nimport java.io.IOException;\nimport java.util.*;\n\nimport static java.util.stream.Collectors.toSet;\n\nclass Reading TSV data {\n    public static void main(String[] args) throws IOException, ApiException {\n        \/\/ Read TSV data\n        List&lt;String[]&gt; data = TSVReader.readLines(\"{PATH OF TSV FILE}\");\n        \/\/ Processing one line by one.\n        for (String[] user : data) {\n            sync(user);\n        }\n    }\n\n\n    \/**\n     * Synchronizing the information of affiliation to Organization of one User\n     * @param user: One line of data read from TSV\n     * @throws ApiException\n     *\/\n    private static void sync(String[] user) throws ApiException {\n        MembershipDataManager manager = new MembershipDataManager();\n\n        \/\/ Retrieve the organization to which the user currently belongs on Questetra BPM Suite\n        Set&lt;Membership&gt; currentMembershipSet = new HashSet&lt;&gt;(\n                            manager.findMemberships(user[0]).getMemberships());\n        \/\/ Create a Set of \"organizations to which the user belongs as a leader\"\n        Set&lt;Membership&gt; currentLeaderSet =\n                            currentMembershipSet.stream()\n                                      .filter(m -&gt; Objects.equals(\n                                              m.getRole(),\"_leader\"))\n                                      .collect(toSet());\n\n        Set&lt;String&gt; currentGroupSet = currentMembershipSet.stream()\n                                                      .map(Membership::getQgroupName)\n                                                      .collect(toSet());\n        Set&lt;String&gt; currentLeaderGroupSet = currentLeaderSet.stream()\n                                                      .map(Membership::getQgroupName)\n                                                      .collect(toSet());\n\n        \/\/ Retrieve information of Organizations to which a User belongs from TSV file\n        Set&lt;String&gt; nextMembershipSet = new HashSet&lt;&gt;(Arrays.asList(user)\n                                                            .subList(1, user.length));\n        \/\/ Create a Set of \"Organization to which the User belongs as a leader\"\n        Set&lt;String&gt; nextLeaderGroupSet =\n                nextMembershipSet.stream()\n                                 .filter(m -&gt; m.endsWith(\"!\"))\n                                 .map(m -&gt; m.substring(0, m.length()-1))\n                                 .collect(toSet());\n        Set&lt;String&gt; nextGroupSet = nextMembershipSet.stream()\n                                    .map(m -&gt; {\n                                        if (m.endsWith(\"!\"))\n                                            return m.substring(0, m.length()-1);\n                                        else return m;}).collect(toSet());\n\n        sync(user[0], currentGroupSet, nextGroupSet,\n                      currentLeaderGroupSet, nextLeaderGroupSet);\n    }\n\n    \/**\n     * Comparing registered information of User's affiliation to Organizations on Questetra BPM Suite and on TSV,\n     * manipulate the registered information via Web API.\n     * @param email: Email address of the User\n     * @param currentGroupSet: Set of Organizations which the User currently belongs to\n     *                           of the information registered on Questetra BPM Suite\n     * @param nextGroupSet: Set of Organizations of User's affiliation instructed in TSV\n     * @param currentLeaderGroupSet: Set of Organizations to which the User is affiliated as a \n     *                              leader, in the information currently registered on Questetra BPM Suite.\n     * @param nextLeaderGroupSet: Set of Organizations of User's affiliation as a leader instructed in TSV\n     * @throws ApiException\n     *\/\n    private static void sync(String email,\n                             Set&lt;String&gt; currentGroupSet,\n                             Set&lt;String&gt; nextGroupSet,\n                             Set&lt;String&gt; currentLeaderGroupSet,\n                             Set&lt;String&gt; nextLeaderGroupSet) throws ApiException {\n        MembershipDataManager manager = new MembershipDataManager();\n\n        \/\/ Create Sets which are \"Organization names that exist only on TSV (to be added)\" and \n        \/\/ \"Organization names that exist only on Questetra BPM Suite (to be deleted)\n\n        \/\/ Set of Organization names to be deleted\n        Set&lt;String&gt; willDelete = subtract(currentGroupSet, nextGroupSet);\n        \/\/ Set of Organization names to be added\n        Set&lt;String&gt; willAdd = subtract(nextGroupSet, currentGroupSet);\n\n        for (String group : willDelete) { \/\/ Delete from affiliation\n            manager.delete(email, group);\n        }\n\n        for (String group : willAdd) { \/\/ Add to affiliation\n            if (nextLeaderGroupSet.contains(group))\n                 manager.add(email, group, true);\n            else manager.add(email, group, false);\n        }\n\n\n        \/\/ Finding Organizations to which the User is affiliated as a leader on Questetra but not on TSV,\n        \/\/ remain Organizations to which continue to affiliate.\n        \/\/ \"Was a leader before, but is not now\" = \"Changed from leader to staff\"\n        \/\/                                          or \"Got out of members of the Organization (willDelete)\"\n        Set&lt;String&gt; wasLeader = subtract(currentLeaderGroupSet, nextLeaderGroupSet);\n        Set&lt;String&gt; toStaff = subtract(wasLeader, willDelete);\n\n        \/\/ Finding Organizations to which the User is affiliated as a leader on TSV but not on Questetra,\n        \/\/ remain Organizations to which continue to affiliate.\n        \/\/ \"Become a new leader\" = \"Changed from staff to leader\"\n        \/\/                          or \"Newly added to the organization as a leader (willAdd)\"\n        Set&lt;String&gt; willLeader = subtract(nextLeaderGroupSet, currentLeaderGroupSet);\n        Set&lt;String&gt; toLeader = subtract(willLeader, willAdd);\n\n        for (String group : toStaff) { \/\/ Change to a staff\n            manager.update(email, group, false);\n        }\n\n        for (String group : toLeader) { \/\/ Change to a leader\n            manager.update(email, group, true);\n        }\n    }\n\n\n    \/**\n     * Returns the difference between two sets (set1 - set2)\n     * @param set1: Minuend set\n     * @param set2: Subtrahend set\n     * @param &lt;T&gt;\n     * @return: Difference set\n     *\/\n    private static &lt;T&gt; Set&lt;T&gt; subtract(Set&lt;T&gt; set1, Set&lt;T&gt; set2) {\n        Set&lt;T&gt; subtraction = new HashSet&lt;&gt;(set1);\n        subtraction.removeAll(set2);\n        return subtraction;\n    }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">MembershipDataManager.java<\/h3>\n\n\n\n<pre><code class=\"java\">import com.questetra.bpms.client.swagger.api.QgroupApi;\nimport com.questetra.bpms.client.swagger.model.*;\nimport com.questetra.bpms.client.swagger.ApiClient;\nimport com.questetra.bpms.client.swagger.ApiException;\nimport com.questetra.bpms.client.swagger.Configuration;\nimport com.questetra.bpms.client.swagger.auth.*;\nimport com.questetra.bpms.client.swagger.api.MembershipApi;\n\nimport java.util.HashMap;\n\n\n\/**\n * List and manipulate the affiliation of Users.\n *\/\nclass MembershipDataManager {\n    private final MembershipApi apiInstance;\n    private final HashMap&lt;String, QuserWithPrimaryQgroup&gt; userMap = new HashMap&lt;&gt;();\n    private final HashMap&lt;String, Qgroup&gt; groupMap = new HashMap&lt;&gt;();\n\n    public MembershipDataManager() {\n        ApiClient defaultClient = Configuration.getDefaultApiClient();\n        \/\/ Set URL\n        defaultClient.setBasePath(\"https:\/\/example.questetra.net\/\");\n\n        \/\/ Basic Authentication\n        HttpBasicAuth basic \n                = (HttpBasicAuth)defaultClient.getAuthentication(\"basic\");\n        basic.setUsername(\"{EMAIL ADDRESS}\");\n        basic.setPassword(\"{PASSWORD for Basic Authentication}\");\n\n        this.apiInstance = new MembershipApi();\n    }\n\n    \/**\n     * Listing the User's affiliation to organization.\n     * @param email: Email address of the User.\n     * @return MembershipList: List of affiliated Organization.\n     *\/\n    public MembershipList findMemberships(String email) throws ApiException {\n        \/\/ Search User ID of the specified email address\n        Long userId = this.findUser(email).getId();\n        MembershipList result = this.apiInstance.listMembershipsByQuser(userId);\n        return result;\n    }\n\n    \/**\n     * Search for Organizations (Qgroup) by Organization name\n     * Throw ApiException if the Organization specified by the name doesn't exist on Questetra BPM Suite\n     * @Param name: Organization name.\n     * @return Qgroup: Organization object that has found by search.\n     *\/\n    private Qgroup findGroup(String name) throws ApiException {\n        \/\/ Organizations that have already been found are added to HashMap\n        if (this.groupMap.containsKey(name)) {\n            return this.groupMap.get(name);\n        }\n        QgroupApi groupApiInstance = new QgroupApi();\n        Qgroup result = groupApiInstance.findQgroup(null, name).getQgroup();\n        \/\/ HashMap\u306b\u8ffd\u52a0\n        this.groupMap.put(name, result);\n        return result;\n    }\n\n    \/**\n     * Search for a User (QuserWithPrimaryQgroup) by email address.\n     * Throw ApiException if the User with specified email address doesn't exist on Questetra BPM Suite\n     *  exist on Questetra BPM Suite\n     * @param email: Email address.\n     * @return QuserWithPrimaryQgroup: Found User object.\n     *\/\n    private QuserWithPrimaryQgroup findUser(String email) throws ApiException {\n        \/\/ Users that have already been found are added to HashMap\n        if (this.userMap.containsKey(email)) {\n            return this.userMap.get(email);\n        }\n        UserDataManager userManager = new UserDataManager();\n        QuserWithPrimaryQgroup result = userManager.find(null, email).getQuser();\n        \/\/ Add to HashMap\n        this.userMap.put(email, result);\n        return result;\n    }\n\n    \/**\n     * Adding organization to information of User's affiliation to Organizations\n     * @param email: Email address of User.\n     * @param group: Organization name\n     * @param isLeader: true for a leader, false for a staff\n     * @return MembershipWrapper\n     *\/\n    public MembershipWrapper add(String email, String group,\n                                 boolean isLeader) throws ApiException {\n        \/\/ Search User ID by the specified email address\n        Long userId = this.findUser(email).getId();\n        \/\/ Search Organization ID by the specified Organization name\n        Long groupId = this.findGroup(group).getId();\n\n        MembershipWrapper result;\n\n        if (isLeader) {\n            result = this.apiInstance.addMembership(userId, groupId, \"_leader\");\n            System.out.printf(\"Add: %s \/ %s, %s\\n\", email, group, \"leader\");\n        } else {\n            result = this.apiInstance.addMembership(userId, groupId, null);\n            System.out.printf(\"Add: %s \/ %s, %s\\n\", email, group, \"staff\");\n        }\n\n        return result;\n    }\n\n    \/**\n     * Deleting organizations from information of User's affiliation to Organizations\n     * @param email: Email address of User.\n     * @param group: Organization name.\n     *\/\n    public void delete(String email, String group) throws ApiException {\n        \/\/ Search User ID by the specified email address\n        Long userId = this.findUser(email).getId();\n        \/\/ Search Organization ID by the specified Organization name\n        Long groupId = this.findGroup(group).getId();\n\n        this.apiInstance.deleteMembership(userId, groupId);\n        System.out.printf(\"Deleted: %s \/ %s\\n\", email, group);\n    }\n\n    \/**\n     * Updating information of User's affiliation to Organizations\n     * @param email: Email address of User.\n     * @param group: Organizational name\n     * @param isLeader: true for a leader, false for a staff\n     * @return MembershipWrapper\n     *\/\n    public MembershipWrapper update(String email, String group,\n                                    boolean isLeader) throws ApiException {\n        \/\/ Search User ID by the specified email address\n        Long userId = this.findUser(email).getId();\n        \/\/ Search Organization ID by the specified Organization name\n        Long groupId = this.findGroup(group).getId();\n\n        MembershipWrapper result;\n\n        \/\/ Change to Leader\n        if (isLeader) {\n            result = this.apiInstance.updateMembership(userId, groupId, \"_leader\");\n            System.out.printf(\"Changed the role: %s \/ %s, \u2192 %s\\n\",\n                              email, group, \"leader\");\n        }\n        \/\/ Change to Staff\n        else {\n            result = this.apiInstance.updateMembership(userId, groupId, null);\n            System.out.printf(\"Changed the role: %s \/ %s, \u2192 %s\\n\",\n                              email, group, \"staff\");\n        }\n\n        return result;\n    }\n\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Synchronize user information on Questetra BPM Suite with local data. In the Organizational Affiliation Chapter, we introduce you a Java program that synchronizes affiliation information such as &#8220;which organization the user is affiliated to&#8221;.<\/p>\n","protected":false},"author":3,"featured_media":102440,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_uag_custom_page_level_css":"","advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_seo_schema_type":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_wpcom_ai_launchpad_first_post":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[296],"tags":[420],"class_list":["post-76781","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developer-blog","tag-questetra-system-settings-api"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1","uagb_featured_image_src":{"full":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1",1200,675,false],"thumbnail":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=440%2C440&ssl=1",440,440,true],"medium":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=560%2C315&ssl=1",560,315,true],"medium_large":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=768%2C432&ssl=1",768,432,true],"large":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1024%2C576&ssl=1",1024,576,true],"1536x1536":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1",1200,675,true],"2048x2048":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1",1200,675,true],"newspack-article-block-landscape-large":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=1200%2C675&ssl=1",1200,675,true],"newspack-article-block-portrait-large":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=900%2C675&ssl=1",900,675,true],"newspack-article-block-square-large":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=1200%2C675&ssl=1",1200,675,true],"newspack-article-block-landscape-medium":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=800%2C600&ssl=1",800,600,true],"newspack-article-block-portrait-medium":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=600%2C675&ssl=1",600,675,true],"newspack-article-block-square-medium":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=800%2C675&ssl=1",800,675,true],"newspack-article-block-landscape-intermediate":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=600%2C450&ssl=1",600,450,true],"newspack-article-block-portrait-intermediate":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=450%2C600&ssl=1",450,600,true],"newspack-article-block-square-intermediate":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=600%2C600&ssl=1",600,600,true],"newspack-article-block-landscape-small":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=400%2C300&ssl=1",400,300,true],"newspack-article-block-portrait-small":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=300%2C400&ssl=1",300,400,true],"newspack-article-block-square-small":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=400%2C400&ssl=1",400,400,true],"newspack-article-block-landscape-tiny":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=200%2C150&ssl=1",200,150,true],"newspack-article-block-portrait-tiny":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=150%2C200&ssl=1",150,200,true],"newspack-article-block-square-tiny":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?resize=200%2C200&ssl=1",200,200,true],"newspack-article-block-uncropped":["https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1",1200,675,true]},"uagb_author_info":{"display_name":"Hirotaka NISHI","author_link":"https:\/\/support.questetra.com\/en\/author\/nishiquestetra\/"},"uagb_comment_info":2,"uagb_excerpt":"Synchronize user information on Questetra BPM Suite with local data. In the Organizational Affiliation Chapter, we introduce you a Java program that synchronizes affiliation information such as \"which organization the user is affiliated to\".","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9DiIh-jYp","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":76060,"url":"https:\/\/support.questetra.com\/en\/developer-blog\/synchronize-users-chapter1\/","url_meta":{"origin":76781,"position":0},"title":"Synchronizing User Information with Local Data (Preparatory Chapter)","author":"Hirotaka NISHI","date":"2021-01-18","format":false,"excerpt":"Synchronize user information on Questetra BPM Suite with local data. In this Preparatory Chapter, introducing a Java program that retrieves for information of users on QBPMS.","rel":"","context":"In &quot;Questetra Developers Blog&quot;","block_context":{"text":"Questetra Developers Blog","link":"https:\/\/support.questetra.com\/en\/category\/developer-blog\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":76239,"url":"https:\/\/support.questetra.com\/en\/developer-blog\/synchronize-users-chapter2\/","url_meta":{"origin":76781,"position":1},"title":"Synchronizing User Information with Local Data (User Information Chapter)","author":"Hirotaka NISHI","date":"2021-01-18","format":false,"excerpt":"Synchronize user information on Questetra BPM Suite with local data. The User information chapter introduces a Java program that synchronizes registration information required to login to Questetra BPM Suite.","rel":"","context":"In &quot;Questetra Developers Blog&quot;","block_context":{"text":"Questetra Developers Blog","link":"https:\/\/support.questetra.com\/en\/category\/developer-blog\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2021\/01\/sync-with-local-data-1200x675-1.png?fit=1200%2C675&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":75420,"url":"https:\/\/support.questetra.com\/en\/templates\/customer-master-data-sync-process-20160719\/","url_meta":{"origin":76781,"position":2},"title":"Customer Master Data Sync Process","author":"Hirotaka NISHI","date":"2021-01-14","format":false,"excerpt":"Synchronizes \"Customer Master\" managed in Google Spreadsheet, automatically. Automatically Starts 1:00 every night, connects to Google spreadsheet API, and acquires \"Customer list\". The acquired customer list is reformatted and updated as \"Customer Master (Options XML)\" on the Workflow platform. It also corresponds to a manually starting by a person or\u2026","rel":"","context":"In &quot;Workflow Apps&quot;","block_context":{"text":"Workflow Apps","link":"https:\/\/support.questetra.com\/en\/category\/templates\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/03\/eye-catch-customer-data-master-sync-process-en.png?fit=1200%2C675&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/03\/eye-catch-customer-data-master-sync-process-en.png?fit=1200%2C675&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/03\/eye-catch-customer-data-master-sync-process-en.png?fit=1200%2C675&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/03\/eye-catch-customer-data-master-sync-process-en.png?fit=1200%2C675&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/03\/eye-catch-customer-data-master-sync-process-en.png?fit=1200%2C675&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":82872,"url":"https:\/\/support.questetra.com\/en\/system-settings\/role\/","url_meta":{"origin":76781,"position":3},"title":"System Settings &#8211; Role List","author":"Peter Glover","date":"2020-03-09","format":false,"excerpt":"The administration of Roles can be done in this screen.","rel":"","context":"In &quot;System Settings&quot;","block_context":{"text":"System Settings","link":"https:\/\/support.questetra.com\/en\/category\/system-settings\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_role_title.png?fit=1200%2C675&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_role_title.png?fit=1200%2C675&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_role_title.png?fit=1200%2C675&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_role_title.png?fit=1200%2C675&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_role_title.png?fit=1200%2C675&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":74056,"url":"https:\/\/support.questetra.com\/en\/incident\/bug-20190110\/","url_meta":{"origin":76781,"position":4},"title":"When Synchronizing with G Suite Group in Batch Registration of Roles, an Error Occurs if There Is a Group with No Member (Fixed)","author":"Hirotaka NISHI","date":"2019-01-10","format":false,"excerpt":"Fixed Version Version 11.9.0 Affected Version and Operation Ver. 11.8.2 To Synchronize with G Suite by [Role batch registration] Bug Details Occurs in operating \"Synchronize with G Suite\" < [Import Roles] < [Role List] < [System Setting] (\"Role\" of Questetra will be synchronized with \"group\" of G Suite) What will\u2026","rel":"","context":"In &quot;Incident Info&quot;","block_context":{"text":"Incident Info","link":"https:\/\/support.questetra.com\/en\/category\/incident\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2020\/04\/bug-report-en-1200x675-1.png?fit=1200%2C675&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2020\/04\/bug-report-en-1200x675-1.png?fit=1200%2C675&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2020\/04\/bug-report-en-1200x675-1.png?fit=1200%2C675&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2020\/04\/bug-report-en-1200x675-1.png?fit=1200%2C675&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2020\/04\/bug-report-en-1200x675-1.png?fit=1200%2C675&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":82829,"url":"https:\/\/support.questetra.com\/en\/system-settings\/user\/","url_meta":{"origin":76781,"position":5},"title":"System Settings &#8211; User List","author":"Peter Glover","date":"2024-05-07","format":false,"excerpt":"The administration of User accounts can be done in this screen.","rel":"","context":"In &quot;System Settings&quot;","block_context":{"text":"System Settings","link":"https:\/\/support.questetra.com\/en\/category\/system-settings\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_user_title.png?fit=1200%2C675&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_user_title.png?fit=1200%2C675&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_user_title.png?fit=1200%2C675&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_user_title.png?fit=1200%2C675&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/support.questetra.com\/wp-content\/uploads\/2019\/12\/Gear_user_title.png?fit=1200%2C675&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"amp_enabled":false,"_links":{"self":[{"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/posts\/76781","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/comments?post=76781"}],"version-history":[{"count":7,"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/posts\/76781\/revisions"}],"predecessor-version":[{"id":113292,"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/posts\/76781\/revisions\/113292"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/media\/102440"}],"wp:attachment":[{"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/media?parent=76781"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/categories?post=76781"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/support.questetra.com\/en\/wp-json\/wp\/v2\/tags?post=76781"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}