You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2014/06/13 15:59:00 UTC

svn commit: r1602430 [1/2] - in /syncope/trunk: common/src/main/java/org/apache/syncope/common/to/ console/src/main/java/org/apache/syncope/console/pages/ console/src/main/java/org/apache/syncope/console/pages/panels/ console/src/main/resources/org/apa...

Author: ilgrosso
Date: Fri Jun 13 13:58:59 2014
New Revision: 1602430

URL: http://svn.apache.org/r1602430
Log:
[SYNCOPE-502] Implementation provided for both core and console

Added:
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskCheck.java
      - copied, changed from r1602423, syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskCheck.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskValidator.java
      - copied, changed from r1602129, syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskValidator.java
Removed:
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskCheck.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskValidator.java
Modified:
    syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSyncTaskTO.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SyncTaskModalPage.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_it.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_pt_BR.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.html
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_it.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_pt_BR.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.html
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_it.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_pt_BR.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.html
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.html
    syncope/trunk/console/src/main/webapp/img/down-icon.png
    syncope/trunk/console/src/main/webapp/img/up-icon.png
    syncope/trunk/core/pom.xml
    syncope/trunk/core/src/main/java/org/apache/syncope/core/init/JobInstanceLoader.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/ExternalResourceValidator.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PriorityPropagationTaskExecutor.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncJob.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/AbstractSyncopeResultHandler.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/DBPasswordSyncActions.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/PushJob.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncJob.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopePushResultHandler.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/sync/SyncTaskTest.java
    syncope/trunk/core/src/test/resources/content.xml

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSyncTaskTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSyncTaskTO.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSyncTaskTO.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSyncTaskTO.java Fri Jun 13 13:58:59 2014
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.common.to;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
@@ -41,12 +43,12 @@ public class AbstractSyncTaskTO extends 
 
     private boolean syncStatus;
 
-    private String actionsClassName;
-
     private UnmatchingRule unmatchigRule;
 
     private MatchingRule matchigRule;
 
+    private List<String> actionsClassNames = new ArrayList<String>();
+
     public String getResource() {
         return resource;
     }
@@ -87,12 +89,8 @@ public class AbstractSyncTaskTO extends 
         this.syncStatus = syncStatus;
     }
 
-    public String getActionsClassName() {
-        return actionsClassName;
-    }
-
-    public void setActionsClassName(final String actionsClassName) {
-        this.actionsClassName = actionsClassName;
+    public List<String> getActionsClassNames() {
+        return actionsClassNames;
     }
 
     public UnmatchingRule getUnmatchigRule() {

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/ResourceTO.java Fri Jun 13 13:58:59 2014
@@ -19,7 +19,9 @@
 package org.apache.syncope.common.to;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
@@ -84,7 +86,7 @@ public class ResourceTO extends Abstract
 
     private String rsyncToken;
 
-    private String propagationActionsClassName;
+    private List<String> propagationActionsClassNames = new ArrayList<String>();
 
     public ResourceTO() {
         super();
@@ -258,11 +260,8 @@ public class ResourceTO extends Abstract
         this.rsyncToken = syncToken;
     }
 
-    public String getPropagationActionsClassName() {
-        return propagationActionsClassName;
+    public List<String> getPropagationActionsClassNames() {
+        return propagationActionsClassNames;
     }
 
-    public void setPropagationActionsClassName(final String propagationActionsClassName) {
-        this.propagationActionsClassName = propagationActionsClassName;
-    }
 }

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SchemaModalPage.java Fri Jun 13 13:58:59 2014
@@ -29,6 +29,7 @@ import org.apache.syncope.common.to.Sche
 import org.apache.syncope.common.types.AttributableType;
 import org.apache.syncope.common.types.AttributeSchemaType;
 import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.types.CipherAlgorithm;
 import org.apache.syncope.console.commons.Constants;
 import org.apache.syncope.console.commons.JexlHelpUtil;
 import org.apache.syncope.console.wicket.markup.html.form.AjaxCheckBoxPanel;
@@ -77,102 +78,98 @@ public class SchemaModalPage extends Abs
         final Form<SchemaTO> schemaForm = new Form<SchemaTO>(FORM);
 
         schemaForm.setModel(new CompoundPropertyModel<SchemaTO>(schema));
-        schemaForm.setOutputMarkupId(Boolean.TRUE);
+        schemaForm.setOutputMarkupId(true);
 
         final AjaxTextFieldPanel name =
                 new AjaxTextFieldPanel("name", getString("name"), new PropertyModel<String>(schema, "name"));
-
         name.addRequiredLabel();
         name.setEnabled(createFlag);
-
-        final AjaxTextFieldPanel conversionPattern = new AjaxTextFieldPanel("conversionPattern",
-                getString("conversionPattern"), new PropertyModel<String>(schema, "conversionPattern"));
-
-        final IModel<List<String>> validatorsList = new LoadableDetachableModel<List<String>>() {
-
-            private static final long serialVersionUID = 5275935387613157437L;
-
-            @Override
-            protected List<String> load() {
-                return schemaRestClient.getAllValidatorClasses();
-            }
-        };
-
-        final AjaxDropDownChoicePanel<String> validatorClass = new AjaxDropDownChoicePanel<String>("validatorClass",
-                getString("validatorClass"), new PropertyModel<String>(schema, "validatorClass"));
-
-        ((DropDownChoice) validatorClass.getField()).setNullValid(true);
-        validatorClass.setChoices(validatorsList.getObject());
+        schemaForm.add(name);
 
         final AjaxDropDownChoicePanel<AttributeSchemaType> type = new AjaxDropDownChoicePanel<AttributeSchemaType>(
                 "type", getString("type"), new PropertyModel<AttributeSchemaType>(schema, "type"));
         type.setChoices(Arrays.asList(AttributeSchemaType.values()));
         type.addRequiredLabel();
+        schemaForm.add(type);
 
+        // -- long, double, date
+        final AjaxTextFieldPanel conversionPattern = new AjaxTextFieldPanel("conversionPattern",
+                getString("conversionPattern"), new PropertyModel<String>(schema, "conversionPattern"));
+        schemaForm.add(conversionPattern);
+
+        final WebMarkupContainer conversionParams = new WebMarkupContainer("conversionParams");
+        conversionParams.setOutputMarkupPlaceholderTag(true);
+        conversionParams.add(conversionPattern);
+        schemaForm.add(conversionParams);
+
+        // -- enum
         final AjaxTextFieldPanel enumerationValuesPanel =
                 new AjaxTextFieldPanel("panel", "enumerationValues", new Model<String>(null));
         @SuppressWarnings({ "unchecked", "rawtypes" })
-        final MultiFieldPanel<String> enumerationValues =
-                new MultiFieldPanel<String>("enumerationValues",
-                        new Model(),
-                        enumerationValuesPanel);
-        schemaForm.add(enumerationValues);
-
+        final MultiFieldPanel<String> enumerationValues = new MultiFieldPanel<String>("enumerationValues",
+                new Model(),
+                enumerationValuesPanel);
         enumerationValues.setModelObject(getEnumValuesAsList(schema.getEnumerationValues()));
 
         @SuppressWarnings({ "unchecked", "rawtypes" })
-        final MultiFieldPanel<String> enumerationKeys =
-                new MultiFieldPanel<String>("enumerationKeys",
-                        new Model(),
-                        new AjaxTextFieldPanel("panel", "enumerationKeys", new Model<String>(null)));
-        schemaForm.add(enumerationKeys);
-
+        final MultiFieldPanel<String> enumerationKeys = new MultiFieldPanel<String>("enumerationKeys",
+                new Model(),
+                new AjaxTextFieldPanel("panel", "enumerationKeys", new Model<String>(null)));
         enumerationKeys.setModelObject(getEnumValuesAsList(schema.getEnumerationKeys()));
 
-        if (AttributeSchemaType.Enum == schema.getType()) {
-            enumerationValues.setEnabled(Boolean.TRUE);
-            enumerationKeys.setEnabled(Boolean.TRUE);
-            enumerationValuesPanel.addRequiredLabel();
-        } else {
-            enumerationValues.setEnabled(Boolean.FALSE);
-            enumerationKeys.setEnabled(Boolean.FALSE);
-        }
-
+        final WebMarkupContainer enumParams = new WebMarkupContainer("enumParams");
+        enumParams.setOutputMarkupPlaceholderTag(true);
+        enumParams.add(enumerationValues);
+        enumParams.add(enumerationKeys);
+        schemaForm.add(enumParams);
+
+        // -- encrypted
+        final AjaxTextFieldPanel secretKey = new AjaxTextFieldPanel("secretKey",
+                getString("secretKey"), new PropertyModel<String>(schema, "secretKey"));
+
+        final AjaxDropDownChoicePanel<CipherAlgorithm> cipherAlgorithm = new AjaxDropDownChoicePanel<CipherAlgorithm>(
+                "cipherAlgorithm", getString("cipherAlgorithm"),
+                new PropertyModel<CipherAlgorithm>(schema, "cipherAlgorithm"));
+        cipherAlgorithm.setChoices(Arrays.asList(CipherAlgorithm.values()));
+
+        final WebMarkupContainer encryptedParams = new WebMarkupContainer("encryptedParams");
+        encryptedParams.setOutputMarkupPlaceholderTag(true);
+        encryptedParams.add(secretKey);
+        encryptedParams.add(cipherAlgorithm);
+        schemaForm.add(encryptedParams);
+
+        showHide(schema, type,
+                conversionParams, conversionPattern,
+                enumParams, enumerationValuesPanel, enumerationValues, enumerationKeys,
+                encryptedParams, secretKey, cipherAlgorithm);
         type.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
             private static final long serialVersionUID = -1107858522700306810L;
 
             @Override
             protected void onUpdate(final AjaxRequestTarget target) {
-                if (AttributeSchemaType.Enum.ordinal() == Integer.parseInt(type.getField().getValue())) {
-                    if (!enumerationValuesPanel.isRequired()) {
-                        enumerationValuesPanel.addRequiredLabel();
-                    }
-                    enumerationValues.setEnabled(Boolean.TRUE);
-                    enumerationValues.setModelObject(getEnumValuesAsList(schema.getEnumerationValues()));
-
-                    enumerationKeys.setEnabled(Boolean.TRUE);
-                    enumerationKeys.setModelObject(getEnumValuesAsList(schema.getEnumerationKeys()));
-                } else {
-                    if (enumerationValuesPanel.isRequired()) {
-                        enumerationValuesPanel.removeRequiredLabel();
-                    }
-                    final List<String> values = new ArrayList<String>();
-                    values.add("");
-
-                    enumerationValues.setEnabled(Boolean.FALSE);
-                    enumerationValues.setModelObject(values);
+                SchemaModalPage.this.showHide(schema, type,
+                        conversionParams, conversionPattern,
+                        enumParams, enumerationValuesPanel, enumerationValues, enumerationKeys,
+                        encryptedParams, secretKey, cipherAlgorithm);
+                target.add(schemaForm);
+            }
+        });
 
-                    final List<String> keys = new ArrayList<String>();
-                    keys.add("");
+        final IModel<List<String>> validatorsList = new LoadableDetachableModel<List<String>>() {
 
-                    enumerationKeys.setEnabled(Boolean.FALSE);
-                    enumerationKeys.setModelObject(keys);
-                }
+            private static final long serialVersionUID = 5275935387613157437L;
 
-                target.add(schemaForm);
+            @Override
+            protected List<String> load() {
+                return schemaRestClient.getAllValidatorClasses();
             }
-        });
+        };
+        final AjaxDropDownChoicePanel<String> validatorClass = new AjaxDropDownChoicePanel<String>("validatorClass",
+                getString("validatorClass"), new PropertyModel<String>(schema, "validatorClass"));
+        ((DropDownChoice) validatorClass.getField()).setNullValid(true);
+        validatorClass.setChoices(validatorsList.getObject());
+        schemaForm.add(validatorClass);
 
         final AutoCompleteTextField<String> mandatoryCondition =
                 new AutoCompleteTextField<String>("mandatoryCondition") {
@@ -185,10 +182,7 @@ public class SchemaModalPage extends Abs
 
                         if (Strings.isEmpty(input)) {
                             choices = Collections.emptyList();
-                            return choices.iterator();
-                        }
-
-                        if ("true".startsWith(input.toLowerCase())) {
+                        } else if ("true".startsWith(input.toLowerCase())) {
                             choices.add("true");
                         } else if ("false".startsWith(input.toLowerCase())) {
                             choices.add("false");
@@ -197,7 +191,6 @@ public class SchemaModalPage extends Abs
                         return choices.iterator();
                     }
                 };
