Files
permission-manager-sdk-java/src/main/java/de/mummeit/pmg/builder/IntegrationBuilder.java

299 lines
12 KiB
Java

package de.mummeit.pmg.builder;
import de.mummeit.pmg.api.model.integration.*;
import java.util.ArrayList;
import java.util.List;
/**
* A fluent builder for creating Permission Manager integrations.
* This builder provides a type-safe way to create various types of integrations including:
* - Domain integrations (create, update, delete)
* - Permission integrations (create, update, delete)
* - Role integrations (create, update, delete)
* - Role-Permission relation integrations
*
* Example usage:
* {@code
* List<Integration<?>> integrations = IntegrationBuilder.create()
* .createDomain("my-domain", "My Domain")
* .addPermission("read", "Read Permission")
* .addRole("user", "User Role")
* .assignPermissionsToRole("user", Arrays.asList("read"))
* .build();
* }
*/
public class IntegrationBuilder {
private final List<Integration<?>> integrations = new ArrayList<>();
private String currentDomain;
/**
* Creates a new instance of the IntegrationBuilder.
*
* @return A new IntegrationBuilder instance
*/
public static IntegrationBuilder create() {
return new IntegrationBuilder();
}
/**
* Selects a domain as the context for subsequent operations without creating an integration.
* This is useful when you need to perform operations on an existing domain.
*
* @param name The name of the domain to select
* @return This builder instance for method chaining
*/
public IntegrationBuilder selectDomain(String name) {
this.currentDomain = name;
return this;
}
/**
* Creates a new domain integration with the specified name and description.
* This also sets the domain context for subsequent operations.
*
* @param name The name of the domain
* @param description The description of the domain
* @return This builder instance for method chaining
*/
public IntegrationBuilder createDomain(String name, String description) {
this.currentDomain = name;
integrations.add(DomainIntegration.builder()
.id(generateIntegrationId("domain", name, Integration.Action.create))
.action(Integration.Action.create)
.data(DomainIntegration.Data.builder()
.name(name)
.description(description)
.build())
.build());
return this;
}
/**
* Updates an existing domain with a new name and/or description.
* This also sets the domain context to the new name for subsequent operations.
*
* @param oldName The current name of the domain to update
* @param newName The new name for the domain
* @param description The new description for the domain
* @return This builder instance for method chaining
*/
public IntegrationBuilder updateDomain(String oldName, String newName, String description) {
integrations.add(DomainIntegration.builder()
.id(generateIntegrationId("domain", oldName, Integration.Action.update))
.action(Integration.Action.update)
.data(DomainIntegration.Data.builder()
.name(newName)
.oldName(oldName)
.description(description)
.build())
.build());
this.currentDomain = newName;
return this;
}
/**
* Deletes a domain.
*
* @param name The name of the domain to delete
* @return This builder instance for method chaining
*/
public IntegrationBuilder deleteDomain(String name) {
integrations.add(DomainIntegration.builder()
.id(generateIntegrationId("domain", name, Integration.Action.delete))
.action(Integration.Action.delete)
.data(DomainIntegration.Data.builder()
.name(name)
.build())
.build());
return this;
}
/**
* Adds a new permission to the current domain.
*
* @param name The name of the permission
* @param description The description of the permission
* @return This builder instance for method chaining
* @throws IllegalStateException if no domain context has been set
*/
public IntegrationBuilder addPermission(String name, String description) {
validateDomain();
integrations.add(PermissionIntegration.builder()
.id(generateIntegrationId("permission", currentDomain + ":" + name, Integration.Action.create))
.action(Integration.Action.create)
.data(PermissionIntegration.Data.builder()
.domain(currentDomain)
.name(name)
.description(description)
.build())
.build());
return this;
}
/**
* Updates an existing permission in the current domain.
*
* @param oldName The current name of the permission to update
* @param newName The new name for the permission
* @param description The new description for the permission
* @return This builder instance for method chaining
* @throws IllegalStateException if no domain context has been set
*/
public IntegrationBuilder updatePermission(String oldName, String newName, String description) {
validateDomain();
integrations.add(PermissionIntegration.builder()
.id(generateIntegrationId("permission", currentDomain + ":" + oldName, Integration.Action.update))
.action(Integration.Action.update)
.data(PermissionIntegration.Data.builder()
.domain(currentDomain)
.name(newName)
.oldName(oldName)
.description(description)
.build())
.build());
return this;
}
/**
* Removes a permission from the current domain.
*
* @param name The name of the permission to remove
* @return This builder instance for method chaining
* @throws IllegalStateException if no domain context has been set
*/
public IntegrationBuilder removePermission(String name) {
validateDomain();
integrations.add(PermissionIntegration.builder()
.id(generateIntegrationId("permission", currentDomain + ":" + name, Integration.Action.delete))
.action(Integration.Action.delete)
.data(PermissionIntegration.Data.builder()
.domain(currentDomain)
.name(name)
.build())
.build());
return this;
}
/**
* Adds a new role to the current domain.
*
* @param name The name of the role
* @param description The description of the role
* @return This builder instance for method chaining
* @throws IllegalStateException if no domain context has been set
*/
public IntegrationBuilder addRole(String name, String description) {
validateDomain();
integrations.add(RoleIntegration.builder()
.id(generateIntegrationId("role", currentDomain + ":" + name, Integration.Action.create))
.action(Integration.Action.create)
.data(RoleIntegration.Data.builder()
.domain(currentDomain)
.name(name)
.description(description)
.build())
.build());
return this;
}
/**
* Updates an existing role in the current domain.
*
* @param oldName The current name of the role to update
* @param newName The new name for the role
* @param description The new description for the role
* @return This builder instance for method chaining
* @throws IllegalStateException if no domain context has been set
*/
public IntegrationBuilder updateRole(String oldName, String newName, String description) {
validateDomain();
integrations.add(RoleIntegration.builder()
.id(generateIntegrationId("role", currentDomain + ":" + oldName, Integration.Action.update))
.action(Integration.Action.update)
.data(RoleIntegration.Data.builder()
.domain(currentDomain)
.name(newName)
.oldName(oldName)
.description(description)
.build())
.build());
return this;
}
/**
* Removes a role from the current domain.
*
* @param name The name of the role to remove
* @return This builder instance for method chaining
* @throws IllegalStateException if no domain context has been set
*/
public IntegrationBuilder removeRole(String name) {
validateDomain();
integrations.add(RoleIntegration.builder()
.id(generateIntegrationId("role", currentDomain + ":" + name, Integration.Action.delete))
.action(Integration.Action.delete)
.data(RoleIntegration.Data.builder()
.domain(currentDomain)
.name(name)
.build())
.build());
return this;
}
/**
* Assigns a list of permissions to a role in the current domain.
*
* @param role The name of the role to assign permissions to
* @param permissions List of permission names to assign to the role
* @return This builder instance for method chaining
* @throws IllegalStateException if no domain context has been set
*/
public IntegrationBuilder assignPermissionsToRole(String role, List<String> permissions) {
validateDomain();
String permissionList = String.join(",", permissions);
integrations.add(RolePermissionRelationIntegration.builder()
.id(generateIntegrationId("role-permissions", currentDomain + ":" + role + ":" + permissionList, Integration.Action.create))
.action(Integration.Action.create)
.data(RolePermissionRelationIntegration.Data.builder()
.domain(currentDomain)
.role(role)
.permissions(permissions)
.build())
.build());
return this;
}
/**
* Builds and returns the list of integrations created by this builder.
*
* @return A new list containing all the integrations created by this builder
*/
public List<Integration<?>> build() {
return new ArrayList<>(integrations);
}
/**
* Validates that a domain context has been set by a previous domain operation.
*
* @throws IllegalStateException if no domain context has been set
*/
private void validateDomain() {
if (currentDomain == null || currentDomain.trim().isEmpty()) {
throw new IllegalStateException("No domain context set. Create, update, or select a domain first.");
}
}
/**
* Generates a deterministic integration ID based on the integration type, name, and action.
* This ensures that the same integration will always have the same ID across different runs.
*
* @param type The type of integration (domain, permission, role, etc.)
* @param name The unique name or identifier for this integration
* @param action The action being performed
* @return A deterministic ID string
*/
private String generateIntegrationId(String type, String name, Integration.Action action) {
return String.format("%s:%s:%s", type, name, action.name().toLowerCase());
}
}