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 2e7ccc4b78c..ada0fb9438a 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 @@ -44,13 +44,8 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; -import static java.util.Collections.emptySet; -import static java.util.Collections.singleton; import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; /** @@ -872,4 +867,40 @@ public static XMLGregorianCalendar getLastTouchTimestamp( } return metadata.getCreateTimestamp(); } + + @NotNull + public static List> mapToExtensionItems(Map values, PrismContainerDefinition extensionDefinition, + PrismContext prismContext) throws SchemaException { + List> extensionItems = new ArrayList<>(); + for (Map.Entry entry : values.entrySet()) { + ItemDefinition> def = extensionDefinition != null + ? extensionDefinition.findItemDefinition(entry.getKey()) + : null; + if (def == null) { + //noinspection unchecked + def = prismContext.getSchemaRegistry().findItemDefinitionByElementName(entry.getKey()); // a bit of hack here + if (def == null) { + throw new SchemaException("No definition of " + entry.getKey() + " in task extension"); + } + } + Item extensionItem = def.instantiate(); + if (entry.getValue() != null) { + if (entry.getValue() instanceof Collection) { + for (Object value : (Collection) entry.getValue()) { + addRealValue(extensionItem, value); + } + } else { + addRealValue(extensionItem, entry.getValue()); + } + } + extensionItems.add(extensionItem); + } + return extensionItems; + } + + private static void addRealValue(Item extensionItem, Object value) throws SchemaException { + if (value != null) { + extensionItem.add(PrismValue.fromRealValue(value).clone()); + } + } } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java index 6abfd6f14dd..3ba55eacfc9 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java @@ -20,12 +20,7 @@ import java.text.Normalizer; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -37,8 +32,10 @@ import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; import org.apache.commons.io.FileUtils; @@ -551,6 +548,16 @@ public Collection getAttributeStringValues(ShadowType shadow, javax.xml. return ShadowUtil.getAttributeValues(shadow, attributeQname, String.class); } + public void setExtensionRealValues(PrismContainerValue containerValue, Map map) throws SchemaException { + PrismContainer ext = containerValue.findOrCreateContainer(ObjectType.F_EXTENSION); + Map qnameKeyedMap = new HashMap<>(); + map.forEach((uri, value) -> qnameKeyedMap.put(QNameUtil.uriToQName(uri, true), value)); + List> items = ObjectTypeUtil.mapToExtensionItems(qnameKeyedMap, ext.getDefinition(), prismContext); + for (Item item : items) { + ext.getValue().addReplaceExisting(item); + } + } + public T getIdentifierValue(ShadowType shadow) throws SchemaException { if (shadow == null) { return null; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java index 13c3165a5a4..29aa21d7371 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java @@ -28,6 +28,7 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.repo.common.expression.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.Validate; @@ -104,10 +105,6 @@ import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.cache.RepositoryCache; import com.evolveum.midpoint.repo.common.CacheRegistry; -import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; -import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; -import com.evolveum.midpoint.repo.common.expression.ItemDeltaItem; -import com.evolveum.midpoint.repo.common.expression.ObjectDeltaObject; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ObjectDeltaOperation; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; @@ -1722,24 +1719,10 @@ public TaskType submitTaskFromTemplate(String templateTaskOid, List> public TaskType submitTaskFromTemplate(String templateTaskOid, Map extensionValues, Task opTask, OperationResult parentResult) throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException, ObjectAlreadyExistsException, PolicyViolationException { - List> extensionItems = new ArrayList<>(); PrismContainerDefinition extDef = prismContext.getSchemaRegistry() .findObjectDefinitionByCompileTimeClass(TaskType.class).findContainerDefinition(TaskType.F_EXTENSION); - for (Map.Entry entry : extensionValues.entrySet()) { - ItemDefinition> def = extDef.findItemDefinition(entry.getKey()); - if (def == null) { - //noinspection unchecked - def = prismContext.getSchemaRegistry().findItemDefinitionByElementName(entry.getKey()); // a bit of hack here - if (def == null) { - throw new SchemaException("No definition of " + entry.getKey() + " in task extension"); - } - } - Item extensionItem = def.instantiate(); - if (entry.getValue() != null) { - extensionItem.add(PrismValue.fromRealValue(entry.getValue()).clone()); - } - extensionItems.add(extensionItem); - } + List> extensionItems = ObjectTypeUtil.mapToExtensionItems(extensionValues, extDef, prismContext); return submitTaskFromTemplate(templateTaskOid, extensionItems, opTask, parentResult); } + } diff --git a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java index ed3c92208ef..b7d73393db2 100644 --- a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java +++ b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java @@ -1020,11 +1020,11 @@ public void test013AddOpenDjAccountToUser() throws Exception { REQUEST_USER_MODIFY_ADD_ACCOUNT_OPENDJ_FILENAME, ObjectDeltaType.class); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); OperationResultType result = modifyObjectViaModelWS(objectChange); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); assertNoRepoCache(); displayJaxb("modifyObject result", result, SchemaConstants.C_RESULT); TestUtil.assertSuccess("modifyObject has failed", result); @@ -1657,11 +1657,11 @@ public void test030DisableUser() throws Exception { assertNoRepoCache(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); OperationResultType result = modifyObjectViaModelWS(objectChange); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); assertNoRepoCache(); displayJaxb("modifyObject result:", result, SchemaConstants.C_RESULT); TestUtil.assertSuccess("modifyObject has failed", result); @@ -1718,12 +1718,12 @@ public void test030DisableUser() throws Exception { assertNoRepoCache(); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modelWeb.getObject(ObjectTypes.SHADOW.getTypeQName(), accountShadowOidOpendj, options, objectHolder, resultHolder); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); assertNoRepoCache(); displayJaxb("getObject result", resultHolder.value, SchemaConstants.C_RESULT); TestUtil.assertSuccess("getObject has failed", resultHolder.value); @@ -3135,11 +3135,11 @@ public void test400ImportFromResource() throws Exception { display("Entry from LDIF", addEntry); // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); TaskType taskType = modelWeb.importFromResource(RESOURCE_OPENDJ_OID, RESOURCE_OPENDJ_ACCOUNT_OBJECTCLASS); // THEN - TestUtil.displayThen(TEST_NAME); + displayThen(TEST_NAME); assertNoRepoCache(); displayJaxb("importFromResource result", taskType.getResult(), SchemaConstants.C_RESULT); AssertJUnit.assertEquals("importFromResource has failed", OperationResultStatusType.IN_PROGRESS, taskType.getResult().getStatus()); diff --git a/testing/sanity/src/test/resources/repo/resource-opendj.xml b/testing/sanity/src/test/resources/repo/resource-opendj.xml index 66d6d9f4fde..df43fa3738b 100644 --- a/testing/sanity/src/test/resources/repo/resource-opendj.xml +++ b/testing/sanity/src/test/resources/repo/resource-opendj.xml @@ -1,6 +1,6 @@ name from user object and string constants. The expression is marked as "default", therefore it will - be evaluated only if the entry already does not have an DN. - - It is an XPath expression, similar to BPEL assignment expressions. --> + be evaluated only if the entry already does not have an DN. --> - declare default namespace "http://midpoint.evolveum.com/xml/ns/public/common/common-3";$user/name + $focus/name @@ -218,19 +212,14 @@ This is now the only account type that midPoint can work with. --> - - declare namespace i="http://midpoint.evolveum.com/xml/ns/public/common/common-3"; - $i:user/i:fullName - + fullName @@ -248,15 +237,7 @@ This is now the only account type that midPoint can work with. --> @@ -265,11 +246,9 @@ This is now the only account type that midPoint can work with. --> @@ -300,11 +279,10 @@ This is now the only account type that midPoint can work with. --> @@ -411,11 +389,7 @@ This is now the only account type that midPoint can work with. --> weak @@ -481,21 +455,12 @@ This is now the only account type that midPoint can work with. --> @@ -518,14 +483,12 @@ This is now the only account type that midPoint can work with. --> @@ -656,16 +619,16 @@ This is now the only account type that midPoint can work with. --> equal to the "uid" attribute of the account. Simply speaking, it will look for match in usernames in the IDM and the resource. --> - declare namespace c="http://midpoint.evolveum.com/xml/ns/public/common/common-3";c:name + + declare namespace c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"; + c:name + - + + declare namespace c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"; + declare namespace dj="http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff"; + $c:account/c:attributes/dj:uid + diff --git a/testing/sanity/src/test/resources/request/herman.ldif b/testing/sanity/src/test/resources/request/herman.ldif index 76d42d45e28..ec84efdf96a 100644 --- a/testing/sanity/src/test/resources/request/herman.ldif +++ b/testing/sanity/src/test/resources/request/herman.ldif @@ -1,7 +1,5 @@ dn: uid=herman,ou=People,dc=example,dc=com -uid: ht uid: herman -uid: htmarley cn: Herman Toothrot cn: Horatio Torquemeda Marley sn: Marley