-
         mandatoryCondition.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
             private static final long serialVersionUID = -1107858522700306810L;
@@ -206,6 +199,7 @@ public class SchemaModalPage extends Abs
             protected void onUpdate(final AjaxRequestTarget target) {
             }
         });
+        schemaForm.add(mandatoryCondition);
 
         final WebMarkupContainer pwdJexlHelp = JexlHelpUtil.getJexlHelpWebContainer("jexlHelp");
 
@@ -215,12 +209,15 @@ public class SchemaModalPage extends Abs
 
         final AjaxCheckBoxPanel multivalue = new AjaxCheckBoxPanel("multivalue", getString("multivalue"),
                 new PropertyModel<Boolean>(schema, "multivalue"));
+        schemaForm.add(multivalue);
 
         final AjaxCheckBoxPanel readonly = new AjaxCheckBoxPanel("readonly", getString("readonly"),
                 new PropertyModel<Boolean>(schema, "readonly"));
+        schemaForm.add(readonly);
 
         final AjaxCheckBoxPanel uniqueConstraint = new AjaxCheckBoxPanel("uniqueConstraint",
                 getString("uniqueConstraint"), new PropertyModel<Boolean>(schema, "uniqueConstraint"));
+        schemaForm.add(uniqueConstraint);
 
         final AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT)) {
 
@@ -261,6 +258,7 @@ public class SchemaModalPage extends Abs
                 feedbackPanel.refresh(target);
             }
         };
+        schemaForm.add(submit);
 
         final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
 
@@ -271,8 +269,8 @@ public class SchemaModalPage extends Abs
                 window.close(target);
             }
         };
-
         cancel.setDefaultFormProcessing(false);
+        schemaForm.add(cancel);
 
         String allowedRoles = createFlag
                 ? xmlRolesReader.getAllAllowedRoles("Schema", "create")
@@ -280,19 +278,97 @@ public class SchemaModalPage extends Abs
 
         MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, allowedRoles);
 
-        schemaForm.add(name);
-        schemaForm.add(conversionPattern);
-        schemaForm.add(validatorClass);
-        schemaForm.add(type);
-        schemaForm.add(mandatoryCondition);
-        schemaForm.add(multivalue);
-        schemaForm.add(readonly);
-        schemaForm.add(uniqueConstraint);
+        add(schemaForm);
+    }
 
