syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject [13/18] syncope git commit: [SYNCOPE-956] Console implementation
Date Tue, 10 Oct 2017 06:37:02 GMT
http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWizardBuilder.java
index 261604b..9142881 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWizardBuilder.java
@@ -21,28 +21,25 @@ package org.apache.syncope.client.console.policies;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.BeanPanel;
 import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.rest.PolicyRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
-import org.apache.syncope.common.lib.info.JavaImplInfo;
 import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
-import org.apache.syncope.common.lib.policy.AccountPolicyTO;
 import org.apache.syncope.common.lib.policy.ComposablePolicy;
 import org.apache.syncope.common.lib.policy.RuleConf;
+import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.ImplementationTO;
 import org.apache.syncope.common.lib.types.ImplementationEngine;
 import org.apache.syncope.common.lib.types.ImplementationType;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.wicket.PageReference;
-import org.apache.wicket.core.util.lang.PropertyResolver;
+import org.apache.wicket.ajax.AjaxEventBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.wizard.WizardModel;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.model.LoadableDetachableModel;
@@ -54,33 +51,7 @@ public class PolicyRuleWizardBuilder extends AjaxWizardBuilder<PolicyRuleWrapper
 
     private static final ObjectMapper MAPPER = new ObjectMapper();
 
-    private static final ImplementationRestClient IMPLEMENTATION_CLIENT = new ImplementationRestClient();
-
-    @SuppressWarnings("unchecked")
-    public static List<PolicyRuleWrapper> getPolicyRuleWrappers(final AbstractPolicyTO policyTO) {
-        Object rules = PropertyResolver.getValue("rules", policyTO);
-        if (rules instanceof List) {
-            return ((List<String>) rules).stream().map(rule -> {
-                ImplementationTO implementation = IMPLEMENTATION_CLIENT.read(rule);
-
-                PolicyRuleWrapper wrapper = null;
-                if (implementation.getEngine() == ImplementationEngine.JAVA) {
-                    try {
-                        RuleConf ruleConf = MAPPER.readValue(implementation.getBody(), RuleConf.class);
-                        wrapper = new PolicyRuleWrapper().
-                                setImplementationKey(implementation.getKey()).
-                                setName(ruleConf.getName());
-                    } catch (Exception e) {
-                        LOG.error("During deserialization", e);
-                    }
-                }
-
-                return wrapper;
-            }).filter(wrapper -> wrapper != null).collect(Collectors.toList());
-        } else {
-            return null;
-        }
-    }
+    private final ImplementationRestClient implementationClient = new ImplementationRestClient();
 
     private final PolicyRestClient restClient = new PolicyRestClient();
 
@@ -91,9 +62,11 @@ public class PolicyRuleWizardBuilder extends AjaxWizardBuilder<PolicyRuleWrapper
     public PolicyRuleWizardBuilder(
             final String policy,
             final PolicyType type,
-            final PolicyRuleWrapper reportlet,
+            final PolicyRuleWrapper policyWrapper,
             final PageReference pageRef) {
-        super(reportlet, pageRef);
+
+        super(policyWrapper, pageRef);
+
         this.policy = policy;
         this.type = type;
     }
@@ -109,28 +82,19 @@ public class PolicyRuleWizardBuilder extends AjaxWizardBuilder<PolicyRuleWrapper
             throw new IllegalStateException("Non composable policy");
         }
 
