diff --git a/config/initial-objects/object-templates/380-object-template-person.xml b/config/initial-objects/object-templates/380-object-template-person.xml
index 4087ecb84ac..1635f3aa5ec 100644
--- a/config/initial-objects/object-templates/380-object-template-person.xml
+++ b/config/initial-objects/object-templates/380-object-template-person.xml
@@ -101,4 +101,29 @@ oid="00000000-0000-0000-0000-000000000380">
fullName
+
+ generate-display-name
+ Generate displayName from preferredName, falling back to fullName.
+ strong
+
+ preferredName
+
+
+ fullName
+
+
+
+
+
+ displayName
+
+
diff --git a/config/initial-objects/report/110-report-user-list.xml b/config/initial-objects/report/110-report-user-list.xml
index 535c8bc9145..ea634859032 100644
--- a/config/initial-objects/report/110-report-user-list.xml
+++ b/config/initial-objects/report/110-report-user-list.xml
@@ -199,6 +199,11 @@
orgColumn
+
+ displayNameColumn
+ displayName
+ accountColumn
+ UserType
diff --git a/config/initial-objects/user/050-user-administrator.xml b/config/initial-objects/user/050-user-administrator.xml
index 1c794769599..ed5bcc761f6 100644
--- a/config/initial-objects/user/050-user-administrator.xml
+++ b/config/initial-objects/user/050-user-administrator.xml
@@ -12,6 +12,7 @@
administratortruemidPoint Administrator
+ midPoint AdministratormidPointAdministrator
diff --git a/config/sql/native/postgres-upgrade.sql b/config/sql/native/postgres-upgrade.sql
index 9c70813ea79..0ae43a73b43 100644
--- a/config/sql/native/postgres-upgrade.sql
+++ b/config/sql/native/postgres-upgrade.sql
@@ -1462,6 +1462,22 @@ CREATE INDEX m_connector_typeVersionHost_key
WHERE connectorHostRefTargetOid IS NOT NULL;
$aa$);
+-- @change: Adds display and preferred name columns and indexes to users.
+-- @since: 4.11
+-- @affects: table m_user | Modified table | Adds display and preferred name columns.
+-- @affects: index m_user_displayNameOrig_idx | New index | Supports lookup by original display name.
+-- @affects: index m_user_preferredNameOrig_idx | New index | Supports lookup by original preferred name.
+call apply_change(58, $aa$
+ALTER TABLE m_user
+ ADD COLUMN displayNameOrig TEXT,
+ ADD COLUMN displayNameNorm TEXT,
+ ADD COLUMN preferredNameOrig TEXT,
+ ADD COLUMN preferredNameNorm TEXT;
+
+CREATE INDEX m_user_displayNameOrig_idx ON m_user (displayNameOrig);
+CREATE INDEX m_user_preferredNameOrig_idx ON m_user (preferredNameOrig);
+$aa$);
+
---
-- WRITE CHANGES ABOVE ^^
-- IMPORTANT: update apply_change number at the end of postgres-new.sql
diff --git a/config/sql/native/postgres.sql b/config/sql/native/postgres.sql
index 5c52d2c32a5..89f5cab77fe 100644
--- a/config/sql/native/postgres.sql
+++ b/config/sql/native/postgres.sql
@@ -849,6 +849,10 @@ CREATE TABLE m_user (
additionalNameOrig TEXT,
-- @description: Additional name in normalized form used for searches.
additionalNameNorm TEXT,
+ -- @description: Display name in original form.
+ displayNameOrig TEXT,
+ -- @description: Display name in normalized form used for searches.
+ displayNameNorm TEXT,
-- @description: Employee number assigned to the user.
employeeNumber TEXT,
-- @description: Family name in original form.
@@ -877,6 +881,10 @@ CREATE TABLE m_user (
nickNameNorm TEXT,
-- @description: Personal number assigned to the user.
personalNumber TEXT,
+ -- @description: Preferred name in original form.
+ preferredNameOrig TEXT,
+ -- @description: Preferred name in normalized form used for searches.
+ preferredNameNorm TEXT,
-- @description: Title in original form.
titleOrig TEXT,
-- @description: Title in normalized form used for searches.
@@ -910,6 +918,9 @@ CREATE INDEX m_user_policySituation_idx ON m_user USING gin(policysituations gin
-- @description: Speeds up filtering by indexed extension values.
-- @usedFor: extension item filters
CREATE INDEX m_user_ext_idx ON m_user USING gin(ext);
+-- @description: Speeds up lookup by display name.
+-- @usedFor: display name searches
+CREATE INDEX m_user_displayNameOrig_idx ON m_user (displayNameOrig);
-- @description: Speeds up lookup by original full name.
-- @usedFor: full name searches
CREATE INDEX m_user_fullNameOrig_idx ON m_user (fullNameOrig);
@@ -922,6 +933,9 @@ CREATE INDEX m_user_givenNameOrig_idx ON m_user (givenNameOrig);
-- @description: Speeds up lookup by employee number.
-- @usedFor: employee number searches
CREATE INDEX m_user_employeeNumber_idx ON m_user (employeeNumber);
+-- @description: Speeds up lookup by preferred name.
+-- @usedFor: preferred name searches
+CREATE INDEX m_user_preferredNameOrig_idx ON m_user (preferredNameOrig);
-- @description: Speeds up filtering by object subtype.
-- @usedFor: subtype filters
CREATE INDEX m_user_subtypes_idx ON m_user USING gin(subtypes);
@@ -4155,4 +4169,4 @@ END $$;
-- This is important to avoid applying any change more than once.
-- Also update SqaleUtils.CURRENT_SCHEMA_CHANGE_NUMBER
-- repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleUtils.java
-call apply_change(57, $$ SELECT 1 $$, true);
+call apply_change(58, $$ SELECT 1 $$, true);
diff --git a/docs/repository/native-postgresql/scripts/postgres-upgrade.adoc b/docs/repository/native-postgresql/scripts/postgres-upgrade.adoc
index 808033bfda6..822ce9384cd 100644
--- a/docs/repository/native-postgresql/scripts/postgres-upgrade.adoc
+++ b/docs/repository/native-postgresql/scripts/postgres-upgrade.adoc
@@ -12,7 +12,7 @@ This page documents schema changes applied to existing databases by `config/sql/
| Changes range
| xref:postgres-upgrade/4.11.adoc[midPoint 4.11]
-| 52-57
+| 52-58
| xref:postgres-upgrade/4.10.adoc[midPoint 4.10]
| 51
@@ -46,6 +46,9 @@ This page documents schema changes applied to existing databases by `config/sql/
| Change
| Description
+| xref:postgres-upgrade/4.11.adoc#change-58[Change 58]
+| Adds display and preferred name columns and indexes to users.
+
| xref:postgres-upgrade/4.11.adoc#change-57[Change 57]
| Recreates connector type/version uniqueness indexes with connector-host specific predicates.
diff --git a/docs/repository/native-postgresql/scripts/postgres-upgrade/4.11.adoc b/docs/repository/native-postgresql/scripts/postgres-upgrade/4.11.adoc
index 7eb862e9614..d02e0a85866 100644
--- a/docs/repository/native-postgresql/scripts/postgres-upgrade/4.11.adoc
+++ b/docs/repository/native-postgresql/scripts/postgres-upgrade/4.11.adoc
@@ -7,6 +7,9 @@
| Change
| Description
+| <>
+| Adds display and preferred name columns and indexes to users.
+
| <>
| Recreates connector type/version uniqueness indexes with connector-host specific predicates.
@@ -27,6 +30,33 @@
|===
+[[change-58]]
+== Change 58
+
+Since version: 4.11
+
+Adds display and preferred name columns and indexes to users.
+
+[cols="1,1,3", options="header"]
+|===
+| Object
+| Change type
+| Description
+
+| `m_user`
+| Modified table
+| Adds display and preferred name columns.
+
+| `m_user_displayNameOrig_idx`
+| New index
+| Supports lookup by original display name.
+
+| `m_user_preferredNameOrig_idx`
+| New index
+| Supports lookup by original preferred name.
+
+|===
+
[[change-57]]
== Change 57
diff --git a/docs/repository/native-postgresql/scripts/postgres/focus-and-users.adoc b/docs/repository/native-postgresql/scripts/postgres/focus-and-users.adoc
index 4a648ddf57a..b807749a268 100644
--- a/docs/repository/native-postgresql/scripts/postgres/focus-and-users.adoc
+++ b/docs/repository/native-postgresql/scripts/postgres/focus-and-users.adoc
@@ -463,6 +463,16 @@ Inherits from: xref:#m_focus[`m_focus`]
|
| Additional name in normalized form used for searches.
+| `displayNameOrig`
+| `TEXT`
+|
+| Display name in original form.
+
+| `displayNameNorm`
+| `TEXT`
+|
+| Display name in normalized form used for searches.
+
| `employeeNumber`
| `TEXT`
|
@@ -533,6 +543,16 @@ Inherits from: xref:#m_focus[`m_focus`]
|
| Personal number assigned to the user.
+| `preferredNameOrig`
+| `TEXT`
+|
+| Preferred name in original form.
+
+| `preferredNameNorm`
+| `TEXT`
+|
+| Preferred name in normalized form used for searches.
+
| `titleOrig`
| `TEXT`
|
@@ -579,6 +599,10 @@ Inherits from: xref:#m_focus[`m_focus`]
| `USING gin (ext)`
| Speeds up filtering by indexed extension values. Used for: extension item filters
+| `m_user_displayNameOrig_idx`
+| `displayNameOrig`
+| Speeds up lookup by display name. Used for: display name searches
+
| `m_user_fullNameOrig_idx`
| `fullNameOrig`
| Speeds up lookup by original full name. Used for: full name searches
@@ -595,6 +619,10 @@ Inherits from: xref:#m_focus[`m_focus`]
| `employeeNumber`
| Speeds up lookup by employee number. Used for: employee number searches
+| `m_user_preferredNameOrig_idx`
+| `preferredNameOrig`
+| Speeds up lookup by preferred name. Used for: preferred name searches
+
| `m_user_subtypes_idx`
| `USING gin (subtypes)`
| Speeds up filtering by object subtype. Used for: subtype filters
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java
index 8857e228edf..3d62ae0751c 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java
@@ -342,14 +342,9 @@ public static String getReferencedObjectDisplayNameAndName(Referencable ref, boo
return getReferencedObjectDisplayNamesAndNames(ref, false, true);
}
ObjectType object = prismObject.asObjectable();
- String displayName = null;
- if (object instanceof UserType) {
- displayName = getTranslatedPolyString(((UserType) object).getFullName());
- } else if (object instanceof AbstractRoleType) {
- displayName = getTranslatedPolyString(((AbstractRoleType) object).getDisplayName());
- }
+ String displayName = getTranslatedPolyString(ObjectTypeUtil.getDisplayName(object));
String name = getTranslatedPolyString(object.getName());
- return StringUtils.isNotEmpty(displayName) ? displayName + " (" + name + ")" : name;
+ return StringUtils.isNotEmpty(displayName) && !Objects.equals(displayName, name) ? displayName + " (" + name + ")" : name;
}
public static String getReferencedObjectDisplayNamesAndNames(List refs, boolean showTypes) {
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchBoxConfigurationBuilder.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchBoxConfigurationBuilder.java
index 83acb6a3f18..52168cd7553 100755
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchBoxConfigurationBuilder.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchBoxConfigurationBuilder.java
@@ -55,7 +55,8 @@ public class SearchBoxConfigurationBuilder {
ItemPath.create(ObjectType.F_NAME))
);
FIXED_SEARCH_ITEMS.put(UserType.class, Arrays.asList(
- ItemPath.create(UserType.F_FULL_NAME)
+ ItemPath.create(UserType.F_FULL_NAME),
+ ItemPath.create(UserType.F_DISPLAY_NAME)
));
FIXED_SEARCH_ITEMS.put(AbstractRoleType.class, Arrays.asList(
ItemPath.create(RoleType.F_DISPLAY_NAME)
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchableItemsDefinitions.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchableItemsDefinitions.java
index 738c87d0026..6e94563ac94 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchableItemsDefinitions.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/component/search/SearchableItemsDefinitions.java
@@ -100,6 +100,7 @@ public SearchableItemsDefinitions additionalSearchContext(SearchContext ctx) {
ItemPath.create(UserType.F_GIVEN_NAME),
ItemPath.create(UserType.F_FAMILY_NAME),
ItemPath.create(UserType.F_FULL_NAME),
+ ItemPath.create(UserType.F_DISPLAY_NAME),
ItemPath.create(UserType.F_ADDITIONAL_NAME),
ItemPath.create(UserType.F_EMPLOYEE_NUMBER),
ItemPath.create(UserType.F_ORGANIZATIONAL_UNIT),
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/page/self/requestAccess/AccessRequestMixin.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/page/self/requestAccess/AccessRequestMixin.java
index 0bcb4a0223c..e42be52c6f9 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/page/self/requestAccess/AccessRequestMixin.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/impl/page/self/requestAccess/AccessRequestMixin.java
@@ -8,7 +8,6 @@
import java.util.function.Function;
-import org.apache.commons.lang3.StringUtils;
import org.apache.wicket.Page;
import com.evolveum.midpoint.gui.api.page.PageBase;
@@ -22,6 +21,7 @@
import com.evolveum.midpoint.schema.constants.ExpressionConstants;
import com.evolveum.midpoint.schema.expression.VariablesMap;
import com.evolveum.midpoint.schema.result.OperationResult;
+import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.DOMUtil;
@@ -74,8 +74,8 @@ default ObjectFilter createAutocompleteFilter(String text, SearchFilterType filt
default String getDefaultUserDisplayName(PrismObject o) {
String name = WebComponentUtil.getOrigStringFromPoly(o.getName());
- String fullName = WebComponentUtil.getOrigStringFromPoly(o.asObjectable().getFullName());
+ String displayName = WebComponentUtil.getOrigStringFromPoly(ObjectTypeUtil.getDisplayName(o));
- return StringUtils.isNotEmpty(fullName) ? fullName + " (" + name + ")" : name;
+ return displayName != null && !displayName.equals(name) ? displayName + " (" + name + ")" : name;
}
}
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/DelegationEditorPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/DelegationEditorPanel.java
index 8279f63d931..4f7af882aa5 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/DelegationEditorPanel.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/DelegationEditorPanel.java
@@ -11,6 +11,7 @@
import com.evolveum.midpoint.gui.api.model.LoadableModel;
import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.api.util.LocalizationUtil;
+import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils;
import com.evolveum.midpoint.gui.impl.component.input.DateTimePickerPanel;
import com.evolveum.midpoint.gui.impl.page.admin.user.PageUser;
@@ -624,8 +625,8 @@ private String getUserDisplayName(){
} else {
UserType delegationUser = getModelObject().getDelegationOwner();
if (getModelObject().getDelegationOwner() != null) {
- if (delegationUser.getFullName() != null && StringUtils.isNotEmpty(delegationUser.getFullName().getOrig())) {
- displayName = delegationUser.getFullName().getOrig() + " (" + delegationUser.getName().getOrig() + ")";
+ if (delegationUser.getDisplayName() != null && StringUtils.isNotEmpty(delegationUser.getDisplayName().getOrig())) {
+ displayName = delegationUser.getDisplayName().getOrig() + " (" + delegationUser.getName().getOrig() + ")";
} else {
displayName = delegationUser.getName() != null ? delegationUser.getName().getOrig() : "";
}
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/column/ColumnUtils.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/column/ColumnUtils.java
index 5686985950d..04fbf214064 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/column/ColumnUtils.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/column/ColumnUtils.java
@@ -321,6 +321,8 @@ public static List, String>> ge
SelectableBeanImpl.F_VALUE + ".familyName", false, true),
new ColumnTypeDto<>("UserType.fullName", UserType.F_FULL_NAME.getLocalPart(),
SelectableBeanImpl.F_VALUE + ".fullName", false, true),
+ new ColumnTypeDto<>("UserType.displayName", UserType.F_DISPLAY_NAME.getLocalPart(),
+ SelectableBeanImpl.F_VALUE + ".displayName", false, true),
new ColumnTypeDto<>("UserType.emailAddress", UserType.F_EMAIL_ADDRESS.getLocalPart(),
SelectableBeanImpl.F_VALUE + ".emailAddress", false)
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/menu/SideBarMenuPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/menu/SideBarMenuPanel.java
index c667fe8e9f7..35b269d7495 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/menu/SideBarMenuPanel.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/menu/SideBarMenuPanel.java
@@ -36,6 +36,7 @@
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.model.api.authentication.CompiledGuiProfile;
import com.evolveum.midpoint.model.api.authentication.GuiProfiledPrincipal;
+import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.security.api.MidPointPrincipal;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
@@ -132,6 +133,9 @@ private String getShortUserName() {
}
if (principalObj instanceof MidPointPrincipal principal) {
+ if (principal.getFocus() != null) {
+ return WebComponentUtil.getOrigStringFromPoly(ObjectTypeUtil.getDisplayName(principal.getFocus()));
+ }
return WebComponentUtil.getOrigStringFromPoly(principal.getName());
}
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCampaignDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCampaignDto.java
index 7dc60da3399..aad0cbf9ae4 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCampaignDto.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCampaignDto.java
@@ -21,6 +21,8 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
+import org.apache.commons.lang3.StringUtils;
+
import static com.evolveum.midpoint.gui.api.page.PageBase.createEnumResourceKey;
import static com.evolveum.midpoint.gui.api.page.PageBase.createStringResourceStatic;
import static com.evolveum.midpoint.schema.util.CertCampaignTypeUtil.norm;
@@ -65,7 +67,7 @@ public static String resolveOwnerName(ObjectReferenceType ownerRef, PageBase pag
ObjectType owner = ownerObject.asObjectable();
if (owner instanceof UserType) {
UserType user = (UserType) owner;
- return WebComponentUtil.getName(user) + " (" + WebComponentUtil.getOrigStringFromPoly(user.getFullName()) + ")";
+ return WebComponentUtil.getName(user) + " (" + WebComponentUtil.getOrigStringFromPoly(user.getDisplayName()) + ")";
} else {
return WebComponentUtil.getName(owner);
}
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/handlers/DirectAssignmentCertGuiHandler.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/handlers/DirectAssignmentCertGuiHandler.java
index dc353d924b0..a7fb1588f66 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/handlers/DirectAssignmentCertGuiHandler.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/handlers/DirectAssignmentCertGuiHandler.java
@@ -73,16 +73,16 @@ public String getCaseInfoButtonTitle(IModel extends CertCaseOrWorkItemDto> row
String objectType = getLocalizedTypeName(acase.getObjectRef().getType(), page);
String objectName = dto.getObjectName();
- // If object is UserType, display user's fullName in addition to the name
+ // If object is UserType, display user's displayName in addition to the name
if (QNameUtil.match(acase.getObjectRef().getType(), UserType.COMPLEX_TYPE)) {
try {
PrismObject object = page.getModelService().getObject(UserType.class, acase.getObjectRef().getOid(), null, page.getPageTask(), page.getPageTask().getResult());
if (object != null) {
UserType userObj = object.asObjectable();
- PolyStringType fullName = userObj.getFullName();
- if (fullName != null && !StringUtils.isEmpty(fullName.getOrig())) {
- objectName = fullName.getOrig() + " (" + objectName + ")";
+ PolyStringType displayName = userObj.getDisplayName();
+ if (displayName != null && !StringUtils.isEmpty(displayName.getOrig())) {
+ objectName = displayName.getOrig() + " (" + objectName + ")";
}
}
} catch (Exception e) {
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/MergeObjectDetailsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/MergeObjectDetailsPanel.java
index c0611a11b08..8459fcfc0d6 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/MergeObjectDetailsPanel.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/MergeObjectDetailsPanel.java
@@ -36,7 +36,7 @@ private void initLayout(Class type){
Label fullNameLabel;
if (UserType.class.equals(type)){
- fullNameLabel = new Label(ID_OBJECT_FULLNAME, ((UserType) mergeObject).getFullName());
+ fullNameLabel = new Label(ID_OBJECT_FULLNAME, ((UserType) mergeObject).getDisplayName());
} else {
fullNameLabel = new Label(ID_OBJECT_FULLNAME, ((AbstractRoleType) mergeObject).getDisplayName());
}
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/UserSummaryPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/UserSummaryPanel.java
index 12456137a3f..830c5abc226 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/UserSummaryPanel.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/UserSummaryPanel.java
@@ -13,11 +13,11 @@
import com.evolveum.midpoint.gui.impl.util.RelationUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
-import org.apache.wicket.model.IModel;
-
import com.evolveum.midpoint.gui.api.GuiStyleConstants;
+import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.web.component.FocusSummaryPanel;
import com.evolveum.midpoint.web.component.util.SummaryTag;
+import org.apache.wicket.model.IModel;
/**
* @author semancik
@@ -123,8 +123,8 @@ protected void initialize(UserType object) {
}
@Override
- protected QName getDisplayNamePropertyName() {
- return UserType.F_FULL_NAME;
+ protected IModel getDisplayNameModel() {
+ return () -> WebComponentUtil.getDisplayName(getModelObject().asPrismObject());
}
@Override
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/PageAttorneySelection.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/PageAttorneySelection.java
index 2b56e8375b9..0c11d28f821 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/PageAttorneySelection.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/PageAttorneySelection.java
@@ -169,6 +169,10 @@ private List, String>> initColumns() {
UserType.F_FAMILY_NAME.getLocalPart(), SelectableBeanImpl.F_VALUE + ".familyName");
columns.add(column);
+ column = new PropertyColumn<>(createStringResource("UserType.displayName"),
+ UserType.F_DISPLAY_NAME.getLocalPart(), SelectableBeanImpl.F_VALUE + ".displayName");
+ columns.add(column);
+
column = new PropertyColumn<>(createStringResource("UserType.fullName"),
UserType.F_FULL_NAME.getLocalPart(), SelectableBeanImpl.F_VALUE + ".fullName");
columns.add(column);
diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java
index cf7902a4ef7..2d2dfbfc1bd 100644
--- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java
+++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java
@@ -690,13 +690,24 @@ public static PolyStringType getDisplayName(PrismObject> object) {
}
public static PolyStringType getDisplayName(ObjectType object) {
- if (object instanceof AbstractRoleType) {
- return ((AbstractRoleType) object).getDisplayName();
+ if (object == null) {
+ return null;
+ } else if (object instanceof AbstractRoleType) {
+ return firstNonEmpty(((AbstractRoleType) object).getDisplayName(), object.getName());
} else if (object instanceof UserType) {
- return ((UserType) object).getFullName();
+ return firstNonEmpty(((UserType) object).getDisplayName(), ((UserType) object).getFullName(), object.getName());
} else {
- return null;
+ return object.getName();
+ }
+ }
+
+ private static PolyStringType firstNonEmpty(PolyStringType... values) {
+ for (PolyStringType value : values) {
+ if (StringUtils.isNotBlank(getOrig(value))) {
+ return value;
+ }
}
+ return null;
}
public static PolyStringType getDisplayName(Referencable ref) {
@@ -884,16 +895,16 @@ public static LocalizableMessage createDisplayInformation(PrismObject> object,
}
/**
- * - User name is in the form of "full name (object name)".
+ * - User name is in the form of "display name (object name)".
* - Names for other objects are either "detailed display name" ({@link #getDetailedDisplayName(Objectable)}) or plain name.
*/
private static Object getDescriptiveName(Objectable object) {
if (object instanceof UserType) {
- PolyStringType fullName = ((UserType) object).getFullName();
- if (fullName != null) {
+ PolyStringType displayName = ((UserType) object).getDisplayName();
+ if (displayName != null) {
return new LocalizableMessageBuilder()
.key(SchemaConstants.USER_DESCRIPTIVE_NAME)
- .arg(fullName)
+ .arg(displayName)
.arg(object.getName())
.build();
} else {
@@ -1112,7 +1123,7 @@ public static Collection createObjectRefs(Collection object) {
@@ -1122,7 +1133,7 @@ public static String getDetailedDisplayName(PrismObject> object) {
public static String getDetailedDisplayName(Objectable objectable) {
if (objectable instanceof UserType) {
- return getOrig(((UserType) objectable).getFullName());
+ return getOrig(((UserType) objectable).getDisplayName());
} else if (objectable instanceof AbstractRoleType) {
return getOrig(((AbstractRoleType) objectable).getDisplayName());
} else if (objectable instanceof ShadowType) {
diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd
index c3f935be45b..6d14e7ca980 100755
--- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd
+++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd
@@ -2123,6 +2123,61 @@
+
+
+
+
+ Preferred name of the user. This is the name that the user prefers
+ to use for display purposes. It does not replace legal-name attributes
+ such as given name, family name, or full name, and it is not intended
+ to be used as a login name, account identifier, or correlation identifier.
+
+ Effective visible name of the user for presentation-oriented display.
+ This property is intended to hold the user's preferred display value
+ for UI, reporting, and outbound provisioning scenarios where a visible
+ name is needed. It is distinct from the legal/full name and from login
+ or account identifiers.
+
+
+
+ UserType.displayNameProperty
+ 106
+ emphasized
+ read
+
+ user-overview
+ include
+
+ UserType.displayNameProperty.help
+
+
+
+
diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-gui-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-gui-3.xsd
index 8fb381cb3a0..1d6ee2ab9dc 100644
--- a/infra/schema/src/main/resources/xml/ns/public/common/common-gui-3.xsd
+++ b/infra/schema/src/main/resources/xml/ns/public/common/common-gui-3.xsd
@@ -436,7 +436,7 @@
Expression that can be used to return String value which describes user object returned by search.
- By default, `user.getFullName() + "(" + user.getName() + ")"` is used.
+ By default, `user.getDisplayName() + " (" + user.getName() + ")"` is used.
DEPRECATED:
Use autocompleteConfiguration.
diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java
index 5ae261ac512..66f94e4027f 100644
--- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java
+++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/util/SchemaTestUtil.java
@@ -47,6 +47,13 @@ public static void assertUserDefinition(PrismObjectDefinition userDefi
PrismAsserts.assertPropertyDefinition(userDefinition, UserType.F_FULL_NAME, SchemaConstants.T_POLY_STRING_TYPE, 0, 1);
PrismAsserts.assertItemDefinitionDisplayName(userDefinition, UserType.F_FULL_NAME, "UserType.fullName");
PrismAsserts.assertItemDefinitionDisplayOrder(userDefinition, UserType.F_FULL_NAME, 100);
+ PrismAsserts.assertPropertyDefinition(userDefinition, UserType.F_PREFERRED_NAME, SchemaConstants.T_POLY_STRING_TYPE, 0, 1);
+ PrismAsserts.assertItemDefinitionDisplayName(userDefinition, UserType.F_PREFERRED_NAME, "UserType.preferredName");
+ PrismAsserts.assertItemDefinitionDisplayOrder(userDefinition, UserType.F_PREFERRED_NAME, 105);
+ PrismAsserts.assertPropertyDefinition(userDefinition, UserType.F_DISPLAY_NAME, SchemaConstants.T_POLY_STRING_TYPE, 0, 1);
+ PrismAsserts.assertItemDefinitionDisplayName(userDefinition, UserType.F_DISPLAY_NAME, "UserType.displayNameProperty");
+ PrismAsserts.assertItemDefinitionDisplayOrder(userDefinition, UserType.F_DISPLAY_NAME, 106);
+ assertFalse("displayName is modifiable", userDefinition.findPropertyDefinition(UserType.F_DISPLAY_NAME).canModify());
PrismAsserts.assertPropertyDefinition(userDefinition, UserType.F_GIVEN_NAME, PrismConstants.POLYSTRING_TYPE_QNAME, 0, 1);
PrismAsserts.assertPropertyDefinition(userDefinition, UserType.F_FAMILY_NAME, PrismConstants.POLYSTRING_TYPE_QNAME, 0, 1);
PrismAsserts.assertPropertyDefinition(userDefinition, UserType.F_ADDITIONAL_NAME, PrismConstants.POLYSTRING_TYPE_QNAME, 0, 1);
diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/DefaultColumnUtils.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/DefaultColumnUtils.java
index 429c9e1bb27..814ecf67fa2 100644
--- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/DefaultColumnUtils.java
+++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/util/DefaultColumnUtils.java
@@ -70,6 +70,7 @@ public class DefaultColumnUtils {
new ColumnWrapper(UserType.F_NAME, true),
new ColumnWrapper(UserType.F_PERSONAL_NUMBER, true),
new ColumnWrapper(UserType.F_FULL_NAME, true),
+ new ColumnWrapper(UserType.F_DISPLAY_NAME, true),
new ColumnWrapper(UserType.F_EMAIL_ADDRESS),
new ColumnWrapper(UserType.F_LINK_REF, "FocusType.accounts", DisplayValueType.NUMBER)))
.put(AbstractRoleType.class, Arrays.asList(
diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/visualizer/Visualizer.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/visualizer/Visualizer.java
index 60c713fe761..ee22e1be382 100644
--- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/visualizer/Visualizer.java
+++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/visualizer/Visualizer.java
@@ -1069,7 +1069,7 @@ private NameImpl createVisualizationName(PrismObject extends ObjectType> objec
ObjectType objectType = object.asObjectable();
name.setDescription(objectType.getDescription());
if (objectType instanceof UserType) {
- name.setDisplayName(getOrig(((UserType) objectType).getFullName()));
+ name.setDisplayName(getOrig(((UserType) objectType).getDisplayName()));
} else if (objectType instanceof AbstractRoleType) {
name.setDisplayName(getOrig(((AbstractRoleType) objectType).getDisplayName()));
}
diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java
index abda5b32de5..c49b720a488 100644
--- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java
+++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestUserTemplate.java
@@ -76,6 +76,15 @@ public class TestUserTemplate extends AbstractInitializedModelIntegrationTest {
private static final TestObject> USER_TEMPLATE_MID_6045 = TestObject.file(
TEST_DIR, "user-template-mid-6045.xml", "f3dbd582-11dc-473f-8b51-a30be5cbd5ce");
+ private static final TestObject OBJECT_TEMPLATE_PERSON = TestObject.file(
+ new File("../../repo/system-init/src/main/resources/initial-objects/object-templates"),
+ "380-object-template-person.xml",
+ "00000000-0000-0000-0000-000000000380");
+ private static final TestObject ARCHETYPE_PERSON = TestObject.file(
+ new File("../../repo/system-init/src/main/resources/initial-objects/archetype"),
+ "702-archetype-person.xml",
+ "00000000-0000-0000-0000-000000000702");
+
private static final String ACCOUNT_STAN_USERNAME = "stan";
private static final String ACCOUNT_STAN_FULLNAME = "Stan the Salesman";
@@ -115,6 +124,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
repoAddObjectFromFile(USER_TEMPLATE_USELESS_FILE, initResult);
repoAdd(USER_TEMPLATE_MID_5892, initResult);
repoAdd(USER_TEMPLATE_MID_6045, initResult);
+ repoAdd(OBJECT_TEMPLATE_PERSON, initResult);
+ repoAdd(ARCHETYPE_PERSON, initResult);
setDefaultObjectTemplate(UserType.COMPLEX_TYPE, USER_TEMPLATE_COMPLEX_OID, initResult);
setDefaultObjectTemplate(UserType.COMPLEX_TYPE, SUBTYPE_MAROONED, USER_TEMPLATE_MAROONED_OID, initResult);
@@ -166,6 +177,67 @@ public void test000Sanity() throws Exception {
assertRoles(getNumberOfRoles());
}
+ /**
+ * MID-8802: Verifies that the person object template derives displayName from preferredName,
+ * falling back to fullName when no preferred name is provided.
+ *
+ * Also verifies that displayName is not maintained automatically for users
+ * without the person archetype.
+ */
+ @Test
+ public void test050PersonTemplateDisplayNameMapping() throws Exception {
+ Task task = getTestTask();
+ OperationResult result = getTestOperationResult();
+
+ when("person user with preferred name is added");
+ String personOid = addObject(
+ new UserType()
+ .name("test050-person")
+ .givenName("Person")
+ .familyName("Template")
+ .fullName("Person Template")
+ .preferredName("Preferred Person")
+ .assignment(new AssignmentType()
+ .targetRef(ARCHETYPE_PERSON.oid, ArchetypeType.COMPLEX_TYPE)),
+ task,
+ result);
+
+ then("displayName is generated from preferredName");
+ assertUserProperty(personOid, UserType.F_DISPLAY_NAME, PolyString.fromOrig("Preferred Person"));
+
+ when("fullName inputs change while preferredName is present");
+ modifyUserReplace(personOid, UserType.F_GIVEN_NAME, task, result, PolyString.fromOrig("Changed"));
+ modifyUserReplace(personOid, UserType.F_FAMILY_NAME, task, result, PolyString.fromOrig("Full Name"));
+
+ then("displayName still follows preferredName");
+ assertUserProperty(personOid, UserType.F_DISPLAY_NAME, PolyString.fromOrig("Preferred Person"));
+
+ when("preferredName is cleared");
+ modifyUserReplace(personOid, UserType.F_PREFERRED_NAME, task, result);
+
+ then("displayName falls back to fullName");
+ assertUserProperty(personOid, UserType.F_DISPLAY_NAME, PolyString.fromOrig("Changed Full Name"));
+
+ when("fullName inputs change without preferredName");
+ modifyUserReplace(personOid, UserType.F_GIVEN_NAME, task, result, PolyString.fromOrig("New"));
+ modifyUserReplace(personOid, UserType.F_FAMILY_NAME, task, result, PolyString.fromOrig("Full Name"));
+
+ then("displayName follows fullName");
+ assertUserProperty(personOid, UserType.F_DISPLAY_NAME, PolyString.fromOrig("New Full Name"));
+
+ when("plain user without person archetype is added");
+ String plainOid = addObject(
+ new UserType()
+ .name("test050-plain")
+ .fullName("Plain Full Name")
+ .preferredName("Plain Preferred Name"),
+ task,
+ result);
+
+ then("displayName is not generated globally");
+ assertUserNoProperty(plainOid, UserType.F_DISPLAY_NAME);
+ }
+
@SuppressWarnings("SameParameterValue")
private void assertObjectTemplate(List defaultObjectPolicyConfigurations,
QName objectType, String subtype, String userTemplateOid) {
diff --git a/model/model-intest/src/test/resources/common/user-administrator.xml b/model/model-intest/src/test/resources/common/user-administrator.xml
index 4196346699b..4fdc30fc505 100644
--- a/model/model-intest/src/test/resources/common/user-administrator.xml
+++ b/model/model-intest/src/test/resources/common/user-administrator.xml
@@ -12,6 +12,7 @@
administratortruemidPoint Administrator
+ midPoint AdministratormidPointAdministratoradministrator@evolveum.com
diff --git a/model/model-intest/src/test/resources/common/user-barbossa.xml b/model/model-intest/src/test/resources/common/user-barbossa.xml
index 45cf145cc79..981d8c6a0c7 100644
--- a/model/model-intest/src/test/resources/common/user-barbossa.xml
+++ b/model/model-intest/src/test/resources/common/user-barbossa.xml
@@ -20,6 +20,7 @@
Hector Barbossa
+ Hector BarbossaHectorBarbossaCaribbean
diff --git a/model/model-intest/src/test/resources/common/user-capsize.xml b/model/model-intest/src/test/resources/common/user-capsize.xml
index 99184243f7b..398614b0047 100644
--- a/model/model-intest/src/test/resources/common/user-capsize.xml
+++ b/model/model-intest/src/test/resources/common/user-capsize.xml
@@ -38,6 +38,7 @@
Kate Capsize
+ Kate CapsizeKateCapsizeCaptain
diff --git a/model/model-intest/src/test/resources/common/user-drake.xml b/model/model-intest/src/test/resources/common/user-drake.xml
index c32c54352dc..a39e3cf22c5 100644
--- a/model/model-intest/src/test/resources/common/user-drake.xml
+++ b/model/model-intest/src/test/resources/common/user-drake.xml
@@ -17,6 +17,7 @@
Golden HindFrancis Drake
+ Francis DrakeFancisDrakeSir
diff --git a/model/model-intest/src/test/resources/common/user-elaine.xml b/model/model-intest/src/test/resources/common/user-elaine.xml
index cbd7114a9ef..c1a7ab8fbc9 100644
--- a/model/model-intest/src/test/resources/common/user-elaine.xml
+++ b/model/model-intest/src/test/resources/common/user-elaine.xml
@@ -37,6 +37,7 @@
Elaine Marley
+ Elaine MarleyElaineMarleyMelee Island
diff --git a/model/model-intest/src/test/resources/common/user-guybrush.xml b/model/model-intest/src/test/resources/common/user-guybrush.xml
index 5882c234e3a..e746a4c7b1f 100644
--- a/model/model-intest/src/test/resources/common/user-guybrush.xml
+++ b/model/model-intest/src/test/resources/common/user-guybrush.xml
@@ -17,6 +17,7 @@
Guybrush Threepwood
+ Guybrush ThreepwoodGuybrushThreepwoodMelee Island
diff --git a/model/model-intest/src/test/resources/common/user-herman.xml b/model/model-intest/src/test/resources/common/user-herman.xml
index 4a221564df0..38e0b98b76e 100644
--- a/model/model-intest/src/test/resources/common/user-herman.xml
+++ b/model/model-intest/src/test/resources/common/user-herman.xml
@@ -20,6 +20,7 @@
Herman Toothrot
+ Herman ToothrotHermanToothrotMonkey Island
diff --git a/model/model-intest/src/test/resources/common/user-jack.xml b/model/model-intest/src/test/resources/common/user-jack.xml
index d08603d52da..745ef2a1a6b 100644
--- a/model/model-intest/src/test/resources/common/user-jack.xml
+++ b/model/model-intest/src/test/resources/common/user-jack.xml
@@ -22,6 +22,7 @@
0Jack Sparrow
+ Jack SparrowJackSparrowJackie
diff --git a/model/model-intest/src/test/resources/common/user-nooid.xml b/model/model-intest/src/test/resources/common/user-nooid.xml
index 44f7028747a..123848de81d 100644
--- a/model/model-intest/src/test/resources/common/user-nooid.xml
+++ b/model/model-intest/src/test/resources/common/user-nooid.xml
@@ -15,6 +15,7 @@
nooidUser with No OIDNeville Nooid
+ Neville NooidNevilleNooid
diff --git a/model/model-intest/src/test/resources/common/user-three-headed-monkey.xml b/model/model-intest/src/test/resources/common/user-three-headed-monkey.xml
index 3f8f274d4ac..3341b3c5229 100644
--- a/model/model-intest/src/test/resources/common/user-three-headed-monkey.xml
+++ b/model/model-intest/src/test/resources/common/user-three-headed-monkey.xml
@@ -14,5 +14,6 @@
xmlns:piracy='http://midpoint.evolveum.com/xml/ns/samples/piracy'>
monkeyThree-Headed Monkey
+ Three-Headed MonkeyMonkey
diff --git a/model/model-intest/src/test/resources/preview/user-rogers.xml b/model/model-intest/src/test/resources/preview/user-rogers.xml
index 9f889264d0c..ac0d3f75814 100644
--- a/model/model-intest/src/test/resources/preview/user-rogers.xml
+++ b/model/model-intest/src/test/resources/preview/user-rogers.xml
@@ -21,6 +21,7 @@
Rum Rogers Sr.
+ Rum Rogers Sr.RumRogers
diff --git a/model/model-intest/src/test/resources/security/role-limited-user-admin.xml b/model/model-intest/src/test/resources/security/role-limited-user-admin.xml
index d66983224bb..6ffc2eec209 100644
--- a/model/model-intest/src/test/resources/security/role-limited-user-admin.xml
+++ b/model/model-intest/src/test/resources/security/role-limited-user-admin.xml
@@ -29,6 +29,7 @@
descriptiongivenNamefullName
+ displayNamefamilyNametitlelocality
@@ -49,6 +50,7 @@
descriptiongivenNamefullName
+ displayNamenickNamefamilyNametitle
diff --git a/model/model-intest/src/test/resources/security/role-prop-get-search-some-modify-some-user.xml b/model/model-intest/src/test/resources/security/role-prop-get-search-some-modify-some-user.xml
index 9f473d0ab59..81cb72ed41b 100644
--- a/model/model-intest/src/test/resources/security/role-prop-get-search-some-modify-some-user.xml
+++ b/model/model-intest/src/test/resources/security/role-prop-get-search-some-modify-some-user.xml
@@ -42,6 +42,7 @@
fullName
+ displayNameadditionalNamedescriptionactivation/validFrom
diff --git a/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some-user-partial.xml b/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some-user-partial.xml
index c7f632722c8..96f8bb188c7 100644
--- a/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some-user-partial.xml
+++ b/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some-user-partial.xml
@@ -36,6 +36,7 @@
fullName
+ displayNamedescription
diff --git a/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some-user.xml b/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some-user.xml
index 18c5da7e105..054140425d4 100644
--- a/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some-user.xml
+++ b/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some-user.xml
@@ -36,6 +36,7 @@
fullName
+ displayNamedescription
diff --git a/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some.xml b/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some.xml
index 87af9ef44c3..f86d1bae4b5 100644
--- a/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some.xml
+++ b/model/model-intest/src/test/resources/security/role-prop-read-all-modify-some.xml
@@ -17,6 +17,7 @@
AUTZreadAllModify2http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#modifyc:fullName
+ c:displayNamec:descriptionextension/shipextension/weapon
diff --git a/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-fullname.xml b/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-fullname.xml
index 1baf5595e0b..8b9ac935eff 100644
--- a/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-fullname.xml
+++ b/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-fullname.xml
@@ -68,6 +68,7 @@
givenNamec:fullName
+ c:displayNamec:additionalNamec:descriptionc:organization
diff --git a/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-req-exec.xml b/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-req-exec.xml
index 65874d57485..f001cfeccfc 100644
--- a/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-req-exec.xml
+++ b/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-req-exec.xml
@@ -45,6 +45,7 @@
http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#modifyexecutionc:fullName
+ c:displayNamec:additionalNamec:descriptionc:organization
diff --git a/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-user.xml b/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-user.xml
index 0c192d9d96f..c70ce8b0a33 100644
--- a/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-user.xml
+++ b/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some-user.xml
@@ -40,6 +40,7 @@
fullName
+ displayNameadditionalNamedescriptionactivation/validFrom
diff --git a/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some.xml b/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some.xml
index cfd3e3d30b5..609dfbaa512 100644
--- a/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some.xml
+++ b/model/model-intest/src/test/resources/security/role-prop-read-some-modify-some.xml
@@ -21,6 +21,7 @@
modify-somehttp://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#modifyfullName
+ displayNameadditionalNamedescriptionactivation/validFrom
diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/events/BaseEventImpl.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/events/BaseEventImpl.java
index c94625ab3fb..68eab8d056d 100644
--- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/events/BaseEventImpl.java
+++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/events/BaseEventImpl.java
@@ -141,7 +141,7 @@ private PolyStringType getDisplayName(ObjectType object) {
return null;
}
if (object instanceof UserType) {
- return ((UserType) object).getFullName();
+ return ((UserType) object).getDisplayName();
} else if (object instanceof AbstractRoleType) {
return ((AbstractRoleType) object).getDisplayName();
} else {
diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/formatters/ValueFormatter.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/formatters/ValueFormatter.java
index f4014043b31..60150ce7f7c 100644
--- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/formatters/ValueFormatter.java
+++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/formatters/ValueFormatter.java
@@ -19,6 +19,7 @@
import com.evolveum.midpoint.schema.util.ShadowUtil;
import com.evolveum.midpoint.util.LocalizableMessage;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
@@ -327,11 +328,11 @@ public String formatUserName(ObjectReferenceType ref, OperationResult result) {
}
public String formatUserName(UserType user, String oid) {
- if (user == null || (user.getName() == null && user.getFullName() == null)) {
+ if (user == null || (user.getName() == null && user.getDisplayName() == null)) {
return oid;
}
- if (user.getFullName() != null) {
- return getOrig(user.getFullName()) + " (" + getOrig(user.getName()) + ")";
+ if (user.getDisplayName() != null) {
+ return getOrig(user.getDisplayName()) + " (" + getOrig(user.getName()) + ")";
} else {
return getOrig(user.getName());
}
diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/AbstractGeneralNotifier.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/AbstractGeneralNotifier.java
index b71e7627883..bc13e9cdaa6 100644
--- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/AbstractGeneralNotifier.java
+++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/AbstractGeneralNotifier.java
@@ -473,8 +473,7 @@ protected String getContentType() {
* . quick
* . safe - it should not make any assumptions about event content that would cause it to throw an exception
* . filter out events that obviously do not match the notifier - e.g. simpleUserNotifier should ensure that
- * the focus type is really UserType; this allows nested filters to assume existence of
- * e.g. requestee.fullName element.
+ * the focus type is really UserType; this allows nested filters to assume existence of user-specific properties.
*/
protected boolean quickCheckApplicability(
ConfigurationItem extends N> notifierConfig,
@@ -680,7 +679,7 @@ String formatRequester(E event, OperationResult result) {
ObjectType requester = requesterRef.resolveObjectType(result, false);
String name = PolyString.getOrig(requester.getName());
if (requester instanceof UserType) {
- return name + " (" + PolyString.getOrig(((UserType) requester).getFullName()) + ")";
+ return name + " (" + PolyString.getOrig(((UserType) requester).getDisplayName()) + ")";
} else {
return name;
}
@@ -693,7 +692,7 @@ void addRequesterAndChannelInformation(StringBuilder body, Event event, Operatio
ObjectType requester = event.getRequester().resolveObjectType(result, false);
if (requester instanceof UserType) {
UserType requesterUser = (UserType) requester;
- body.append(requesterUser.getFullName()).append(" (").append(requester.getName()).append(")");
+ body.append(requesterUser.getDisplayName()).append(" (").append(requester.getName()).append(")");
} else {
body.append(ObjectTypeUtil.toShortString(requester));
}
diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/AccountActivationNotifier.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/AccountActivationNotifier.java
index 1630e8110f1..0b1d8d3b4ec 100644
--- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/AccountActivationNotifier.java
+++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/AccountActivationNotifier.java
@@ -150,8 +150,8 @@ private String getRequestorDisplayName(ObjectType requester) {
name = requester.asPrismObject().getDisplayName();
}
if (requester instanceof UserType) {
- if (((UserType) requester).getFullName() != null) {
- name = ((UserType) requester).getFullName().getOrig();
+ if (((UserType) requester).getDisplayName() != null) {
+ name = ((UserType) requester).getDisplayName().getOrig();
}
}
return name;
diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleFocalObjectNotifier.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleFocalObjectNotifier.java
index bf5fa92ddad..4418d5d4cc6 100644
--- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleFocalObjectNotifier.java
+++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleFocalObjectNotifier.java
@@ -11,7 +11,6 @@
import java.util.Date;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Component;
import com.evolveum.midpoint.model.api.context.ModelContext;
@@ -24,14 +23,13 @@
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.schema.config.ConfigurationItem;
import com.evolveum.midpoint.schema.result.OperationResult;
+import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SimpleFocalObjectNotifierType;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
/**
* This is the "main" notifier that deals with modifications of focal objects i.e. AssignmentHolderType and below.
@@ -123,7 +121,7 @@ protected String getBody(ConfigurationItem extends SimpleFocalObjectNotifierTy
AssignmentHolderType focus = focusObject.asObjectable();
String oid = focusContext.getOid();
- String fullName = emptyIfNull(getFullName(focus));
+ String displayName = emptyIfNull(getDisplayName(focus));
ObjectDelta delta = ObjectDeltaCollectionsUtil.summarize(event.getFocusDeltas());
@@ -133,7 +131,7 @@ protected String getBody(ConfigurationItem extends SimpleFocalObjectNotifierTy
String attemptedTo = event.isSuccess() ? "" : "(attempted to be) ";
body.append("Notification about ").append(typeNameLower).append("-related operation (status: ").append(status).append(")\n\n");
- body.append(typeName).append(": ").append(fullName).append(" (").append(focus.getName()).append(", oid ").append(oid).append(")\n");
+ body.append(typeName).append(": ").append(displayName).append(" (").append(focus.getName()).append(", oid ").append(oid).append(")\n");
body.append("Notification created on: ").append(new Date()).append("\n\n");
boolean watchAuxiliaryAttributes = isWatchAuxiliaryAttributes(configuration.value());
@@ -163,17 +161,8 @@ protected String getBody(ConfigurationItem extends SimpleFocalObjectNotifierTy
return body.toString();
}
- @Nullable
- private String getFullName(AssignmentHolderType focus) {
- String fullName;
- if (focus instanceof UserType) {
- fullName = PolyString.getOrig(((UserType) focus).getFullName());
- } else if (focus instanceof AbstractRoleType) {
- fullName = PolyString.getOrig(((AbstractRoleType) focus).getDisplayName());
- } else {
- fullName = ""; // TODO
- }
- return fullName;
+ private String getDisplayName(AssignmentHolderType focus) {
+ return PolyString.getOrig(ObjectTypeUtil.getDisplayName(focus));
}
@Override
diff --git a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleTaskNotifier.java b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleTaskNotifier.java
index 5ebf83ca91b..d5e9c5cd9e7 100644
--- a/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleTaskNotifier.java
+++ b/model/notifications-impl/src/main/java/com/evolveum/midpoint/notifications/impl/notifiers/SimpleTaskNotifier.java
@@ -87,7 +87,7 @@ protected String getBody(
FocusType owner = taskOwner.asObjectable();
body.append("Task owner: ");
if (owner instanceof UserType) {
- body.append(((UserType)owner).getFullName()).append(" (").append(owner.getName()).append(")");
+ body.append(PolyString.getOrig(((UserType) owner).getDisplayName())).append(" (").append(owner.getName()).append(")");
} else {
body.append(owner.getName());
}
diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReportExportClassic.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReportExportClassic.java
index d2ecfa0ea3b..9e041d197ad 100644
--- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReportExportClassic.java
+++ b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvReportExportClassic.java
@@ -118,7 +118,7 @@ public void test104AuditCollectionReportEmpty() throws Exception {
@Test
public void test110ObjectCollectionReportWithDefaultColumn() throws Exception {
- testClassicExport(REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN, 54, 5, null);
+ testClassicExport(REPORT_OBJECT_COLLECTION_WITH_DEFAULT_COLUMN, 54, 6, null);
}
@Test
@@ -145,12 +145,12 @@ public void test114ObjectCollectionReportWithFilterAndBasicCollection() throws E
@Test
public void test115ObjectCollectionReportWithCondition() throws Exception {
- testClassicExport(REPORT_OBJECT_COLLECTION_WITH_CONDITION, 2, 5, null);
+ testClassicExport(REPORT_OBJECT_COLLECTION_WITH_CONDITION, 2, 6, null);
}
@Test
public void test116ObjectCollectionEmptyReport() throws Exception {
- testClassicExport(REPORT_OBJECT_COLLECTION_EMPTY, 1, 5, null);
+ testClassicExport(REPORT_OBJECT_COLLECTION_EMPTY, 1, 6, null);
}
@Test
@@ -171,7 +171,7 @@ public void test119ObjectCollectionWithSubreportParamReport() throws Exception {
@Test
public void test120RunMidpointUsers() throws Exception {
- testClassicExport(REPORT_USER_LIST, 54, 5, null);
+ testClassicExport(REPORT_USER_LIST, 54, 6, null);
}
@Test
@@ -180,7 +180,7 @@ public void test121RunMidpointUsersScript() throws Exception {
displaySkip();
return;
}
- testClassicExport(REPORT_USER_LIST_SCRIPT, 54, 5, null);
+ testClassicExport(REPORT_USER_LIST_SCRIPT, 54, 6, null);
File targetFile = new File(MidPointTestConstants.TARGET_DIR_PATH, "report-users");
assertTrue("Target file is not there", targetFile.exists());
}
diff --git a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvSimulationReport.java b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvSimulationReport.java
index 46b7eadf9ee..14f68c18f01 100644
--- a/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvSimulationReport.java
+++ b/model/report-impl/src/test/java/com/evolveum/midpoint/report/TestCsvSimulationReport.java
@@ -779,6 +779,8 @@ public void test150ModifyUserWithAssignedAccount() throws Exception {
UserType user = new UserType()
.name(userName)
.fullName("Jack Sparrow")
+ .preferredName("Jack Sparrow")
+ .displayName("Jack Sparrow")
.assignment(RESOURCE_DUMMY_OUTBOUND.assignmentWithConstructionOf(null, null))
.assignment(ARCHETYPE_BLUE.assignmentTo());
addObject(user.asPrismObject(), task, result);
diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/AbstractTestAssignmentApproval.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/AbstractTestAssignmentApproval.java
index 35e61a6f70d..4ac65a538b4 100644
--- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/AbstractTestAssignmentApproval.java
+++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/AbstractTestAssignmentApproval.java
@@ -355,7 +355,7 @@ private void executeAssignRole1(
String userOid = userObject.oid;
PrismObject user = getUser(userOid);
- String userDisplayName = user.asObjectable().getFullName() + " (" + user.asObjectable().getName() + ")";
+ String userDisplayName = user.asObjectable().getDisplayName() + " (" + user.asObjectable().getName() + ")";
TestObject roleObject = getRole(1);
diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/TestAssignmentsAdvanced.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/TestAssignmentsAdvanced.java
index 490cdbd7ad4..757104a99e4 100644
--- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/TestAssignmentsAdvanced.java
+++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/TestAssignmentsAdvanced.java
@@ -472,6 +472,8 @@ public void test610ModifyAssignmentOfRole29() throws Exception {
ObjectDelta delta0 = prismContext.deltaFor(UserType.class)
.item(UserType.F_FULL_NAME)
.replace(PolyString.fromOrig("new full name"))
+ .item(UserType.F_DISPLAY_NAME)
+ .replace(PolyString.fromOrig("new full name"))
.asObjectDelta(USER_JACK.oid);
// +THEN
@@ -595,6 +597,8 @@ public void test620ModifyAssignmentOfRole29Immediate() throws Exception {
ObjectDelta delta0 = prismContext.deltaFor(UserType.class)
.item(UserType.F_FULL_NAME)
.replace(PolyString.fromOrig("new full name 2"))
+ .item(UserType.F_DISPLAY_NAME)
+ .replace(PolyString.fromOrig("new full name 2"))
.asObjectDelta(USER_JACK.oid);
// +THEN
@@ -717,6 +721,8 @@ public void test700AssignRole28() throws Exception {
ObjectDelta delta0 = prismContext.deltaFor(UserType.class)
.item(UserType.F_FULL_NAME)
.replace(PolyString.fromOrig("new full name 3"))
+ .item(UserType.F_DISPLAY_NAME)
+ .replace(PolyString.fromOrig("new full name 3"))
.asObjectDelta(USER_JACK.oid);
PrismObject jackBefore = getUser(USER_JACK.oid);
@@ -829,6 +835,8 @@ public void test710ModifyAssignmentOfRole28() throws Exception {
ObjectDelta delta0 = prismContext.deltaFor(UserType.class)
.item(UserType.F_FULL_NAME)
.replace(PolyString.fromOrig("new full name 4"))
+ .item(UserType.F_DISPLAY_NAME)
+ .replace(PolyString.fromOrig("new full name 4"))
.asObjectDelta(USER_JACK.oid);
// +THEN
@@ -934,6 +942,8 @@ public void test720UnassignRole28() throws Exception {
ObjectDelta delta0 = prismContext.deltaFor(UserType.class)
.item(UserType.F_FULL_NAME)
.replace(PolyString.fromOrig("new full name 5"))
+ .item(UserType.F_DISPLAY_NAME)
+ .replace(PolyString.fromOrig("new full name 5"))
.asObjectDelta(USER_JACK.oid);
// +THEN
diff --git a/model/workflow-impl/src/test/resources/assignments/user-draft.xml b/model/workflow-impl/src/test/resources/assignments/user-draft.xml
index 903d4c9220f..a0a9a7e971e 100644
--- a/model/workflow-impl/src/test/resources/assignments/user-draft.xml
+++ b/model/workflow-impl/src/test/resources/assignments/user-draft.xml
@@ -8,4 +8,5 @@
draftdraftDraft
+ Draft
diff --git a/release-notes.adoc b/release-notes.adoc
index ba525f61429..7058c300fa8 100644
--- a/release-notes.adoc
+++ b/release-notes.adoc
@@ -72,6 +72,7 @@ Overall, midPoint 4.10 opens up the world of identity management and governance
* Improved handling of clockwork collisions in multi-thread setup, problem was reflected in duplication of assignments. See bug:MID-10714[].
* Improved patch management of docker images, updated tagging of docker images. See https://docs.evolveum.com/midpoint/install/containers/container-image-naming/[docs].
* Implemented new configuration options for processing uploaded images.
+* bug:MID-8802[] Added displayName and preferredName to UserType.
=== Major Bugfixes
@@ -436,7 +437,7 @@ Modified:
* 200-lookup-languages.xml - Added Slovenian (sl) and Latvian (lv) languages.
* 210-lookup-locales.xml - Added Slovenian (sl) and Latvian (lv) locales.
* 250-mark-privileged-access.xml - Added archetype.
-* 380-object-template-person.xml - Fixed max. iterations for the "Full name" construction.
+* 380-object-template-person.xml - Fixed max. iterations for the "Full name" construction. Added displayName mapping from preferredName, falling back to fullName.
* 300-policy-require-classification.xml - Added archetype.
* 300-policy-require-owner.xml - Added archetype.
* 000-system-configuration.xml - Poly-string translation keys added.
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleUtils.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleUtils.java
index cfedcb621a1..f81da93266a 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleUtils.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleUtils.java
@@ -38,7 +38,7 @@ public class SqaleUtils {
*/
public static final String SCHEMA_AUDIT_CHANGE_NUMBER = "schemaAuditChangeNumber";
- public static final int CURRENT_SCHEMA_CHANGE_NUMBER = 57;
+ public static final int CURRENT_SCHEMA_CHANGE_NUMBER = 58;
public static final int CURRENT_SCHEMA_AUDIT_CHANGE_NUMBER = 12;
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/MUser.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/MUser.java
index b6bf031fcf9..8f12c3de4a6 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/MUser.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/MUser.java
@@ -15,6 +15,8 @@ public class MUser extends MFocus {
public String additionalNameOrig;
public String additionalNameNorm;
+ public String displayNameOrig;
+ public String displayNameNorm;
public String employeeNumber;
public String familyNameOrig;
public String familyNameNorm;
@@ -29,6 +31,8 @@ public class MUser extends MFocus {
public String nickNameOrig;
public String nickNameNorm;
public String personalNumber;
+ public String preferredNameOrig;
+ public String preferredNameNorm;
public String titleOrig;
public String titleNorm;
public Jsonb organizations;
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUser.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUser.java
index 8a2e1d9ec71..c63db4f04de 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUser.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUser.java
@@ -29,6 +29,10 @@ public class QUser extends QFocus {
ColumnMetadata.named("additionalNameOrig").ofType(Types.VARCHAR);
public static final ColumnMetadata ADDITIONAL_NAME_NORM =
ColumnMetadata.named("additionalNameNorm").ofType(Types.VARCHAR);
+ public static final ColumnMetadata DISPLAY_NAME_ORIG =
+ ColumnMetadata.named("displayNameOrig").ofType(Types.VARCHAR);
+ public static final ColumnMetadata DISPLAY_NAME_NORM =
+ ColumnMetadata.named("displayNameNorm").ofType(Types.VARCHAR);
public static final ColumnMetadata EMPLOYEE_NUMBER =
ColumnMetadata.named("employeeNumber").ofType(Types.VARCHAR);
public static final ColumnMetadata FAMILY_NAME_ORIG =
@@ -55,6 +59,10 @@ public class QUser extends QFocus {
ColumnMetadata.named("nickNameOrig").ofType(Types.VARCHAR);
public static final ColumnMetadata NICK_NAME_NORM =
ColumnMetadata.named("nickNameNorm").ofType(Types.VARCHAR);
+ public static final ColumnMetadata PREFERRED_NAME_ORIG =
+ ColumnMetadata.named("preferredNameOrig").ofType(Types.VARCHAR);
+ public static final ColumnMetadata PREFERRED_NAME_NORM =
+ ColumnMetadata.named("preferredNameNorm").ofType(Types.VARCHAR);
public static final ColumnMetadata TITLE_ORIG =
ColumnMetadata.named("titleOrig").ofType(Types.VARCHAR);
public static final ColumnMetadata TITLE_NORM =
@@ -67,6 +75,8 @@ public class QUser extends QFocus {
public final StringPath additionalNameOrig = createString("additionalNameOrig", ADDITIONAL_NAME_ORIG);
public final StringPath additionalNameNorm = createString("additionalNameNorm", ADDITIONAL_NAME_NORM);
+ public final StringPath displayNameOrig = createString("displayNameOrig", DISPLAY_NAME_ORIG);
+ public final StringPath displayNameNorm = createString("displayNameNorm", DISPLAY_NAME_NORM);
public final StringPath employeeNumber = createString("employeeNumber", EMPLOYEE_NUMBER);
public final StringPath familyNameOrig = createString("familyNameOrig", FAMILY_NAME_ORIG);
public final StringPath familyNameNorm = createString("familyNameNorm", FAMILY_NAME_NORM);
@@ -80,6 +90,8 @@ public class QUser extends QFocus {
public final StringPath honorificSuffixNorm = createString("honorificSuffixNorm", HONORIFIC_SUFFIX_NORM);
public final StringPath nickNameOrig = createString("nickNameOrig", NICK_NAME_ORIG);
public final StringPath nickNameNorm = createString("nickNameNorm", NICK_NAME_NORM);
+ public final StringPath preferredNameOrig = createString("preferredNameOrig", PREFERRED_NAME_ORIG);
+ public final StringPath preferredNameNorm = createString("preferredNameNorm", PREFERRED_NAME_NORM);
public final StringPath titleOrig = createString("titleOrig", TITLE_ORIG);
public final StringPath titleNorm = createString("titleNorm", TITLE_NORM);
public final JsonbPath organizations =
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java
index 2a70552e449..a2590835385 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java
@@ -44,6 +44,8 @@ private QUserMapping(@NotNull SqaleRepoContext repositoryContext) {
addItemMapping(F_ADDITIONAL_NAME, polyStringMapper(
q -> q.additionalNameOrig, q -> q.additionalNameNorm));
+ addItemMapping(F_DISPLAY_NAME, polyStringMapper(
+ q -> q.displayNameOrig, q -> q.displayNameNorm));
addItemMapping(F_EMPLOYEE_NUMBER, stringMapper(q -> q.employeeNumber));
addItemMapping(F_PERSONAL_NUMBER, stringMapper(q -> q.personalNumber));
addItemMapping(F_FAMILY_NAME, polyStringMapper(
@@ -58,6 +60,8 @@ private QUserMapping(@NotNull SqaleRepoContext repositoryContext) {
q -> q.honorificSuffixOrig, q -> q.honorificSuffixNorm));
addItemMapping(F_NICK_NAME, polyStringMapper(
q -> q.nickNameOrig, q -> q.nickNameNorm));
+ addItemMapping(F_PREFERRED_NAME, polyStringMapper(
+ q -> q.preferredNameOrig, q -> q.preferredNameNorm));
addItemMapping(F_TITLE, polyStringMapper(
q -> q.titleOrig, q -> q.titleNorm));
addItemMapping(F_ORGANIZATION, multiPolyStringMapper(q -> q.organizations));
@@ -81,6 +85,8 @@ public MUser newRowObject() {
setPolyString(user.getAdditionalName(),
o -> row.additionalNameOrig = o, n -> row.additionalNameNorm = n);
+ setPolyString(user.getDisplayName(),
+ o -> row.displayNameOrig = o, n -> row.displayNameNorm = n);
row.employeeNumber = user.getEmployeeNumber();
row.personalNumber = user.getPersonalNumber();
setPolyString(user.getFamilyName(),
@@ -92,6 +98,8 @@ public MUser newRowObject() {
setPolyString(user.getHonorificSuffix(),
o -> row.honorificSuffixOrig = o, n -> row.honorificSuffixNorm = n);
setPolyString(user.getNickName(), o -> row.nickNameOrig = o, n -> row.nickNameNorm = n);
+ setPolyString(user.getPreferredName(),
+ o -> row.preferredNameOrig = o, n -> row.preferredNameNorm = n);
setPolyString(user.getTitle(), o -> row.titleOrig = o, n -> row.titleNorm = n);
row.organizations = JsonbUtils.polyStringTypesToJsonb(user.getOrganization());
row.organizationUnits = JsonbUtils.polyStringTypesToJsonb(user.getOrganizationalUnit());
diff --git a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java
index b859f0dd3f8..d0c9507d252 100644
--- a/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java
+++ b/repo/repo-sqale/src/test/java/com/evolveum/midpoint/repo/sqale/func/SqaleRepoAddDeleteObjectTest.java
@@ -2003,6 +2003,7 @@ public void test825User() throws Exception {
UserType user = new UserType()
.name(objectName)
.additionalName("additional-name")
+ .displayName("display-name")
.employeeNumber("3")
.familyName("family-name")
.fullName("full-name")
@@ -2010,6 +2011,7 @@ public void test825User() throws Exception {
.honorificPrefix("honorific-prefix")
.honorificSuffix("honorific-suffix")
.nickName("nick-name")
+ .preferredName("preferred-name")
.title("title")
.organization("org-1")
.organization("org-2")
@@ -2027,6 +2029,8 @@ public void test825User() throws Exception {
// all items from MUser
assertThat(row.additionalNameOrig).isEqualTo("additional-name");
assertThat(row.additionalNameNorm).isEqualTo("additionalname");
+ assertThat(row.displayNameOrig).isEqualTo("display-name");
+ assertThat(row.displayNameNorm).isEqualTo("displayname");
assertThat(row.employeeNumber).isEqualTo("3");
assertThat(row.familyNameOrig).isEqualTo("family-name");
assertThat(row.familyNameNorm).isEqualTo("familyname");
@@ -2040,6 +2044,8 @@ public void test825User() throws Exception {
assertThat(row.honorificSuffixNorm).isEqualTo("honorificsuffix");
assertThat(row.nickNameOrig).isEqualTo("nick-name");
assertThat(row.nickNameNorm).isEqualTo("nickname");
+ assertThat(row.preferredNameOrig).isEqualTo("preferred-name");
+ assertThat(row.preferredNameNorm).isEqualTo("preferredname");
assertThat(row.titleOrig).isEqualTo("title");
assertThat(row.titleNorm).isEqualTo("title");
assertThat(row.organizations).isNotNull();
diff --git a/repo/system-init/src/main/resources/initial-objects/object-templates/380-object-template-person.xml b/repo/system-init/src/main/resources/initial-objects/object-templates/380-object-template-person.xml
index 4087ecb84ac..1635f3aa5ec 100644
--- a/repo/system-init/src/main/resources/initial-objects/object-templates/380-object-template-person.xml
+++ b/repo/system-init/src/main/resources/initial-objects/object-templates/380-object-template-person.xml
@@ -101,4 +101,29 @@ oid="00000000-0000-0000-0000-000000000380">
fullName
+
+ generate-display-name
+ Generate displayName from preferredName, falling back to fullName.
+ strong
+
+ preferredName
+
+
+ fullName
+
+
+
+
+
+ displayName
+
+
diff --git a/repo/system-init/src/main/resources/initial-objects/report/110-report-user-list.xml b/repo/system-init/src/main/resources/initial-objects/report/110-report-user-list.xml
index 535c8bc9145..ea634859032 100644
--- a/repo/system-init/src/main/resources/initial-objects/report/110-report-user-list.xml
+++ b/repo/system-init/src/main/resources/initial-objects/report/110-report-user-list.xml
@@ -199,6 +199,11 @@
orgColumn
+
+ displayNameColumn
+ displayName
+ accountColumn
+ UserType
diff --git a/repo/system-init/src/main/resources/initial-objects/user/050-user-administrator.xml b/repo/system-init/src/main/resources/initial-objects/user/050-user-administrator.xml
index 1c794769599..ed5bcc761f6 100644
--- a/repo/system-init/src/main/resources/initial-objects/user/050-user-administrator.xml
+++ b/repo/system-init/src/main/resources/initial-objects/user/050-user-administrator.xml
@@ -12,6 +12,7 @@
administratortruemidPoint Administrator
+ midPoint AdministratormidPointAdministrator
diff --git a/testing/story/src/test/resources/common/user-administrator.xml b/testing/story/src/test/resources/common/user-administrator.xml
index dcc1ca2d5a5..a3f59244a46 100644
--- a/testing/story/src/test/resources/common/user-administrator.xml
+++ b/testing/story/src/test/resources/common/user-administrator.xml
@@ -12,6 +12,7 @@
xmlns:t='http://prism.evolveum.com/xml/ns/public/types-3'>
administratormidPoint Administrator
+ midPoint AdministratormidPointAdministratoradministrator@evolveum.com
diff --git a/testing/story/src/test/resources/strings/users/bob.xml b/testing/story/src/test/resources/strings/users/bob.xml
index 24aa5506d31..dd0f1bba7e5 100644
--- a/testing/story/src/test/resources/strings/users/bob.xml
+++ b/testing/story/src/test/resources/strings/users/bob.xml
@@ -17,6 +17,7 @@
Ghost Pirate Bob
+ Ghost Pirate BobBobbob@evolveum.com
diff --git a/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/action/mining/ExportMiningConsumerWorker.java b/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/action/mining/ExportMiningConsumerWorker.java
index 8b7eb36b0b7..739061e3149 100644
--- a/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/action/mining/ExportMiningConsumerWorker.java
+++ b/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/action/mining/ExportMiningConsumerWorker.java
@@ -84,8 +84,8 @@ public class ExportMiningConsumerWorker extends AbstractWriterConsumerWorker DEFAULT_EXCLUDED_ATTRIBUTES = List.of("description", "documentation", "emailAddress",
- "telephoneNumber", "name", "fullName", "givenName", "familyName", "additionalName", "nickName", "personalNumber",
- "identifier", "jpegPhoto");
+ "telephoneNumber", "name", "fullName", "preferredName", "displayName", "givenName", "familyName",
+ "additionalName", "nickName", "personalNumber", "identifier", "jpegPhoto");
public ExportMiningConsumerWorker(NinjaContext context, ExportMiningOptions options, BlockingQueue queue,
OperationStatus operation) {
diff --git a/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/action/stats/ExportFocusStatisticsAction.java b/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/action/stats/ExportFocusStatisticsAction.java
index 52a1f58258c..c7019310b74 100644
--- a/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/action/stats/ExportFocusStatisticsAction.java
+++ b/tools/ninja/src/main/java/com/evolveum/midpoint/ninja/action/stats/ExportFocusStatisticsAction.java
@@ -22,10 +22,11 @@ public class ExportFocusStatisticsAction extends AbstractRepositorySearchAction<
new ItemName(SchemaConstants.NS_C, "locality"), new ItemName(SchemaConstants.NS_C, "preferredLanguage"),
new ItemName(SchemaConstants.NS_C, "locale"), new ItemName(SchemaConstants.NS_C, "timezone"),
new ItemName(SchemaConstants.NS_C, "emailAddress"), new ItemName(SchemaConstants.NS_C, "telephoneNumber"),
- new ItemName(SchemaConstants.NS_C, "fullName"), new ItemName(SchemaConstants.NS_C, "givenName"),
- new ItemName(SchemaConstants.NS_C, "familyName"), new ItemName(SchemaConstants.NS_C, "additionalName"),
- new ItemName(SchemaConstants.NS_C, "nickName"), new ItemName(SchemaConstants.NS_C, "honorificPrefix"),
- new ItemName(SchemaConstants.NS_C, "honorificSuffix"), new ItemName(SchemaConstants.NS_C, "title"),
+ new ItemName(SchemaConstants.NS_C, "fullName"), new ItemName(SchemaConstants.NS_C, "preferredName"),
+ new ItemName(SchemaConstants.NS_C, "givenName"), new ItemName(SchemaConstants.NS_C, "familyName"),
+ new ItemName(SchemaConstants.NS_C, "additionalName"), new ItemName(SchemaConstants.NS_C, "nickName"),
+ new ItemName(SchemaConstants.NS_C, "honorificPrefix"), new ItemName(SchemaConstants.NS_C, "honorificSuffix"),
+ new ItemName(SchemaConstants.NS_C, "title"),
new ItemName(SchemaConstants.NS_C, "employeeNumber"), new ItemName(SchemaConstants.NS_C, "personalNumber"),
new ItemName(SchemaConstants.NS_C, "organization"),
new ItemName(SchemaConstants.NS_C, "organizationalUnit"), new ItemName(SchemaConstants.NS_C, "displayName"),