-        schemaForm.add(submit);
-        schemaForm.add(cancel);
+    private void showHide(final SchemaTO schema, final AjaxDropDownChoicePanel<AttributeSchemaType> type,
+            final WebMarkupContainer conversionParams, final AjaxTextFieldPanel conversionPattern,
+            final WebMarkupContainer enumParams, final AjaxTextFieldPanel enumerationValuesPanel,
+            final MultiFieldPanel<String> enumerationValues, final MultiFieldPanel<String> enumerationKeys,
+            final WebMarkupContainer encryptedParams,
+            final AjaxTextFieldPanel secretKey, final AjaxDropDownChoicePanel<CipherAlgorithm> cipherAlgorithm) {
+
+        final int typeOrdinal = Integer.parseInt(type.getField().getValue());
+        if (AttributeSchemaType.Long.ordinal() == typeOrdinal || AttributeSchemaType.Double.ordinal() == typeOrdinal
+                || AttributeSchemaType.Date.ordinal() == typeOrdinal) {
+
+            conversionParams.setVisible(true);
+
+            enumParams.setVisible(false);
+            if (enumerationValuesPanel.isRequired()) {
+                enumerationValuesPanel.removeRequiredLabel();
+            }
+            enumerationValues.setModelObject(getEnumValuesAsList(null));
+            enumerationKeys.setModelObject(getEnumValuesAsList(null));
 
-        add(schemaForm);
+            encryptedParams.setVisible(false);
+            if (secretKey.isRequired()) {
+                secretKey.removeRequiredLabel();
+            }
+            secretKey.setModelObject(null);
+            if (cipherAlgorithm.isRequired()) {
+                cipherAlgorithm.removeRequiredLabel();
+            }
+            cipherAlgorithm.setModelObject(null);
+        } else if (AttributeSchemaType.Enum.ordinal() == typeOrdinal) {
+            conversionParams.setVisible(false);
+            conversionPattern.setModelObject(null);
+
+            enumParams.setVisible(true);
+            if (!enumerationValuesPanel.isRequired()) {
+                enumerationValuesPanel.addRequiredLabel();
+            }
+            enumerationValues.setModelObject(getEnumValuesAsList(schema.getEnumerationValues()));
+            enumerationKeys.setModelObject(getEnumValuesAsList(schema.getEnumerationKeys()));
+
+            encryptedParams.setVisible(false);
+            if (secretKey.isRequired()) {
+                secretKey.removeRequiredLabel();
+            }
+            secretKey.setModelObject(null);
+            if (cipherAlgorithm.isRequired()) {
+                cipherAlgorithm.removeRequiredLabel();
+            }
+            cipherAlgorithm.setModelObject(null);
+        } else if (AttributeSchemaType.Encrypted.ordinal() == typeOrdinal) {
+            conversionParams.setVisible(false);
+            conversionPattern.setModelObject(null);
+
+            enumParams.setVisible(false);
+            if (enumerationValuesPanel.isRequired()) {
+                enumerationValuesPanel.removeRequiredLabel();
+            }
+            enumerationValues.setModelObject(getEnumValuesAsList(null));
+            enumerationKeys.setModelObject(getEnumValuesAsList(null));
+
+            encryptedParams.setVisible(true);
+            if (!secretKey.isRequired()) {
+                secretKey.addRequiredLabel();
+            }
+            if (cipherAlgorithm.isRequired()) {
+                cipherAlgorithm.addRequiredLabel();
+            }
+        } else {
+            conversionParams.setVisible(false);
+            conversionPattern.setModelObject(null);
+
+            enumParams.setVisible(false);
+            if (enumerationValuesPanel.isRequired()) {
+                enumerationValuesPanel.removeRequiredLabel();
+            }
+            enumerationValues.setModelObject(getEnumValuesAsList(null));
+            enumerationKeys.setModelObject(getEnumValuesAsList(null));
+
+            encryptedParams.setVisible(false);
+            if (secretKey.isRequired()) {
+                secretKey.removeRequiredLabel();
+            }
+            secretKey.setModelObject(null);
+            if (cipherAlgorithm.isRequired()) {
+                cipherAlgorithm.removeRequiredLabel();
+            }
+            cipherAlgorithm.setModelObject(null);
+        }
     }
 
     private String getEnumValuesAsString(final List<String> enumerationValues) {
@@ -319,7 +395,7 @@ public class SchemaModalPage extends Abs
                 values.add(value.trim());
             }
         } else {
-            values.add("");
+            values.add(StringUtils.EMPTY);
         }
 
         return values;

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SyncTaskModalPage.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SyncTaskModalPage.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SyncTaskModalPage.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/SyncTaskModalPage.java Fri Jun 13 13:58:59 2014
@@ -20,15 +20,26 @@ package org.apache.syncope.console.pages
 
 import java.util.ArrayList;
 import java.util.List;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.to.ResourceTO;
 import org.apache.syncope.common.to.SyncTaskTO;
