Overview
Party is the abstract base class for all party types (Organization, Person). It manages roles and registered identifiers with policy enforcement and event tracking.
Package: com.softwarearchetypes.party
Source: /party/src/main/java/com/softwarearchetypes/party/Party.java:27
Class Hierarchy
public sealed abstract class Party permits Organization, Person
Party is a sealed class with two permitted subtypes:
Organization: Companies, organizational units
Person: Individual people
Constructor
Party(PartyId partyId,
Set<Role> roles,
Set<RegisteredIdentifier> registeredIdentifiers,
Version version,
RegisteredIdentifierDefiningPolicy identifierPolicy,
PartyRoleDefiningPolicy roleDefiningPolicy)
Initial roles (can be empty)
registeredIdentifiers
Set<RegisteredIdentifier>
required
Initial registered identifiers (can be empty)
Version for optimistic locking
identifierPolicy
RegisteredIdentifierDefiningPolicy
required
Policy for validating identifiers
roleDefiningPolicy
PartyRoleDefiningPolicy
required
Policy for validating roles
Accessor Methods
Returns the party identifier.
roles
Returns all roles assigned to this party.
registeredIdentifiers
final Set<RegisteredIdentifier> registeredIdentifiers()
Returns all registered identifiers.
return
Set<RegisteredIdentifier>
Immutable set of registered identifiers
version
Returns the current version.
The version for optimistic locking
events
List<PartyRelatedEvent> events()
Returns all events recorded by this party.
publishedEvents
List<PublishedEvent> publishedEvents()
Returns only events marked for publishing.
Role Management
add (Role)
Result<String, Party> add(Role role)
Adds a role to this party. The operation:
- Checks if role is allowed by policy
- If already present: records skip event (idempotent)
- If new: adds role and records success event
Success with updated Party, or failure with “POLICY_NOT_MET”
Example:
Role customerRole = Role.of("CUSTOMER");
Result<String, Party> result = party.add(customerRole);
if (result.success()) {
party = result.getSuccess();
// Event recorded: RoleAdded
assert party.roles().contains(customerRole);
} else {
System.out.println("Failed: " + result.getFailure());
}
// Adding same role again is idempotent
Result<String, Party> result2 = party.add(customerRole);
assert result2.success();
// Event recorded: RoleAdditionSkipped
remove (Role)
Result<String, Party> remove(Role role)
Removes a role from this party. The operation is always successful:
- If present: removes role and records removal event
- If not present: records skip event (idempotent)
Always succeeds with updated Party
Example:
Result<String, Party> result = party.remove(customerRole);
party = result.getSuccess();
assert !party.roles().contains(customerRole);
// Event recorded: RoleRemoved or RoleRemovalSkipped
Registered Identifier Management
add (RegisteredIdentifier)
Result<String, Party> add(RegisteredIdentifier identifier)
Adds a registered identifier. The operation:
- Checks if identifier is allowed by policy
- If already present: records skip event (idempotent)
- If new: adds identifier and records success event
identifier
RegisteredIdentifier
required
The identifier to add
Success with updated Party, or failure with “IDENTIFIER_NOT_ALLOWED_FOR_PARTY_TYPE”
Example:
// For a Person
PersonalIdentificationNumber pesel = new PersonalIdentificationNumber("12345678901");
Result<String, Party> result = person.add(pesel);
if (result.success()) {
person = result.getSuccess();
// Event recorded: RegisteredIdentifierAdded
assert person.registeredIdentifiers().contains(pesel);
} else {
System.out.println("Failed: " + result.getFailure());
}
// For an Organization
TaxNumber taxId = new TaxNumber("1234567890");
Result<String, Party> result2 = company.add(taxId);
// Event recorded: RegisteredIdentifierAdded
canRegister
boolean canRegister(RegisteredIdentifier identifier)
Checks if a given identifier can be registered for this party according to the policy.
identifier
RegisteredIdentifier
required
The identifier to check
true if identifier is allowed, false otherwise
Example:
PersonalIdentificationNumber pesel = new PersonalIdentificationNumber("12345678901");
if (person.canRegister(pesel)) {
person.add(pesel);
}
// Tax numbers not allowed for persons
TaxNumber taxId = new TaxNumber("1234567890");
assert !person.canRegister(taxId); // false
remove (RegisteredIdentifier)
Result<String, Party> remove(RegisteredIdentifier identifier)
Removes a registered identifier. The operation is always successful:
- If present: removes identifier and records removal event
- If not present: records skip event (idempotent)
identifier
RegisteredIdentifier
required
The identifier to remove
Always succeeds with updated Party
Events
The Party class generates the following events:
Role Events
RoleAdded: Role successfully added
RoleAdditionSkipped: Role already present
RoleRemoved: Role successfully removed
RoleRemovalSkipped: Role was not present
Identifier Events
RegisteredIdentifierAdded: Identifier successfully added
RegisteredIdentifierAdditionSkipped: Identifier already present
RegisteredIdentifierRemoved: Identifier successfully removed
RegisteredIdentifierRemovalSkipped: Identifier was not present
Policies
RegisteredIdentifierDefiningPolicy
Controls which identifiers can be registered for a party type.
Default policies:
// Allow all identifiers
Regis