diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypeWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypeWizardBuilder.java index ab6e018b0ff..9570a917d6e 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypeWizardBuilder.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypeWizardBuilder.java @@ -179,8 +179,7 @@ public void setObject(final String object) { LOG.error("Invalid Locale: {}", validatable.getValue(), e); validatable.error(new ValidationError("Invalid Locale: " + validatable.getValue())); - RequestCycle.get().find(AjaxRequestTarget.class). - ifPresent(target -> target.add(Labels.this)); + RequestCycle.get().find(AjaxRequestTarget.class).ifPresent(t -> t.add(Labels.this)); } }); item.add(locale); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java index ad1e1bcbae8..1023a794a16 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.lib.batch.BatchRequest; import org.apache.syncope.client.ui.commons.DateOps; import org.apache.syncope.common.lib.form.SyncopeForm; @@ -194,7 +195,8 @@ public T readTask(final TaskType type, final String taskKey) } public SyncopeForm getMacroTaskForm(final String taskKey) { - return getService(TaskService.class).getMacroTaskForm(taskKey); + return getService(TaskService.class). + getMacroTaskForm(taskKey, SyncopeConsoleSession.get().getLocale().toLanguageTag()); } public void delete(final TaskType type, final String taskKey) { diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.java index ccb458da648..9859f123067 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.java @@ -21,6 +21,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Optional; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -89,13 +90,6 @@ public FormPropertyDefsPanel( protected void populateItem(final ListItem item) { FormPropertyDefTO fpd = item.getModelObject(); - AjaxTextFieldPanel key = new AjaxTextFieldPanel( - "key", - "key", - new PropertyModel<>(fpd, "key"), - true); - item.add(key.setRequired(true).hideLabel()); - AjaxTextFieldPanel name = new AjaxTextFieldPanel( "name", "name", @@ -103,6 +97,12 @@ protected void populateItem(final ListItem item) { true); item.add(name.setRequired(true).hideLabel()); + AjaxGridFieldPanel labels = new AjaxGridFieldPanel<>( + "labels", + "labels", + new PropertyModel<>(fpd, "labels")); + item.add(labels.hideLabel()); + AjaxCheckBoxPanel readable = new AjaxCheckBoxPanel( "readable", "readable", diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.html index 933b16e7866..7ab57b28012 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.html +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.html @@ -25,8 +25,8 @@ wicket:id="propertyDefContainer"> - + @@ -37,10 +37,10 @@ - + - + diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.properties index 5831fc80ca7..c61b80b25d0 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.properties @@ -24,3 +24,4 @@ enumValues=Values datePattern=Pattern dropdownSingleSelection=Single Selection dropdownFreeForm=Free Form +labels=Labels diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_fr_CA.properties index 5831fc80ca7..c61b80b25d0 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_fr_CA.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_fr_CA.properties @@ -24,3 +24,4 @@ enumValues=Values datePattern=Pattern dropdownSingleSelection=Single Selection dropdownFreeForm=Free Form +labels=Labels diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_it.properties index 5cd41d2b8be..aa7ba2735a6 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_it.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_it.properties @@ -24,3 +24,4 @@ enumValues=Valori datePattern=Modello dropdownSingleSelection=Selezione Singola dropdownFreeForm=Modalit\u00e0 libera +labels=Etichette diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_ja.properties index 5831fc80ca7..c61b80b25d0 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_ja.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_ja.properties @@ -24,3 +24,4 @@ enumValues=Values datePattern=Pattern dropdownSingleSelection=Single Selection dropdownFreeForm=Free Form +labels=Labels diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_pt_BR.properties index 5831fc80ca7..c61b80b25d0 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_pt_BR.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_pt_BR.properties @@ -24,3 +24,4 @@ enumValues=Values datePattern=Pattern dropdownSingleSelection=Single Selection dropdownFreeForm=Free Form +labels=Labels diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_ru.properties index 5831fc80ca7..c61b80b25d0 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_ru.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel_ru.properties @@ -24,3 +24,4 @@ enumValues=Values datePattern=Pattern dropdownSingleSelection=Single Selection dropdownFreeForm=Free Form +labels=Labels diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/FormPropertyDefTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/FormPropertyDefTO.java index 4f1d24aba53..a7c5df45aa2 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/FormPropertyDefTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/FormPropertyDefTO.java @@ -18,7 +18,10 @@ */ package org.apache.syncope.common.lib.to; +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.Locale; import java.util.Map; import java.util.regex.Pattern; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -33,6 +36,8 @@ public class FormPropertyDefTO implements NamedEntityTO { private String name; + private final Map labels = new HashMap<>(); + private FormPropertyType type; private boolean readable = true; @@ -71,6 +76,15 @@ public void setName(final String name) { this.name = name; } + @JsonIgnore + public String getLabel(final Locale locale) { + return labels.getOrDefault(locale, key); + } + + public Map getLabels() { + return labels; + } + public FormPropertyType getType() { return type; } @@ -144,6 +158,7 @@ public int hashCode() { return new HashCodeBuilder(). append(key). append(name). + append(labels). append(type). append(readable). append(writable). @@ -171,6 +186,7 @@ public boolean equals(final Object obj) { return new EqualsBuilder(). append(key, other.key). append(name, other.name). + append(labels, other.labels). append(type, other.type). append(readable, other.readable). append(writable, other.writable). diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java index d880e9b8213..a01ed2b6dab 100644 --- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java +++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java @@ -169,12 +169,13 @@ Response purgePropagations( * Fetches the form to fill and submit for execution, for the given macro task (if defined). * * @param key macro task key + * @param locale form locale * @return the form to fill and submit for execution, for the given macro task (if defined) */ @GET @Path("MACRO/{key}/form") @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - SyncopeForm getMacroTaskForm(@NotNull @PathParam("key") String key); + SyncopeForm getMacroTaskForm(@NotNull @PathParam("key") String key, @NotNull @QueryParam("locale") String locale); /** * Executes the macro task matching the given specs, with the provided form as input. diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java index 1b2edcbf227..4b28b4574db 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java @@ -22,6 +22,7 @@ import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -284,14 +285,14 @@ public T read(final TaskType type, final String key, final bo @PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_READ + "')") @Transactional(readOnly = true) - public SyncopeForm getMacroTaskForm(final String key) { + public SyncopeForm getMacroTaskForm(final String key, final Locale locale) { MacroTask task = taskDAO.find(key). filter(MacroTask.class::isInstance).map(MacroTask.class::cast). orElseThrow(() -> new NotFoundException("MacroTask " + key)); securityChecks(IdRepoEntitlement.TASK_READ, task.getRealm().getFullPath()); - return binder.getMacroTaskForm(task); + return binder.getMacroTaskForm(task, locale); } protected ExecTO doExecute( diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java index b27bcefeb56..29d3d259a70 100644 --- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java +++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java @@ -21,14 +21,18 @@ import java.net.URI; import java.time.OffsetDateTime; import java.util.List; +import java.util.Locale; import javax.ws.rs.BadRequestException; import javax.ws.rs.core.Response; +import org.apache.commons.lang3.LocaleUtils; import org.apache.commons.lang3.tuple.Pair; +import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.form.SyncopeForm; import org.apache.syncope.common.lib.to.ExecTO; import org.apache.syncope.common.lib.to.PagedResult; import org.apache.syncope.common.lib.to.SchedTaskTO; import org.apache.syncope.common.lib.to.TaskTO; +import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.ExecStatus; import org.apache.syncope.common.lib.types.TaskType; import org.apache.syncope.common.rest.api.RESTHeaders; @@ -114,8 +118,19 @@ public Response purgePropagations( } @Override - public SyncopeForm getMacroTaskForm(final String key) { - return logic.getMacroTaskForm(key); + public SyncopeForm getMacroTaskForm(final String key, final String locale) { + Locale localeObj = null; + try { + localeObj = LocaleUtils.toLocale(locale); + } catch (Exception e) { + LOG.error("While attempting to convert {} to Locale", locale, e); + + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidEntity); + sce.getElements().add("Invalid locale '" + locale + "'"); + throw sce; + } + + return logic.getMacroTaskForm(key, localeObj); } @Override diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/FormPropertyDef.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/FormPropertyDef.java index 518ab750d7b..551990a886f 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/FormPropertyDef.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/FormPropertyDef.java @@ -18,12 +18,14 @@ */ package org.apache.syncope.core.persistence.api.entity.task; +import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.regex.Pattern; import org.apache.syncope.common.lib.form.FormPropertyType; -import org.apache.syncope.core.persistence.api.entity.ProvidedKeyEntity; +import org.apache.syncope.core.persistence.api.entity.Entity; -public interface FormPropertyDef extends ProvidedKeyEntity { +public interface FormPropertyDef extends Entity { MacroTask getMacroTask(); @@ -33,6 +35,10 @@ public interface FormPropertyDef extends ProvidedKeyEntity { void setName(String name); + Optional getLabel(Locale locale); + + Map getLabels(); + FormPropertyType getType(); void setType(FormPropertyType type); diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java index a2b64b64da9..0230673fd22 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java @@ -54,6 +54,7 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskUtils; import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory; import org.apache.syncope.core.persistence.jpa.entity.task.JPAMacroTask; +import org.apache.syncope.core.persistence.jpa.entity.task.JPAMacroTaskCommand; import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask; import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask; import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTaskExec; @@ -198,8 +199,9 @@ public List findByRealm(final Realm realm) { @Override public List findByCommand(final Implementation command) { - TypedQuery query = entityManager().createQuery("SELECT e FROM " + JPAMacroTask.class.getSimpleName() - + " e WHERE :command MEMBER OF e.commands", MacroTask.class); + TypedQuery query = entityManager().createQuery( + "SELECT e.macroTask FROM " + JPAMacroTaskCommand.class.getSimpleName() + " e " + + "WHERE e.command=:command", MacroTask.class); query.setParameter("command", command); return query.getResultList(); diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAFormPropertyDef.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAFormPropertyDef.java index 5581675a437..99988194c07 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAFormPropertyDef.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAFormPropertyDef.java @@ -19,6 +19,8 @@ package org.apache.syncope.core.persistence.jpa.entity.task; import com.fasterxml.jackson.core.type.TypeReference; +import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.regex.Pattern; @@ -27,25 +29,36 @@ import javax.persistence.Enumerated; import javax.persistence.Lob; import javax.persistence.ManyToOne; +import javax.persistence.PostLoad; +import javax.persistence.PostPersist; +import javax.persistence.PostUpdate; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; import javax.persistence.Table; +import javax.persistence.Transient; import javax.validation.constraints.NotNull; import org.apache.syncope.common.lib.form.FormPropertyType; import org.apache.syncope.core.persistence.api.entity.task.FormPropertyDef; import org.apache.syncope.core.persistence.api.entity.task.MacroTask; -import org.apache.syncope.core.persistence.jpa.entity.AbstractProvidedKeyEntity; +import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity; import org.apache.syncope.core.persistence.jpa.validation.entity.FormPropertyDefCheck; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; @Entity @Table(name = JPAFormPropertyDef.TABLE) @FormPropertyDefCheck -public class JPAFormPropertyDef extends AbstractProvidedKeyEntity implements FormPropertyDef { +public class JPAFormPropertyDef extends AbstractGeneratedKeyEntity implements FormPropertyDef { private static final long serialVersionUID = -5839990371546587373L; public static final String TABLE = "FormPropertyDef"; - protected static final TypeReference> TYPEREF = new TypeReference>() { + protected static final TypeReference> ENUMVALUES_TYPEREF = + new TypeReference>() { + }; + + protected static final TypeReference> LABEL_TYPEREF = + new TypeReference>() { }; private int idx; @@ -56,6 +69,12 @@ public class JPAFormPropertyDef extends AbstractProvidedKeyEntity implements For @NotNull private String name; + @Lob + private String labels; + + @Transient + private Map labelMap = new HashMap<>(); + @NotNull @Enumerated(EnumType.STRING) private FormPropertyType type; @@ -107,6 +126,16 @@ public void setName(final String name) { this.name = name; } + @Override + public Optional getLabel(final Locale locale) { + return Optional.ofNullable(labelMap.get(locale)); + } + + @Override + public Map getLabels() { + return labelMap; + } + @Override public FormPropertyType getType() { return type; @@ -169,7 +198,7 @@ public void setDatePattern(final String datePattern) { @Override public Map getEnumValues() { - return Optional.ofNullable(enumValues).map(v -> POJOHelper.deserialize(v, TYPEREF)).orElse(Map.of()); + return Optional.ofNullable(enumValues).map(v -> POJOHelper.deserialize(v, ENUMVALUES_TYPEREF)).orElse(Map.of()); } @Override @@ -196,4 +225,30 @@ public boolean isDropdownFreeForm() { public void setDropdownFreeForm(final boolean dropdownFreeForm) { this.dropdownFreeForm = dropdownFreeForm; } + + protected void json2map(final boolean clearFirst) { + if (clearFirst) { + getLabels().clear(); + } + if (labels != null) { + getLabels().putAll(POJOHelper.deserialize(labels, LABEL_TYPEREF)); + } + } + + @PostLoad + public void postLoad() { + json2map(false); + } + + @PostPersist + @PostUpdate + public void postSave() { + json2map(true); + } + + @PrePersist + @PreUpdate + public void map2json() { + labels = POJOHelper.serialize(getLabels()); + } } diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java index 6f55bca310b..4edb9705f13 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java @@ -27,6 +27,7 @@ import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -195,8 +196,8 @@ public void saveMacroTask() throws Exception { task.add(macroTaskCommand); FormPropertyDef formPropertyDef = entityFactory.newEntity(FormPropertyDef.class); - formPropertyDef.setKey("one"); - formPropertyDef.setName("One"); + formPropertyDef.setName("one"); + formPropertyDef.getLabels().put(Locale.ENGLISH, "One"); formPropertyDef.setType(FormPropertyType.Enum); task.add(formPropertyDef); @@ -222,6 +223,7 @@ public void saveMacroTask() throws Exception { assertEquals(1, task.getCommands().size()); assertEquals(command, task.getCommands().get(0).getCommand()); assertEquals(1, task.getFormPropertyDefs().size()); + assertNotNull(task.getFormPropertyDefs().get(0).getKey()); assertEquals(formPropertyDef, task.getFormPropertyDefs().get(0)); MacroTask actual = (MacroTask) taskDAO.find(TaskType.MACRO, task.getKey()); diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/TaskDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/TaskDataBinder.java index a8a1dc56af7..464437ac1aa 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/TaskDataBinder.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/TaskDataBinder.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.provisioning.api.data; +import java.util.Locale; import org.apache.syncope.common.lib.form.SyncopeForm; import org.apache.syncope.common.lib.to.ExecTO; import org.apache.syncope.common.lib.to.SchedTaskTO; @@ -40,5 +41,5 @@ public interface TaskDataBinder { T getTaskTO(Task task, TaskUtils taskUtil, boolean details); - SyncopeForm getMacroTaskForm(MacroTask task); + SyncopeForm getMacroTaskForm(MacroTask task, Locale locale); } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java index 87c0a7fd049..26689efb690 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.provisioning.java.data; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -280,8 +281,8 @@ protected void fill(final MacroTask macroTask, final MacroTaskTO macroTaskTO) { macroTask.getFormPropertyDefs().clear(); macroTaskTO.getFormPropertyDefs().forEach(fpdTO -> { FormPropertyDef fpd = entityFactory.newEntity(FormPropertyDef.class); - fpd.setKey(fpdTO.getKey()); fpd.setName(fpdTO.getName()); + fpd.getLabels().putAll(fpdTO.getLabels()); fpd.setType(fpdTO.getType()); fpd.setReadable(fpdTO.isReadable()); fpd.setWritable(fpdTO.isWritable()); @@ -515,6 +516,7 @@ public T getTaskTO(final Task task, final TaskUtils taskUt FormPropertyDefTO fpdTO = new FormPropertyDefTO(); fpdTO.setKey(fpd.getKey()); fpdTO.setName(fpd.getName()); + fpdTO.getLabels().putAll(fpd.getLabels()); fpdTO.setType(fpd.getType()); fpdTO.setReadable(fpd.isReadable()); fpdTO.setWritable(fpd.isWritable()); @@ -596,7 +598,7 @@ public T getTaskTO(final Task task, final TaskUtils taskUt } @Override - public SyncopeForm getMacroTaskForm(final MacroTask task) { + public SyncopeForm getMacroTaskForm(final MacroTask task, final Locale locale) { if (task.getFormPropertyDefs().isEmpty()) { throw new NotFoundException("No form properties defined for MacroTask " + task.getKey()); } @@ -623,13 +625,13 @@ public SyncopeForm getMacroTaskForm(final MacroTask task) { form.getProperties().addAll(task.getFormPropertyDefs().stream().map(fpd -> { FormProperty prop = new FormProperty(); - prop.setId(fpd.getKey()); - prop.setName(fpd.getName()); + prop.setId(fpd.getName()); + prop.setName(fpd.getLabels().getOrDefault(locale, fpd.getName())); prop.setReadable(fpd.isReadable()); prop.setRequired(fpd.isRequired()); prop.setWritable(fpd.isWritable()); prop.setType(fpd.getType()); - actions.flatMap(a -> a.getDefaultValue(fpd.getKey())).ifPresent(v -> prop.setValue(v)); + actions.flatMap(a -> a.getDefaultValue(fpd.getName())).ifPresent(v -> prop.setValue(v)); switch (prop.getType()) { case String: prop.setStringRegEx(fpd.getStringRegEx()); @@ -640,13 +642,12 @@ public SyncopeForm getMacroTaskForm(final MacroTask task) { break; case Enum: - fpd.getEnumValues(). - forEach((key, value) -> prop.getEnumValues().add(new FormPropertyValue(key, value))); + fpd.getEnumValues().forEach((k, v) -> prop.getEnumValues().add(new FormPropertyValue(k, v))); break; case Dropdown: - actions.ifPresent(a -> a.getDropdownValues(fpd.getKey()). - forEach((key, value) -> prop.getDropdownValues().add(new FormPropertyValue(key, value)))); + actions.ifPresent(a -> a.getDropdownValues(fpd.getName()). + forEach((k, v) -> prop.getDropdownValues().add(new FormPropertyValue(k, v)))); prop.setDropdownSingleSelection(fpd.isDropdownSingleSelection()); prop.setDropdownFreeForm(fpd.isDropdownFreeForm()); break; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java index cbab1934334..0718efc70be 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java @@ -92,8 +92,8 @@ protected Optional check( Set missingFormProperties = task.getFormPropertyDefs().stream(). filter(FormPropertyDef::isRequired). map(fpd -> Pair.of( - fpd.getKey(), - macroTaskForm.getProperty(fpd.getKey()).map(p -> p.getValue() != null))). + fpd.getName(), + macroTaskForm.getProperty(fpd.getName()).map(p -> p.getValue() != null))). filter(pair -> pair.getRight().isEmpty()). map(Pair::getLeft). collect(Collectors.toSet()); @@ -104,7 +104,7 @@ protected Optional check( // build the JEXL context where variables are mapped to property values, built according to the defined type Map vars = new HashMap<>(); for (FormPropertyDef fpd : task.getFormPropertyDefs()) { - String value = macroTaskForm.getProperty(fpd.getKey()).map(FormProperty::getValue).orElse(null); + String value = macroTaskForm.getProperty(fpd.getName()).map(FormProperty::getValue).orElse(null); if (value == null) { continue; } @@ -115,40 +115,40 @@ protected Optional check( map(pattern -> !pattern.matcher(value).matches()). orElse(false)) { - throw new JobExecutionException("RegEx not matching for " + fpd.getKey() + ": " + value); + throw new JobExecutionException("RegEx not matching for " + fpd.getName() + ": " + value); } - vars.put(fpd.getKey(), value); + vars.put(fpd.getName(), value); break; case Password: - vars.put(fpd.getKey(), value); + vars.put(fpd.getName(), value); break; case Boolean: - vars.put(fpd.getKey(), BooleanUtils.toBoolean(value)); + vars.put(fpd.getName(), BooleanUtils.toBoolean(value)); break; case Date: try { - vars.put(fpd.getKey(), StringUtils.isBlank(fpd.getDatePattern()) + vars.put(fpd.getName(), StringUtils.isBlank(fpd.getDatePattern()) ? FormatUtils.parseDate(value) : FormatUtils.parseDate(value, fpd.getDatePattern())); } catch (DateTimeParseException e) { - throw new JobExecutionException("Unparseable date " + fpd.getKey() + ": " + value, e); + throw new JobExecutionException("Unparseable date " + fpd.getName() + ": " + value, e); } break; case Long: - vars.put(fpd.getKey(), NumberUtils.toLong(value)); + vars.put(fpd.getName(), NumberUtils.toLong(value)); break; case Enum: if (!fpd.getEnumValues().containsKey(value)) { - throw new JobExecutionException("Not allowed for " + fpd.getKey() + ": " + value); + throw new JobExecutionException("Not allowed for " + fpd.getName() + ": " + value); } - vars.put(fpd.getKey(), value); + vars.put(fpd.getName(), value); break; case Dropdown: @@ -157,14 +157,14 @@ protected Optional check( ? List.of(value) : List.of(value.split(";")); - if (!actions.map(a -> a.getDropdownValues(fpd.getKey()).keySet()). + if (!actions.map(a -> a.getDropdownValues(fpd.getName()).keySet()). orElse(Set.of()).containsAll(values)) { - throw new JobExecutionException("Not allowed for " + fpd.getKey() + ": " + values); + throw new JobExecutionException("Not allowed for " + fpd.getName() + ": " + values); } } - vars.put(fpd.getKey(), value); + vars.put(fpd.getName(), value); break; default: @@ -311,7 +311,9 @@ protected String doExecute(final boolean dryRun, final String executor, final Jo throw new JobExecutionException( "While running " + command.getKey(), - new IllegalArgumentException(args.getClass().getName())); + new IllegalArgumentException(violations.stream(). + map(v -> v.getPropertyPath() + ": " + v.getMessage()). + collect(Collectors.joining(",")))); } } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MacroTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MacroTaskITCase.java index 315b2ec1dfc..d692c320d42 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MacroTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MacroTaskITCase.java @@ -26,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.fail; import java.nio.charset.StandardCharsets; +import java.util.Locale; import java.util.concurrent.TimeUnit; import javax.ws.rs.core.Response; import org.apache.commons.io.IOUtils; @@ -130,16 +131,16 @@ public static void testCommandsSetup() throws Exception { new CommandTO.Builder(TestCommand.class.getSimpleName()).args(TCA).build()); FormPropertyDefTO realm = new FormPropertyDefTO(); - realm.setKey("realm"); - realm.setName("Realm"); + realm.setName("realm"); + realm.getLabels().put(Locale.ENGLISH, "Realm"); realm.setWritable(true); realm.setRequired(true); realm.setType(FormPropertyType.String); task.getFormPropertyDefs().add(realm); FormPropertyDefTO parent = new FormPropertyDefTO(); - parent.setKey("parent"); - parent.setName("Parent Realm"); + parent.setName("parent"); + parent.getLabels().put(Locale.ENGLISH, "Parent Realm"); parent.setWritable(true); parent.setRequired(true); parent.setType(FormPropertyType.Dropdown); @@ -166,7 +167,7 @@ public static void cleanup() { @Test public void execute() { - SyncopeForm form = TASK_SERVICE.getMacroTaskForm(MACRO_TASK_KEY); + SyncopeForm form = TASK_SERVICE.getMacroTaskForm(MACRO_TASK_KEY, Locale.ENGLISH.toLanguageTag()); form.getProperty("realm").orElseThrow().setValue("macro"); FormProperty parent = form.getProperty("parent").orElseThrow(); assertTrue(parent.getDropdownValues().stream().anyMatch(v -> "/odd".equals(v.getKey())));