+import org.apache.syncope.console.commons.Constants;
 import org.apache.syncope.console.commons.SelectChoiceRenderer;
 import org.apache.syncope.console.wicket.markup.html.form.AjaxCheckBoxPanel;
 import org.apache.syncope.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
 import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
 
 /**
@@ -68,11 +79,82 @@ public class SyncTaskModalPage extends A
 
         profile.add(resource);
 
-        final AjaxDropDownChoicePanel<String> actionsClassName = new AjaxDropDownChoicePanel<String>(
-                "actionsClassName", getString("actionsClass"), new PropertyModel<String>(taskTO, "actionsClassName"));
-        actionsClassName.setChoices(taskRestClient.getSyncActionsClasses());
-        actionsClassName.setStyleSheet("ui-widget-content ui-corner-all long_dynamicsize");
-        profile.add(actionsClassName);
+        final WebMarkupContainer syncActionsClassNames = new WebMarkupContainer("syncActionsClassNames");
+        syncActionsClassNames.setOutputMarkupId(true);
+        profile.add(syncActionsClassNames);
+
+        final AjaxLink<Void> first = new IndicatingAjaxLink<Void>("first") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                taskTO.getActionsClassNames().add(StringUtils.EMPTY);
+                setVisible(false);
+                target.add(syncActionsClassNames);
+            }
+        };
+        first.setOutputMarkupPlaceholderTag(true);
+        first.setVisible(taskTO.getActionsClassNames().isEmpty());
+        syncActionsClassNames.add(first);
+
+        final ListView<String> actionsClasses = new ListView<String>("actionsClasses",
+                new PropertyModel<List<String>>(taskTO, "actionsClassNames")) {
+
+                    private static final long serialVersionUID = 9101744072914090143L;
+
+                    @Override
+                    protected void populateItem(final ListItem<String> item) {
+                        final String className = item.getModelObject();
+
+                        final DropDownChoice<String> actionsClass = new DropDownChoice<String>(
+                                "actionsClass", new Model<String>(className), taskRestClient.getSyncActionsClasses());
+                        actionsClass.setNullValid(true);
+                        actionsClass.setRequired(true);
+                        actionsClass.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
+
+                            private static final long serialVersionUID = -1107858522700306810L;
+
+                            @Override
+                            protected void onUpdate(final AjaxRequestTarget target) {
+                                taskTO.getActionsClassNames().
+                                set(item.getIndex(), actionsClass.getModelObject());
+                            }
+                        });
+                        actionsClass.setRequired(true);
+                        actionsClass.setOutputMarkupId(true);
+                        actionsClass.setRequired(true);
+                        item.add(actionsClass);
+
+                        AjaxLink<Void> minus = new IndicatingAjaxLink<Void>("drop") {
+
+                            private static final long serialVersionUID = -7978723352517770644L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target) {
+                                taskTO.getActionsClassNames().remove(className);
+                                first.setVisible(taskTO.getActionsClassNames().isEmpty());
+                                target.add(syncActionsClassNames);
+                            }
+                        };
+                        item.add(minus);
+
+                        final AjaxLink<Void> plus = new IndicatingAjaxLink<Void>("add") {
+
+                            private static final long serialVersionUID = -7978723352517770644L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target) {
+                                taskTO.getActionsClassNames().add(StringUtils.EMPTY);
+                                target.add(syncActionsClassNames);
+                            }
+                        };
+                        plus.setOutputMarkupPlaceholderTag(true);
+                        plus.setVisible(item.getIndex() == taskTO.getActionsClassNames().size() - 1);
+                        item.add(plus);
+                    }
+                };
+        syncActionsClassNames.add(actionsClasses);
 
         final AjaxCheckBoxPanel creates = new AjaxCheckBoxPanel("performCreate", getString("creates"),
                 new PropertyModel<Boolean>(taskTO, "performCreate"));

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.java Fri Jun 13 13:58:59 2014
@@ -127,75 +127,70 @@ public class DerivedAttributesPanel exte
                 target.add(attributesContainer);
             }
         };
-
-        add(addAttributeBtn.setDefaultFormProcessing(Boolean.FALSE));
+        add(addAttributeBtn.setDefaultFormProcessing(false));
 
         ListView<AttributeTO> attributes = new ListView<AttributeTO>("attrs",
                 new PropertyModel<List<? extends AttributeTO>>(entityTO, "derAttrs")) {
 
-            private static final long serialVersionUID = 9101744072914090143L;
-
-            @Override
-            protected void populateItem(final ListItem<AttributeTO> item) {
-                final AttributeTO attributeTO = item.getModelObject();
-
-                item.add(new AjaxDecoratedCheckbox("toRemove", new Model<Boolean>(Boolean.FALSE)) {
-
-                    private static final long serialVersionUID = 7170946748485726506L;
+                    private static final long serialVersionUID = 9101744072914090143L;
 
                     @Override
-                    protected void onUpdate(final AjaxRequestTarget target) {
-                        entityTO.getDerAttrs().remove(attributeTO);
-                        target.add(attributesContainer);
-                    }
+                    protected void populateItem(final ListItem<AttributeTO> item) {
+                        final AttributeTO attributeTO = item.getModelObject();
 
-                    @Override
-                    protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
-                        super.updateAjaxAttributes(attributes);
-
-                        IAjaxCallListener ajaxCallListener = new AjaxCallListener() {
+                        item.add(new AjaxDecoratedCheckbox("toRemove", new Model<Boolean>(Boolean.FALSE)) {
 
-                            private static final long serialVersionUID = 7160235486520935153L;
+                            private static final long serialVersionUID = 7170946748485726506L;
 
                             @Override
-                            public CharSequence getPrecondition(final Component component) {
-                                return "if (!confirm('" + getString("confirmDelete") + "')) return false;";
+                            protected void onUpdate(final AjaxRequestTarget target) {
+                                entityTO.getDerAttrs().remove(attributeTO);
+                                target.add(attributesContainer);
                             }
-                        };
-                        attributes.getAjaxCallListeners().add(ajaxCallListener);
-                    }
-                });
 
-                final DropDownChoice<String> schemaChoice = new DropDownChoice<String>("schema",
-                        new PropertyModel<String>(attributeTO, "schema"), derSchemas);
+                            @Override
+                            protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
+                                super.updateAjaxAttributes(attributes);
 
-                schemaChoice.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
+                                IAjaxCallListener ajaxCallListener = new AjaxCallListener() {
 
-                    private static final long serialVersionUID = -1107858522700306810L;
+                                    private static final long serialVersionUID = 7160235486520935153L;
 
-                    @Override
-                    protected void onUpdate(final AjaxRequestTarget target) {
-                        attributeTO.setSchema(schemaChoice.getModelObject());
-                    }
-                });
+                                    @Override
+                                    public CharSequence getPrecondition(final Component component) {
+                                        return "if (!confirm('" + getString("confirmDelete") + "')) return false;";
+                                    }
+                                };
+                                attributes.getAjaxCallListeners().add(ajaxCallListener);
+                            }
+                        });
 
-                item.add(schemaChoice.setRequired(true));
+                        final DropDownChoice<String> schemaChoice = new DropDownChoice<String>("schema",
+                                new PropertyModel<String>(attributeTO, "schema"), derSchemas);
+                        schemaChoice.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
 
-                schemaChoice.setOutputMarkupId(true);
-                schemaChoice.setRequired(true);
-                item.add(schemaChoice);
-
-                final List<String> values = attributeTO.getValues();
-                if (values == null || values.isEmpty()) {
-                    item.add(new TextField<String>("value",
-                            new Model<String>(null)).setVisible(Boolean.FALSE));
-                } else {
-                    item.add(new TextField<String>("value",
-                            new Model<String>(values.get(0))).setEnabled(Boolean.FALSE));
-                }
-            }
-        };
+                            private static final long serialVersionUID = -1107858522700306810L;
 
+                            @Override
+                            protected void onUpdate(final AjaxRequestTarget target) {
+                                attributeTO.setSchema(schemaChoice.getModelObject());
+                            }
+                        });
+                        schemaChoice.setRequired(true);
+                        schemaChoice.setOutputMarkupId(true);
+                        schemaChoice.setRequired(true);
+                        item.add(schemaChoice);
+
+                        final List<String> values = attributeTO.getValues();
+                        if (values == null || values.isEmpty()) {
+                            item.add(new TextField<String>("value",
+                                            new Model<String>(null)).setVisible(false));
+                        } else {
+                            item.add(new TextField<String>("value",
+                                            new Model<String>(values.get(0))).setEnabled(false));
+                        }
+                    }
+                };
         attributesContainer.add(attributes);
     }
 

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.java Fri Jun 13 13:58:59 2014
@@ -20,6 +20,7 @@ package org.apache.syncope.console.pages
 
 import java.util.Arrays;
 import java.util.List;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.to.ConnInstanceTO;
 import org.apache.syncope.common.to.ResourceTO;
 import org.apache.syncope.common.types.PropagationMode;
@@ -33,8 +34,14 @@ import org.apache.syncope.console.wicket
 import org.apache.syncope.console.wicket.markup.html.form.SpinnerFieldPanel;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.form.ChoiceRenderer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.LoadableDetachableModel;
@@ -52,7 +59,7 @@ public class ResourceDetailsPanel extend
     /**
      * Logger.
      */
-    protected static final Logger LOG = LoggerFactory.getLogger(ResourceDetailsPanel.class);
+    private static final Logger LOG = LoggerFactory.getLogger(ResourceDetailsPanel.class);
 
     @SpringBean
     private ConnectorRestClient connRestClient;
@@ -98,12 +105,82 @@ public class ResourceDetailsPanel extend
                 new PropertyModel<Boolean>(resourceTO, "randomPwdIfNotProvided"));
         add(randomPwdIfNotProvided);
 
-        final AjaxDropDownChoicePanel<String> actionsClassName = new AjaxDropDownChoicePanel<String>(
-                "propagationActionsClassName", new ResourceModel("actionsClass", "actionsClass").getObject(),
-                new PropertyModel<String>(resourceTO, "propagationActionsClassName"));
-        actionsClassName.setChoices(actionClassNames);
-        actionsClassName.setStyleSheet("ui-widget-content ui-corner-all long_dynamicsize");
-        add(actionsClassName);
+        final WebMarkupContainer propagationActionsClassNames = new WebMarkupContainer("propagationActionsClassNames");
+        propagationActionsClassNames.setOutputMarkupId(true);
+        add(propagationActionsClassNames);
+
+        final AjaxLink<Void> first = new IndicatingAjaxLink<Void>("first") {
+
+            private static final long serialVersionUID = -7978723352517770644L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target) {
+                resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY);
+                setVisible(false);
+                target.add(propagationActionsClassNames);
+            }
+        };
+        first.setOutputMarkupPlaceholderTag(true);
+        first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty());
+        propagationActionsClassNames.add(first);
+
+        final ListView<String> actionsClasses = new ListView<String>("actionsClasses",
+                new PropertyModel<List<String>>(resourceTO, "propagationActionsClassNames")) {
+
+                    private static final long serialVersionUID = 9101744072914090143L;
+
+                    @Override
+                    protected void populateItem(final ListItem<String> item) {
+                        final String className = item.getModelObject();
+
+                        final DropDownChoice<String> actionsClass = new DropDownChoice<String>(
+                                "actionsClass", new Model<String>(className), actionClassNames);
+                        actionsClass.setNullValid(true);
+                        actionsClass.setRequired(true);
+                        actionsClass.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) {
+
+                            private static final long serialVersionUID = -1107858522700306810L;
+
+                            @Override
+                            protected void onUpdate(final AjaxRequestTarget target) {
+                                resourceTO.getPropagationActionsClassNames().
+                                set(item.getIndex(), actionsClass.getModelObject());
+                            }
+                        });
+                        actionsClass.setRequired(true);
+                        actionsClass.setOutputMarkupId(true);
+                        actionsClass.setRequired(true);
+                        item.add(actionsClass);
+
+                        AjaxLink<Void> minus = new IndicatingAjaxLink<Void>("drop") {
+
+                            private static final long serialVersionUID = -7978723352517770644L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target) {
+                                resourceTO.getPropagationActionsClassNames().remove(className);
+                                first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty());
+                                target.add(propagationActionsClassNames);
+                            }
+                        };
+                        item.add(minus);
+
+                        final AjaxLink<Void> plus = new IndicatingAjaxLink<Void>("add") {
+
+                            private static final long serialVersionUID = -7978723352517770644L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target) {
+                                resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY);
+                                target.add(propagationActionsClassNames);
+                            }
+                        };
+                        plus.setOutputMarkupPlaceholderTag(true);
+                        plus.setVisible(item.getIndex() == resourceTO.getPropagationActionsClassNames().size() - 1);
+                        item.add(plus);
+                    }
+                };
+        propagationActionsClassNames.add(actionsClasses);
 
         final AjaxDropDownChoicePanel<TraceLevel> createTraceLevel = new AjaxDropDownChoicePanel<TraceLevel>(
                 "createTraceLevel", new ResourceModel("createTraceLevel", "createTraceLevel").getObject(),

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java Fri Jun 13 13:58:59 2014
@@ -110,14 +110,10 @@ public class ResourcesPanel extends Pane
                     new PropertyModel<List<String>>(attributableTO, "resources"),
                     new ListModel<String>(allResources), builder.statusPanel);
         } else if (attributableTO instanceof RoleTO) {
-            List<String> selectedResources = new ArrayList<String>(((RoleTO) attributableTO).getResources());
-            Collections.sort(selectedResources);
-
             resourcesPalette = new AjaxPalettePanel<String>("resourcesPalette",
                     new PropertyModel<List<String>>(attributableTO, "resources"), new ListModel<String>(allResources));
         }
         add(resourcesPalette);
