-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e0a72f4
commit d61b9f4
Showing
53 changed files
with
4,348 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,6 +57,7 @@ DO $$ BEGIN | |
'REPORT_DATA', | ||
'RESOURCE', | ||
'ROLE', | ||
'MINING', | ||
'SECURITY_POLICY', | ||
'SEQUENCE', | ||
'SERVICE', | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
...in/java/com/evolveum/midpoint/gui/api/component/mining/analyse/tools/grouper/Grouper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/* | ||
* Copyright (C) 2010-2023 Evolveum and contributors | ||
* | ||
* This work is dual-licensed under the Apache License 2.0 | ||
* and European Union Public License. See LICENSE file for details. | ||
*/ | ||
|
||
package com.evolveum.midpoint.gui.api.component.mining.analyse.tools.grouper; | ||
|
||
import com.evolveum.midpoint.gui.api.component.mining.analyse.tools.jaccard.UniqueRoleSet; | ||
import com.evolveum.midpoint.gui.api.component.mining.analyse.tools.utils.RoleUtils; | ||
import com.evolveum.midpoint.prism.PrismObject; | ||
import com.evolveum.midpoint.schema.util.OidUtil; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.TreeMap; | ||
|
||
import static com.evolveum.midpoint.gui.api.component.mining.analyse.tools.utils.RoleUtils.getRolesId; | ||
import static com.evolveum.midpoint.gui.api.component.mining.analyse.tools.utils.RoleUtils.intersectionCount; | ||
|
||
public class Grouper { | ||
private static List<PrismObject<UserType>> extractUsersWithMinimumIntersection(List<PrismObject<UserType>> users, | ||
int minIntersection) { | ||
List<PrismObject<UserType>> result = new ArrayList<>(); | ||
|
||
for (int i = 0; i < users.size(); i++) { | ||
PrismObject<UserType> currentUser = users.get(i); | ||
int intersectionCount = 0; | ||
|
||
for (int j = 0; j < users.size(); j++) { | ||
if (i != j) { | ||
PrismObject<UserType> otherUser = users.get(j); | ||
|
||
List<String> currentUserValues = getRolesId(currentUser.asObjectable()); | ||
List<String> otherUserValues = getRolesId(otherUser.asObjectable()); | ||
|
||
int matchingValues = intersectionCount(currentUserValues, otherUserValues); | ||
|
||
if (matchingValues >= minIntersection) { | ||
intersectionCount++; | ||
} | ||
} | ||
} | ||
|
||
if (intersectionCount >= minIntersection) { | ||
result.add(currentUser); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
public static List<UniqueRoleSet> generateIntersectionGroups(List<PrismObject<UserType>> users, int minIntersection) { | ||
|
||
List<UniqueRoleSet> usersGroupedByRoles = new ArrayList<>(); | ||
|
||
List<PrismObject<UserType>> userTypeList; | ||
List<String> roleTypeList; | ||
for (int i = 1; i < users.size(); i++) { | ||
PrismObject<UserType> userA = users.get(i); | ||
roleTypeList = new ArrayList<>(getRolesId(userA.asObjectable())); | ||
userTypeList = new ArrayList<>(); | ||
userTypeList.add(userA); | ||
|
||
for (PrismObject<UserType> userB : users) { | ||
int similarity = intersectionCount(getRolesId(userA.asObjectable()), getRolesId(userB.asObjectable())); | ||
if (similarity >= minIntersection) { | ||
userTypeList.add(userB); | ||
} | ||
} | ||
|
||
List<PrismObject<UserType>> prismObjects = extractUsersWithMinimumIntersection(userTypeList, minIntersection); | ||
usersGroupedByRoles.add(new UniqueRoleSet(userA.getName().toString(), roleTypeList, prismObjects)); | ||
} | ||
|
||
return usersGroupedByRoles; | ||
} | ||
|
||
public static List<UniqueRoleSet> generateUniqueSetsGroup(List<PrismObject<UserType>> users) { | ||
|
||
Map<String, List<PrismObject<UserType>>> roleUserMap = new TreeMap<>(); | ||
for (PrismObject<UserType> user : users) { | ||
List<String> roles = new ArrayList<>(getRolesId(user.asObjectable())); | ||
if (roles.isEmpty()) { | ||
continue; | ||
} | ||
|
||
String roleKey = roles.toString(); | ||
|
||
if (roleUserMap.containsKey(roleKey)) { | ||
roleUserMap.get(roleKey).add(user); | ||
} else { | ||
List<PrismObject<UserType>> userList = new ArrayList<>(); | ||
userList.add(user); | ||
roleUserMap.put(roleKey, userList); | ||
} | ||
} | ||
|
||
List<UniqueRoleSet> usersGroupedByRoles = new ArrayList<>(); | ||
|
||
for (List<PrismObject<UserType>> usersList : roleUserMap.values()) { | ||
usersGroupedByRoles.add(new UniqueRoleSet(OidUtil.generateOid(), | ||
getRolesId(usersList.get(0).asObjectable()), usersList)); | ||
} | ||
|
||
return usersGroupedByRoles; | ||
} | ||
|
||
|
||
public static List<UniqueRoleSet> getRoleGroupByJc(List<PrismObject<UserType>> users, double threshold) { | ||
|
||
List<UniqueRoleSet> usersGroupedByRoles = new ArrayList<>(); | ||
|
||
List<PrismObject<UserType>> userTypeList; | ||
List<String> roleTypeList; | ||
for (int i = 1; i < users.size(); i++) { | ||
PrismObject<UserType> userA = users.get(i); | ||
roleTypeList = new ArrayList<>(getRolesId(userA.asObjectable())); | ||
userTypeList = new ArrayList<>(); | ||
userTypeList.add(userA); | ||
|
||
for (int j = i + 1; j < users.size(); j++) { | ||
PrismObject<UserType> userB = users.get(j); | ||
double similarity = RoleUtils.jacquardSimilarity( | ||
getRolesId(userA.asObjectable()), getRolesId(userB.asObjectable())); | ||
if (similarity >= threshold) { | ||
userTypeList.add(userB); | ||
} | ||
} | ||
usersGroupedByRoles.add(new UniqueRoleSet(OidUtil.generateOid(), roleTypeList, userTypeList)); | ||
|
||
} | ||
|
||
return usersGroupedByRoles; | ||
} | ||
|
||
} |
71 changes: 71 additions & 0 deletions
71
.../java/com/evolveum/midpoint/gui/api/component/mining/analyse/tools/grouper/MiningSet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* Copyright (C) 2010-2023 Evolveum and contributors | ||
* | ||
* This work is dual-licensed under the Apache License 2.0 | ||
* and European Union Public License. See LICENSE file for details. | ||
*/ | ||
|
||
package com.evolveum.midpoint.gui.api.component.mining.analyse.tools.grouper; | ||
|
||
import java.io.Serializable; | ||
import java.util.List; | ||
|
||
import com.evolveum.midpoint.prism.PrismObject; | ||
import com.evolveum.midpoint.web.component.util.SelectableBeanImpl; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; | ||
|
||
public class MiningSet extends SelectableBeanImpl<MiningSet> implements Serializable { | ||
public static final String F_RATION = "groupOverlapRation"; | ||
public static final String F_GROUP = "groupIdentifier"; | ||
public static final String F_USER_SIZE = "users"; | ||
public static final String F_ID = "id"; | ||
public static final String F_ROLES_BY_TRESHOLD = "rolesByThresholdId"; | ||
|
||
int groupIdentifier; | ||
double groupOverlapRation; | ||
List<String> roles; | ||
List<PrismObject<UserType>> users; | ||
List<Integer> rolesByThresholdId; | ||
private boolean selected; | ||
|
||
public String getId() { | ||
return id; | ||
} | ||
|
||
String id; | ||
|
||
public MiningSet(String id, int groupIdentifier, double groupOverlapRation, List<String> roles, | ||
List<Integer> rolesByThresholdId, List<PrismObject<UserType>> users) { | ||
this.groupIdentifier = groupIdentifier; | ||
this.groupOverlapRation = groupOverlapRation; | ||
this.roles = roles; | ||
this.rolesByThresholdId = rolesByThresholdId; | ||
this.users = users; | ||
this.id = id; | ||
|
||
} | ||
|
||
public void setSelected(boolean selected) { | ||
this.selected = selected; | ||
} | ||
|
||
public int getGroupIdentifier() { | ||
return groupIdentifier; | ||
} | ||
|
||
public double getGroupOverlapRation() { | ||
return groupOverlapRation; | ||
} | ||
|
||
public List<String> getRoles() { | ||
return roles; | ||
} | ||
|
||
public List<PrismObject<UserType>> getUsers() { | ||
return users; | ||
} | ||
|
||
public List<Integer> getRolesByThresholdId() { | ||
return rolesByThresholdId; | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
...n/java/com/evolveum/midpoint/gui/api/component/mining/analyse/tools/grouper/Preparer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
* Copyright (C) 2010-2023 Evolveum and contributors | ||
* | ||
* This work is dual-licensed under the Apache License 2.0 | ||
* and European Union Public License. See LICENSE file for details. | ||
*/ | ||
|
||
package com.evolveum.midpoint.gui.api.component.mining.analyse.tools.grouper; | ||
|
||
import static com.evolveum.midpoint.gui.api.component.mining.analyse.tools.jaccard.JacquardSorter.jaccSortUn; | ||
import static com.evolveum.midpoint.gui.api.component.mining.analyse.tools.grouper.Grouper.generateIntersectionGroups; | ||
import static com.evolveum.midpoint.gui.api.component.mining.analyse.tools.grouper.Grouper.generateUniqueSetsGroup; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import com.evolveum.midpoint.gui.api.component.mining.analyse.tools.utils.RoleUtils; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
|
||
import com.evolveum.midpoint.gui.api.component.mining.analyse.tools.jaccard.UniqueRoleSet; | ||
import com.evolveum.midpoint.prism.PrismObject; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; | ||
|
||
public class Preparer { | ||
|
||
public @NotNull | ||
static List<MiningSet> prepareMiningSet(List<PrismObject<UserType>> users, double threshold) { | ||
List<MiningSet> miningSets = new ArrayList<>(); | ||
List<UniqueRoleSet> uniqueRoleSet = jaccSortUn(generateUniqueSetsGroup(users)); | ||
int size = uniqueRoleSet.size(); | ||
|
||
for (int i = 0; i < size; i++) { | ||
List<Integer> rolesByThreshold = new ArrayList<>(); | ||
double ration = 0; | ||
for (int j = 0; j < size; j++) { | ||
if (j != i) { | ||
|
||
double similarity = RoleUtils.jacquardSimilarity(uniqueRoleSet.get(i).getRoles(), | ||
uniqueRoleSet.get(j).getRoles()); | ||
ration += similarity; | ||
|
||
if (similarity >= threshold) { | ||
rolesByThreshold.add(j); | ||
} | ||
|
||
} | ||
} | ||
ration /= size; | ||
UniqueRoleSet roleSet = uniqueRoleSet.get(i); | ||
miningSets.add(new MiningSet(uniqueRoleSet.get(i).getoId(), | ||
i, ration, roleSet.getRoles(), rolesByThreshold, roleSet.getUsers())); | ||
} | ||
return miningSets; | ||
} | ||
|
||
public @NotNull | ||
static List<MiningSet> prepareMiningSetIntersected(List<PrismObject<UserType>> users, int minIntersection, double threshold) { | ||
List<MiningSet> miningSets = new ArrayList<>(); | ||
List<UniqueRoleSet> uniqueRoleSet = jaccSortUn(generateIntersectionGroups(users, minIntersection)); | ||
int size = uniqueRoleSet.size(); | ||
|
||
for (int i = 0; i < size; i++) { | ||
List<Integer> rolesByThreshold = new ArrayList<>(); | ||
double ration = 0; | ||
for (int j = 0; j < size; j++) { | ||
if (j != i) { | ||
|
||
double similarity = RoleUtils.jacquardSimilarity(uniqueRoleSet.get(i).getRoles(), | ||
uniqueRoleSet.get(j).getRoles()); | ||
ration += similarity; | ||
|
||
if (similarity >= threshold) { | ||
rolesByThreshold.add(j); | ||
} | ||
|
||
} | ||
} | ||
ration /= size; | ||
UniqueRoleSet roleSet = uniqueRoleSet.get(i); | ||
miningSets.add(new MiningSet(uniqueRoleSet.get(i).getoId(), i, ration, roleSet.getRoles(), | ||
rolesByThreshold, roleSet.getUsers())); | ||
} | ||
return miningSets; | ||
} | ||
|
||
} |
Oops, something went wrong.