Include Page | ||||
---|---|---|---|---|
|
Table of Contents |
---|
Panel | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
This topic is discussed in the "Grouper API - Part 2" training video. |
...
Code Block |
---|
export GSH_JVMARGS="-Dlibrary.jansi.path=/some/other/temp/path/with/exec" |
Supported Commands
Grouper API methods
Any Grouper API method can be directly invoked just by referencing it, inclusive of the class in which it is defined. Methods return a java object which can be stored in a variable. For example, the following gsh session determines all of the groups to which a given subject belongs:
Environment variables that affect GSH startup:
- GROUPER_HOME: if set to a valid Grouper directory, it will use this directory. Otherwise, it will determine it based on the path to gsh
- GROUPER_CONF: if set to a valid conf directory, it will use this directory. Otherwise it will determine it based on GROUPER_HOME
- MEM_START: Override the default -Xms Java parameter (initial Java heap size)
- MEM_MAX: Override the default -Xmx Java parameter (maximum Java heap size)
- CLASSPATH: Will prepend to the constructed classpath
- GSH_JVMARGS: Additional arguments to pass to Java
- GSH_CYGWIN: (since 2.4.0 api patch 3) if set and not blank, the script will convert paths and the classpath to Windows-style, for use with Windows Java under Cygwin
- GSH_QUIET: (since 2.4.0 api patch 3) if set and not blank, will not output preliminary diagnostic information before starting Java, other than errors
Command line arg in script
Code Block |
---|
./gsh -runarg 'userToFind="user1"\n:load "/opt/grouper/scripts/myGSHScript.gsh"' |
Supported Commands
Grouper API methods
Any Grouper API method can be directly invoked just by referencing it, inclusive of the class in which it is defined. Methods return a java object which can be stored in a variable. For example, the following gsh session determines all of the groups to which a given subject belongs:
No Format |
---|
gsh 0% GrouperSession.startRootSession();
gsh 0% subj = findSubject("SD00125")
subject: |
No Format |
gsh 0% GrouperSession.startRootSession(); gsh 0% subj = findSubject("SD00125") subject: id='SD00125' type='person' source='kitn-person' name='Barton, Tom' gsh 1% sess = GrouperSession.start(subj) edu.internet2.middleware.grouper.GrouperSession: 29c40f97-9fb0-4e45-88bc-a14877a6c9b5,'SD00125','person' gsh 2% member = MemberFinder.findBySubject(sess, subj) member: id='SD00125' type='person' source='kitn-person' uuidname='d0fa765e-1439-4701-89b1-9b08b4ce9daaBarton, Tom' gsh 1% sess 3%= memberGrouperSession.getGroupsstart(subj) edu.internet2.middleware.grouper.GrouperSession: 29c40f97-9fb0-4e45-88bc-a14877a6c9b5,'SD00125','person' gsh 2% member = MemberFinder.findBySubject(sess, subj) member: id='SD00125' type='person' source='kitn-person' uuid='d0fa765e-1439-4701-89b1-9b08b4ce9daa' gsh 3% member.getGroups() group: name='etc:sysadmingroup' displayName='Grouper Administration:SysAdmin Group' uuid='6f77fb36-b466-481a-84a7-7af609f1ad09' |
...
Code Block |
---|
new GroupSave(grouperSession).assignName("stem1:a").assignCreateParentStemsIfNotExist(true).save(); |
Group Types
Set attribute on group
New group types on folder
Code Block | ||||
---|---|---|---|---|
GrouperSession grouperSession = GrouperSession.startRootSession();
Stem stem = StemFinder.findByName(grouperSession, "test:gdg:app", true);
AttributeDefName typeMarker = AttributeDefNameFinder.findByName("etc:objectTypes:grouperObjectTypeMarker", true);
AttributeAssign attributeAssign = stem.getAttributeDelegate().hasAttribute(typeMarker) ? stem.getAttributeDelegate().retrieveAssignments(typeMarker).iterator().next() : stem.getAttributeDelegate().addAttribute(typeMarker).getAttributeAssign();
attributeAssign.getAttributeValueDelegate().assignValue("etc:objectTypes:grouperObjectTypeDirectAssignment | ||||
Code Block | ||||
| ||||
grouperSession = GrouperSession.startRootSession();
g = GroupFinder.findByName(session, "admin:loader_groups");
type = typeAdd("sync_group");
type.addAttribute(session, "sync_group", false, "sync");
groupAddType("admin:loader_groups", "sync_group");
g.setAttribute("sync", "true"); |
...
Command
...
Description
...
groupAddType(group name, type name)
...
Add type to group
...
groupDelType(group name, type name)
...
Delete type from group
...
groupGetTypes(group name)
...
Get group's types
...
groupHasType(group name, type name)
...
Check whether group had type
...
typeAdd(type name)
...
Create custom group type
...
typeAddAttr(type name, attr name, read, write, required)
...
Create custom group attribute. read and write must be an AccessPrivilege
(e.g. AccessPrivilege.ADMIN
)
...
typeAddList(type name, attr name, read, write)
...
Create a custom list. read and write must be an AccessPrivilege
(e.g. AccessPrivilege.ADMIN
).
...
typeDel(type name)
...
Delete group type
...
typeDelField(type name, field name)
...
Delete custom field from group type
...
typeFind(type name)
...
Find the group
...
typeGetFields(type name)
...
Get fields associated with the group type
attributeAssign.getAttributeValueDelegate().assignValue("etc:objectTypes:grouperObjectTypeName", "app"); |
Set attribute on group
Code Block | ||||
---|---|---|---|---|
| ||||
grouperSession = GrouperSession.startRootSession();
g = GroupFinder.findByName(session, "admin:loader_groups");
type = typeAdd("sync_group");
type.addAttribute(session, "sync_group", false, "sync");
groupAddType("admin:loader_groups", "sync_group");
g.setAttribute("sync", "true"); |
Command | Description |
---|---|
groupAddType(group name, type name) | Add type to group |
groupDelType(group name, type name) | Delete type from group |
groupGetTypes(group name) | Get group's types |
groupHasType(group name, type name) | Check whether group had type |
typeAdd(type name) | Create custom group type |
typeAddAttr(type name, attr name, read, write, required) | Create custom group attribute. read and write must be an |
typeAddList(type name, attr name, read, write) | Create a custom list. read and write must be an |
typeDel(type name) | Delete group type |
typeDelField(type name, field name) | Delete custom field from group type |
typeFind(type name) | Find the group |
typeGetFields(type name) | Get fields associated with the group type |
Member change subject
Change subject of a Member object, e.g.:
grouperSession = GrouperSession.startRootSession();
oldSubject = findSubject("10021368");
member = MemberFinder.findBySubject(grouperSession, oldSubject);
newSubject = findSubject("10021366");
member.changeSubject(newSubject);
Command | Description |
---|---|
member.changeSubject(newSubject); |
Member change subject
Change subject of a Member object, e.g.:
grouperSession = GrouperSession.startRootSession();
oldSubject = findSubject("10021368");
member = MemberFinder.findBySubject(grouperSession, oldSubject);
newSubject = findSubject("10021366");
member.changeSubject(newSubject);
Command | Description |
---|---|
member.changeSubject(newSubject); | Change the subject of the member object. If the subject is the same, its a no-op. If the new subject does not have a Member object, then the existing member object simply gets new subject information. If the new subject does have a member object, then all objects in the grouper registry which uses the old member, will be updated to the new member. Then the old member object is deleted from the registry |
member.changeSubject(newSubject,!Member.DELETE_OLD_MEMBER); | Change the subject, but dont delete the old member. Do this if the way which deletes the old member doesnt work due to foreign keys. This will do all the work it can, and the rest can be manual |
member.changeSubjectReport(newSubject,Member.DELETE_OLD_MEMBER); | Dont do any of the work, just print a report to the screen of what will be done. Dry-run. |
...
Command | Description | ||
---|---|---|---|
addSubject(id, type, name) | Add local subject to registry. You need the jdbc source for this to work. The type parameter describes the type of subject (e.g. "people"), and is required non-null even though there are few useful api methods to query it. In 2.4.0.api.41+ patch, this will In 2.4.0.api.41+ patch, this will also create the id, name, description, and loginid attribute (unless grouper.properties create.attributes.when.creating.registry.subjects is false) | ||
RegistrySubject.addOrUpdate(grouperSession, id, type, name, nameAttributeValue, loginid, description, email) | In 2.4.0.api.41+ patch, add a registry subject like addSubject, but specify the attribute values of name, loginid, etc e.g. RegistrySubject.addOrUpdate(grouperSession, "someTestSubject", "person", "Some Testsubject", "Name Some Test Subject", "stsub", "Some Testsubject - employee - also alumni", "some@test.subject"); | ||
RegistrySubject.find(id, errorOnNotFound) | In 2.4.0.api.41+ patch, get a registry subject e.g. registrySubject = RegistrySubject.find("someTestSubject", false); | ||
registrySubject.delete(grouperSession) | In 2.4.0.api.41+ patch, delete a registry subject e.g. registrySubject.delete(grouperSession); | ||
RegistrySubjectAttribute.addOrUpdate(subjectId, attributeName, attributeValue) | In 2.4.0.api.41+ patch, add or update a registry subject attribute | ||
registrySubjectAttribute.delete() | In 2.4.0.api.41+ patch, delete an attribute value | ||
findSubject(ididOrIdentifier) | Find a subject by id or identifier | ||
findSubject(ididOrIdentifier, type) | Find a subject by id or identifier; type is a deprecated parameter that is ignored | ||
findSubject(ididOrIdentifier, type, source) | Find a subject by id or identifier for a specific subject source; type is a deprecated parameter that is ignored | ||
getSources() | Find all Subject sources | ||
grouperSession = GrouperSession.startRootSession(); | Find all subjects in a source by search string | ||
grouperSession = GrouperSession.startRootSession(); | Find a subject by id in a certain source | ||
grouperSession = GrouperSession.startRootSession(); | Find a subject by identifier in a certain source | ||
grouperSession = GrouperSession.startRootSession(); | Find a subject by id or identifier in a certain source | ||
add test subjects to registry (e.g. test.subject.0 through 9) | grouperSession = GrouperSession.startRootSession(); | ||
Edit subject (in this case name) | RegistrySubject registrySubject = GrouperDAOFactory.getFactory().getRegistrySubject().find("user1a", "person", true); | ||
add a subject application principal with attributes (GSH) |
| ||
remove a subject with attributes (GSH) |
|
...
Above, it describes how you can kick off the loader in daemon mode. You can also execute one job with:
Command | Description |
---|---|
grouperSession = GrouperSession.startRootSession(); | Kick off the loader for one group (configured by group attributes) |
loaderRunOneJob("MAINTENANCE_cleanLogs"); | Kick off the loader by job name |
loaderRunOneJob("CHANGE_LOG_changeLogTempToChangeLog"); | Move change log entries from the temp table to the real table |
loaderRunOneJob("CHANGE_LOG_consumer_grouperRules"); | Run the Grouper Rules daemon (the changelog or full version) |
loaderRunOneJob("CHANGE_LOG_consumer_test"); | Run a change log consumer |
This query (in Oracle) will find jobs with no success in the last day and make a gsh script:
Code Block |
---|
select distinct 'loaderRunOneJob("' || job_name || '");' as script
from grouper_loader_log gll where started_time > sysdate-1 and status != 'SUCCESS'
and gll.job_name not like 'subjobFor%'
and not exists (select 1 from grouper_loader_log gll2 where gll2.started_time > sysdate-1
and gll2.status = 'SUCCESS' and gll2.job_name = gll.job_name) |
Code Block | ||||
---|---|---|---|---|
| ||||
select distinct job_name from grouper_loader_log gll where started_time > CURRENT_DATE - 1 DAY and status != 'SUCCESS' and gll.job_name not like 'subjobFor%'
AND NOT EXISTS (select job_name from grouper_loader_log gll2 where gll2.started_time > CURRENT_DATE - 1 DAY and gll2.status = 'SUCCESS' and gll2.job_name = gll.job_name) |
v1.6+ loader
...
Command
...
Description
...
loaderRunOneJobAttr(attirbuteDef)
...
Run an attribute definition loader job
You can run the loader as a linux service
GrouperShell Variables (BeanShell only)
gsh has several variables that can be set to modify runtime behavior
...
Variable
...
Description
...
GSH_DEBUG
...
Stack traces will be printed upon failure if true
...
GSH_DEVEL
...
Summaries of returned objects are not automatically printed if true
...
GSH_TIMER
...
Prints time spent evaluating each command if true
grouperSession = GrouperSession.startRootSession(); | Kick off the loader for one group (configured by group attributes) |
loaderRunOneJob("MAINTENANCE_cleanLogs"); | Kick off the loader by job name |
loaderRunOneJob("CHANGE_LOG_changeLogTempToChangeLog"); | Move change log entries from the temp table to the real table |
loaderRunOneJob("CHANGE_LOG_consumer_grouperRules"); | Run the Grouper Rules daemon (the changelog or full version) |
loaderRunOneJob("CHANGE_LOG_consumer_test"); | Run a change log consumer |
This query (in Oracle) will find jobs with no success in the last day and make a gsh script:
Code Block |
---|
select distinct 'loaderRunOneJob("' || job_name || '");' as script
from grouper_loader_log gll where started_time > sysdate-1 and status != 'SUCCESS'
and gll.job_name not like 'subjobFor%'
and not exists (select 1 from grouper_loader_log gll2 where gll2.started_time > sysdate-1
and gll2.status = 'SUCCESS' and gll2.job_name = gll.job_name) |
Code Block | ||||
---|---|---|---|---|
| ||||
select distinct job_name from grouper_loader_log gll where started_time > CURRENT_DATE - 1 DAY and status != 'SUCCESS' and gll.job_name not like 'subjobFor%'
AND NOT EXISTS (select job_name from grouper_loader_log gll2 where gll2.started_time > CURRENT_DATE - 1 DAY and gll2.status = 'SUCCESS' and gll2.job_name = gll.job_name) |
v1.6+ loader
Command | Description |
---|---|
loaderRunOneJobAttr(attirbuteDef) | Run an attribute definition loader job |
You can run the loader as a linux service
GrouperShell Variables (BeanShell only)
gsh has several variables that can be set to modify runtime behavior
Variable | Description |
---|---|
GSH_DEBUG | Stack traces will be printed upon failure if true |
GSH_DEVEL | Summaries of returned objects are not automatically printed if true |
GSH_TIMER | Prints time spent evaluating each command if true |
Example:
No Format |
---|
gsh 4% GSH_DEVEL = true
gsh 5% subj = findSubject("SD00125")
gsh 6% sess = GrouperSession.start(subj)
gsh 7% member = MemberFinder.findBySubject(sess, subj)
gsh 8% p(member.getGroups())
group: name='etc:sysadmingroup' displayName='Grouper Administration:SysAdmin Group' uuid='6f77fb36-b466-481a-84a7-7af609f1ad09'
|
Membership scripts
Code Block |
---|
# (1) Print tab-separated summary of all group members, and flags for direct, indirect, or both
# Depending on the results, you could use the data to create a scrutinized list of Ids to delete, then import it and delete in a loop
me = SubjectFinder.findByIdentifierAndSource("my-username", "pid", true);
session = GrouperSession.start(me);
// OR: session = GrouperSession.startRootSession(True)
group = GroupFinder.findByName(session, "tmp:my:group", true);
effectiveMembers = group.getEffectiveMembers();
immediateMembers = group.getImmediateMembers();
System.out.println(String.join("\t", "id", "name", "Effective", "Immediate"));
for (Member m: group.getMembers()) {
System.out.print(m.getSubject().getId() + "\t" + m.getSubject().getName() + "\t");
System.out.print(effectiveMembers.contains(m).toString() + "\t");
System.out.println(immediateMembers.contains(m).toString() + "\t");
}
# (2) Get the immediate and effective members for a specific source ("pid" in this example), intersect them to find the redundant ones
# This has a dryRun flag, so you can test first
sources = new HashSet<Source>()
sources.add(SourceManager.getInstance().getSource("pid"))
effectiveUsers = group.getEffectiveMembers(Group.getDefaultList(), sources, null)
immediateUsers = group.getImmediateMembers(Group.getDefaultList(), sources, null)
# use retainAll() to find the intersection; i.e., users both as effective and immediate member
immediateUsers.retainAll(effectiveUsers)
System.out.println("There are " + immediateUsers.size() + " users having both direct + indirect memberships");
dryRun = true
for (Member m: immediateUsers) {
if (dryRun) {
System.out.println("Ok to delete " |
Example:
No Format |
---|
gsh 4% GSH_DEVEL = true
gsh 5% subj = findSubject("SD00125")
gsh 6% sess = GrouperSession.start(subj)
gsh 7% member = MemberFinder.findBySubject(sess, subj)
gsh 8% p(member.getGroups())
group: name='etc:sysadmingroup' displayName='Grouper Administration:SysAdmin Group' uuid='6f77fb36-b466-481a-84a7-7af609f1ad09'
|
Membership scripts
Code Block |
---|
# (1) Print tab-separated summary of all group members, and flags for direct, indirect, or both # Depending on the results, you could use the data to create a scrutinized list of Ids to delete, then import it and delete in a loop me = SubjectFinder.findByIdentifierAndSource("my-username", "pid", true); session = GrouperSession.start(me); // OR: session = GrouperSession.startRootSession(True) group = GroupFinder.findByName(session, "tmp:my:group", true); effectiveMembers = group.getEffectiveMembers(); immediateMembers = group.getImmediateMembers(); System.out.println(String.join("\t", "id", "name", "Effective", "Immediate")); for (Member m: group.getMembers()) { System.out.print(m.getSubject().getId() + "\t" + m.getSubject().getNamegetId()) + "\t"); ; } else { System.out.print(effectiveMembers.contains(m).toString() + "\t"); System.out.println(immediateMembers.contains(m).toString() + "\t"); } println("Deleting " + m.getSubject().getId()); group.deleteMember(m, false); } } # (23) Get the immediategroups andthis effectivesubject members foris a specificmember source ("pid" in this example), intersect them to find the redundant ones # Thisof. Note that a group is a kind of subject, and has a dryRun flag, so you can test first sources = new HashSet<Source>() sources.add(SourceManager.getInstance().getSource("pid")) effectiveUsers = group.getEffectiveMembers(Group.getDefaultList(), sources, null) immediateUsers = group.getImmediateMembers(Group.getDefaultList(), sources, null) # use retainAll() to find the intersection; i.e., users both as effective and immediate member immediateUsers.retainAll(effectiveUsers) System.out.println("There are " + immediateUsers.size() + " users having both direct + indirect memberships"); dryRun = true for (Member m: immediateUsers) { if (dryRun) { System.out.println("Ok to delete " + m.getSubject().getId()); } else { System.out.println("Deleting " + m.getSubject().getId()); group.deleteMember(m, false); } } toSubject() method to convert it. import edu.internet2.middleware.grouper.membership.MembershipSubjectContainer GrouperSession grouperSession = GrouperSession.startRootSession(); Group group = GroupFinder.findByName(grouperSession, "test:testGroup", true); Subject subject = g.toSubject(); Set<MembershipSubjectContainer> msc = new MembershipFinder().addSubject(subject).findMembershipResult().getMembershipSubjectContainers(); for (MembershipSubjectContainer membershipSubjectContainer : msc) { println(membershipSubjectContainer.getGroupOwner().getName());} //Note there are a few other options for the search. Add these to the MembershipFinder method chain before calling findMembershipResult(): // - search immediate, effective, etc. (needs to import MembershipType) import edu.internet2.middleware.grouper.membership.MembershipType membershipFinder.assignMembershipType(MembershipType.IMMEDIATE) // options are IMMEDIATE|NONIMMEDIATE|EFFECTIVE|COMPOSITE // - retrieve specific groups based on pattern membershipFinder.assignScope("%:test:%") // - Enabled status -- true means enabled only, false, means disabled only, and null means all membershipFinder.assignEnabled(false) // For other methods, refer to the Javadoc at http://internet2.github.io/grouper/master/grouper-parent/apidocs/edu/internet2/middleware/grouper/MembershipFinder.html |
Misc
Note: you cannot encrypt passwords with GSH since the passwords end up in the GSH history. To encrypt passwords, issue the command:
...
Code Block |
---|
gsh 0% HibernateSession.bySqlStatic().listSelect(String.class, "SELECT DISTINCT gaaa.value_string FROM grouper_attribute_assign_value gaaa, grouper_attribute_assign gaa, grouper_attribute_def_name gadn WHERE gaaa.attribute_assign_id = gaa.id AND gaa.attribute_def_name_id = gadn.id AND gadn.extension IN ('provision_to', 'do_not_provision_to')", null, null); java.util.ArrayList: [ad, ldap] |
Example of finding which groups are provisioned to a certain target (from daemon where PSPNG is installed)
Code Block |
---|
provisioner_name="xyz"; // Whatever your provisioner is called in grouper_loader.properties
gs=GrouperSession.startRootSession();
provisioner=edu.internet2.middleware.grouper.pspng.ProvisionerFactory.createProvisioner(provisioner_name,false);
provisioner.getAllGroupsForProvisioner(); |
Long hand example of which groups are provisioned to a certain target
Code Block |
---|
String provisionTarget = "ad"; GrouperSession grouperSession = GrouperSession.startRootSession(); Set stemsToProvisionToSet = HibernateSession.byHqlStatic().createQuery("select s from Stem s, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where s.id = aa.ownerStemId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'stem' and aa.enabledDb = 'T' and adn.extensionDb = 'provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class); for (Object stemObject : stemsToProvisionToSet) { Stem stem = (Stem)stemObject; System.out.println("provision_to assigned to stem: " + stem.getName()); } Set stemsToNotProvisionToSet = HibernateSession.byHqlStatic().createQuery("select s from Stem s, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where s.id = aa.ownerStemId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'stem' and aa.enabledDb = 'T' and adn.extensionDb = 'do_not_provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class); for (Object stemObject : stemsToNotProvisionToSet) { Stem stem = (Stem)stemObject; System.out.println("do_not_provision_to assigned to stem: " + stem.getName()); } Set groupsToProvisionToSet = HibernateSession.byHqlStatic().createQuery("select g from Group g, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where g.id = aa.ownerGroupId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'group' and aa.enabledDb = 'T' and adn.extensionDb = 'provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class); for (Object groupObject : groupsToProvisionToSet) { Group group = (Group)groupObject; System.out.println("provision_to assigned to group: " + group.getName()); } Set groupsToNotProvisionToSet = HibernateSession.byHqlStatic().createQuery("select g from Group g, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where g.id = aa.ownerGroupId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'group' and aa.enabledDb = 'T' and adn.extensionDb = 'do_not_provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class); for (Object groupObject : groupsToNotProvisionToSet) { Group group = (Group)groupObject; System.out.println("do_not_provision_to assigned to group: " + group.getName()); } Set allGroups = new LinkedHashSet(); Set allGroupsToProvision = new TreeSet(); allGroupsToProvision.addAll(groupsToProvisionToSet); Set stemNamesToNotProvisionTo = new HashSet(); Set stemNamesToProvisionTo = new HashSet(); for (Object stemToProvision : stemsToProvisionToSet) { stemNamesToProvisionTo.add(((Stem)stemToProvision).getName()); } for (Object stemNotToProvision : stemsToNotProvisionToSet) { stemNamesToNotProvisionTo.add(((Stem)stemNotToProvision).getName()); } for (Object stemToProvision : stemsToProvisionToSet) { allGroups.addAll(((Stem)stemToProvision).getChildGroups(edu.internet2.middleware.grouper.Stem.Scope.SUB)); } Map groupToPaths = new HashMap(); for (Object groupObject : allGroups) { Group group = (Group)groupObject; if (allGroupsToProvision.contains(group)) {continue;} if (groupsToNotProvisionToSet.contains(group)) {continue;} List paths = new ArrayList(); groupToPaths.put(group, paths); String currentName = group.getName(); paths.add(currentName); while(true) { currentName = GrouperUtil.parentStemNameFromName(currentName); if (GrouperUtil.isBlank(currentName)) {break;} paths.add(currentName); } } for (Object groupObject : groupToPaths.keySet()) {Group group = (Group)groupObject; List paths = (List)groupToPaths.get(group); for (Object pathObject : paths) { String path = (String)pathObject; if (stemNamesToProvisionTo.contains(path)) { allGroupsToProvision.add(group); break; } if (stemNamesToNotProvisionTo.contains(path)) { break; } } } for (Object groupObject : allGroupsToProvision) { Group group = (Group)groupObject; System.out.println("configured to provision to: " + provisionTarget + ": " + group.getName()); } |
...