This article comes from IBM DeveloperWorks China website
Http://www-900.ibm.com/developerWorks/cn/lotus/ls-groups/index.shtml
Level: Intermediate
Andre Guirard (andre_guirard@us.ibm.com)) EI product developers, IBM 2005 January
This article will show how to use built-in NotesAdministrationProcess classes and two custom LotusScript classes to process groups in LotusScript.
The group is a NOTES document type in Domino Directory. You can operate the Group document using the NotesDocument class. The problem is to know what the value in the field represents and knows how to handle groups (nested groups) containing other groups, or how to handle groups that need to be exceeded.
In this article, we will discuss the methods of two processing groups. First, look at the built-in LotusScript Class NotesAdministrationProcess, which can be used in Lotus Notes / Domino 6.0 and later. This class can add members to the group, rename groups and delete groups (and many other functions that are not related to the group). It has not been able to delete the user from the group; however, if the user is completely deleted, then these users will be deleted from the group. For more information on the NotesAdministrationProcess class, see "LotusScript: The Notesadministration Process Class in Notes / Domino 6".
We also offer two custom LotusScript classes that support a larger group operation. This code is written for Lotus Notes / Domino 6.0 and higher; when you use it in version 5, you need to change it. This article contains several proxy examples that will display how to use these classes for different tasks. These classes cannot be used in COM because they use the List data type internally, and Visual Basic does not support this data type.
The actual code of the classes listed herein, all proxy examples, all properties, and methods of all properties, and methods are included in the database example, which can be downloaded from Sandbox. (In the database, you can view all documents for custom classes using the GMAN help or press F1 from any view.) Customized class named NotesgroupManager and Notesgroup. To use them, you need to copy the LotusScript GroupManager script library from the database sample to its own application and put it into your script via the USE statement. This class contains functions that do the following:
Find all addresses. Search all of the Group documents in all address books or specified subset. Create and delete groups. Add and delete members. Sort the member list. Processing groups containing other groups. Determine if someone is a member in the group, or gets a list of all members in the group, including members of the nesting group. Managing Groups of members that have a member of a Group document can be accommodated by dividing the group into multiple documents.
The database example contains some design elements that are copied from the public address book template (Pubnames.ntf) to use the tool to the data in the database, thereby avoiding the group in Domino Directory. This code can be used in any application.
This article assumes that you are an experienced LotusScript developer.
The group method of the NotesadministrationProcess class is as mentioned in the introduction, the NotesAdministrationProcess class allows some simple group operations (and many other functions that are not related to the group). The following sections list the relevant methods. Each method works by creating a request document in the Notes Management Request Database (Admin4.nsf). When running Admin, on the server, it takes these requests and then performs all the requests. Some requests may require other people to approval, while others may be passed to other Notes domains there.
The benefits of using this class are:
It allows requests to be issued, even when the server cannot directly access the execution request. If the user waits for the script, this class allows you to do faster because the actual work is done by the server. AdminP can delete and rename the group more thoroughly. It not only deletes or change the group record, but also tracks the reference to the original group name and updates these references.
weakness is:
With this method, you can only perform very little operation. The request is not necessarily executed immediately. If the group contains too many members without placing these members in a Group document, then this method cannot process the operation of adding the user to the group.
Most of these classes can return the Note ID of the new request document in the management request database. If a request cannot be created (for example, because the current user is not authorized), it will return an empty string ("") or generate an error condition according to the cause of failure.
The concept of returning the Note ID is: If you prefer, you can use the monitoring document to see when to complete the request. ADMINP Create a response document to display when the task is completed. Depending on server settings, AdMinP may run on a server different from the server that issues a request, thereby producing a long latency, while waiting to perform copying to the management server or copying from the server. You can't do anything to do anything, you can't access it manually. This operation is done automatically by adminP.
Here, we will no longer discuss the full grammar of these methods, but it is recommended that you refer to Domino Designer Help. There, we provide the summary of these grammar and some useful details information not available.
AddGroupMembers method gives the group name (string) and the user name number, which adds these names to the group. This may involve searching for multiple directorys to find groups. If there is no group of this given name, you need to create the group and provide common types for it, which means it can be used for email or access control. The name existing in the group does not have to be added.
Note: Domino Designer Document Description Member Parameters can be a string containing a single username, but it seems to be until Lotus Notes / Domino 6.5.4, which is useful. You can use an array of elements to add a single username.
Example 1: Automatic subscription mail list Set the following proxy (Admin PRocess Subscription Requests) is set to the new MEMO document in the Mail-In database and run on the MEMO document. It will check the subject field to see if you contain the word "subscribe" in the topic. If this word is included, the user is added to the group:
Option publicoption declare 'Always Use Option Declare
Sub initialize
DIM session as new notessession
Dim AdminP as NotesadministrationProcess
DIM DB AS NotesDatabaseDoase
DIM Coll As NotesDocumentCollectionDim DocRequest as NotesDocument
DIM STRID AS STRING
Dim strnewmembersArray () AS STRING
DIM INTNEWMEMBERCOUNT AS INTEGER
Set db = session.currentDatabase
Set coll = db.unprocessedDocuments
SET DOCREQUEST = COLL.GETFIRSTDOCUMENT ()
Do Until DocRequest is nothing
If DocRequest.Subject (0) = "Subscribe" THEN
Redim Preserve StrnewMembersArray (0 to intneWMembercount)
StrnewMembersArray (intnewMembercount) =
DOCREQUEST.GETITEMVALUE ("from") (0)
IntnewMembercount = IntnewMemberCount 1
END IF
Session.UpdateProcessedDoc DocRequest
SET DOCREQUEST = COLL.GetNextDocument (DocRequest)
Loop
IF intnewmembercount> 0 Then 'there is some members to add
Set adminp = session.createadministrationProcess ("bobpection")
Strid = adminp.addgroupmembers ("Hazardous Joke
Mailing List ", strnewmembersArray)
If strid = "" "Probable Insufficient Access
Msgbox {UNABLE TO CREATE Admin Add Request "Add or Modify
Group "}, 0, {adminp failure}
END IF
END IF
End Sub
After the deletegroup gives the group name, this method will remove this group from Domino Directory. In addition, this group name will be removed from the ACL of the database and from the database's ACL and from the document reader and Author name fields from all databases, from the Document Reader and Author name fields. Suppose the server uses the Windows operating system, then the method can also delete the Windows group of the same name.
RenameGroupRenameGroup method uses two string parameters: the original name and new name of the group. In addition to changing the name in the actual group record, this method can also update the database ACL list, other groups of members, and other locations where this group may be used.
The GroupManager Scripting Group The GroupManager script library contains two classes and multiple constants that can be used as the method parameters and attribute values, which are very useful in the ON Error statement. The two classes are:
NotesgroupManager traces Domino Directory and manages caches in the memory of the group information. This allows you to effectively perform multiple operations for multiple groups without frequent groups to memory. Saving changes may be delayed after all processing is completed. NotesgroupManager can be used in recursive or non-recursive modes. In recursive mode, which groups will be viewed in which groups contain other groups and allow recursive operations, such as deleting users from the current group and all their subgroups. Notesgroup contains information about a single group. By providing group name as a parameter, most tasks can be done directly through the NotesGroupManager method. If you need to use a Notesgroup class, you can request a Notesgroup object from the NotesGroupManager using the getGroup or creategroup method. This helps to perform some advanced operations (such as remember the ownership of the group), and use simpler code when performing multiple operations in the same group, thereby achieving higher efficiency.
Substation, broken subgroup and recursive mode The GroupManager script contains hierarchies of the processing group (including other groups as a member), and can contain 6 layers of nested. In this article, we group another group of members as a subgroup.
When you create a NotesGroupManager object, you can choose to disable recursive features and a "FLAT" collection of the group as a member to get better performance. This does not mean that members of the subgroup are members of the primary group. Just indicate that you can't explain them, unless they are members of the primary group.
There is a special type of subgroup called a Breakout Subgroup. If a given total field (in this example, the field contains a list of members) is limited to 32 kb, then the disconnect sub group needs to be used when too many members want to put into the primary group. The Group Manager automatically creates enough other groups to include a full list of members and add these groups as a member to the primary group.
The name of the disconnect subgroup is the name of the primary group, plus spaces and numbers. This is our practice of our code, not a practice of Lotus Domino. Lotus Domino does not process the group according to the name, but the group manager will do this.
Note: The disconnect subgroup is only functional in recursive mode.
As an example of the ordinary subgroup and the disconnect subgroup, two group hierarchies can be considered, as shown in FIG.
Figure 1. Ordinary subgroups and disconnect subgroups
The Sailors group contains some seafarers' names, and other two groups; each Pirate is a seafarer, each Naval Office is also a seafarer. We put them in a separate group so that we will help us. For example, the Naval Offers group allows access to all personnel performance evaluation databases that non-officers who cannot use, the Pirates group can be used as a post list of Pillage Newsletter, which is not related to the general seafarer.
Compared with the Sailors group, Group Hispaniola CREW includes a broken sub-group. Its subgroups are not used anywhere, and their existence is not for convenience and organization, but because the Notes field has a size limit. We will hear more discussions about these groups.
Example 2: More Mailing List Maintenance As in Example 1, the agent Gman Process Subscription Requests controls the membership of the group of the group according to the user's Mail-in subscription request. In order to provide some processing data to the agent, the database reform contains some Mail-in subscriptions and MEMOS views that are not subscribed. Of course, usually Domino Directory will definitely be a mail-in database; putting group records in the same database is merely illustrative. The agent Gman Process Subscription Requests is set to run after the new email arrives. It processes each memo in the unprocessedDocuments collection. The code of the agent is shown below. So you can try the agent without creating a Mail-In database. There is a similar agent "Gman Samples / 1. Process Subscription Requests", you can run it on the document selected in the Memos view.
Option public
Option Declare 'Always Use Option Declare
Use "groupmanager"
Sub initialize
DIM session as new notessession
DIM DB AS NotesDatabaseDoase
DIM Coll As NotesDocumentCollection
DIM DOC AS NotesDocument
DIM STRSUBJECT AS STRING, STRVERB AS STRING, STRGROUPNAME
AS String, strfrom as string
Dim Result As Boolean
Dim Gman As New NotesgroupManager (TRUE)
Call Gman.LoadPublicAddressBooks
gman.defaulttype = group_type_mail 'IF We CREATE
'a group, make it it a mail-only group.
Set db = session.currentDatabase
Set coll = db.unprocessedDocuments
Set doc = coll.getfirstdocument ()
Do Until Doc is Nothing
STRSUBJECT = FullTrim (Doc.getItemValue ("Subject") (0))
'We expect subject = "subscribe" or "unsubscribe"
'Followed by group name.
Strverb = lcase (strsUbject, ")))
strgroupname = strright (strsubject, ")
Strfrom = Doc.getItemValue ("from") (0)
'Make Sure Group Name Specified Is One We let People
'Subscribe to, E.g., Don't Allow Changes To LocalDomainadmins
'membership.
IF validategroup (strgroupname) THEN
If strrverb = "unsubscribe" the
'Remove Sender's Email from Group. Also from ALSO
'Subgroups, In Case List Is So Large That there is' 'Breakout' Subgroups.
Call gman.removefromgroup (strgroupname,
Strfrom, group_recurse)
SendMessage DB, Strfrom, "Your unsubscribe Request
WAS Processed, {You Have Been Removed from Group "}
& stroupname & {". so long!}
Elseif strverb = "subscribe" the
'Add member to the group with these options:
'- Create the group if it doesn't exist.
'- Don't add name if it's already in a subsgroup.
'- if Name is already there but not an exact match,
'Update IT.
Result = gman.addtogroup (strgroupname, strfrom, 0,
Group_create group_recurse group_update)
IF results
'Not already in the group (or name change) -
'Welcome.
SendMessage DB, Strfrom, "Your Subscription TO
"& stroupname &" was processed. ",
{Welcome to the "} & strunname &
{"Mailing List! Please review Our Policy
At http://www.iupp.org before posting to
THIS List.}
END IF
END IF 'SUBSCRIBE
Endiff 'Group name Valid
Call session.UpdateProcessedDoc (DOC)
Set Doc = Coll.getNextDocument (DOC)
Loop
Gman.saveall 'or None of Your Group Changes Will Be Saved
End Sub
There is no display of subroutines ValidateGroup and SendMessage here, but they contain them. The realization of ValidateGroup will change due to the alternative groups that allow this agent management, and SendMessage is not within the scope of this article. Unlike Example 1, this agent can handle subscriptions and not subscribe requests. Most code can get information about which operations needed. This code is actually performed in the following code line:
Use "GroupManager" loads the GroupManager library. DIM GMAN AS New NotesgroupManager Creates a NotesGroupManager object. Call Gman.LoadPublicAddressBooks tells the group manager to use all Domino Directory / Public Address Book. Gman.defaulttype = group_type_mail Specifies whether to automatically create a group (so we can add someone to this group), which will be a mailing list group. Call Gman.RemoveFromGroup (strgroupname, strfrom, group_recurse) Removes an employee from the group and all subgroups. By default, this employee is removed from the specified group. This is important when dealing with a large group of broken subgroups. He is still a member of the primary group unless employees are removed from all subgroups. Result = gman.addtogroup (strgroupname, strfrom, 0, group_create group_recurse group_update) Add an employee to the group. Some points related to this line code are: The third parameter (0) is a zero index of the directory. If a group does not exist, this group is created in the directory. This index is based on the list of loaded Domino Directory. 0 is the index of the main Domino Directory - Names.nsf because the previous calls is called. The group_recurse option specifies that if someone is already a member of the subgroup, this person cannot be added to the primary group. This option should be specified for all add items when processing the groups to be submitted. Group_UPDATE controls the following scenarios: If an email address of a member in the group is the same as the member of the member you want to add, these two members are not exactly the same (for example, if "Hester Prynne <10ter@bigredletter.org>" is in group Members, and we request to add "Hester A. Prynne <10ter@bigredletter.org>"). By default, the group will not be updated; if group_update is specified, you will need to update the group so that it is fully matched with the new name. Gman.saveAll saves all changes to the group manager. Example 3: Deleting and Creating Group Agents "Gman Sample and Create Groups" Show how to delete and create groups, and how to handle the simple hierarchy. The agent first deletes all groups shown in Figure 1. For Sailors, Naval Offers, and Pirates groups, this operation is relatively simple because we know the name of these groups, so you can use Gman.RemoveGroup. However, for group Hispaniola Crew, the situation is more complicated because there may be unknown disconnect subgroups in these groups. Deleting the primary group does not automatically delete any subgroups, so you must manually encode to delete subgroups. Below is the code used to delete all these groups:
Dim Gman As New NotesgroupManager (TRUE)
Dim Group as notesgroup
.
Call gman.removegroup ("pirates")
Call gman.removegroup ("soilors")
Call Gman.Removegroup ("Naval Offers") 'Because We'll Be Doing Several Operations On One Group,
'Get a notesgroup object to make..
Set group = gman.getgroup ("hispaniola crew")
IF not (group is nothing).
DIM Subgroups
'Are there Subgroups to hold overflow (E.G., "Hispaniola Crew 2")?
Subgroups = group.breakoutsubgroups
FORALL SUBGROUP IN SUBGROUROUPS
DIM STRTEMP
Strtemp = Subgroup.name
Call group.removemembers (strtemp, 0) 'Remove Subgroup from
Main group.
Call gman.removegroup (strTemp) 'delete the group altogether.
End forall
Gman.RemoveGroup ("hispaniola crew")
END IF
BreakoutSubGroups Attributes Returns the name of the subgroup, the name of these subgroups compliant with the code named these names (add spaces and numbers after the primary group name). In this example, the NotesGroupManager class does not access the properties required to disconnect the subgroup associated with the group, so you must use the Notesgroup object to get the details of a specific group.
Another method of deleting a group and all of its disconnect subgroups is to determine their name and delete any group below by this name:
Sub deletebreakOutgroup (Gman As NotesgroupManager, Strname As String)
DIM INTIND AS INTEGER
IF gman.removegroup (strname) THEN
INTIND = 2
While gman.removegroup (strname & "& inf"
INTIND = INTIND 1
Wend
END IF
End Sub
If there is a group where you want to delete, the RemoveGroup method returns true's Boolean value so that you can test the return value to determine if you need to find more similar names. This is a relatively simple code, but the security is relatively poor because the user cannot be absolutely guaranteed to have a broken subgroup without manual deletion, so it will leak a larger group.
Then we want to recreate the group just deleted. There are two ways to create a group: add members using Group_create options as in Case 2, or use Gman.createGroup as shown below:
Redim Values (0 to 3) AS STRING
Set group = gman.creategroup ("naval offester", group_type_multi, 0)
Group.description = "current serving officers" ""
VALUES (0) = "Horatio Hornblower / Hotspur / HRMN"
VALUES (1) = "Jack aubrey / surprise / hrmn" VALUES (2) = "Stephen maturin / surprise / hrmn"
VALUES (3) = "James Hook / Badguys / Neverland"
Call group.addmembers (Values, 0) '2nd argument isbo
Note that we use the Notesgroup Description attribute to assign a list description field. This object is only available when you include a Notesgroup object. Of course, you can usually use getGroup to get Notesgroup objects after this, for example:
Gman.getGroup ("pirates"). Description = "scourges of the sea"
So far, we have discussed two ways to add members, gman.addtogroup and group.addmembers. All methods used to add and delete members accept a single string or string array, so you can handle multiple members at the same time. In this example, we have not assigned an element of the array and then pass the array to addmembers, but write the following code:
Call group.addmembers ("Horatio Hornblower / Hotspur / HRMN", 0)
Call Group.addmembers ("Jack Aubrey / Surprise / HRMN", 0)
Call group.addmembers ("Stephen Maturin / Surprise / HRMN", 0)
Call group.addmembers ("James Hook / Badguys / Neverland", 0)
Note We use the Notes ID of the abbreviation format. The username in the Group document must be a standard format ("CN = ..."), but the group manager code accepts any of these two formats, and then automatically performs format conversion.
The third way to add members to group is the use of Notesgroup's MEMBERS attribute so that they can assign them with array values while changing the entire group. Here is some of the code in the proxy example:
Set group = gman.creategroup ("soilors", group_type_multi, 0)
Group.description = "all navvies"
VALUES (0) = "QueequeG / pequod / WHALERS"
VALUES (1) = "Jack Dawson / Titanic / White Star"
VALUES (2) = "pirates" 'the group
VALUES (3) = "Naval Offers" 'The Group
Group.members = VALUES
The method of such a designated group member is usually a "flat" addition. The member list is entirely the item you specify, even if there are some repetitive names in the subgroup.
Example 4: Creating a disconnect subgroup, as shown in the foregoing example, creating a broken subgroup is not different from creating a normal subgroup. All must be done is to ensure that the NotesgroupManager object is created under recursive mode (in other words, that is, the parameter of the New method is true), if the group is too large, this will be automatically performed. The agent "GMAN Samples / 3. Add Many Members" shows this situation. To create a large group that requires a broken subgroup, it contains a Pirate name generator that randomly selects a name, such as Long John Silver or WHistling Ned Doggett in the list of adjectives, names, and last names. The random name is added to the Hispaniola Crew group as follows:
IF group.addmembers (strcrewname, group_recurse) THEN
INTCOUNT = INTCOUNT 1
END IF
When processing a large group that may include a large group of broken subgroups, you can use the group_recurse option. Otherwise, someone you already exist in the discharge subgroup may be added to the primary group. Use this option when you delete a member.
The return value using AddMembers determines if the name is indeed added. If the person is still not a member, then this method will return to TRUE. In this example, we will perform this operation to track how many unique names have been added, so you can know when to stop adding.
If you want to know how many members can put into a group, you can run this agent multiple times. About 16,000 adjectives, names, and last names; you can edit the agent and add a list to increase the number of combinations.
Example 5: Search group NotesgroupManager contains attribute cachedgroups, which is a list of all groups in its cache in the NoteSgroupManager. Typically, a group is loaded when using the name request group; all subgroups of the requested group are also loaded in recursive mode.
You can use Group.ftsearch to search for groups that match the full text query. Group.ftsearch uses the query string as the parameters, in each Domino Directory, which is known to the Group Manager, which is used as the parameter of the ftsearch method. The group documentation that matches the search will be stored in the cache.
If Domino Directory is a full-text index, you can use this method to quickly find all groups containing specific person as a member using this method. You can then use the Group.Ismember property to clear the error match. The following code comes from the agent "Gman Samples / 4. Full Text Search":
Strsearch = Trim (INPUTBOX ("Search String:"))
.
LNGCOUNT = Gman.ftsearch (strSearch)
Dim Grouplist As Variant
Dim strowdesc as string
IF lngcount = 0 THEN
MsgBox "no groups matched your query."
Else
Grouplist = gman.cachedgroups
FORALL Group in GroupList
Stroupdesc = strgroupdesc & "& group.name
End forall
Msgbox "The Following" & lngcount & "Groups Matchedyour Query:" & Mid $ (strgroupdesc, 3)
END IF
If you only want the group that matches the search results, you must use the group manager in non-recursive mode.
There are several other methods for operating the cache: LoadAllGroups, LoadGroup, UNCache, and ClearCache. LoadAllGroups Get all information about all groups in all directories so you can use a loop (such as the loop described earlier) to iterate in these directories.
Conclusion This example is provided herein to get you start using this custom code. There are also other methods and properties we have not mentioned, which allows you to control group ownership, sort the members list, directly access the Group document to change any fields without the corresponding properties, and so on. All of this has been detailed in Sample Database.
Once you have source code, you can modify or expand classes as needed. If you write version 5 or COM version, it is recommended that you submit it to Sandbox so others can use. If you encounter a database illustrated document or any code, please email the author.
Reference
You can see this article in our website on our world. The complete documentation of the class, proxy examples, and all attributes and methods listed herein are included in the database example, which can be downloaded from Sandbox. For more information on the NotesAdministrationProcess class, see "LotusScript: The Notesadministration Process Class in Notes / Domino 6". For a complete description of the methods discussed herein, see Domino Designer Help. Join the developerWorks community by participating in developerWorks Blogs. You can purchase discounts for sale in the Lotus zone of Developer Bookstore.
About the author Andre Guirard is a member of the IBM Lotus Software Department Enterprise Integration team, which developed Lotus Enterprise Integrator (LEI) and some other products that allow you to connect different data sources and connect to Lotus Notes. Andre will also be attended the IBM meeting as a speaker. His article has been published in LDD and published in The View Magazine and elsewhere.