-
     }
 
     private class AjaxRecordingPalettePanel<T> extends AjaxPalettePanel<T> {

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.properties?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage.properties Fri Jun 13 13:58:59 2014
@@ -56,7 +56,7 @@ resetToken=Reset token
 success_connection=Successful connection
 error_connection=Connection failure
 check=Check connection
-actionsClass=Actions class
+actionsClasses=Actions classes
 rmapping=Role mapping
 new=New
 randomPwdIfNotProvided=Generate random passwords when missing

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_it.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_it.properties?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_it.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_it.properties Fri Jun 13 13:58:59 2014
@@ -57,8 +57,7 @@ resetToken=Reset token
 success_connection=Connessione avvenuta con successo
 error_connection=Connessione non riuscita
 check=Verifica connessione
-actionsClass=Classe azioni
+actionsClasses=Classi azioni
 rmapping=Mapping ruoli
 new=Nuova
-randomPwdIfNotProvided=GGenera password casuali se mancanti
-enera password casuali se mancanti
+randomPwdIfNotProvided=Genera password casuali se mancanti

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_pt_BR.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_pt_BR.properties?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_pt_BR.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/ResourceModalPage_pt_BR.properties Fri Jun 13 13:58:59 2014
@@ -15,48 +15,48 @@
 # specific language governing permissions and limitations
 # under the License.
 resource=Detalhes de Recursos
-umapping=Mapeamento de usu\u00E1rios
+umapping=Mapeamento de usu\u00e1rios
 connectorProperties=Propriedades de Conectores
-security=Seguran\u00E7a
+security=Seguran\u00e7a
 create_attribute=Criar novo recurso
-required_alert=Todos os campos deste formul\u00E1rio s\u00E3o obrigat\u00F3rios
+required_alert=Todos os campos deste formul\u00e1rio s\u00e3o obrigat\u00f3rios
 connector=Conector
 existing_resources=Recursos Existentes
-action=A\u00E7\u00E3o
+action=A\u00e7\u00e3o
 edit_attribute=Alterar Recurso
 title=Recurso
 extAttrNames=Atributos Externos
 intMappingTypes=Tipos internos de mapeamentos
 entity=Entidade
-roleSchema=Esquema de Fun\u00E7\u00E3o
+roleSchema=Esquema de Fun\u00e7\u00e3o
 accountId=Identificador da Conta
-mandatoryCondition=Obrigat\u00F3rio
+mandatoryCondition=Obrigat\u00f3rio
 password=Senha
-purpose=Prop\u00F3sito
-mappingUserSchema=Esquema de mapeamento de usu\u00E1rio
-mappingRoleSchema=Esquema de mapeamento de fun\u00E7\u00E3o
+purpose=Prop\u00f3sito
+mappingUserSchema=Esquema de mapeamento de usu\u00e1rio
+mappingRoleSchema=Esquema de mapeamento de fun\u00e7\u00e3o
 delete=Excluir
 intAttrNames=Atributos internos
-enforceMandatoryCondition=Aplicar condi\u00E7\u00E3o obrigat\u00F3ria
+enforceMandatoryCondition=Aplicar condi\u00e7\u00e3o obrigat\u00f3ria
 fieldName=Nome do Campo
 
 accountIdValidation=Precisa ser exatamente um Identificador de Conta
-propagationMode=Modo de propaga\u00E7\u00E3o
+propagationMode=Modo de propaga\u00e7\u00e3o
 accountLink=Link de Conta
 enable=Habilitado
 
-createTraceLevel=Criar n\u00EDvel de trace
-updateTraceLevel=Atualizar n\u00EDvel de trace
-deleteTraceLevel=Excluir n\u00EDvel de trace
-syncTraceLevel=N\u00EDvel de trace de sincroniza\u00E7\u00E3o
-propagationPriority=Prioridade de propaga\u00E7\u00E3o
-propagationPrimary=Propaga\u00E7\u00E3o prim\u00E1ria
+createTraceLevel=Criar n\u00edvel de trace
+updateTraceLevel=Atualizar n\u00edvel de trace
+deleteTraceLevel=Excluir n\u00edvel de trace
+syncTraceLevel=N\u00edvel de trace de sincroniza\u00e7\u00e3o
+propagationPriority=Prioridade de propaga\u00e7\u00e3o
+propagationPrimary=Propaga\u00e7\u00e3o prim\u00e1ria
 resetToken=Resetar token
 
-success_connection=Conex\u00E3o com sucesso
-error_connection=Conex\u00E3o sem sucesso
-check=Verificar a conex\u00E3o
-actionsClass=Classe de A\u00E7\u00F5es
+success_connection=Conex\u00e3o com sucesso
+error_connection=Conex\u00e3o sem sucesso
+check=Verificar a conex\u00e3o
+actionsClasses=Classes de a\u00e7\u00f5es
 rmapping=Regra de Mapeamento
 new=novo
-randomPwdIfNotProvided=Gerar senhas aleat\u00F3rias quando n\u00E3o houver
+randomPwdIfNotProvided=Gerar senhas aleat\u00f3rias quando n\u00e3o houver

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.html?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.html Fri Jun 13 13:58:59 2014
@@ -40,30 +40,52 @@ under the License.
             </div>
           </div>
 
-          <div class="tablerow alt">
-            <div class="tablecolumn_label short_dynamicsize">
-              <label for="conversionPattern"><wicket:message key="conversionPattern"/></label>
-            </div>
-            <div class="tablecolumn_field medium_dynamicsize">
-              <span wicket:id="conversionPattern">[conversionPattern]</span>
+          <div wicket:id="conversionParams">
+            <div class="tablerow alt">
+              <div class="tablecolumn_label short_dynamicsize">
+                <label for="conversionPattern"><wicket:message key="conversionPattern"/></label>
+              </div>
+              <div class="tablecolumn_field medium_dynamicsize">
+                <span wicket:id="conversionPattern">[conversionPattern]</span>
+              </div>
             </div>
           </div>
 
-          <div class="tablerow">
-            <div class="tablecolumn_label short_dynamicsize">
-              <label for="enumerationValues"><wicket:message key="enumerationValues"/></label>
-            </div>
-            <div class="tablecolumn_field medium_dynamicsize">
-              <span wicket:id="enumerationValues">[enumerationValues]</span>
+          <div wicket:id="enumParams">
+            <div class="tablerow">
+              <div class="tablecolumn_label short_dynamicsize">
+                <label for="enumerationValues"><wicket:message key="enumerationValues"/></label>
+              </div>
+              <div class="tablecolumn_field medium_dynamicsize">
+                <span wicket:id="enumerationValues">[enumerationValues]</span>
+              </div>
+            </div>
+            <div class="tablerow alt">
+              <div class="tablecolumn_label short_dynamicsize">
+                <label for="enumerationKeys"><wicket:message key="enumerationKeys"/></label>
+              </div>
+              <div class="tablecolumn_field medium_dynamicsize">
+                <span wicket:id="enumerationKeys">[enumerationKeys]</span>
+              </div>
             </div>
           </div>
 
-          <div class="tablerow alt">
-            <div class="tablecolumn_label short_dynamicsize">
-              <label for="enumerationKeys"><wicket:message key="enumerationKeys"/></label>
-            </div>
-            <div class="tablecolumn_field medium_dynamicsize">
-              <span wicket:id="enumerationKeys">[enumerationValues]</span>
+          <div wicket:id="encryptedParams">
+            <div class="tablerow">
+              <div class="tablecolumn_label short_dynamicsize">
+                <label for="secretKey"><wicket:message key="secretKey"/></label>
+              </div>
+              <div class="tablecolumn_field medium_dynamicsize">
+                <span wicket:id="secretKey">[secretKey]</span>
+              </div>
+            </div>
+            <div class="tablerow alt">
+              <div class="tablecolumn_label short_dynamicsize">
+                <label for="cipherAlgorithm"><wicket:message key="cipherAlgorithm"/></label>
+              </div>
+              <div class="tablecolumn_field medium_dynamicsize">
+                <span wicket:id="cipherAlgorithm">[cipherAlgorithm]</span>
+              </div>
             </div>
           </div>
 

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.properties?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage.properties Fri Jun 13 13:58:59 2014
@@ -34,3 +34,5 @@ action=Action
 edit_attribute=Edit attribute
 title=Schema
 readonly=Read-only
+secretKey=Secret key
+cipherAlgorithm=Cipher algorithm

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_it.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_it.properties?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_it.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_it.properties Fri Jun 13 13:58:59 2014
@@ -27,10 +27,12 @@ multivalue=Multivalore
 type=Tipo
 validatorClass=Validatore
 conversionPattern=Conversion pattern
-existing_schemas=Schema esistenti
+existing_schemas=Schema esistenti:
 action=Azione
 edit_attribute=Modifica attributo
 title=Schema
 readonly=Read-only
 uniqueConstraint=Univoco
 multivalueAndUniqueConstr.validation=Le opzioni 'Multivalore' e 'Vincolo unique' non possono essere entrambe impostate
+secretKey=Chiave segreta
+cipherAlgorithm=Algoritmo di cifratura

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_pt_BR.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_pt_BR.properties?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_pt_BR.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SchemaModalPage_pt_BR.properties Fri Jun 13 13:58:59 2014
@@ -16,21 +16,23 @@
 # under the License.
 tab1=Atributos
 tab2=Atributos derivados
-tab3=Atributos de usu\u00E1rios
-tab4=Atributos derivados de usu\u00E1rios
+tab3=Atributos de usu\u00e1rios
+tab4=Atributos derivados de usu\u00e1rios
 create_attribute=Criar novo atributo
-required_alert=Todos os campos s\u00E3o obrigat\u00F3rios
-mandatoryCondition=obrigat\u00F3rio
+required_alert=Todos os campos s\u00e3o obrigat\u00f3rios
+mandatoryCondition=obrigat\u00f3rio
 enumerationValues= Valores enumerados
-enumerationKeys= R\u00F3tulos de enumera\u00E7\u00E3o
-uniqueConstraint=\u00DAnico
+enumerationKeys= R\u00f3tulos de enumera\u00e7\u00e3o
+uniqueConstraint=\u00danico
 multivalue=Multivalorado
-multivalueAndUniqueConstr.validation=As op\u00E7\u00F5es 'Multivalorado' e 'Restri\u00E7\u00E3o \u00FAnica' n\u00E3o podem serem ambas selecionadas
+multivalueAndUniqueConstr.validation=As op\u00e7\u00f5es 'Multivalorado' e 'Restri\u00e7\u00e3o \u00fanica' n\u00e3o podem serem ambas selecionadas
 type=Tipo
-validatorClass=Classe de Valida\u00E7\u00E3o
-conversionPattern=Padr\u00E3o de Convers\u00E3o
+validatorClass=Classe de Valida\u00e7\u00e3o
+conversionPattern=Padr\u00e3o de Convers\u00e3o
 existing_schemas=Esquemas Existentes\:
-action=A\u00E7\u00E3o
+action=A\u00e7\u00e3o
 edit_attribute=Editar Atributo
 title=Esquema
 readonly=Apenas leitura
+secretKey=Chave secreta
+cipherAlgorithm=Algoritmo de criptografia

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.html?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.html Fri Jun 13 13:58:59 2014
@@ -30,7 +30,7 @@ under the License.
             <li><a href="#executions"><span><wicket:message key="executions"/></span></a></li>
           </ul>
           <div id="profile">
-            <div id="users-contain" class="ui-widget">
+            <div class="ui-widget">
               <span wicket:id="profile">
                 <div id="formtable">
 
@@ -90,11 +90,17 @@ under the License.
 
                   <div class="tablerow alt">
                     <div class="tablecolumn_label short_dynamicsize">
-                      <label for="actionsClassName"><wicket:message key="actionsClass"/></label>
-                    </div>
-                    <div class="tablecolumn_field medium_dynamicsize">
-                      <span wicket:id="actionsClassName">[actionsClassName]</span>
+                      <label for="actionsClassNames"><wicket:message key="actionsClasses"/></label>
                     </div>
+                    <span wicket:id="syncActionsClassNames">
+                      <span wicket:id="actionsClasses">
+                        <select class="text ui-widget-content ui-corner-all" wicket:id="actionsClass"/>
+                        <a wicket:id="drop"><img src="img/minus-icon.png" alt="remove icon" class="drop_button"/></a>
+                        <a wicket:id="add"><img src="img/plus-icon.png" alt="add icon" class="add_button"/></a>
+                        <br/>
+                      </span>
+                      <a wicket:id="first"><img src="img/plus-icon.png" alt="add icon" class="add_button"/></a>
+                    </span>                         
                   </div>
 
                   <div class="tablerow">

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.properties?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage.properties Fri Jun 13 13:58:59 2014
@@ -38,4 +38,4 @@ creates=Create new identities
 deletes=Delete matching identities
 syncStatus=Synchronize user status
 fullReconciliation=Full reconciliation
-actionsClass=Actions class
+actionsClasses=Actions classes

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_it.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_it.properties?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_it.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_it.properties Fri Jun 13 13:58:59 2014
@@ -38,4 +38,5 @@ creates=Crea nuove identit\u00e0
 deletes=Elimina identit\u00e0 esistenti
 status=Sincronizza stato utente
 fullReconciliation=Riconciliazione totale
-actionsClass=Classe azioni
+actionsClasses=Classi azioni
+syncStatus=Sincronizza stato utente

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_pt_BR.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_pt_BR.properties?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_pt_BR.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/SyncTaskModalPage_pt_BR.properties Fri Jun 13 13:58:59 2014
@@ -16,18 +16,18 @@
 # under the License.
 profile=Perfil
 crontab=Agenda
-executions=Execu\u00E7\u00F5es
+executions=Execu\u00e7\u00f5es
 title=Tarefas
 resourceName=Nome de Recursos
 name=Nome
-description=Descri\u00E7\u00E3o
-lastExec=\u00DAltima Execu\u00E7\u00E3o
-nextExec=Pr\u00F3xima Execu\u00E7\u00E3o
+description=Descri\u00e7\u00e3o
+lastExec=\u00daltima Execu\u00e7\u00e3o
+nextExec=Pr\u00f3xima Execu\u00e7\u00e3o
 updates=Atualizar Identidades correspondentes
-cron=Agenda (segundos, minutos, horas, dias do m\u00EAs, meses, dias da semana)
+cron=Agenda (segundos, minutos, horas, dias do m\u00eas, meses, dias da semana)
 templates=Remover tarefa agendada / usar template para agendar
 apply=Salvar
-startDate=Data de In\u00EDcio
+startDate=Data de In\u00edcio
 endDate=Data Final
 status=Estatus
 message=Mensagem
@@ -36,6 +36,6 @@ showMessage=Mostrar
 chooseForTemplate=Usar um template
 creates=Criar Nova identidade
 deletes=Excluir identidades correspondentes
-syncStatus=Sincronizar status de usu\u00E1rio
-fullReconciliation=Reconcilia\u00E7\u00E3o completa
-actionsClass=Classes de a\u00E7\u00F5es
+syncStatus=Sincronizar status de usu\u00e1rio
+fullReconciliation=Reconcilia\u00e7\u00e3o completa
+actionsClasses=Classes de a\u00e7\u00f5es

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.html?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/DerivedAttributesPanel.html Fri Jun 13 13:58:59 2014
@@ -33,7 +33,7 @@ under the License.
         <tr>
           <td>
             <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
-                   wicket:id="addAttributeBtn" />
+                   wicket:id="addAttributeBtn"/>
           </td>
         </tr>
       </tfoot>
@@ -41,7 +41,7 @@ under the License.
       <tbody wicket:id="derAttrContainer">
         <tr wicket:id="attrs">
           <td align="center" valign="middle">
-            <input type="checkbox" class="text ui-widget-content ui-corner-all"  wicket:id="toRemove"/>
+            <input type="checkbox" class="text ui-widget-content ui-corner-all" wicket:id="toRemove"/>
           </td>
 
           <td>

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.html?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/panels/ResourceDetailsPanel.html Fri Jun 13 13:58:59 2014
@@ -84,11 +84,17 @@ under the License.
 
       <div class="tablerow">
         <div class="tablecolumn_label short_dynamicsize">
-          <label for="propagationActionsClassName"><wicket:message key="actionsClass"/></label>
-        </div>
-        <div class="tablecolumn_field medium_dynamicsize">
-          <span wicket:id="propagationActionsClassName">[propagationActionsClassName]</span>
+          <label for="propagationActionsClassNames"><wicket:message key="actionsClasses"/></label>
         </div>
+        <span wicket:id="propagationActionsClassNames">
+          <span wicket:id="actionsClasses">
+            <select class="text ui-widget-content ui-corner-all" wicket:id="actionsClass"/>
+            <a wicket:id="drop"><img src="img/minus-icon.png" alt="remove icon" class="drop_button"/></a>
+            <a wicket:id="add"><img src="img/plus-icon.png" alt="add icon" class="add_button"/></a>
+            <br/>
+          </span>
+          <a wicket:id="first"><img src="img/plus-icon.png" alt="add icon" class="add_button"/></a>
+        </span>        
       </div>
 
       <div class="tablerow alt">

Modified: syncope/trunk/console/src/main/webapp/img/down-icon.png
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/webapp/img/down-icon.png?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
Binary files - no diff available.

Modified: syncope/trunk/console/src/main/webapp/img/up-icon.png
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/webapp/img/up-icon.png?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
Binary files - no diff available.

Modified: syncope/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/core/pom.xml?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/core/pom.xml (original)
+++ syncope/trunk/core/pom.xml Fri Jun 13 13:58:59 2014
@@ -742,6 +742,11 @@ under the License.
           <groupId>com.h2database</groupId>
           <artifactId>h2</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.apache.openjpa</groupId>
+          <artifactId>openjpa</artifactId>
+          <version>${openjpa.version}</version>
+        </dependency>        
       </dependencies>
 
       <build>
@@ -772,7 +777,7 @@ under the License.
                   <dependency>org.apache.geronimo.specs:geronimo-jpa_2.0_spec</dependency>
                   <dependency>org.apache.geronimo.specs:geronimo-jms_1.1_spec</dependency>
                   <dependency>org.apache.geronimo.specs:geronimo-jta_1.1_spec</dependency>
-                  <dependency>javax.validation:validation-api</dependency>
+                  <dependency>org.apache.geronimo.specs:geronimo-validation_1.0_spec</dependency>
                   <dependency>net.sourceforge.serp:serp</dependency>
                   <dependency>commons-pool:commons-pool</dependency>
                   <dependency>commons-dbcp:commons-dbcp</dependency>

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/init/JobInstanceLoader.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/init/JobInstanceLoader.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/init/JobInstanceLoader.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/init/JobInstanceLoader.java Fri Jun 13 13:58:59 2014
@@ -19,7 +19,9 @@
 package org.apache.syncope.core.init;
 
 import java.text.ParseException;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -38,8 +40,6 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.quartz.TaskJob;
 import org.apache.syncope.core.report.ReportJob;
 import org.apache.syncope.core.sync.AbstractSyncActions;
-import org.apache.syncope.core.sync.DefaultPushActions;
-import org.apache.syncope.core.sync.DefaultSyncActions;
 import org.apache.syncope.core.sync.impl.AbstractSyncJob;
 import org.apache.syncope.core.util.ApplicationContextProvider;
 import org.quartz.Job;
@@ -172,34 +172,22 @@ public class JobInstanceLoader {
         // In case of synchronization job/task retrieve and set synchronization actions:
         // actions cannot be changed at runtime but connector and synchronization policies (reloaded at execution time).
         if (jobInstance instanceof AbstractSyncJob && task instanceof AbstractSyncTask) {
-            final String jobActionsClassName = ((AbstractSyncTask) task).getActionsClassName();
-
-            try {
-
-                Class<?> syncActionsClass = Class.forName(jobActionsClassName);
-
-                final AbstractSyncActions<?> syncActions =
-                        (AbstractSyncActions<?>) ApplicationContextProvider.getBeanFactory().
-                        createBean(syncActionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
-
-                // Assume that syncActions object implements the right interface: 
-                // * SyncActions for a SyncJob; 
-                // * PushActions for a PushJob.
-                ((AbstractSyncJob) jobInstance).setActions(syncActions);
-
-            } catch (Exception e) {
-                final Class<? extends AbstractSyncActions<?>> defaultSyncActions =
-                        task instanceof SyncTask ? DefaultSyncActions.class : DefaultPushActions.class;
-
-                LOG.info("Class '{}' not found, reverting to {}", jobActionsClassName, defaultSyncActions.getName());
-
+            final List<AbstractSyncActions<?>> actions = new ArrayList<AbstractSyncActions<?>>();
+            for (String className : ((AbstractSyncTask) task).getActionsClassNames()) {
                 try {
-                    ((AbstractSyncJob) jobInstance).setActions(defaultSyncActions.newInstance());
-                } catch (Exception ie) {
-                    // Shouldn't happen, BTW ...
-                    LOG.error("Default action class {} instantiation failed", defaultSyncActions.getName(), ie);
+                    Class<?> actionsClass = Class.forName(className);
+
+                    final AbstractSyncActions<?> syncActions =
+                            (AbstractSyncActions<?>) ApplicationContextProvider.getBeanFactory().
+                            createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
+
+                    actions.add(syncActions);
+                } catch (Exception e) {
+                    LOG.info("Class '{}' not found", className, e);
                 }
             }
+
+            ((AbstractSyncJob) jobInstance).setActions(actions);
         }
 
         registerJob(getJobName(task), jobInstance, cronExpression);

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSyncTask.java Fri Jun 13 13:58:59 2014
@@ -18,19 +18,23 @@
  */
 package org.apache.syncope.core.persistence.beans;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.persistence.Basic;
+import javax.persistence.ElementCollection;
 import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
 import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import org.apache.syncope.common.types.MatchingRule;
 import org.apache.syncope.common.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.validation.entity.SyncTaskCheck;
+import org.apache.syncope.core.persistence.validation.entity.AbstractSyncTaskCheck;
 
 @MappedSuperclass
-@SyncTaskCheck
+@AbstractSyncTaskCheck
 public abstract class AbstractSyncTask extends SchedTask {
 
     private static final long serialVersionUID = -4141057723006682562L;
@@ -61,8 +65,6 @@ public abstract class AbstractSyncTask e
     @Max(1)
     private Integer syncStatus;
 
-    private String actionsClassName;
-
     /**
      * @see UnmatchingRule
      */
@@ -75,6 +77,9 @@ public abstract class AbstractSyncTask e
     @Enumerated(EnumType.STRING)
     protected MatchingRule matchigRule;
 
+    @ElementCollection(fetch = FetchType.EAGER)
+    private List<String> actionsClassNames = new ArrayList<String>();
+
     public AbstractSyncTask(final String jobClassName) {
         super();
         super.setJobClassName(jobClassName);
@@ -125,14 +130,6 @@ public abstract class AbstractSyncTask e
         this.syncStatus = getBooleanAsInteger(syncStatus);
     }
 
-    public String getActionsClassName() {
-        return actionsClassName;
-    }
-
-    public void setActionsClassName(final String actionsClassName) {
-        this.actionsClassName = actionsClassName;
-    }
-
     public abstract UnmatchingRule getUnmatchigRule();
 
     public void setUnmatchigRule(final UnmatchingRule unmatchigRule) {
@@ -144,4 +141,8 @@ public abstract class AbstractSyncTask e
     public void setMatchigRule(final MatchingRule matchigRule) {
         this.matchigRule = matchigRule;
     }
+
+    public List<String> getActionsClassNames() {
+        return actionsClassNames;
+    }
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/ExternalResource.java Fri Jun 13 13:58:59 2014
@@ -18,12 +18,15 @@
  */
 package org.apache.syncope.core.persistence.beans;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import javax.persistence.Basic;
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
+import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
@@ -36,6 +39,7 @@ import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import javax.validation.constraints.NotNull;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.openjpa.persistence.PersistentCollection;
 import org.apache.syncope.common.types.ConnConfProperty;
 import org.apache.syncope.common.types.PropagationMode;
 import org.apache.syncope.common.types.TraceLevel;
@@ -163,9 +167,10 @@ public class ExternalResource extends Ab
     private String rserializedSyncToken;
 
     /**
-     * (Optional) class for PropagationAction.
+     * (Optional) classes for PropagationAction.
      */
-    private String propagationActionsClassName;
+    @ElementCollection(fetch = FetchType.EAGER)
+    private List<String> propagationActionsClassNames = new ArrayList<String>();
 
     /**
      * Default constructor.
@@ -319,7 +324,7 @@ public class ExternalResource extends Ab
         return pushPolicy;
     }
 
-    public void setPushPolicy(PushPolicy pushPolicy) {
+    public void setPushPolicy(final PushPolicy pushPolicy) {
         this.pushPolicy = pushPolicy;
     }
 
@@ -375,11 +380,8 @@ public class ExternalResource extends Ab
         this.rserializedSyncToken = XMLSerializer.serialize(syncToken);
     }
 
-    public String getPropagationActionsClassName() {
-        return propagationActionsClassName;
+    public List<String> getPropagationActionsClassNames() {
+        return propagationActionsClassNames;
     }
 
-    public void setPropagationActionsClassName(final String propagationActionsClassName) {
-        this.propagationActionsClassName = propagationActionsClassName;
-    }
 }

Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskCheck.java (from r1602423, syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskCheck.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskCheck.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskCheck.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskCheck.java&r1=1602423&r2=1602430&rev=1602430&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskCheck.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskCheck.java Fri Jun 13 13:58:59 2014
@@ -29,11 +29,11 @@ import javax.validation.Payload;
 
 @Target( { ElementType.TYPE })
 @Retention(RetentionPolicy.RUNTIME)
-@Constraint(validatedBy = SyncTaskValidator.class)
+@Constraint(validatedBy = AbstractSyncTaskValidator.class)
 @Documented
-public @interface SyncTaskCheck {
+public @interface AbstractSyncTaskCheck {
 
-    String message() default "{org.apache.syncope.core.validation.synctask}";
+    String message() default "{org.apache.syncope.core.validation.abstractsynctask}";
 
     Class<?>[] groups() default {};
 

Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskValidator.java (from r1602129, syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskValidator.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskValidator.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskValidator.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskValidator.java&r1=1602129&r2=1602430&rev=1602430&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncTaskValidator.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/AbstractSyncTaskValidator.java Fri Jun 13 13:58:59 2014
@@ -19,17 +19,18 @@
 package org.apache.syncope.core.persistence.validation.entity;
 
 import javax.validation.ConstraintValidatorContext;
-
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.types.EntityViolationType;
 import org.apache.syncope.core.persistence.beans.AbstractSyncTask;
+import org.apache.syncope.core.persistence.beans.PushTask;
+import org.apache.syncope.core.persistence.beans.SyncTask;
+import org.apache.syncope.core.sync.PushActions;
 import org.apache.syncope.core.sync.SyncActions;
 
-public class SyncTaskValidator extends AbstractValidator<SyncTaskCheck, AbstractSyncTask> {
+public class AbstractSyncTaskValidator extends AbstractValidator<AbstractSyncTaskCheck, AbstractSyncTask> {
 
     private final SchedTaskValidator schedV;
 
-    public SyncTaskValidator() {
+    public AbstractSyncTaskValidator() {
         super();
 
         schedV = new SchedTaskValidator();
@@ -50,24 +51,30 @@ public class SyncTaskValidator extends A
                         addNode("resource").addConstraintViolation();
             }
 
-            if (StringUtils.isNotBlank(object.getActionsClassName())) {
-                Class<?> actionsClass = null;
-                boolean isAssignable = false;
-                try {
-                    actionsClass = Class.forName(object.getActionsClassName());
-                    isAssignable = SyncActions.class.isAssignableFrom(actionsClass);
-                } catch (Exception e) {
-                    LOG.error("Invalid SyncActions specified", e);
-                    isValid = false;
-                }
-
-                if (actionsClass == null || !isAssignable) {
-                    isValid = false;
-
-                    context.disableDefaultConstraintViolation();
-                    context.buildConstraintViolationWithTemplate(
-                            getTemplate(EntityViolationType.InvalidSyncTask, "Invalid class name")).
-                            addNode("actionsClassName").addConstraintViolation();
+            if (!object.getActionsClassNames().isEmpty()) {
+                for (String className : object.getActionsClassNames()) {
+                    Class<?> actionsClass = null;
+                    boolean isAssignable = false;
+                    try {
+                        actionsClass = Class.forName(className);
+                        isAssignable = object instanceof SyncTask
+                                ? SyncActions.class.isAssignableFrom(actionsClass)
+                                : object instanceof PushTask
+                                ? PushActions.class.isAssignableFrom(actionsClass)
+                                : false;
+                    } catch (Exception e) {
+                        LOG.error("Invalid SyncActions specified", e);
+                        isValid = false;
+                    }
+
+                    if (actionsClass == null || !isAssignable) {
+                        isValid = false;
+
+                        context.disableDefaultConstraintViolation();
+                        context.buildConstraintViolationWithTemplate(
+                                getTemplate(EntityViolationType.InvalidSyncTask, "Invalid class name")).
+                                addNode("actionsClassName").addConstraintViolation();
+                    }
                 }
             }
         }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/ExternalResourceValidator.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/ExternalResourceValidator.java?rev=1602430&r1=1602429&r2=1602430&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/ExternalResourceValidator.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/ExternalResourceValidator.java Fri Jun 13 13:58:59 2014
@@ -105,21 +105,23 @@ public class ExternalResourceValidator e
             return false;
         }
 
-        if (StringUtils.isNotBlank(resource.getPropagationActionsClassName())) {
-            Class<?> actionsClass = null;
-            boolean isAssignable = false;
-            try {
-                actionsClass = Class.forName(resource.getPropagationActionsClassName());
-                isAssignable = PropagationActions.class.isAssignableFrom(actionsClass);
-            } catch (Exception e) {
-                LOG.error("Invalid PropagationActions specified: {}", resource.getPropagationActionsClassName(), e);
-            }
+        if (!resource.getPropagationActionsClassNames().isEmpty()) {
+            for (String className : resource.getPropagationActionsClassNames()) {
+                Class<?> actionsClass = null;
+                boolean isAssignable = false;
+                try {
+                    actionsClass = Class.forName(className);
+                    isAssignable = PropagationActions.class.isAssignableFrom(actionsClass);
+                } catch (Exception e) {
+                    LOG.error("Invalid PropagationActions specified: {}", className, e);
+                }
 
-            if (actionsClass == null || !isAssignable) {
-                context.buildConstraintViolationWithTemplate(
-                        getTemplate(EntityViolationType.InvalidResource, "Ivalid actions class name")).
-                        addNode("actionsClassName").addConstraintViolation();
-                return false;
+                if (actionsClass == null || !isAssignable) {
+                    context.buildConstraintViolationWithTemplate(
+                            getTemplate(EntityViolationType.InvalidResource, "Invalid actions class name")).
+                            addNode("actionsClassName").addConstraintViolation();
+                    return false;
+                }
             }
         }