-        ImplementationTO rule = new ImplementationTO();
-        rule.setKey(modelObject.getName());
-        rule.setEngine(ImplementationEngine.JAVA);
-        rule.setType(composable instanceof AccountPolicyTO
-                ? ImplementationType.ACCOUNT_RULE : ImplementationType.PASSWORD_RULE);
-        try {
-            rule.setBody(MAPPER.writeValueAsString(modelObject.getConf()));
-
-            rule = IMPLEMENTATION_CLIENT.create(rule);
-        } catch (Exception e) {
-            throw new IllegalStateException("Could not create rule", e);
+        if (modelObject.getImplementationEngine() == ImplementationEngine.JAVA) {
+            ImplementationTO rule = implementationClient.read(modelObject.getImplementationKey());
+            try {
+                rule.setBody(MAPPER.writeValueAsString(modelObject.getConf()));
+                implementationClient.update(rule);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
         }
 
-        if (!modelObject.isNew()) {
-            List<PolicyRuleWrapper> wrappers = getPolicyRuleWrappers(policyTO);
-            wrappers.removeAll(wrappers.stream().
-                    filter(wrapper -> wrapper.getName().equals(modelObject.getOldName())).collect(Collectors.toSet()));
-            composable.getRules().clear();
-            composable.getRules().addAll(wrappers.stream().
-                    map(PolicyRuleWrapper::getImplementationKey).collect(Collectors.toSet()));
+        if (modelObject.isNew()) {
+            composable.getRules().add(modelObject.getImplementationKey());
         }
-        composable.getRules().add(rule.getKey());
 
         restClient.updatePolicy(policyTO);
         return modelObject;
@@ -147,75 +111,69 @@ public class PolicyRuleWizardBuilder extends AjaxWizardBuilder<PolicyRuleWrapper
 
         private static final long serialVersionUID = -3043839139187792810L;
 
+        private final PolicyRuleWrapper rule;
+
         public Profile(final PolicyRuleWrapper rule) {
-            final AjaxTextFieldPanel name = new AjaxTextFieldPanel(
-                    "name", "rule", new PropertyModel<>(rule, "name"), false);
-            name.addRequiredLabel();
-            add(name);
+            this.rule = rule;
 
             final AjaxDropDownChoicePanel<String> conf = new AjaxDropDownChoicePanel<>(
-                    "configuration", "configuration", new PropertyModel<String>(rule, "conf") {
-
-                private static final long serialVersionUID = -6427731218492117883L;
-
-                @Override
-                public String getObject() {
-                    return rule.getConf() == null ? null : rule.getConf().getClass().getName();
-                }
-
-                @Override
-                public void setObject(final String object) {
-                    RuleConf conf = null;
+                    "rule", "rule", new PropertyModel<>(rule, "implementationKey"));
 
-                    try {
-                        conf = RuleConf.class.cast(Class.forName(object).newInstance());
-                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
-                        LOG.warn("Error retrieving reportlet configuration instance", e);
-                    }
-
-                    rule.setConf(conf);
-                }
-            });
-
-            Optional<JavaImplInfo> providers;
             List<String> choices;
             switch (type) {
                 case ACCOUNT:
-                    providers = SyncopeConsoleSession.get().getPlatformInfo().
-                            getJavaImplInfo(ImplementationType.ACCOUNT_RULE);
-                    choices = providers.isPresent()
-                            ? new ArrayList<>(providers.get().getClasses())
-                            : new ArrayList<>();
+                    choices = implementationClient.list(ImplementationType.ACCOUNT_RULE).stream().
+                            map(EntityTO::getKey).sorted().collect(Collectors.toList());
                     break;
 
                 case PASSWORD:
-                    providers = SyncopeConsoleSession.get().getPlatformInfo().
-                            getJavaImplInfo(ImplementationType.PASSWORD_RULE);
-                    choices = providers.isPresent()
-                            ? new ArrayList<>(providers.get().getClasses())
-                            : new ArrayList<>();
+                    choices = implementationClient.list(ImplementationType.PASSWORD_RULE).stream().
+                            map(EntityTO::getKey).sorted().collect(Collectors.toList());
                     break;
 
                 default:
                     choices = new ArrayList<>();
             }
 
-            Collections.<String>sort(choices);
             conf.setChoices(choices);
-
             conf.addRequiredLabel();
+            conf.setNullValid(false);
+            conf.setEnabled(rule.isNew());
+            conf.add(new AjaxEventBehavior(Constants.ON_CHANGE) {
+
+                private static final long serialVersionUID = -7133385027739964990L;
+
+                @Override
+                protected void onEvent(final AjaxRequestTarget target) {
+                    ImplementationTO implementation = implementationClient.read(conf.getModelObject());
+                    rule.setImplementationEngine(implementation.getEngine());
+                    if (implementation.getEngine() == ImplementationEngine.JAVA) {
+                        try {
+                            RuleConf ruleConf = MAPPER.readValue(implementation.getBody(), RuleConf.class);
+                            rule.setConf(ruleConf);
+                        } catch (Exception e) {
+                            LOG.error("During deserialization", e);
+                        }
+                    }
+                }
+            });
             add(conf);
         }
+
+        @Override
+        public void applyState() {
+            if (rule.getImplementationEngine() == ImplementationEngine.GROOVY) {
+                getWizardModel().finish();
+            }
+        }
     }
 
     public class Configuration extends WizardStep {
 
         private static final long serialVersionUID = -785981096328637758L;
 
-        private final LoadableDetachableModel<Serializable> bean;
-
         public Configuration(final PolicyRuleWrapper rule) {
-            bean = new LoadableDetachableModel<Serializable>() {
+            LoadableDetachableModel<Serializable> bean = new LoadableDetachableModel<Serializable>() {
 
                 private static final long serialVersionUID = 2092144708018739371L;
 
@@ -224,7 +182,6 @@ public class PolicyRuleWizardBuilder extends AjaxWizardBuilder<PolicyRuleWrapper
                     return rule.getConf();
                 }
             };
-
             add(new BeanPanel<>("bean", bean).setRenderBodyOnly(true));
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWrapper.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWrapper.java b/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWrapper.java
index b05eabc..c8d52ea 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWrapper.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleWrapper.java
@@ -20,33 +20,30 @@ package org.apache.syncope.client.console.policies;
 
 import java.io.Serializable;
 import org.apache.syncope.common.lib.policy.RuleConf;
+import org.apache.syncope.common.lib.types.ImplementationEngine;
 
 public class PolicyRuleWrapper implements Serializable {
 
     private static final long serialVersionUID = 2472755929742424558L;
 
-    private String implementationKey;
+    private final boolean isNew;
 
-    private String oldname;
+    private String implementationKey;
 
-    private String name;
+    private ImplementationEngine implementationEngine;
 
     private RuleConf conf;
 
-    public String getImplementationKey() {
-        return implementationKey;
+    public PolicyRuleWrapper(final boolean isNew) {
+        this.isNew = isNew;
     }
 
     public boolean isNew() {
-        return oldname == null;
-    }
-
-    public String getOldName() {
-        return this.oldname;
+        return isNew;
     }
 
-    public String getName() {
-        return this.name;
+    public String getImplementationKey() {
+        return implementationKey;
     }
 
     public PolicyRuleWrapper setImplementationKey(final String implementationKey) {
@@ -54,8 +51,12 @@ public class PolicyRuleWrapper implements Serializable {
         return this;
     }
 
-    public PolicyRuleWrapper setName(final String name) {
-        this.name = name;
+    public ImplementationEngine getImplementationEngine() {
+        return implementationEngine;
+    }
+
+    public PolicyRuleWrapper setImplementationEngine(final ImplementationEngine implementationEngine) {
+        this.implementationEngine = implementationEngine;
         return this;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicySpecModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicySpecModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicySpecModalPanel.java
index 7cee8ab..313d869 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicySpecModalPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/policies/PolicySpecModalPanel.java
@@ -26,7 +26,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
@@ -34,6 +33,7 @@ import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.panels.AbstractModalPanel;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
+import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.rest.PolicyRestClient;
 import org.apache.syncope.client.console.rest.SchemaRestClient;
 import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
@@ -41,7 +41,6 @@ import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.Bas
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.MultiPanel;
-import org.apache.syncope.common.lib.info.JavaImplInfo;
 import org.apache.syncope.common.lib.policy.PullPolicyTO;
 import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -61,6 +60,12 @@ public class PolicySpecModalPanel extends AbstractModalPanel<PullPolicyTO> {
 
     private static final long serialVersionUID = 5945391813567245081L;
 
+    private enum CorrelationRuleType {
+        PLAIN_ATTRIBUTES,
+        CUSTOM;
+
+    }
+
     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
 
     private final IModel<List<CorrelationRule>> model;
@@ -83,13 +88,9 @@ public class PolicySpecModalPanel extends AbstractModalPanel<PullPolicyTO> {
 
             private static final long serialVersionUID = -8168676563540297301L;
 
-            private List<CorrelationRule> rules =
-                    (policyTO.getSpecification().getCorrelationRules() == null
-                            ? Collections.<String>emptySet()
-                            : policyTO.getSpecification().getCorrelationRules().keySet()).stream().
-                            map(rule -> new CorrelationRule(
-                            rule, policyTO.getSpecification().getCorrelationRules().get(rule))).
-                            collect(Collectors.toList());
+            private List<CorrelationRule> rules = policyTO.getSpecification().getCorrelationRules().keySet().stream().
+                    map(rule -> new CorrelationRule(rule, policyTO.getSpecification().getCorrelationRules().get(rule))).
+                    collect(Collectors.toList());
 
             @Override
             public List<CorrelationRule> getObject() {
@@ -143,7 +144,9 @@ public class PolicySpecModalPanel extends AbstractModalPanel<PullPolicyTO> {
 
         private static final long serialVersionUID = -4708008994320210839L;
 
-        public CorrelationRulePanel(final String id, final IModel<CorrelationRule> rule) {
+        private final ImplementationRestClient implRestClient = new ImplementationRestClient();
+
+        CorrelationRulePanel(final String id, final IModel<CorrelationRule> rule) {
             super(id);
 
             AjaxDropDownChoicePanel<String> anyType = new AjaxDropDownChoicePanel<>(
@@ -152,25 +155,21 @@ public class PolicySpecModalPanel extends AbstractModalPanel<PullPolicyTO> {
                     setChoices(new AnyTypeRestClient().list());
             add(anyType);
 
-            final AjaxDropDownChoicePanel<String> ruleType = new AjaxDropDownChoicePanel<>(
-                    "ruleType", "rule.type", new PropertyModel<String>(rule.getObject(), "type"), false).
+            final AjaxDropDownChoicePanel<CorrelationRuleType> ruleType = new AjaxDropDownChoicePanel<>(
+                    "ruleType", "rule.type", new PropertyModel<CorrelationRuleType>(rule.getObject(), "type"), false).
                     setNullValid(true).
-                    setChoices(Arrays.asList("PLAIN ATTRIBUTES", "JAVA"));
+                    setChoices(Arrays.stream(CorrelationRuleType.values()).collect(Collectors.toList()));
             add(ruleType);
 
             // ---------------------------------------------------------------
-            // Java rule palette
+            // Custom rule palette
             // ---------------------------------------------------------------
-            Optional<JavaImplInfo> pullCorrelationRules = SyncopeConsoleSession.get().getPlatformInfo().
-                    getJavaImplInfo(ImplementationType.PULL_CORRELATION_RULE);
-            List<String> load = pullCorrelationRules.isPresent()
-                    ? new ArrayList<>(pullCorrelationRules.get().getClasses())
-                    : new ArrayList<>();
-            Collections.sort(load);
-            final AjaxDropDownChoicePanel<String> javaRule = new AjaxDropDownChoicePanel<>(
-                    "javaRule", "rule.java", new PropertyModel<String>(rule.getObject(), "rule")).setChoices(load);
-            javaRule.setOutputMarkupPlaceholderTag(true);
-            add(javaRule.setVisible("JAVA".equals(rule.getObject().getType())));
+            List<String> rules = implRestClient.list(ImplementationType.PULL_CORRELATION_RULE).stream().
+                    map(EntityTO::getKey).sorted().collect(Collectors.toList());
+            final AjaxDropDownChoicePanel<String> customRule = new AjaxDropDownChoicePanel<>(
+                    "customRule", "rule.custom", new PropertyModel<String>(rule.getObject(), "rule")).setChoices(rules);
+            customRule.setOutputMarkupPlaceholderTag(true);
+            add(customRule.setVisible(CorrelationRuleType.CUSTOM == rule.getObject().getType()));
             // ---------------------------------------------------------------
 
             // ---------------------------------------------------------------
@@ -245,7 +244,7 @@ public class PolicySpecModalPanel extends AbstractModalPanel<PullPolicyTO> {
                 }
             });
 
-            add(jsonRule.setVisible("PLAIN ATTRIBUTES".equals(rule.getObject().getType())));
+            add(jsonRule.setVisible(CorrelationRuleType.PLAIN_ATTRIBUTES == rule.getObject().getType()));
             // ---------------------------------------------------------------
 
             ruleType.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
@@ -254,23 +253,25 @@ public class PolicySpecModalPanel extends AbstractModalPanel<PullPolicyTO> {
 
                 @Override
                 protected void onUpdate(final AjaxRequestTarget target) {
-                    switch (ruleType.getModelObject() == null ? StringUtils.EMPTY : ruleType.getModelObject()) {
-                        case "PLAIN ATTRIBUTES":
+                    switch (ruleType.getModelObject()) {
+                        case PLAIN_ATTRIBUTES:
                             jsonRule.setVisible(true);
-                            javaRule.setVisible(false);
+                            customRule.setVisible(false);
                             jsonRule.reload(target);
                             break;
-                        case "JAVA":
+
+                        case CUSTOM:
                             jsonRule.setVisible(false);
-                            javaRule.setVisible(true);
+                            customRule.setVisible(true);
                             break;
+
                         default:
-                            javaRule.setVisible(false);
+                            customRule.setVisible(false);
                             jsonRule.setVisible(false);
 
                     }
                     target.add(jsonRule);
-                    target.add(javaRule);
+                    target.add(customRule);
                 }
             });
         }
@@ -293,25 +294,26 @@ public class PolicySpecModalPanel extends AbstractModalPanel<PullPolicyTO> {
         }
     }
 
-    protected static class CorrelationRule implements Serializable {
+    private static class CorrelationRule implements Serializable {
 
         private static final long serialVersionUID = 5250228867297353011L;
 
         private String any;
 
-        private String type;
+        private CorrelationRuleType type;
 
         private String rule;
 
-        public CorrelationRule() {
+        CorrelationRule() {
             this.any = AnyTypeKind.USER.name();
-            this.type = "PLAIN ATTRIBUTES";
+            this.type = CorrelationRuleType.PLAIN_ATTRIBUTES;
             this.rule = "[]";
         }
 
-        public CorrelationRule(final String any, final String rule) {
+        CorrelationRule(final String any, final String rule) {
             this.any = any;
-            this.type = StringUtils.isEmpty(rule) || rule.trim().startsWith("[") ? "PLAIN ATTRIBUTES" : "JAVA";
+            this.type = StringUtils.isEmpty(rule) || rule.trim().startsWith("[") ? CorrelationRuleType.PLAIN_ATTRIBUTES
+                    : CorrelationRuleType.CUSTOM;
             this.rule = rule;
         }
 
@@ -319,7 +321,7 @@ public class PolicySpecModalPanel extends AbstractModalPanel<PullPolicyTO> {
             return any;
         }
 
-        public String getType() {
+        public CorrelationRuleType getType() {
             return type;
         }
 
@@ -331,7 +333,7 @@ public class PolicySpecModalPanel extends AbstractModalPanel<PullPolicyTO> {
             this.any = any;
         }
 
-        public void setType(final String type) {
+        public void setType(final CorrelationRuleType type) {
             this.type = type;
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/policies/PullPolicyDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/policies/PullPolicyDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/policies/PullPolicyDirectoryPanel.java
index 32b81b7..4d55249 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/policies/PullPolicyDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/policies/PullPolicyDirectoryPanel.java
@@ -63,7 +63,7 @@ public class PullPolicyDirectoryPanel extends PolicyDirectoryPanel<PullPolicyTO>
                         new PolicySpecModalPanel(model.getObject(), policySpecModal, pageRef)));
 
                 policySpecModal.header(new StringResourceModel(
-                        "policy.rule.conf", PullPolicyDirectoryPanel.this, Model.of(model.getObject())));
+                        "policy.rules", PullPolicyDirectoryPanel.this, Model.of(model.getObject())));
 
                 MetaDataRoleAuthorizationStrategy.authorize(
                         policySpecModal.getForm(), ENABLE, StandardEntitlement.POLICY_UPDATE);

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
index 721ab0e..667cc92 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
@@ -18,12 +18,14 @@
  */
 package org.apache.syncope.client.console.reports;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.stream.Collectors;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
@@ -33,6 +35,7 @@ import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.panels.DirectoryPanel;
 import org.apache.syncope.client.console.panels.ModalPanel;
+import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.rest.ReportRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
@@ -42,7 +45,9 @@ import org.apache.syncope.client.console.wizards.AjaxWizard;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.report.ReportletConf;
+import org.apache.syncope.common.lib.to.ImplementationTO;
 import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.types.ImplementationEngine;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
@@ -68,6 +73,8 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
 
     private static final long serialVersionUID = 4984337552918213290L;
 
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
     private final BaseModal<ReportTO> baseModal;
 
     private final String report;
@@ -84,7 +91,8 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
 
         enableExitButton();
 
-        this.addNewItemPanelBuilder(new ReportletWizardBuilder(report, new ReportletWrapper(), pageRef), true);
+        this.addNewItemPanelBuilder(
+                new ReportletWizardBuilder(report, new ReportletWrapper(true), pageRef), true);
 
         MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, StandardEntitlement.REPORT_UPDATE);
         initResultTable();
@@ -95,7 +103,7 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
         final List<IColumn<ReportletWrapper, String>> columns = new ArrayList<>();
 
         columns.add(new PropertyColumn<>(
-                new StringResourceModel("reportlet", this), "name", "name"));
+                new StringResourceModel("reportlet", this), "implementationKey", "implementationKey"));
 
         columns.add(new AbstractColumn<ReportletWrapper, String>(
                 new StringResourceModel("configuration", this)) {
@@ -108,7 +116,11 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
                     final String componentId,
                     final IModel<ReportletWrapper> rowModel) {
 
-                cellItem.add(new Label(componentId, rowModel.getObject().getConf().getClass().getName()));
+                if (rowModel.getObject().getConf() == null) {
+                    cellItem.add(new Label(componentId, ""));
+                } else {
+                    cellItem.add(new Label(componentId, rowModel.getObject().getConf().getClass().getName()));
+                }
             }
         });
 
@@ -130,8 +142,7 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
 
                 send(ReportletDirectoryPanel.this, Broadcast.EXACT,
                         new AjaxWizard.EditItemActionEvent<>(
-                                new ReportletWrapper().setConf(clone).setName(null),
-                                target));
+                                new ReportletWrapper(true).setConf(clone), target));
             }
         }, ActionLink.ActionType.CLONE, StandardEntitlement.REPORT_CREATE);
         panel.add(new ActionLink<ReportletWrapper>() {
@@ -141,8 +152,12 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
             @Override
             public void onClick(final AjaxRequestTarget target, final ReportletWrapper ignore) {
                 ReportletDirectoryPanel.this.getTogglePanel().close(target);
-                send(ReportletDirectoryPanel.this, Broadcast.EXACT,
-                        new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
+                if (model.getObject().getConf() == null) {
+                    SyncopeConsoleSession.get().info(getString("noConf"));
+                } else {
+                    send(ReportletDirectoryPanel.this, Broadcast.EXACT,
+                            new AjaxWizard.EditItemActionEvent<>(model.getObject(), target));
+                }
             }
         }, ActionLink.ActionType.EDIT, StandardEntitlement.REPORT_UPDATE);
         panel.add(new ActionLink<ReportletWrapper>() {
@@ -210,21 +225,43 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
 
         private static final long serialVersionUID = 4725679400450513556L;
 
+        private final ImplementationRestClient implementationClient = new ImplementationRestClient();
+
         private final SortableDataProviderComparator<ReportletWrapper> comparator;
 
         public ReportDataProvider(final int paginatorRows) {
             super(paginatorRows);
 
             //Default sorting
-            setSort("name", SortOrder.ASCENDING);
+            setSort("implementationKey", SortOrder.ASCENDING);
             comparator = new SortableDataProviderComparator<>(this);
         }
 
+        private List<ReportletWrapper> getReportletWrappers(final ReportTO reportTO) {
+            return reportTO.getReportlets().stream().map(reportlet -> {
+                ImplementationTO implementation = implementationClient.read(reportlet);
+
+                ReportletWrapper wrapper = new ReportletWrapper(false).
+                        setImplementationKey(implementation.getKey()).
+                        setImplementationEngine(implementation.getEngine());
+                if (implementation.getEngine() == ImplementationEngine.JAVA) {
+                    try {
+                        ReportletConf reportletConf = MAPPER.readValue(implementation.getBody(), ReportletConf.class);
+                        wrapper.setConf(reportletConf);
+                    } catch (Exception e) {
+                        LOG.error("During deserialization", e);
+                    }
+                }
+
+                return wrapper;
+            }).filter(wrapper -> wrapper != null).collect(Collectors.toList());
+        }
+
         @Override
         public Iterator<ReportletWrapper> iterator(final long first, final long count) {
             final ReportTO actual = restClient.read(report);
 
-            List<ReportletWrapper> reportlets = ReportletWizardBuilder.getReportletWrappers(actual);
+            List<ReportletWrapper> reportlets = getReportletWrappers(actual);
 
             Collections.sort(reportlets, comparator);
             return reportlets.subList((int) first, (int) (first + count)).iterator();
@@ -233,7 +270,7 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
         @Override
         public long size() {
             final ReportTO actual = restClient.read(report);
-            return ReportletWizardBuilder.getReportletWrappers(actual).size();
+            return getReportletWrappers(actual).size();
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
index 0355ce6..8668103 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
@@ -20,25 +20,22 @@ package org.apache.syncope.client.console.reports;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.BeanPanel;
 import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.rest.ReportRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
-import org.apache.syncope.common.lib.info.JavaImplInfo;
-import org.apache.syncope.common.lib.report.AbstractReportletConf;
 import org.apache.syncope.common.lib.report.ReportletConf;
+import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.ImplementationTO;
 import org.apache.syncope.common.lib.to.ReportTO;
 import org.apache.syncope.common.lib.types.ImplementationEngine;
 import org.apache.syncope.common.lib.types.ImplementationType;
 import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxEventBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.wizard.WizardModel;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.model.PropertyModel;
@@ -50,27 +47,7 @@ public class ReportletWizardBuilder extends AjaxWizardBuilder<ReportletWrapper>
 
     private static final ObjectMapper MAPPER = new ObjectMapper();
 
-    private static final ImplementationRestClient IMPLEMENTATION_CLIENT = new ImplementationRestClient();
-
-    public static List<ReportletWrapper> getReportletWrappers(final ReportTO reportTO) {
-        return reportTO.getReportlets().stream().map(reportlet -> {
-            ImplementationTO implementation = IMPLEMENTATION_CLIENT.read(reportlet);
-
-            ReportletWrapper wrapper = null;
-            if (implementation.getEngine() == ImplementationEngine.JAVA) {
-                try {
-                    ReportletConf reportletCOnf = MAPPER.readValue(implementation.getBody(), ReportletConf.class);
-                    wrapper = new ReportletWrapper().
-                            setImplementationKey(implementation.getKey()).
-                            setName(reportletCOnf.getName());
-                } catch (Exception e) {
-                    LOG.error("During deserialization", e);
-                }
-            }
-
-            return wrapper;
-        }).filter(wrapper -> wrapper != null).collect(Collectors.toList());
-    }
+    private final ImplementationRestClient implementationClient = new ImplementationRestClient();
 
     private final ReportRestClient restClient = new ReportRestClient();
 
@@ -86,28 +63,20 @@ public class ReportletWizardBuilder extends AjaxWizardBuilder<ReportletWrapper>
 
     @Override
     protected Serializable onApplyInternal(final ReportletWrapper modelObject) {
-        ImplementationTO reportlet = new ImplementationTO();
-        reportlet.setKey(modelObject.getName());
-        reportlet.setEngine(ImplementationEngine.JAVA);
-        reportlet.setType(ImplementationType.REPORTLET);
-        try {
-            reportlet.setBody(MAPPER.writeValueAsString(modelObject.getConf()));
-
-            reportlet = IMPLEMENTATION_CLIENT.create(reportlet);
-        } catch (Exception e) {
-            throw new IllegalStateException("Could not create reportlet", e);
+        if (modelObject.getImplementationEngine() == ImplementationEngine.JAVA) {
+            ImplementationTO reportlet = implementationClient.read(modelObject.getImplementationKey());
+            try {
+                reportlet.setBody(MAPPER.writeValueAsString(modelObject.getConf()));
+                implementationClient.update(reportlet);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
         }
 
         ReportTO reportTO = restClient.read(report);
-        if (!modelObject.isNew()) {
-            List<ReportletWrapper> wrappers = getReportletWrappers(reportTO);
-            wrappers.removeAll(wrappers.stream().
-                    filter(wrapper -> wrapper.getName().equals(modelObject.getOldName())).collect(Collectors.toSet()));
-            reportTO.getReportlets().clear();
-            reportTO.getReportlets().addAll(wrappers.stream().
-                    map(ReportletWrapper::getImplementationKey).collect(Collectors.toSet()));
+        if (modelObject.isNew()) {
+            reportTO.getReportlets().add(modelObject.getImplementationKey());
         }
-        reportTO.getReportlets().add(reportlet.getKey());
 
         restClient.update(reportTO);
         return modelObject;
@@ -126,45 +95,32 @@ public class ReportletWizardBuilder extends AjaxWizardBuilder<ReportletWrapper>
         private static final long serialVersionUID = -3043839139187792810L;
 
         public Profile(final ReportletWrapper reportlet) {
-
-            final AjaxTextFieldPanel name = new AjaxTextFieldPanel(
-                    "name", "reportlet", new PropertyModel<>(reportlet, "name"), false);
-            name.addRequiredLabel();
-            name.setEnabled(true);
-            add(name);
-
             final AjaxDropDownChoicePanel<String> conf = new AjaxDropDownChoicePanel<>(
-                    "configuration", getString("configuration"), new PropertyModel<String>(reportlet, "conf") {
+                    "reportlet", getString("reportlet"), new PropertyModel<String>(reportlet, "implementationKey"));
 
-                private static final long serialVersionUID = -6427731218492117883L;
+            conf.setChoices(implementationClient.list(ImplementationType.REPORTLET).stream().
+                    map(EntityTO::getKey).sorted().collect(Collectors.toList()));
+            conf.addRequiredLabel();
+            conf.setNullValid(false);
+            conf.setEnabled(reportlet.isNew());
+            conf.add(new AjaxEventBehavior(Constants.ON_CHANGE) {
 
-                @Override
-                public String getObject() {
-                    return reportlet.getConf() == null ? null : reportlet.getConf().getClass().getName();
-                }
+                private static final long serialVersionUID = -7133385027739964990L;
 
                 @Override
-                public void setObject(final String object) {
-                    AbstractReportletConf conf = null;
-
-                    try {
-                        conf = AbstractReportletConf.class.cast(Class.forName(object).newInstance());
-                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
-                        LOG.warn("Error retrieving reportlet configuration instance", e);
+                protected void onEvent(final AjaxRequestTarget target) {
+                    ImplementationTO implementation = implementationClient.read(conf.getModelObject());
+                    reportlet.setImplementationEngine(implementation.getEngine());
+                    if (implementation.getEngine() == ImplementationEngine.JAVA) {
+                        try {
+                            ReportletConf conf = MAPPER.readValue(implementation.getBody(), ReportletConf.class);
+                            reportlet.setConf(conf);
+                        } catch (Exception e) {
+                            LOG.error("During deserialization", e);
+                        }
                     }
-
-                    reportlet.setConf(conf);
                 }
             });
-
-            Optional<JavaImplInfo> reportlets = SyncopeConsoleSession.get().getPlatformInfo().
-                    getJavaImplInfo(ImplementationType.REPORTLET);
-            List<String> choices = reportlets.isPresent()
-                    ? new ArrayList<>(reportlets.get().getClasses())
-                    : new ArrayList<>();
-            conf.setChoices(choices);
-
-            conf.addRequiredLabel();
             add(conf);
         }
     }
@@ -183,8 +139,7 @@ public class ReportletWizardBuilder extends AjaxWizardBuilder<ReportletWrapper>
                     return reportlet.getConf();
                 }
             };
-
-            add(new BeanPanel<>("bean", bean, reportlet.getSCondWrapper(), "name", "reportletClassName").
+            add(new BeanPanel<>("bean", bean, reportlet.getSCondWrapper(), "name", "reportlet").
                     setRenderBodyOnly(true));
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWrapper.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWrapper.java b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWrapper.java
index d6d1d77..be628a7 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWrapper.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWrapper.java
@@ -26,28 +26,29 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.panels.search.SearchClause;
 import org.apache.syncope.common.lib.report.ReportletConf;
 import org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.types.ImplementationEngine;
 
 public class ReportletWrapper implements Serializable {
 
     private static final long serialVersionUID = 2472755929742424558L;
 
-    private String implementationKey;
+    private final boolean isNew;
 
-    private String oldname;
+    private String implementationKey;
 
-    private String name;
+    private ImplementationEngine implementationEngine;
 
     private ReportletConf conf;
 
     private final Map<String, Pair<AbstractFiqlSearchConditionBuilder, List<SearchClause>>> scondWrapper;
 
-    public ReportletWrapper() {
-        this(null);
+    public ReportletWrapper(final boolean isNew) {
+        this.isNew = isNew;
+        this.scondWrapper = new HashMap<>();
     }
 
-    public ReportletWrapper(final String name) {
-        this.oldname = name;
-        this.scondWrapper = new HashMap<>();
+    public boolean isNew() {
+        return isNew;
     }
 
     public String getImplementationKey() {
@@ -59,20 +60,12 @@ public class ReportletWrapper implements Serializable {
         return this;
     }
 
-    public boolean isNew() {
-        return oldname == null;
-    }
-
-    public String getOldName() {
-        return this.oldname;
-    }
-
-    public String getName() {
-        return this.name;
+    public ImplementationEngine getImplementationEngine() {
+        return implementationEngine;
     }
 
-    public ReportletWrapper setName(final String name) {
-        this.name = name;
+    public ReportletWrapper setImplementationEngine(final ImplementationEngine implementationEngine) {
+        this.implementationEngine = implementationEngine;
         return this;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/rest/ImplementationRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ImplementationRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ImplementationRestClient.java
index 2de2a54..106d271 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ImplementationRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ImplementationRestClient.java
@@ -18,17 +18,20 @@
  */
 package org.apache.syncope.client.console.rest;
 
-import static org.apache.syncope.client.console.rest.BaseRestClient.getObject;
-import static org.apache.syncope.client.console.rest.BaseRestClient.getService;
-
+import java.util.List;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.to.ImplementationTO;
+import org.apache.syncope.common.lib.types.ImplementationType;
 import org.apache.syncope.common.rest.api.service.ImplementationService;
 
 public class ImplementationRestClient extends BaseRestClient {
 
     private static final long serialVersionUID = -4111950555473526287L;
 
+    public List<ImplementationTO> list(final ImplementationType type) {
+        return getService(ImplementationService.class).list(type);
+    }
+
     public ImplementationTO read(final String key) {
         return getService(ImplementationService.class).read(key);
     }
@@ -38,4 +41,13 @@ public class ImplementationRestClient extends BaseRestClient {
         Response response = service.create(implementation);
         return getObject(service, response.getLocation(), ImplementationTO.class);
     }
+
+    public void update(final ImplementationTO implementation) {
+        getService(ImplementationService.class).update(implementation);
+    }
+
+    public void delete(final String key) {
+        getService(ImplementationService.class).delete(key);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
index a2c48fd..5135193 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
@@ -132,8 +132,8 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
         columns.add(new PropertyColumn<>(
                 new StringResourceModel("name", this), "name", "name"));
 
-        columns.add(new PropertyColumn<T, String>(new StringResourceModel(
-                "jobDelegateClassName", this), "jobDelegateClassName", "jobDelegateClassName") {
+        columns.add(new PropertyColumn<T, String>(
+                new StringResourceModel("jobDelegate", this), "jobDelegate", "jobDelegate") {
 
             private static final long serialVersionUID = -3223917055078733093L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
index b940cf1..03e4338 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskWizardBuilder.java
@@ -19,14 +19,12 @@
 package org.apache.syncope.client.console.tasks;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.rest.RealmRestClient;
 import org.apache.syncope.client.console.rest.TaskRestClient;
 import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
@@ -35,8 +33,8 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownCho
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
-import org.apache.syncope.common.lib.info.JavaImplInfo;
 import org.apache.syncope.common.lib.to.AbstractProvisioningTaskTO;
+import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
 import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.to.PushTaskTO;
@@ -61,6 +59,8 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
 
     private final TaskRestClient taskRestClient = new TaskRestClient();
 
+    private final ImplementationRestClient implRestClient = new ImplementationRestClient();
+
     private PushTaskWrapper wrapper;
 
     private CrontabPanel crontabPanel;
@@ -113,68 +113,47 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
 
         private static final long serialVersionUID = -3043839139187792810L;
 
-        private final IModel<List<String>> taskJobClasses = new LoadableDetachableModel<List<String>>() {
+        private final IModel<List<String>> taskJobDelegates = new LoadableDetachableModel<List<String>>() {
 
             private static final long serialVersionUID = 5275935387613157437L;
 
             @Override
             protected List<String> load() {
-                Optional<JavaImplInfo> taskJobDelegates = SyncopeConsoleSession.get().getPlatformInfo().
-                        getJavaImplInfo(ImplementationType.TASKJOB_DELEGATE);
-                List<String> load = taskJobDelegates.isPresent()
-                        ? new ArrayList<>(taskJobDelegates.get().getClasses())
-                        : new ArrayList<>();
-                Collections.sort(load);
-                return load;
+                return implRestClient.list(ImplementationType.TASKJOB_DELEGATE).stream().
+                        map(EntityTO::getKey).sorted().collect(Collectors.toList());
             }
         };
 
-        private final IModel<List<String>> reconciliationFilterBuilderClasses =
-                new LoadableDetachableModel<List<String>>() {
+        private final IModel<List<String>> reconFilterBuilders = new LoadableDetachableModel<List<String>>() {
 
             private static final long serialVersionUID = 5275935387613157437L;
 
             @Override
             protected List<String> load() {
-                Optional<JavaImplInfo> reconFilterBuilders = SyncopeConsoleSession.get().getPlatformInfo().
-                        getJavaImplInfo(ImplementationType.RECON_FILTER_BUILDER);
-                List<String> load = reconFilterBuilders.isPresent()
-                        ? new ArrayList<>(reconFilterBuilders.get().getClasses())
-                        : new ArrayList<>();
-                Collections.sort(load);
-                return load;
+                return implRestClient.list(ImplementationType.RECON_FILTER_BUILDER).stream().
+                        map(EntityTO::getKey).sorted().collect(Collectors.toList());
             }
         };
 
-        private final IModel<List<String>> pullActionsClasses = new LoadableDetachableModel<List<String>>() {
+        private final IModel<List<String>> pullActions = new LoadableDetachableModel<List<String>>() {
 
             private static final long serialVersionUID = 5275935387613157437L;
 
             @Override
             protected List<String> load() {
-                Optional<JavaImplInfo> pullActions = SyncopeConsoleSession.get().getPlatformInfo().
-                        getJavaImplInfo(ImplementationType.PULL_ACTIONS);
-                List<String> load = pullActions.isPresent()
-                        ? new ArrayList<>(pullActions.get().getClasses())
-                        : new ArrayList<>();
-                Collections.sort(load);
-                return load;
+                return implRestClient.list(ImplementationType.PULL_ACTIONS).stream().
+                        map(EntityTO::getKey).sorted().collect(Collectors.toList());
             }
         };
 
-        private final IModel<List<String>> pushActionsClasses = new LoadableDetachableModel<List<String>>() {
+        private final IModel<List<String>> pushActions = new LoadableDetachableModel<List<String>>() {
 
             private static final long serialVersionUID = 5275935387613157437L;
 
             @Override
             protected List<String> load() {
-                Optional<JavaImplInfo> pushActions = SyncopeConsoleSession.get().getPlatformInfo().
-                        getJavaImplInfo(ImplementationType.PUSH_ACTIONS);
-                List<String> load = pushActions.isPresent()
-                        ? new ArrayList<>(pushActions.get().getClasses())
-                        : new ArrayList<>();
-                Collections.sort(load);
-                return load;
+                return implRestClient.list(ImplementationType.PUSH_ACTIONS).stream().
+                        map(EntityTO::getKey).sorted().collect(Collectors.toList());
             }
         };
 
@@ -194,14 +173,13 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
                     false);
             add(active);
 
-            AjaxDropDownChoicePanel<String> jobDelegateClassName = new AjaxDropDownChoicePanel<>(
-                    "jobDelegateClassName", "jobDelegateClassName",
-                    new PropertyModel<>(taskTO, "jobDelegateClassName"), false);
-            jobDelegateClassName.setChoices(taskJobClasses.getObject());
-            jobDelegateClassName.addRequiredLabel();
-            jobDelegateClassName.setEnabled(taskTO.getKey() == null);
-            jobDelegateClassName.setStyleSheet("ui-widget-content ui-corner-all long_dynamicsize");
-            add(jobDelegateClassName);
+            AjaxDropDownChoicePanel<String> jobDelegate = new AjaxDropDownChoicePanel<>(
+                    "jobDelegate", "jobDelegate", new PropertyModel<>(taskTO, "jobDelegate"), false);
+            jobDelegate.setChoices(taskJobDelegates.getObject());
+            jobDelegate.addRequiredLabel();
+            jobDelegate.setEnabled(taskTO.getKey() == null);
+            jobDelegate.setStyleSheet("ui-widget-content ui-corner-all long_dynamicsize");
+            add(jobDelegate);
 
             // ------------------------------
             // Only for pull tasks
@@ -225,14 +203,14 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
             pullMode.setNullValid(!(taskTO instanceof PullTaskTO));
             pullTaskSpecifics.add(pullMode);
 
-            final AjaxDropDownChoicePanel<String> reconciliationFilterBuilderClassName = new AjaxDropDownChoicePanel<>(
-                    "reconciliationFilterBuilderClassName", "reconciliationFilterBuilderClassName",
-                    new PropertyModel<>(taskTO, "reconciliationFilterBuilderClassName"), false);
-            reconciliationFilterBuilderClassName.setChoices(reconciliationFilterBuilderClasses.getObject());
-            reconciliationFilterBuilderClassName.setStyleSheet("ui-widget-content ui-corner-all long_dynamicsize");
-            reconciliationFilterBuilderClassName.setEnabled(isFiltered);
-            reconciliationFilterBuilderClassName.setRequired(isFiltered);
-            pullTaskSpecifics.add(reconciliationFilterBuilderClassName);
+            final AjaxDropDownChoicePanel<String> reconFilterBuilder = new AjaxDropDownChoicePanel<>(
+                    "reconFilterBuilder", "reconFilterBuilder",
+                    new PropertyModel<>(taskTO, "reconFilterBuilder"), false);
+            reconFilterBuilder.setChoices(reconFilterBuilders.getObject());
+            reconFilterBuilder.setStyleSheet("ui-widget-content ui-corner-all long_dynamicsize");
+            reconFilterBuilder.setEnabled(isFiltered);
+            reconFilterBuilder.setRequired(isFiltered);
+            pullTaskSpecifics.add(reconFilterBuilder);
 
             pullMode.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
@@ -240,11 +218,11 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
 
                 @Override
                 protected void onUpdate(final AjaxRequestTarget target) {
-                    reconciliationFilterBuilderClassName.setEnabled(
+                    reconFilterBuilder.setEnabled(
                             pullMode.getModelObject() == PullMode.FILTERED_RECONCILIATION);
-                    reconciliationFilterBuilderClassName.setRequired(
+                    reconFilterBuilder.setRequired(
                             pullMode.getModelObject() == PullMode.FILTERED_RECONCILIATION);
-                    target.add(reconciliationFilterBuilderClassName);
+                    target.add(reconFilterBuilder);
                 }
             });
 
@@ -285,19 +263,19 @@ public class SchedTaskWizardBuilder<T extends SchedTaskTO> extends AjaxWizardBui
             add(provisioningTaskSpecifics.setRenderBodyOnly(true));
 
             if (taskTO instanceof AbstractProvisioningTaskTO) {
-                jobDelegateClassName.setEnabled(false).setVisible(false);
+                jobDelegate.setEnabled(false).setVisible(false);
             } else {
                 provisioningTaskSpecifics.setEnabled(false).setVisible(false);
             }
 
-            AjaxPalettePanel<String> actionsClassNames = new AjaxPalettePanel.Builder<String>().
+            AjaxPalettePanel<String> actions = new AjaxPalettePanel.Builder<String>().
                     setAllowMoveAll(true).setAllowOrder(true).
-                    build("actionsClassNames",
-                            new PropertyModel<List<String>>(taskTO, "actionsClassNames"),
+                    build("actions",
+                            new PropertyModel<List<String>>(taskTO, "actions"),
                             new ListModel<>(taskTO instanceof PushTaskTO
-                                    ? pushActionsClasses.getObject() : pullActionsClasses.getObject()));
-            actionsClassNames.setOutputMarkupId(true);
-            provisioningTaskSpecifics.add(actionsClassNames);
+                                    ? pushActions.getObject() : pullActions.getObject()));
+            actions.setOutputMarkupId(true);
+            provisioningTaskSpecifics.add(actions);
 
             AjaxDropDownChoicePanel<MatchingRule> matchingRule = new AjaxDropDownChoicePanel<>(
                     "matchingRule", "matchingRule", new PropertyModel<>(taskTO, "matchingRule"), false);

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
index 5478c61..da5f451 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksTogglePanel.java
@@ -112,11 +112,11 @@ public class ActionLinksTogglePanel<T extends Serializable> extends TogglePanel<
         } else if (modelObject instanceof StatusBean) {
             header = ((StatusBean) modelObject).getResource();
         } else if (modelObject instanceof PolicyRuleWrapper) {
-            header = ((PolicyRuleWrapper) modelObject).getName();
+            header = ((PolicyRuleWrapper) modelObject).getImplementationKey();
         } else if (modelObject instanceof PolicyRuleWrapper) {
-            header = ((PolicyRuleWrapper) modelObject).getName();
+            header = ((PolicyRuleWrapper) modelObject).getImplementationKey();
         } else if (modelObject instanceof ReportletWrapper) {
-            header = ((ReportletWrapper) modelObject).getName();
+            header = ((ReportletWrapper) modelObject).getImplementationKey();
         } else if (modelObject instanceof JobTO) {
             header = ((JobTO) modelObject).getRefKey() == null
                     ? ((JobTO) modelObject).getRefDesc() : ((JobTO) modelObject).getRefKey();

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
index 6282061..6e9a892 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Ownership.java
@@ -54,7 +54,7 @@ import org.apache.wicket.authroles.authorization.strategies.role.Roles;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.event.IEvent;
 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
-import org.apache.wicket.extensions.wizard.WizardModel;
+import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.CheckBox;
@@ -65,7 +65,7 @@ import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.util.ListModel;
 
-public class Ownership extends WizardStep implements WizardModel.ICondition {
+public class Ownership extends WizardStep implements ICondition {
 
     private static final long serialVersionUID = 855618618337931784L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
index 9da914b..2c333b1 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
@@ -63,7 +63,7 @@ import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.event.IEvent;
 import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
 import org.apache.wicket.extensions.wizard.IWizard;
-import org.apache.wicket.extensions.wizard.WizardModel;
+import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
@@ -77,7 +77,7 @@ import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.util.ListModel;
 
-public class Relationships extends WizardStep implements WizardModel.ICondition {
+public class Relationships extends WizardStep implements ICondition {
 
     private static final long serialVersionUID = 855618618337931784L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
index 806b87c..ccf71f2 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Resources.java
@@ -32,13 +32,13 @@ import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.ActionPermissions;
 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.extensions.wizard.WizardModel;
+import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.util.ListModel;
 
-public class Resources extends WizardStep implements WizardModel.ICondition {
+public class Resources extends WizardStep implements ICondition {
 
     private static final long serialVersionUID = 552437609667518888L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.java
index 3746443..c93d6b0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.java
@@ -29,7 +29,7 @@ import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
-import org.apache.wicket.extensions.wizard.WizardModel;
+import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.Form;
@@ -37,9 +37,7 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.ResourceModel;
 
-public abstract class AbstractConnConfPanel<T extends AbstractBaseBean>
-        extends WizardStep
-        implements WizardModel.ICondition {
+public abstract class AbstractConnConfPanel<T extends AbstractBaseBean> extends WizardStep implements ICondition {
 
     private static final long serialVersionUID = -2025535531121434050L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
index 9b10057..1aa783f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ItemTransformersTogglePanel.java
@@ -19,15 +19,14 @@
 package org.apache.syncope.client.console.wizards.resources;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Optional;
+import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.panels.TogglePanel;
+import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
-import org.apache.syncope.common.lib.info.JavaImplInfo;
+import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.ItemTO;
 import org.apache.syncope.common.lib.types.ImplementationType;
 import org.apache.wicket.PageReference;
@@ -44,6 +43,8 @@ public class ItemTransformersTogglePanel extends TogglePanel<Serializable> {
 
     private static final long serialVersionUID = -3195479265440591519L;
 
+    private final ImplementationRestClient implRestClient = new ImplementationRestClient();
+
     private ItemTO item;
 
     public ItemTransformersTogglePanel(final WebMarkupContainer container, final PageReference pageRef) {
@@ -65,12 +66,8 @@ public class ItemTransformersTogglePanel extends TogglePanel<Serializable> {
         Form<?> form = new Form<>("form");
         addInnerObject(form);
 
-        Optional<JavaImplInfo> itemTransformers = SyncopeConsoleSession.get().getPlatformInfo().
-                getJavaImplInfo(ImplementationType.ITEM_TRANSFORMER);
-        List<String> choices = itemTransformers.isPresent()
-                ? new ArrayList<>(itemTransformers.get().getClasses())
-                : new ArrayList<>();
-        Collections.sort(choices);
+        List<String> choices = implRestClient.list(ImplementationType.ITEM_TRANSFORMER).stream().
+                map(EntityTO::getKey).sorted().collect(Collectors.toList());
 
         form.add(new AjaxPalettePanel.Builder<String>().setAllowOrder(true).setRenderer(new IChoiceRenderer<String>() {
 
@@ -109,11 +106,6 @@ public class ItemTransformersTogglePanel extends TogglePanel<Serializable> {
             @Override
             public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
                 toggle(target, false);
-
-                // [!] this is required to disable changed with close button
-                item.getTransformers().clear();
-                item.getTransformers().addAll(model.getObject());
-
                 target.add(container);
             }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java
index 9e26700..0f14284 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ObjectTypeTogglePanel.java
@@ -34,10 +34,6 @@ public abstract class ObjectTypeTogglePanel extends TogglePanel<Serializable> {
 
     private static final long serialVersionUID = -1366846136630731264L;
 
-    protected PropertyModel<String> typeModel;
-
-    private final Form<Object> form;
-
     ObjectTypeTogglePanel(
             final String id,
             final ResourceProvision item,
@@ -45,10 +41,10 @@ public abstract class ObjectTypeTogglePanel extends TogglePanel<Serializable> {
             final PageReference pageRef) {
         super(id, pageRef);
 
-        form = new Form<>("objectTypeForm");
+        Form<?> form = new Form<>("objectTypeForm");
         addInnerObject(form);
 
-        typeModel = new PropertyModel<>(item, "anyType");
+        PropertyModel<String> typeModel = new PropertyModel<>(item, "anyType");
 
         form.add(new AjaxDropDownChoicePanel<>(
                 "type", "type", typeModel, false).

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
index 4ebbfb3..ce29438 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
@@ -37,6 +37,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.wizard.WizardModel;
+import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.model.Model;
@@ -92,7 +93,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ResourceProvision>
     /**
      * AuxClasses definition step.
      */
-    private static final class AuxClasses extends WizardStep implements WizardModel.ICondition {
+    private static final class AuxClasses extends WizardStep implements ICondition {
 
         private static final long serialVersionUID = 5315236191866427500L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceDetailsPanel.java
index 9c24f9a..52f3b0d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceDetailsPanel.java
@@ -18,19 +18,16 @@
  */
 package org.apache.syncope.client.console.wizards.resources;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.rest.ImplementationRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSpinnerFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.common.lib.info.JavaImplInfo;
+import org.apache.syncope.common.lib.to.EntityTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ImplementationType;
 import org.apache.syncope.common.lib.types.TraceLevel;
@@ -47,19 +44,16 @@ public class ResourceDetailsPanel extends WizardStep {
 
     private static final long serialVersionUID = -7982691107029848579L;
 
-    private final IModel<List<String>> propagationActionsClasses = new LoadableDetachableModel<List<String>>() {
+    private final ImplementationRestClient implRestClient = new ImplementationRestClient();
+
+    private final IModel<List<String>> propagationActions = new LoadableDetachableModel<List<String>>() {
 
         private static final long serialVersionUID = 5275935387613157437L;
 
         @Override
         protected List<String> load() {
-            Optional<JavaImplInfo> propagationActions = SyncopeConsoleSession.get().getPlatformInfo().
-                    getJavaImplInfo(ImplementationType.PROPAGATION_ACTIONS);
-            List<String> load = propagationActions.isPresent()
-                    ? new ArrayList<>(propagationActions.get().getClasses())
-                    : new ArrayList<>();
-            Collections.sort(load);
-            return load;
+            return implRestClient.list(ImplementationType.PROPAGATION_ACTIONS).stream().
+                    map(EntityTO::getKey).sorted().collect(Collectors.toList());
         }
     };
 
@@ -98,9 +92,9 @@ public class ResourceDetailsPanel extends WizardStep {
 
         container.add(new AjaxPalettePanel.Builder<String>().
                 setAllowMoveAll(true).setAllowOrder(true).
-                build("propagationActionsClassNames",
-                        new PropertyModel<List<String>>(resourceTO, "propagationActionsClassNames"),
-                        new ListModel<>(propagationActionsClasses.getObject())).
+                build("propagationActions",
+                        new PropertyModel<List<String>>(resourceTO, "propagationActions"),
+                        new ListModel<>(propagationActions.getObject())).
                 setOutputMarkupId(true));
 
         container.add(new AjaxDropDownChoicePanel<>(

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/resources/console.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/console.properties b/client/console/src/main/resources/console.properties
index 781a7ef..bc9a009 100644
--- a/client/console/src/main/resources/console.properties
+++ b/client/console/src/main/resources/console.properties
@@ -41,6 +41,7 @@ page.topology=org.apache.syncope.client.console.topology.Topology
 page.reports=org.apache.syncope.client.console.pages.Reports
 page.workflow=org.apache.syncope.client.console.pages.Workflow
 page.audit=org.apache.syncope.client.console.pages.Audit
+page.implementations=org.apache.syncope.client.console.pages.Implementations
 page.logs=org.apache.syncope.client.console.pages.Logs
 page.securityquestions=org.apache.syncope.client.console.pages.SecurityQuestions
 page.types=org.apache.syncope.client.console.pages.Types

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication.properties b/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication.properties
index 59143bf..cca9dea 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication.properties
@@ -71,3 +71,4 @@ connectors.confirm.reload=This request is potentially dangerous for running oper
 intAttrNameInfo.help=Besides auto-completed attributes, you can also refer to groups, any objects or memberships  (if applicable); for example:
 confirmGlobalLogout=Do you really want to perform global logout?
 administration=Administration
+implementations=Implementations

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_it.properties
index 1f13919..8aadcef 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_it.properties
@@ -71,3 +71,4 @@ connectors.confirm.reload=Questa richiesta \u00e8 potenzialmente dannosa per le
 intAttrNameInfo.help=Oltre agli attributi auto-completati, \u00e8 possibile fare riferimento anche a gruppi, any object e membership (se applicabile); ad esempio:
 confirmGlobalLogout=Vuoi davvero procedere al logout globale?
 administration=Amministrazione
+implementations=Implementazioni

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_pt_BR.properties
index b292d50..6916cf2 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_pt_BR.properties
@@ -71,3 +71,4 @@ connectors.confirm.reload=Esta requis\u00e7\u00e3o \u00e9 potencialmente perigos
 intAttrNameInfo.help=Besides auto-completed attributes, you can also refer to groups, any objects or memberships  (if applicable); for example:
 confirmGlobalLogout=Do you really want to perform global logout?
 administration=Administra\u00e7\u00e3o
+implementations=Implementa\u00e7\u00f5es

http://git-wip-us.apache.org/repos/asf/syncope/blob/98890722/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_ru.properties
index 62183d7..fc2a17a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/SyncopeConsoleApplication_ru.properties
@@ -31,7 +31,7 @@ confirmUnlink=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u043
 confirmUnassign=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u0434\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432?
 confirmDeprovision=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043e\u0437\u0432\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b?
 confirmProvision=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b?
-confirmClone=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b\u003f
+confirmClone=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b?
 dropDownChoiceField.nullValid=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435
 DateTimeField$HoursValidator=\u0427\u0430\u0441\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 (1, 12)
 error=\u041e\u0448\u0438\u0431\u043a\u0430
@@ -70,3 +70,4 @@ connectors.confirm.reload=\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438
 intAttrNameInfo.help=\u041f\u043e\u043c\u0438\u043c\u043e \u0430\u0432\u0442\u043e\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u0432\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u044b, \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438 \u0447\u043b\u0435\u043d\u0441\u0442\u0432\u043e (\u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438), \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:
 confirmGlobalLogout=Do you really want to perform global logout?
 administration=Administration
+implementations=\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438


Mime
View raw message