You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2012/02/23 17:25:00 UTC

svn commit: r1292842 - in /incubator/syncope/trunk: client/src/main/java/org/syncope/types/ console/src/main/java/org/syncope/console/pages/ console/src/main/java/org/syncope/console/pages/panels/ console/src/main/resources/org/syncope/console/pages/ c...

Author: fmartelli
Date: Thu Feb 23 16:24:59 2012
New Revision: 1292842

URL: http://svn.apache.org/viewvc?rev=1292842&view=rev
Log:
SYNCOPE-7 #resolve #close #time 4d

Added:
    incubator/syncope/trunk/client/src/main/java/org/syncope/types/Entity.java   (with props)
Modified:
    incubator/syncope/trunk/client/src/main/java/org/syncope/types/IntMappingType.java
    incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/Resources.java
    incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/panels/   (props changed)
    incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/panels/ResourceMappingPanel.java
    incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage.properties
    incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage_it.properties
    incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/panels/ResourceMappingPanel.html
    incubator/syncope/trunk/console/src/main/webapp/css/fieldstyle.css
    incubator/syncope/trunk/core/src/main/java/org/syncope/core/propagation/PropagationManager.java
    incubator/syncope/trunk/core/src/test/java/org/syncope/core/persistence/dao/ResourceTest.java
    incubator/syncope/trunk/core/src/test/java/org/syncope/core/rest/UserTestITCase.java
    incubator/syncope/trunk/core/src/test/resources/   (props changed)
    incubator/syncope/trunk/core/src/test/resources/content.xml
    incubator/syncope/trunk/core/src/test/resources/test.csv

Added: incubator/syncope/trunk/client/src/main/java/org/syncope/types/Entity.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/client/src/main/java/org/syncope/types/Entity.java?rev=1292842&view=auto
==============================================================================
--- incubator/syncope/trunk/client/src/main/java/org/syncope/types/Entity.java (added)
+++ incubator/syncope/trunk/client/src/main/java/org/syncope/types/Entity.java Thu Feb 23 16:24:59 2012
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.syncope.types;
+
+/**
+ * Mapping type.
+ */
+public enum Entity {
+
+    USER, ROLE, MEMBERSHIP;
+}

Propchange: incubator/syncope/trunk/client/src/main/java/org/syncope/types/Entity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/syncope/trunk/client/src/main/java/org/syncope/types/Entity.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/syncope/trunk/client/src/main/java/org/syncope/types/Entity.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/syncope/trunk/client/src/main/java/org/syncope/types/IntMappingType.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/client/src/main/java/org/syncope/types/IntMappingType.java?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/client/src/main/java/org/syncope/types/IntMappingType.java (original)
+++ incubator/syncope/trunk/client/src/main/java/org/syncope/types/IntMappingType.java Thu Feb 23 16:24:59 2012
@@ -18,26 +18,113 @@
  */
 package org.syncope.types;
 
-/*
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *  under the License.
+import java.util.EnumSet;
+
+/**
+ * Internal attribute mapping type.
  */
 public enum IntMappingType {
 
-    UserSchema,
-    UserDerivedSchema,
-    UserVirtualSchema,
-    SyncopeUserId,
-    Password,
-    Username;
+    // Unfortunately enum type cannot be extended ...
+    // -------------------------
+    // User attribute types (the same in UserMappingType)
+    // -------------------------
+    UserSchema(Entity.USER),
+    UserDerivedSchema(Entity.USER),
+    UserVirtualSchema(Entity.USER),
+    SyncopeUserId(Entity.USER),
+    Password(Entity.USER),
+    Username(Entity.USER),
+    // -------------------------
+    // Role attribute types (the same in RoleMappingType)
+    // -------------------------
+    RoleSchema(Entity.ROLE),
+    RoleDerivedSchema(Entity.ROLE),
+    RoleVirtualSchema(Entity.ROLE),
+    // -------------------------
+    // Membership attribute types (the same in MembershipMappingType)
+    // -------------------------
+    MembershipSchema(Entity.MEMBERSHIP),
+    MembershipDerivedSchema(Entity.MEMBERSHIP),
+    MembershipVirtualSchema(Entity.MEMBERSHIP);
+
+    private Entity entity;
+
+    private IntMappingType(final Entity entity) {
+        this.entity = entity;
+    }
+
+    public Entity getEntity() {
+        return entity;
+    }
+
+    /**
+     * Get attribute types for a certain entity.
+     *
+     * @param entity entity.
+     * @return set of attribute types.
+     */
+    public static EnumSet getAttributeTypes(final Entity entity) {
+        switch (entity) {
+            case ROLE:
+                return EnumSet.allOf(RoleMappingType.class);
+            case MEMBERSHIP:
+                return EnumSet.allOf(MembershipMappingType.class);
+            default:
+                return EnumSet.allOf(UserMappingType.class);
+        }
+    }
+
+    /**
+     * Check if attribute type belongs to the specified entity set.
+     *
+     * @param entity entity.
+     * @param type attrybute type.
+     * @return true if attribute type belongs to the specified entity set.
+     */
+    public static boolean contains(
+            final Entity entity, final String type) {
+
+        switch (entity) {
+            case ROLE:
+                return RoleMappingType.valueOf(type) != null;
+            case MEMBERSHIP:
+                return MembershipMappingType.valueOf(type) != null;
+            default:
+                return UserMappingType.valueOf(type) != null;
+        }
+    }
+
+    /**
+     * User attribute types.
+     */
+    enum UserMappingType {
+
+        UserSchema,
+        UserDerivedSchema,
+        UserVirtualSchema,
+        SyncopeUserId,
+        Password,
+        Username;
+    }
+
+    /**
+     * Role attribute types.
+     */
+    private enum RoleMappingType {
+
+        RoleSchema,
+        RoleDerivedSchema,
+        RoleVirtualSchema;
+    }
+
+    /**
+     * Membership attribute types.
+     */
+    private enum MembershipMappingType {
+
+        MembershipSchema,
+        MembershipDerivedSchema,
+        MembershipVirtualSchema;
+    }
 }

Modified: incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/Resources.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/Resources.java?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/Resources.java (original)
+++ incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/Resources.java Thu Feb 23 16:24:59 2012
@@ -81,9 +81,9 @@ public class Resources extends BasePage 
 
     private final ModalWindow editConnectorWin;
 
-    private static final int WIN_HEIGHT = 500;
+    private static final int WIN_HEIGHT = 600;
 
-    private static final int WIN_WIDTH = 900;
+    private static final int WIN_WIDTH = 950;
 
     private WebMarkupContainer resourceContainer;
 

Propchange: incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/panels/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Thu Feb 23 16:24:59 2012
@@ -0,0 +1 @@
+.ResourceMappingPanel.java.swp

Modified: incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/panels/ResourceMappingPanel.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/panels/ResourceMappingPanel.java?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/panels/ResourceMappingPanel.java (original)
+++ incubator/syncope/trunk/console/src/main/java/org/syncope/console/pages/panels/ResourceMappingPanel.java Thu Feb 23 16:24:59 2012
@@ -21,6 +21,7 @@ package org.syncope.console.pages.panels
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -36,8 +37,6 @@ import org.apache.wicket.markup.html.for
 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;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.ResourceModel;
@@ -56,10 +55,17 @@ import org.syncope.console.wicket.markup
 import org.syncope.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.syncope.console.wicket.markup.html.form.FieldPanel;
 import org.syncope.types.ConnConfProperty;
+import org.syncope.types.Entity;
 import org.syncope.types.IntMappingType;
 
+/**
+ * Resource mapping panel.
+ */
 public class ResourceMappingPanel extends Panel {
 
+    /**
+     * Serial verion UID.
+     */
     private static final long serialVersionUID = -7982691107029848579L;
 
     /**
@@ -68,36 +74,89 @@ public class ResourceMappingPanel extend
     protected static final Logger LOG =
             LoggerFactory.getLogger(ResourceMappingPanel.class);
 
+    /**
+     * Schema rest client.
+     */
     @SpringBean
-    private SchemaRestClient schemaRestClient;
+    private transient SchemaRestClient schemaRestClient;
 
+    /**
+     * ConnInstance rest client.
+     */
     @SpringBean
-    private ConnectorRestClient connRestClient;
+    private transient ConnectorRestClient connRestClient;
 
-    private List<String> uSchemaAttrNames;
+    /**
+     * Resource schema name.
+     */
+    private List<String> schemaNames;
 
-    private List<String> uDerSchemaAttrNames;
+    /**
+     * Internal attribute types.
+     */
+    private List<IntMappingType> attrTypes = new ArrayList<IntMappingType>();
 
-    private List<String> uVirSchemaAttrNames;
+    /**
+     * Add mapping button.
+     */
+    private final AjaxButton addMappingBtn;
 
-    private List<String> resourceSchemaNames;
+    /**
+     * All mappings.
+     */
+    private final ListView mappings;
 
-    private AjaxButton addSchemaMappingBtn;
+    /**
+     * External resource to be updated.
+     */
+    private final ResourceTO resourceTO;
 
-    private ListView mappings;
+    /**
+     * Mapping container.
+     */
+    private final WebMarkupContainer mappingContainer;
 
-    private ResourceTO resourceTO;
+    /**
+     * Create flag.
+     */
+    private final boolean createFlag;
+
+    /**
+     * OnChange event name.
+     */
+    private static String onchange = "onchange";
 
-    private WebMarkupContainer mappingContainer;
+    /**
+     * Mapping field style sheet.
+     */
+    private static String fieldStyle =
+            "ui-widget-content ui-corner-all short_fixedsize";
 
-    private boolean createFlag;
+    /**
+     * Mapping field style sheet.
+     */
+    private static String defFieldStyle =
+            "ui-widget-content ui-corner-all";
 
+    /**
+     * Mapping field style sheet.
+     */
+    private static String shortFieldStyle =
+            "ui-widget-content ui-corner-all veryshort_fixedsize";
+
+    /**
+     * Attribute Mapping Panel.
+     *
+     * @param panelid panel id.
+     * @param resourceTO external resource.
+     * @param createFlag create flag.
+     */
     public ResourceMappingPanel(
-            final String id,
+            final String panelid,
             final ResourceTO resourceTO,
             final boolean createFlag) {
 
-        super(id);
+        super(panelid);
         setOutputMarkupId(true);
 
         this.resourceTO = resourceTO;
@@ -105,25 +164,6 @@ public class ResourceMappingPanel extend
 
         initResourceSchemaNames();
 
-        uSchemaAttrNames =
-                schemaRestClient.getSchemaNames("user");
-        uDerSchemaAttrNames =
-                schemaRestClient.getDerivedSchemaNames("user");
-        uVirSchemaAttrNames =
-                schemaRestClient.getVirtualSchemaNames("user");
-
-        final IModel<List<IntMappingType>> intMappingTypes =
-                new LoadableDetachableModel<List<IntMappingType>>() {
-
-                    private static final long serialVersionUID =
-                            5275935387613157437L;
-
-                    @Override
-                    protected List<IntMappingType> load() {
-                        return Arrays.asList(IntMappingType.values());
-                    }
-                };
-
         final AjaxTextFieldPanel accountLink = new AjaxTextFieldPanel(
                 "accountLink",
                 new ResourceModel("accountLink", "accountLink").getObject(),
@@ -137,6 +177,9 @@ public class ResourceMappingPanel extend
         mappings = new ListView<SchemaMappingTO>(
                 "mappings", resourceTO.getMappings()) {
 
+            /**
+             * Serial version UID.
+             */
             private static final long serialVersionUID = 4949588177564901031L;
 
             @Override
@@ -145,6 +188,11 @@ public class ResourceMappingPanel extend
 
                 final SchemaMappingTO mappingTO = item.getModelObject();
 
+                final Entity entity = mappingTO.getIntMappingType() == null
+                        ? null : mappingTO.getIntMappingType().getEntity();
+
+                attrTypes = getAttributeTypes(entity);
+
                 item.add(new AjaxDecoratedCheckbox("toRemove",
                         new Model(Boolean.FALSE)) {
 
@@ -201,73 +249,81 @@ public class ResourceMappingPanel extend
                         getString("intAttrNames"),
                         new PropertyModel(mappingTO, "intAttrName"),
                         true);
-                intAttrNames.setChoices(resourceSchemaNames);
+                intAttrNames.setChoices(schemaNames);
                 intAttrNames.setRequired(true);
-                intAttrNames.setStyleShet(
-                        "ui-widget-content ui-corner-all short_fixedsize");
-
-                if (mappingTO.getIntMappingType() == null) {
-                    intAttrNames.setChoices(Collections.EMPTY_LIST);
-                } else {
-                    switch (mappingTO.getIntMappingType()) {
-                        case UserSchema:
-                            intAttrNames.setChoices(uSchemaAttrNames);
-                            break;
-
-                        case UserDerivedSchema:
-                            intAttrNames.setChoices(uDerSchemaAttrNames);
-                            break;
-
-                        case UserVirtualSchema:
-                            intAttrNames.setChoices(uVirSchemaAttrNames);
-                            break;
-
-                        case SyncopeUserId:
-                            intAttrNames.setEnabled(false);
-                            intAttrNames.setRequired(false);
-                            intAttrNames.setChoices(Collections.EMPTY_LIST);
-                            mappingTO.setIntAttrName("SyncopeUserId");
-                            break;
-
-                        case Password:
-                            intAttrNames.setEnabled(false);
-                            intAttrNames.setRequired(false);
-                            intAttrNames.setChoices(Collections.EMPTY_LIST);
-                            mappingTO.setIntAttrName("Password");
-                            break;
-
-                        case Username:
-                            intAttrNames.setEnabled(false);
-                            intAttrNames.setRequired(false);
-                            intAttrNames.setChoices(Collections.EMPTY_LIST);
-                            mappingTO.setIntAttrName("Username");
-                            break;
+                intAttrNames.setStyleShet(fieldStyle);
 
-                        default:
-                            intAttrNames.setChoices(Collections.EMPTY_LIST);
-                    }
-                }
+                setAttrNames(mappingTO.getIntMappingType(), intAttrNames);
 
                 item.add(intAttrNames);
 
-                final IntMappingTypesDropDownChoice mappingTypesPanel =
-                        new IntMappingTypesDropDownChoice(
+
+                final AjaxDropDownChoicePanel typesPanel =
+                        new AjaxDropDownChoicePanel(
                         "intMappingTypes",
                         new ResourceModel("intMappingTypes", "intMappingTypes").
                         getObject(),
                         new PropertyModel<IntMappingType>(
-                        mappingTO, "intMappingType"),
-                        intAttrNames);
+                        mappingTO, "intMappingType"), false);
+
+                typesPanel.getField().add(
+                        new AjaxFormComponentUpdatingBehavior(onchange) {
+
+                            private static final long serialVersionUID =
+                                    -1107858522700306810L;
+
+                            @Override
+                            protected void onUpdate(
+                                    final AjaxRequestTarget target) {
+                                setAttrNames(
+                                        (IntMappingType) typesPanel.
+                                        getModelObject(), intAttrNames);
+                                target.add(intAttrNames);
+                            }
+                        });
+
+                typesPanel.setRequired(true);
+                typesPanel.setChoices(attrTypes);
+                typesPanel.setStyleShet(fieldStyle);
+                item.add(typesPanel);
+
+                final AjaxDropDownChoicePanel mappingTypesPanel =
+                        new AjaxDropDownChoicePanel(
+                        "mappingTypes",
+                        new ResourceModel("mappingTypes", "mappingTypes").
+                        getObject(), new Model(entity), false);
+
+                mappingTypesPanel.setChoices(Arrays.asList(Entity.values()));
+                mappingTypesPanel.setStyleShet(defFieldStyle);
 
-                mappingTypesPanel.setRequired(true);
-                mappingTypesPanel.setChoices(intMappingTypes.getObject());
-                mappingTypesPanel.setStyleShet(
-                        "ui-widget-content ui-corner-all short_fixedsize");
                 item.add(mappingTypesPanel);
 
+                mappingTypesPanel.getField().add(
+                        new AjaxFormComponentUpdatingBehavior(onchange) {
+
+                            private static final long serialVersionUID =
+                                    -1107858522700306810L;
+
+                            @Override
+                            protected void onUpdate(
+                                    final AjaxRequestTarget target) {
+
+                                attrTypes = getAttributeTypes(
+                                        (Entity) mappingTypesPanel.
+                                        getModelObject());
+
+                                typesPanel.setChoices(attrTypes);
+                                intAttrNames.setChoices(Collections.EMPTY_LIST);
+
+                                target.add(typesPanel.getField());
+                                target.add(intAttrNames.getField());
+
+                            }
+                        });
+
                 final FieldPanel extAttrName;
 
-                if (resourceSchemaNames.isEmpty()) {
+                if (schemaNames.isEmpty()) {
                     extAttrName = new AjaxTextFieldPanel(
                             "extAttrName",
                             new ResourceModel("extAttrNames", "extAttrNames").
@@ -284,7 +340,7 @@ public class ResourceMappingPanel extend
                             new PropertyModel(mappingTO, "extAttrName"),
                             true);
                     ((AjaxDropDownChoicePanel) extAttrName).setChoices(
-                            resourceSchemaNames);
+                            schemaNames);
 
                 }
 
@@ -294,26 +350,23 @@ public class ResourceMappingPanel extend
                 extAttrName.setRequired(required);
                 extAttrName.setEnabled(required);
 
-                extAttrName.setStyleShet(
-                        "ui-widget-content ui-corner-all short_fixedsize");
+                extAttrName.setStyleShet(fieldStyle);
                 item.add(extAttrName);
 
-                final AjaxTextFieldPanel mandatoryCondition =
+                final AjaxTextFieldPanel mandatory =
                         new AjaxTextFieldPanel(
                         "mandatoryCondition",
                         new ResourceModel(
                         "mandatoryCondition", "mandatoryCondition").getObject(),
-                        new PropertyModel(mappingTO,
-                        "mandatoryCondition"),
+                        new PropertyModel(mappingTO, "mandatoryCondition"),
                         true);
 
-                mandatoryCondition.setChoices(
+                mandatory.setChoices(
                         Arrays.asList(new String[]{"true", "false"}));
 
-                mandatoryCondition.setStyleShet(
-                        "ui-widget-content ui-corner-all short_fixedsize");
+                mandatory.setStyleShet(shortFieldStyle);
 
-                item.add(mandatoryCondition);
+                item.add(mandatory);
 
                 final AjaxCheckBoxPanel accountId =
                         new AjaxCheckBoxPanel(
@@ -322,7 +375,7 @@ public class ResourceMappingPanel extend
                         new PropertyModel(mappingTO, "accountid"), false);
 
                 accountId.getField().add(
-                        new AjaxFormComponentUpdatingBehavior("onchange") {
+                        new AjaxFormComponentUpdatingBehavior(onchange) {
 
                             private static final long serialVersionUID =
                                     -1107858522700306810L;
@@ -349,14 +402,14 @@ public class ResourceMappingPanel extend
                         new PropertyModel(mappingTO, "password"), true);
 
                 password.getField().add(
-                        new AjaxFormComponentUpdatingBehavior("onchange") {
+                        new AjaxFormComponentUpdatingBehavior(onchange) {
 
                             private static final long serialVersionUID =
                                     -1107858522700306810L;
 
                             @Override
                             protected void onUpdate(
-                                    AjaxRequestTarget target) {
+                                    final AjaxRequestTarget target) {
                                 extAttrName.setEnabled(
                                         !mappingTO.isAccountid()
                                         && !password.getModelObject());
@@ -374,7 +427,7 @@ public class ResourceMappingPanel extend
         mappings.setReuseItems(true);
         mappingContainer.add(mappings);
 
-        addSchemaMappingBtn = new IndicatingAjaxButton(
+        addMappingBtn = new IndicatingAjaxButton(
                 "addUserSchemaMappingBtn", new ResourceModel("add")) {
 
             private static final long serialVersionUID = -4804368561204623354L;
@@ -388,77 +441,19 @@ public class ResourceMappingPanel extend
             }
 
             @Override
-            protected void onError(AjaxRequestTarget target, Form<?> form) {
+            protected void onError(
+                    final AjaxRequestTarget target, final Form<?> form) {
                 // ignore errors
             }
         };
 
-        addSchemaMappingBtn.setDefaultFormProcessing(false);
-        addSchemaMappingBtn.setEnabled(!createFlag);
-        mappingContainer.add(addSchemaMappingBtn);
+        addMappingBtn.setDefaultFormProcessing(false);
+        addMappingBtn.setEnabled(!createFlag);
+        mappingContainer.add(addMappingBtn);
 
     }
 
     /**
-     * Extension class of DropDownChoice. It's purposed for storing values in
-     * the corresponding property model after pressing 'Add' button.
-     */
-    private class IntMappingTypesDropDownChoice
-            extends AjaxDropDownChoicePanel {
-
-        private static final long serialVersionUID = -2855668124505116627L;
-
-        public IntMappingTypesDropDownChoice(
-                final String id,
-                final String name,
-                final PropertyModel<IntMappingType> model,
-                final AjaxDropDownChoicePanel<String> chooserToPopulate) {
-
-            super(id, name, model, false);
-
-            field.add(new AjaxFormComponentUpdatingBehavior("onchange") {
-
-                private static final long serialVersionUID =
-                        -1107858522700306810L;
-
-                @Override
-                protected void onUpdate(final AjaxRequestTarget target) {
-
-                    chooserToPopulate.setRequired(true);
-                    chooserToPopulate.setEnabled(true);
-
-                    final List<String> result;
-
-                    switch (model.getObject()) {
-                        case UserSchema:
-                            result = uSchemaAttrNames;
-                            break;
-
-                        case UserDerivedSchema:
-                            result = uDerSchemaAttrNames;
-                            break;
-
-                        case UserVirtualSchema:
-                            result = uVirSchemaAttrNames;
-                            break;
-
-                        case SyncopeUserId:
-                        case Password:
-                        case Username:
-                        default:
-                            chooserToPopulate.setRequired(false);
-                            chooserToPopulate.setEnabled(false);
-                            result = Collections.EMPTY_LIST;
-                    }
-
-                    chooserToPopulate.setChoices(result);
-                    target.add(chooserToPopulate);
-                }
-            });
-        }
-    }
-
-    /**
      * Initialize resource schema names.
      */
     private void initResourceSchemaNames() {
@@ -472,12 +467,12 @@ public class ResourceMappingPanel extend
             connInstanceTO.setConfiguration(
                     resourceTO.getConnConfProperties());
 
-            resourceSchemaNames = getResourceSchemaNames(
+            schemaNames = getResourceSchemaNames(
                     resourceTO.getConnectorId(),
                     resourceTO.getConnConfProperties());
 
         } else {
-            resourceSchemaNames = Collections.EMPTY_LIST;
+            schemaNames = Collections.EMPTY_LIST;
         }
     }
 
@@ -520,15 +515,106 @@ public class ResourceMappingPanel extend
 
             mappings.removeAll();
 
-            addSchemaMappingBtn.setEnabled(
+            addMappingBtn.setEnabled(
                     resourceTO.getConnectorId() != null
                     && resourceTO.getConnectorId() > 0);
 
-            resourceSchemaNames = getResourceSchemaNames(
+            schemaNames = getResourceSchemaNames(
                     resourceTO.getConnectorId(),
                     new HashSet<ConnConfProperty>(conf));
 
             target.add(mappingContainer);
         }
     }
+
+    /**
+     * Seta attribute names for a drop down chice list.
+     *
+     * @param attrType attribute type.
+     * @param toBeUpdated drop down choice to be updated.
+     */
+    private void setAttrNames(
+            final IntMappingType attrType,
+            final AjaxDropDownChoicePanel toBeUpdated) {
+
+        toBeUpdated.setRequired(true);
+        toBeUpdated.setEnabled(true);
+
+        if (attrType == null || attrType.getEntity() == null) {
+            toBeUpdated.setChoices(Collections.EMPTY_LIST);
+        } else {
+
+            switch (attrType) {
+                // user attribute names
+                case UserSchema:
+                case RoleSchema:
+                case MembershipSchema:
+                    toBeUpdated.setChoices(
+                            schemaRestClient.getSchemaNames(
+                            attrType.getEntity().toString().toLowerCase()));
+                    break;
+
+                case UserDerivedSchema:
+                case RoleDerivedSchema:
+                case MembershipDerivedSchema:
+                    toBeUpdated.setChoices(
+                            schemaRestClient.getDerivedSchemaNames(
+                            attrType.getEntity().toString().toLowerCase()));
+                    break;
+
+                case UserVirtualSchema:
+                case RoleVirtualSchema:
+                case MembershipVirtualSchema:
+                    toBeUpdated.setChoices(
+                            schemaRestClient.getVirtualSchemaNames(
+                            attrType.getEntity().toString().toLowerCase()));
+                    break;
+
+                case SyncopeUserId:
+                    toBeUpdated.setEnabled(false);
+                    toBeUpdated.setRequired(false);
+                    toBeUpdated.setChoices(Collections.EMPTY_LIST);
+                    break;
+
+                case Password:
+                    toBeUpdated.setEnabled(false);
+                    toBeUpdated.setRequired(false);
+                    toBeUpdated.setChoices(Collections.EMPTY_LIST);
+                    break;
+
+                case Username:
+                    toBeUpdated.setEnabled(false);
+                    toBeUpdated.setRequired(false);
+                    toBeUpdated.setChoices(Collections.EMPTY_LIST);
+                    break;
+
+                default:
+                    toBeUpdated.setRequired(false);
+                    toBeUpdated.setEnabled(false);
+                    toBeUpdated.setChoices(Collections.EMPTY_LIST);
+            }
+        }
+    }
+
+    /**
+     * Get all attribute types from a selected attribute type.
+     *
+     * @param entity entity.
+     * @return all attribute types.
+     */
+    private List<IntMappingType> getAttributeTypes(final Entity entity) {
+        final List<IntMappingType> res = new ArrayList<IntMappingType>();
+
+        if (entity != null) {
+            final EnumSet types = IntMappingType.getAttributeTypes(
+                    Entity.valueOf(entity.toString()));
+
+            for (Object type : types) {
+                res.add(IntMappingType.valueOf(
+                        type.toString()));
+            }
+        }
+
+        return res;
+    }
 }

Modified: incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage.properties
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage.properties?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage.properties (original)
+++ incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage.properties Thu Feb 23 16:24:59 2012
@@ -28,9 +28,10 @@ edit_attribute=Edit resource
 title=Resource
 extAttrNames=External Attributes
 intMappingTypes=Internal mapping types
+entity=Entity
 roleSchema=Role Schema
-accountId=Account Id
-mandatoryCondition=Mandatory condition
+accountId=AccountId
+mandatoryCondition=Mandatory
 password=Password
 mappingUserSchema=Mapping User Schema
 mappingRoleSchema=Mapping Role Schema

Modified: incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage_it.properties
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage_it.properties?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage_it.properties (original)
+++ incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/ResourceModalPage_it.properties Thu Feb 23 16:24:59 2012
@@ -29,9 +29,10 @@ edit_attribute=Modifica risorsa
 title=Risorsa
 extAttrNames=Attributi esterni
 intMappingTypes=Tipo mapping interno
+entity=Entit&agrave;
 roleSchema=Schema Ruolo
-accountId=Id Account
-mandatoryCondition=Condizione d'obbligatoriet\u00e0
+accountId=AccountId
+mandatoryCondition=Obbligatorio
 password=Password
 mappingUserSchema=Mapping User Schema
 mappingRoleSchema=Mapping Role Schema

Modified: incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/panels/ResourceMappingPanel.html
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/panels/ResourceMappingPanel.html?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/panels/ResourceMappingPanel.html (original)
+++ incubator/syncope/trunk/console/src/main/resources/org/syncope/console/pages/panels/ResourceMappingPanel.html Thu Feb 23 16:24:59 2012
@@ -25,6 +25,7 @@
                         <thead>
                             <tr class="ui-widget-header">
                                 <th><wicket:message key="delete"/></th>
+                        <th><wicket:message key="entity"/></th>
                         <th><wicket:message key="intMappingTypes"/></th>
                         <th><wicket:message key="intAttrNames"/></th>
                         <th><wicket:message key="extAttrNames"/></th>
@@ -47,6 +48,9 @@
                                     <input type="checkbox" class="text ui-widget-content ui-corner-all"  wicket:id="toRemove"/>
                                 </td>
                                 <td align="center" valign="middle">
+                                    <span wicket:id="mappingTypes">[mappingTypes]</span>
+                                </td>
+                                <td align="center" valign="middle">
                                     <span wicket:id="intMappingTypes">[intMappingTypes]</span>
                                 </td>
                                 <td align="center" valign="middle">

Modified: incubator/syncope/trunk/console/src/main/webapp/css/fieldstyle.css
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/console/src/main/webapp/css/fieldstyle.css?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/console/src/main/webapp/css/fieldstyle.css (original)
+++ incubator/syncope/trunk/console/src/main/webapp/css/fieldstyle.css Thu Feb 23 16:24:59 2012
@@ -36,6 +36,10 @@
     width: 150px;
 }
 
+.veryshort_fixedsize{
+    width: 70px;
+}
+
 .all_dynamicsize{
     width: 100%;
 }

Modified: incubator/syncope/trunk/core/src/main/java/org/syncope/core/propagation/PropagationManager.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/syncope/core/propagation/PropagationManager.java?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/java/org/syncope/core/propagation/PropagationManager.java (original)
+++ incubator/syncope/trunk/core/src/main/java/org/syncope/core/propagation/PropagationManager.java Thu Feb 23 16:24:59 2012
@@ -26,6 +26,7 @@ import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import javassist.NotFoundException;
 import org.apache.commons.collections.keyvalue.DefaultMapEntry;
@@ -48,19 +49,27 @@ import org.syncope.client.mod.AttributeM
 import org.syncope.client.to.AttributeTO;
 import org.syncope.core.init.ConnInstanceLoader;
 import org.syncope.core.persistence.beans.AbstractAttrValue;
+import org.syncope.core.persistence.beans.AbstractAttributable;
+import org.syncope.core.persistence.beans.AbstractDerAttr;
 import org.syncope.core.persistence.beans.AbstractSchema;
+import org.syncope.core.persistence.beans.AbstractVirAttr;
 import org.syncope.core.persistence.beans.ConnInstance;
 import org.syncope.core.persistence.beans.ExternalResource;
 import org.syncope.core.persistence.beans.PropagationTask;
 import org.syncope.core.persistence.beans.SchemaMapping;
 import org.syncope.core.persistence.beans.TaskExec;
+import org.syncope.core.persistence.beans.membership.MDerSchema;
+import org.syncope.core.persistence.beans.membership.MSchema;
+import org.syncope.core.persistence.beans.membership.MVirSchema;
+import org.syncope.core.persistence.beans.membership.Membership;
+import org.syncope.core.persistence.beans.role.RDerSchema;
+import org.syncope.core.persistence.beans.role.RSchema;
+import org.syncope.core.persistence.beans.role.RVirSchema;
 import org.syncope.core.persistence.beans.user.SyncopeUser;
 import org.syncope.core.persistence.beans.user.UAttr;
 import org.syncope.core.persistence.beans.user.UAttrValue;
-import org.syncope.core.persistence.beans.user.UDerAttr;
 import org.syncope.core.persistence.beans.user.UDerSchema;
 import org.syncope.core.persistence.beans.user.USchema;
-import org.syncope.core.persistence.beans.user.UVirAttr;
 import org.syncope.core.persistence.beans.user.UVirSchema;
 import org.syncope.core.persistence.dao.ResourceDAO;
 import org.syncope.core.persistence.dao.SchemaDAO;
@@ -408,14 +417,32 @@ public class PropagationManager {
             case UserSchema:
                 result = USchema.class;
                 break;
+            case RoleSchema:
+                result = RSchema.class;
+                break;
+            case MembershipSchema:
+                result = MSchema.class;
+                break;
 
             case UserDerivedSchema:
                 result = UDerSchema.class;
                 break;
+            case RoleDerivedSchema:
+                result = RDerSchema.class;
+                break;
+            case MembershipDerivedSchema:
+                result = MDerSchema.class;
+                break;
 
             case UserVirtualSchema:
                 result = UVirSchema.class;
                 break;
+            case RoleVirtualSchema:
+                result = RVirSchema.class;
+                break;
+            case MembershipVirtualSchema:
+                result = MVirSchema.class;
+                break;
 
             default:
                 result = null;
@@ -440,163 +467,220 @@ public class PropagationManager {
             final String password)
             throws ClassNotFoundException {
 
+        final List<AbstractAttributable> attributables =
+                new ArrayList<AbstractAttributable>();
+
+        switch (mapping.getIntMappingType().getEntity()) {
+            case USER:
+                attributables.addAll(Collections.singleton(user));
+                break;
+            case ROLE:
+                final List<Membership> memberships = user.getMemberships();
+                for (Membership membership : memberships) {
+                    attributables.add(membership.getSyncopeRole());
+                }
+                break;
+            case MEMBERSHIP:
+                attributables.addAll(user.getMemberships());
+                break;
+            default:
+        }
+
+        final Entry<AbstractSchema, List<AbstractAttrValue>> entry =
+                getAttributeValues(mapping, attributables, password);
+
+        final List<AbstractAttrValue> values = entry.getValue();
+        final AbstractSchema schema = entry.getKey();
+        final SchemaType schemaType =
+                schema == null ? SchemaType.String : schema.getType();
+
+        LOG.debug("Define mapping for: "
+                + "\n* ExtAttrName " + mapping.getExtAttrName()
+                + "\n* is accountId " + mapping.isAccountid()
+                + "\n* is password " + (mapping.isPassword()
+                || mapping.getIntMappingType().equals(
+                IntMappingType.Password))
+                + "\n* mandatory condition "
+                + mapping.getMandatoryCondition()
+                + "\n* Schema " + mapping.getIntAttrName()
+                + "\n* IntMappingType "
+                + mapping.getIntMappingType().toString()
+                + "\n* ClassType " + schemaType.getClassName()
+                + "\n* Values " + values);
+
+        List<Object> objValues = new ArrayList<Object>();
+        for (AbstractAttrValue value : values) {
+            if (FrameworkUtil.isSupportedAttributeType(
+                    Class.forName(schemaType.getClassName()))) {
+                objValues.add(value.getValue());
+            } else {
+                objValues.add(value.getValueAsString());
+            }
+        }
+
+        Map.Entry<String, Attribute> res;
+
+        if (mapping.isAccountid()) {
+
+            res = new DefaultMapEntry(
+                    objValues.iterator().next().toString(), null);
+
+        } else if (mapping.isPassword()) {
+
+            res = new DefaultMapEntry(null,
+                    AttributeBuilder.buildPassword(
+                    objValues.iterator().next().toString().toCharArray()));
+
+        } else {
+            if (schema != null && schema.isMultivalue()) {
+                res = new DefaultMapEntry(null,
+                        AttributeBuilder.build(mapping.getExtAttrName(),
+                        objValues));
+
+            } else {
+                res = new DefaultMapEntry(null,
+                        objValues.isEmpty()
+                        ? AttributeBuilder.build(mapping.getExtAttrName())
+                        : AttributeBuilder.build(mapping.getExtAttrName(),
+                        objValues.iterator().next()));
+            }
+        }
+
+        return res;
+    }
+
+    /**
+     * Get attribute values.
+     *
+     * @param mapping mapping.
+     * @param attributables list of attributables.
+     * @param password password.
+     * @return schema and attribute values.
+     */
+    private Entry<AbstractSchema, List<AbstractAttrValue>> getAttributeValues(
+            final SchemaMapping mapping,
+            final List<AbstractAttributable> attributables,
+            final String password) {
+
+
+        LOG.debug("Get attributes for '{}' and mapping type '{}'",
+                attributables, mapping.getIntMappingType());
+
         AbstractSchema schema = null;
-        SchemaType schemaType = null;
-        List<AbstractAttrValue> values = null;
+
+        List<AbstractAttrValue> values = new ArrayList<AbstractAttrValue>();
         AbstractAttrValue attrValue;
+
         switch (mapping.getIntMappingType()) {
             case UserSchema:
+            case RoleSchema:
+            case MembershipSchema:
                 schema = schemaDAO.find(mapping.getIntAttrName(),
-                        getIntMappingTypeClass(
-                        mapping.getIntMappingType()));
-                schemaType = schema.getType();
-
-                UAttr attr = user.getAttribute(mapping.getIntAttrName());
-                values = attr != null
-                        ? (schema.isUniqueConstraint()
-                        ? Collections.singletonList(attr.getUniqueValue())
-                        : attr.getValues())
-                        : Collections.EMPTY_LIST;
-
-                LOG.debug("Retrieved attribute {}", attr
-                        + "\n* IntAttrName {}"
-                        + "\n* IntMappingType {}"
-                        + "\n* Attribute values {}",
-                        new Object[]{mapping.getIntAttrName(),
-                            mapping.getIntMappingType(), values});
+                        getIntMappingTypeClass(mapping.getIntMappingType()));
+
+                for (AbstractAttributable attributable : attributables) {
+                    final UAttr attr =
+                            attributable.getAttribute(mapping.getIntAttrName());
+
+                    if (attr != null && attr.getValues() != null) {
+                        values.addAll(schema.isUniqueConstraint()
+                                ? Collections.singletonList(
+                                attr.getUniqueValue())
+                                : attr.getValues());
+                    }
+
+                    LOG.debug("Retrieved attribute {}"
+                            + "\n* IntAttrName {}"
+                            + "\n* IntMappingType {}"
+                            + "\n* Attribute values {}",
+                            new Object[]{attr, mapping.getIntAttrName(),
+                                mapping.getIntMappingType(), values});
+                }
+
                 break;
 
             case UserVirtualSchema:
-                schemaType = SchemaType.String;
-
-                UVirAttr virAttr = user.getVirtualAttribute(
-                        mapping.getIntAttrName());
+            case RoleVirtualSchema:
+            case MembershipVirtualSchema:
 
-                values = new ArrayList<AbstractAttrValue>();
-                if (virAttr != null && virAttr.getValues() != null) {
-                    for (String value : virAttr.getValues()) {
-                        attrValue = new UAttrValue();
-                        attrValue.setStringValue(value);
-                        values.add(attrValue);
+                for (AbstractAttributable attributable : attributables) {
+                    AbstractVirAttr virAttr = attributable.getVirtualAttribute(
+                            mapping.getIntAttrName());
+
+                    if (virAttr != null && virAttr.getValues() != null) {
+                        for (String value : virAttr.getValues()) {
+                            attrValue = new UAttrValue();
+                            attrValue.setStringValue(value);
+                            values.add(attrValue);
+                        }
                     }
-                }
 
-                LOG.debug("Retrieved virtual attribute {}", virAttr
-                        + "\n* IntAttrName {}"
-                        + "\n* IntMappingType {}"
-                        + "\n* Attribute values {}",
-                        new Object[]{mapping.getIntAttrName(),
-                            mapping.getIntMappingType(), values});
+                    LOG.debug("Retrieved virtual attribute {}"
+                            + "\n* IntAttrName {}"
+                            + "\n* IntMappingType {}"
+                            + "\n* Attribute values {}",
+                            new Object[]{virAttr, mapping.getIntAttrName(),
+                                mapping.getIntMappingType(), values});
+                }
                 break;
 
             case UserDerivedSchema:
-                schemaType = SchemaType.String;
+            case RoleDerivedSchema:
+            case MembershipDerivedSchema:
+                for (AbstractAttributable attributable : attributables) {
+                    AbstractDerAttr derAttr = attributable.getDerivedAttribute(
+                            mapping.getIntAttrName());
 
-                UDerAttr derAttr = user.getDerivedAttribute(
-                        mapping.getIntAttrName());
-                attrValue = new UAttrValue();
-                if (derAttr != null) {
-                    attrValue.setStringValue(
-                            derAttr.getValue(user.getAttributes()));
+                    if (derAttr != null) {
+                        attrValue = new UAttrValue();
+                        attrValue.setStringValue(
+                                derAttr.getValue(attributable.getAttributes()));
+                        values.add(attrValue);
+                    }
 
-                    values = Collections.singletonList(attrValue);
-                } else {
-                    values = Collections.EMPTY_LIST;
+                    LOG.debug("Retrieved attribute {}"
+                            + "\n* IntAttrName {}"
+                            + "\n* IntMappingType {}"
+                            + "\n* Attribute values {}",
+                            new Object[]{derAttr, mapping.getIntAttrName(),
+                                mapping.getIntMappingType(), values});
                 }
-
-                LOG.debug("Retrieved attribute {}", derAttr
-                        + "\n* IntAttrName {}"
-                        + "\n* IntMappingType {}"
-                        + "\n* Attribute values {}",
-                        new Object[]{mapping.getIntAttrName(),
-                            mapping.getIntMappingType(), values});
                 break;
 
-
             case Username:
-                schema = null;
-                schemaType = SchemaType.String;
-
-                attrValue = new UAttrValue();
-                attrValue.setStringValue(user.getUsername());
+                for (AbstractAttributable attributable : attributables) {
+                    attrValue = new UAttrValue();
+                    attrValue.setStringValue(
+                            ((SyncopeUser) attributable).getUsername());
 
-                values = Collections.singletonList(attrValue);
+                    values.add(attrValue);
+                }
                 break;
 
             case SyncopeUserId:
-                schema = null;
-                schemaType = SchemaType.String;
-                attrValue = new UAttrValue();
-                attrValue.setStringValue(user.getId().toString());
-                values = Collections.singletonList(attrValue);
+                for (AbstractAttributable attributable : attributables) {
+                    attrValue = new UAttrValue();
+                    attrValue.setStringValue(attributable.getId().toString());
+                    values.add(attrValue);
+                }
                 break;
 
             case Password:
-                schema = null;
-                schemaType = SchemaType.String;
                 attrValue = new UAttrValue();
 
                 if (password != null) {
                     attrValue.setStringValue(password);
                 }
 
-                values = Collections.singletonList(attrValue);
+                values.add(attrValue);
                 break;
 
             default:
         }
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Define mapping for: "
-                    + "\n* ExtAttrName " + mapping.getExtAttrName()
-                    + "\n* is accountId " + mapping.isAccountid()
-                    + "\n* is password " + (mapping.isPassword()
-                    || mapping.getIntMappingType().equals(
-                    IntMappingType.Password))
-                    + "\n* mandatory condition "
-                    + mapping.getMandatoryCondition()
-                    + "\n* Schema " + mapping.getIntAttrName()
-                    + "\n* IntMappingType "
-                    + mapping.getIntMappingType().toString()
-                    + "\n* ClassType " + schemaType.getClassName()
-                    + "\n* Values " + values);
-        }
-
-        List<Object> objValues = new ArrayList<Object>();
-        for (AbstractAttrValue value : values) {
-            if (!FrameworkUtil.isSupportedAttributeType(
-                    Class.forName(schemaType.getClassName()))) {
-
-                objValues.add(value.getValueAsString());
-            } else {
-                objValues.add(value.getValue());
-            }
-        }
-
-        String accountId = null;
-        if (mapping.isAccountid()) {
-            accountId = objValues.iterator().next().toString();
-        }
-
-        Attribute attribute = null;
-        if (mapping.isPassword()) {
-            attribute = AttributeBuilder.buildPassword(
-                    objValues.iterator().next().toString().toCharArray());
-        }
+        LOG.debug("Retrived values '{}'", values);
 
-        if (!mapping.isPassword() && !mapping.isAccountid()) {
-            if (schema != null && schema.isMultivalue()) {
-                attribute = AttributeBuilder.build(mapping.getExtAttrName(),
-                        objValues);
-            } else {
-                attribute = objValues.isEmpty()
-                        ? AttributeBuilder.build(mapping.getExtAttrName())
-                        : AttributeBuilder.build(mapping.getExtAttrName(),
-                        objValues.iterator().next());
-            }
-        }
-
-        return new DefaultMapEntry(accountId, attribute);
+        return new DefaultMapEntry(schema, values);
     }
 
     /**
@@ -635,7 +719,9 @@ public class PropagationManager {
                     final Attribute alreadyAdded = AttributeUtil.find(
                             preparedAttribute.getValue().getName(), attributes);
 
-                    if (alreadyAdded != null) {
+                    if (alreadyAdded == null) {
+                        attributes.add(preparedAttribute.getValue());
+                    } else {
                         attributes.remove(alreadyAdded);
 
                         Set values = new HashSet(alreadyAdded.getValue());
@@ -644,8 +730,6 @@ public class PropagationManager {
                         attributes.add(AttributeBuilder.build(
                                 preparedAttribute.getValue().getName(),
                                 values));
-                    } else {
-                        attributes.add(preparedAttribute.getValue());
                     }
 
                 }
@@ -658,25 +742,22 @@ public class PropagationManager {
         if (!StringUtils.hasText(accountId)) {
             // LOG error but avoid to throw exception: leave it to the 
             //external resource
-
-            LOG.error(
-                    "Failure preparing attributes for '{}': missing accountId",
-                    resource.getName());
+            LOG.error("Missing accountId for '{}': ", resource.getName());
         }
 
         // Evaluate AccountLink expression
-        String evaluatedAccountLink =
+        String evalAccountLink =
                 jexlUtil.evaluate(resource.getAccountLink(), user);
 
         // AccountId must be propagated. It could be a simple attribute for
         // the target resource or the key (depending on the accountLink)
-        if (evaluatedAccountLink.isEmpty()) {
+        if (evalAccountLink.isEmpty()) {
             // add accountId as __NAME__ attribute ...
             LOG.debug("Add AccountId [{}] as __NAME__", accountId);
             attributes.add(new Name(accountId));
         } else {
-            LOG.debug("Add AccountLink [{}] as __NAME__", evaluatedAccountLink);
-            attributes.add(new Name(evaluatedAccountLink));
+            LOG.debug("Add AccountLink [{}] as __NAME__", evalAccountLink);
+            attributes.add(new Name(evalAccountLink));
 
             // AccountId not propagated: 
             // it will be used to set the value for __UID__ attribute

Modified: incubator/syncope/trunk/core/src/test/java/org/syncope/core/persistence/dao/ResourceTest.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/syncope/core/persistence/dao/ResourceTest.java?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/syncope/core/persistence/dao/ResourceTest.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/syncope/core/persistence/dao/ResourceTest.java Thu Feb 23 16:24:59 2012
@@ -31,6 +31,7 @@ import org.syncope.core.persistence.bean
 import org.syncope.core.persistence.beans.SchemaMapping;
 import org.syncope.core.AbstractTest;
 import org.syncope.core.persistence.validation.entity.InvalidEntityException;
+import org.syncope.types.Entity;
 import org.syncope.types.IntMappingType;
 
 @Transactional
@@ -121,6 +122,11 @@ public class ResourceTest extends Abstra
         ExternalResource resource = new ExternalResource();
         resource.setName("ws-target-resource-basic-save-invalid");
 
+        ConnInstance connector =
+                resourceDAO.find("ws-target-resource-1").getConnector();
+
+        resource.setConnector(connector);
+
         SchemaMapping accountId = new SchemaMapping();
         accountId.setResource(resource);
         accountId.setAccountid(true);
@@ -140,6 +146,11 @@ public class ResourceTest extends Abstra
         ExternalResource resource = new ExternalResource();
         resource.setName("ws-target-resource-basic-save-invalid");
 
+        ConnInstance connector =
+                resourceDAO.find("ws-target-resource-1").getConnector();
+
+        resource.setConnector(connector);
+
         SchemaMapping mapping = new SchemaMapping();
         mapping.setResource(resource);
         mapping.setAccountid(true);
@@ -150,15 +161,70 @@ public class ResourceTest extends Abstra
 
         mapping = new SchemaMapping();
         mapping.setResource(resource);
+        mapping.setIntAttrName("userId");
+        mapping.setIntMappingType(IntMappingType.UserSchema);
+
+        resource.addMapping(mapping);
+
+        resourceDAO.save(resource);
+    }
+
+    @Test
+    public void saveWithRoleMappingType() {
+
+        ExternalResource resource = new ExternalResource();
+        resource.setName("ws-target-resource-basic-save-invalid");
+
+        ConnInstance connector =
+                resourceDAO.find("ws-target-resource-1").getConnector();
+
+        resource.setConnector(connector);
+
+        SchemaMapping mapping = new SchemaMapping();
+        mapping.setResource(resource);
+        mapping.setAccountid(true);
         mapping.setIntAttrName("fullname");
         mapping.setIntMappingType(IntMappingType.UserSchema);
 
         resource.addMapping(mapping);
 
+        mapping = new SchemaMapping();
+        mapping.setResource(resource);
+        mapping.setIntAttrName("icon");
+        mapping.setExtAttrName("icon");
+        mapping.setIntMappingType(IntMappingType.RoleSchema);
+
+        resource.addMapping(mapping);
+
+        mapping = new SchemaMapping();
+        mapping.setResource(resource);
+        mapping.setIntAttrName("mderiveddata");
+        mapping.setExtAttrName("mderiveddata");
+        mapping.setIntMappingType(IntMappingType.MembershipDerivedSchema);
+
+        resource.addMapping(mapping);
+
         // save the resource
         ExternalResource actual = resourceDAO.save(resource);
 
         assertNotNull(actual);
+
+        assertEquals(3, actual.getMappings().size());
+
+        for (SchemaMapping schemaMapping : actual.getMappings()) {
+
+            if ("icon".equals(schemaMapping.getIntAttrName())) {
+                assertTrue(IntMappingType.contains(
+                        Entity.ROLE,
+                        schemaMapping.getIntMappingType().toString()));
+            }
+
+            if ("mderiveddata".equals(schemaMapping.getIntAttrName())) {
+                assertTrue(IntMappingType.contains(
+                        Entity.MEMBERSHIP,
+                        schemaMapping.getIntMappingType().toString()));
+            }
+        }
     }
 
     @Test

Modified: incubator/syncope/trunk/core/src/test/java/org/syncope/core/rest/UserTestITCase.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/syncope/core/rest/UserTestITCase.java?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/syncope/core/rest/UserTestITCase.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/syncope/core/rest/UserTestITCase.java Thu Feb 23 16:24:59 2012
@@ -489,10 +489,10 @@ public class UserTestITCase extends Abst
         userTO.addMembership(membershipTO);
 
         // add an attribute with no values: must be ignored
-        AttributeTO nullValueAttributeTO = new AttributeTO();
-        nullValueAttributeTO.setSchema("subscriptionDate");
-        nullValueAttributeTO.setValues(null);
-        membershipTO.addAttribute(nullValueAttributeTO);
+        AttributeTO nullValueAttrTO = new AttributeTO();
+        nullValueAttrTO.setSchema("subscriptionDate");
+        nullValueAttrTO.setValues(null);
+        membershipTO.addAttribute(nullValueAttrTO);
 
         // add an attribute with a non-existing schema: must be ignored
         AttributeTO attrWithInvalidSchemaTO = new AttributeTO();
@@ -501,10 +501,10 @@ public class UserTestITCase extends Abst
         userTO.addAttribute(attrWithInvalidSchemaTO);
 
         // add an attribute with null value: must be ignored
-        nullValueAttributeTO = new AttributeTO();
-        nullValueAttributeTO.setSchema("activationDate");
-        nullValueAttributeTO.addValue(null);
-        userTO.addAttribute(nullValueAttributeTO);
+        nullValueAttrTO = new AttributeTO();
+        nullValueAttrTO.setSchema("activationDate");
+        nullValueAttrTO.addValue(null);
+        userTO.addAttribute(nullValueAttrTO);
 
         // 1. create user
         UserTO newUserTO = restTemplate.postForObject(
@@ -1655,4 +1655,94 @@ public class UserTestITCase extends Abst
                     SyncopeClientExceptionType.InvalidValues));
         }
     }
+
+    @Test
+    public void roleAttrPropagation() {
+        UserTO userTO = getSampleTO("checkRoleAttrPropagation@syncope-idm.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerivedAttributes().clear();
+        userTO.getVirtualAttributes().clear();
+
+        AttributeTO csvuserid = new AttributeTO();
+        csvuserid.setSchema("csvuserid");
+        userTO.addDerivedAttribute(csvuserid);
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(1L);
+
+        userTO.addMembership(membershipTO);
+
+        userTO.addResource("resource-csv");
+
+        UserTO actual = restTemplate.postForObject(
+                BASE_URL + "user/create", userTO, UserTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getDerivedAttributeMap().get("csvuserid"));
+
+        ConnObjectTO connObjectTO = restTemplate.getForObject(
+                BASE_URL + "/resource/{resourceName}/read/{objectId}.json",
+                ConnObjectTO.class,
+                "resource-csv",
+                actual.getDerivedAttributeMap().get("csvuserid").getValues().
+                get(0));
+
+        assertNotNull(connObjectTO);
+
+        assertEquals("sx-dx", connObjectTO.getAttributeMap().get("ROLE").
+                getValues().get(0));
+    }
+    
+    @Test
+    public void membershipAttrPropagation() {
+        UserTO userTO = getSampleTO("checkMembAttrPropagation@syncope-idm.org");
+        userTO.getResources().clear();
+        userTO.getMemberships().clear();
+        userTO.getDerivedAttributes().clear();
+        userTO.getVirtualAttributes().clear();
+
+        AttributeTO csvuserid = new AttributeTO();
+        csvuserid.setSchema("csvuserid");
+        userTO.addDerivedAttribute(csvuserid);
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(1L);
+        
+        AttributeTO mderived_sx = new AttributeTO();
+        mderived_sx.setSchema("mderived_sx");
+        mderived_sx.setValues(Collections.singletonList("sx"));
+        membershipTO.addAttribute(mderived_sx);
+        
+        AttributeTO mderived_dx = new AttributeTO();
+        mderived_dx.setSchema("mderived_dx");
+        mderived_dx.setValues(Collections.singletonList("dx"));
+        membershipTO.addAttribute(mderived_dx);
+        
+        AttributeTO mderiveddata = new AttributeTO();
+        mderiveddata.setSchema("mderToBePropagated");
+        membershipTO.addDerivedAttribute(mderiveddata);
+
+        userTO.addMembership(membershipTO);
+
+        userTO.addResource("resource-csv");
+
+        UserTO actual = restTemplate.postForObject(
+                BASE_URL + "user/create", userTO, UserTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getDerivedAttributeMap().get("csvuserid"));
+
+        ConnObjectTO connObjectTO = restTemplate.getForObject(
+                BASE_URL + "/resource/{resourceName}/read/{objectId}.json",
+                ConnObjectTO.class,
+                "resource-csv",
+                actual.getDerivedAttributeMap().get("csvuserid").getValues().
+                get(0));
+
+        assertNotNull(connObjectTO);
+
+        assertEquals("sx-dx", connObjectTO.getAttributeMap().get("MEMBERSHIP").
+                getValues().get(0));
+    }
 }

Propchange: incubator/syncope/trunk/core/src/test/resources/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Thu Feb 23 16:24:59 2012
@@ -0,0 +1 @@
+.test.csv.swp

Modified: incubator/syncope/trunk/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/resources/content.xml?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/resources/content.xml (original)
+++ incubator/syncope/trunk/core/src/test/resources/content.xml Thu Feb 23 16:24:59 2012
@@ -172,8 +172,16 @@ under the License.
 
     <RDerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"/>
     <RDerAttr id="1000" derivedSchema_name="rderiveddata" owner_id="1"/>
+    
+    <RDerSchema name="displayProperty" expression="icon + ': ' + show"/>
+
+    <RDerAttr id="1001" derivedSchema_name="displayProperty" owner_id="1"/>
+    <RDerAttr id="1002" derivedSchema_name="displayProperty" owner_id="4"/>
 
-    <!-- rderiveddata is used th verify der schema deletion -->
+    <RDerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"/>
+    <RDerAttr id="1003" derivedSchema_name="rderToBePropagated" owner_id="1"/>
+    
+    <!-- rderiveddata is used to verify der schema deletion -->
     <RDerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"/>
 
     <MAttr id="100" owner_id="4" schema_name="subscriptionDate"/>
@@ -189,6 +197,8 @@ under the License.
 
     <MDerSchema name="mderiveddata" expression="mderived_sx + '-' + mderived_dx"/>
     <MDerAttr id="100" derivedSchema_name="mderiveddata" owner_id="1"/>
+    
+    <MDerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx"/>
 
     <UVirSchema name="virtualdata"/>
     <UVirAttr id="100" virtualSchema_name="virtualdata" owner_id="3"/>
@@ -251,7 +261,7 @@ under the License.
                   bundleName="org.connid.bundles.csvdir"
                   connectorName="org.connid.csvdir.CSVDirConnector"
                   version="${connid.csvdir.version}"
-                  xmlConfiguration="%3Cset%3E%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Ekeyseparator%3C/name%3E%0A++++++%3CdisplayName%3EKey+separator%3C/displayName%3E%0A++++++%3ChelpMessage%3ECharacter+used+to+separate+keys+in+a+multi-key+scenario%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3E%2C%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Eencoding%3C/name%3E%0A++++++%3CdisplayName%3EFile+encoding%3C/displayName%3E%0A++++++%3ChelpMessage%3EBasic+encoding+of+the+file%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/or
 g.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EquotationRequired%3C/name%3E%0A++++++%3CdisplayName%3EValue+quotation+required%3C/displayName%3E%0A++++++%3ChelpMessage%3ESpecify+if+value+quotation+is+required%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.Boolean%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.Boolean%3Efalse%3C/java.lang.Boolean%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EfileMask%3C/name%3E%0A++++++%3CdisplayName%3EFile+mask%3C/displayName%3E%0A++++++%3ChelpMessage%3ERegular+expression+describing+files+to+be+processed%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Et
 est.csv%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EpasswordColumnName%3C/name%3E%0A++++++%3CdisplayName%3EPassword+column+name%3C/displayName%3E%0A++++++%3ChelpMessage%3EName+of+the+column+used+to+specify+user+password%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Epassword%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EtextQualifier%3C/name%3E%0A++++++%3CdisplayName%3EText+qualifier%3C/displayName%3E%0A++++++%3ChelpMessage%3EDelimiter+to+determine+begin+and+end+of+text+in+value%3C/helpMessage%3E%0A++++++%3Ctype%3Echar%3
 C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EdeleteColumnName%3C/name%3E%0A++++++%3CdisplayName%3EDelete+column+name%3C/displayName%3E%0A++++++%3ChelpMessage%3EName+of+the+column+used+to+specify+users+to+be+deleted%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Edeleted%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EsourcePath%3C/name%3E%0A++++++%3CdisplayName%3ESource+path%3C/displayName%3E%0A++++++%3ChelpMessage%3EAbsolute+path+of+a+directory+where+are+located+CSV+files+to+be+processed%3C
 /helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3E/${urlencoded.java.io.tmpdir}%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EfieldDelimiter%3C/name%3E%0A++++++%3CdisplayName%3EfieldDelimiter%3C/displayName%3E%0A++++++%3ChelpMessage%3EfieldDelimiter%3C/helpMessage%3E%0A++++++%3Ctype%3Echar%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.Character%3E%2C%3C/java.lang.Character%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EkeyColumnNames%3C/name%3E%0A++++++%3CdisplayName%3EKey+column+name%3C/displ
 ayName%3E%0A++++++%3ChelpMessage%3EName+of+the+column+used+to+identify+user+uniquely%3C/helpMessage%3E%0A++++++%3Ctype%3E%5BLjava.lang.String%3B%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Ename%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Esurname%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EignoreHeader%3C/name%3E%0A++++++%3CdisplayName%3EIgnore+header%3C/displayName%3E%0A++++++%3ChelpMessage%3ESpecify+it+first+line+file+must+be+ignored%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.Boolean%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.Boolean%3Efalse%3C/java.lang.Boolean%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%
 0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Efields%3C/name%3E%0A++++++%3CdisplayName%3Efields%3C/displayName%3E%0A++++++%3ChelpMessage%3EColumn+names+separated+by+comma%3C/helpMessage%3E%0A++++++%3Ctype%3E%5BLjava.lang.String%3B%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eid%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Ename%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Esurname%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Eemail%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Epassword%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Estatus%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Edeleted%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EstatusColumn%3C/name%3E%0A++++++%3CdisplayName%3EstatusColumn%3C/di
 splayName%3E%0A++++++%3ChelpMessage%3EStatus+column%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Estatus%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%3C/set%3E"/>
+                  xmlConfiguration="%3Cset%3E%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Ekeyseparator%3C/name%3E%0A++++++%3CdisplayName%3EKey+separator%3C/displayName%3E%0A++++++%3ChelpMessage%3ECharacter+used+to+separate+keys+in+a+multi-key+scenario%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3E%2C%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Eencoding%3C/name%3E%0A++++++%3CdisplayName%3EFile+encoding%3C/displayName%3E%0A++++++%3ChelpMessage%3EBasic+encoding+of+the+file%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/or
 g.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EquotationRequired%3C/name%3E%0A++++++%3CdisplayName%3EValue+quotation+required%3C/displayName%3E%0A++++++%3ChelpMessage%3ESpecify+if+value+quotation+is+required%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.Boolean%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.Boolean%3Efalse%3C/java.lang.Boolean%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EfileMask%3C/name%3E%0A++++++%3CdisplayName%3EFile+mask%3C/displayName%3E%0A++++++%3ChelpMessage%3ERegular+expression+describing+files+to+be+processed%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Et
 est.csv%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EpasswordColumnName%3C/name%3E%0A++++++%3CdisplayName%3EPassword+column+name%3C/displayName%3E%0A++++++%3ChelpMessage%3EName+of+the+column+used+to+specify+user+password%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Epassword%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EtextQualifier%3C/name%3E%0A++++++%3CdisplayName%3EText+qualifier%3C/displayName%3E%0A++++++%3ChelpMessage%3EDelimiter+to+determine+begin+and+end+of+text+in+value%3C/helpMessage%3E%0A++++++%3Ctype%3Echar%3
 C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EdeleteColumnName%3C/name%3E%0A++++++%3CdisplayName%3EDelete+column+name%3C/displayName%3E%0A++++++%3ChelpMessage%3EName+of+the+column+used+to+specify+users+to+be+deleted%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Edeleted%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EsourcePath%3C/name%3E%0A++++++%3CdisplayName%3ESource+path%3C/displayName%3E%0A++++++%3ChelpMessage%3EAbsolute+path+of+a+directory+where+are+located+CSV+files+to+be+processed%3C
 /helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3E/${urlencoded.java.io.tmpdir}%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EfieldDelimiter%3C/name%3E%0A++++++%3CdisplayName%3EfieldDelimiter%3C/displayName%3E%0A++++++%3ChelpMessage%3EfieldDelimiter%3C/helpMessage%3E%0A++++++%3Ctype%3Echar%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.Character%3E%2C%3C/java.lang.Character%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EkeyColumnNames%3C/name%3E%0A++++++%3CdisplayName%3EKey+column+name%3C/displ
 ayName%3E%0A++++++%3ChelpMessage%3EName+of+the+column+used+to+identify+user+uniquely%3C/helpMessage%3E%0A++++++%3Ctype%3E%5BLjava.lang.String%3B%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Ename%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Esurname%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EignoreHeader%3C/name%3E%0A++++++%3CdisplayName%3EIgnore+header%3C/displayName%3E%0A++++++%3ChelpMessage%3ESpecify+it+first+line+file+must+be+ignored%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.Boolean%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.Boolean%3Efalse%3C/java.lang.Boolean%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%
 0A%0A++%3Corg.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Efields%3C/name%3E%0A++++++%3CdisplayName%3Efields%3C/displayName%3E%0A++++++%3ChelpMessage%3EColumn+names+separated+by+comma%3C/helpMessage%3E%0A++++++%3Ctype%3E%5BLjava.lang.String%3B%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eid%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Ename%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Esurname%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Eemail%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Epassword%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Erole%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Emembership%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Estatus%3C/java.lang.String%3E%0A%3Cjava.lang.String%3Edeleted%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%3Corg.syncope.types.ConnConfProper
 ty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EstatusColumn%3C/name%3E%0A++++++%3CdisplayName%3EstatusColumn%3C/displayName%3E%0A++++++%3ChelpMessage%3EStatus+column%3C/helpMessage%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Estatus%3C/java.lang.String%3E%0A%3C/values%3E%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.syncope.types.ConnConfProperty%3E%0A%3C/set%3E"/>
     <ConnInstance_capabilities ConnInstance_id="104" capabilities="ONE_PHASE_CREATE"/>
     <ConnInstance_capabilities ConnInstance_id="104" capabilities="ONE_PHASE_UPDATE"/>
     <ConnInstance_capabilities ConnInstance_id="104" capabilities="ONE_PHASE_DELETE"/>
@@ -430,6 +440,14 @@ under the License.
                    resource_name="resource-csv"
                    intAttrName="csvuserid" intMappingType="UserDerivedSchema" mandatoryCondition="true"
                    accountid="1" password="0"/>
+    <SchemaMapping id="208" extAttrName="role"
+                   resource_name="resource-csv"
+                   intAttrName="rderToBePropagated" intMappingType="RoleDerivedSchema" mandatoryCondition="false"
+                   accountid="0" password="0"/>
+    <SchemaMapping id="209" extAttrName="membership"
+                   resource_name="resource-csv"
+                   intAttrName="mderToBePropagated" intMappingType="MembershipDerivedSchema" mandatoryCondition="false"
+                   accountid="0" password="0"/>
                    
     <SchemaMapping id="300" extAttrName="userId"
                    resource_name="ws-target-resource-update-resetsynctoken"
@@ -476,11 +494,6 @@ under the License.
     <Task DTYPE="SyncTask" id="7" resource_name="resource-testdb"
           performCreate="1" performUpdate="1" performDelete="0" syncStatus="1" fullReconciliation="1"
           jobClassName="org.syncope.core.scheduling.SyncJob"/>
-                
-    <RDerSchema name="displayProperty" expression="icon + ': ' + show"/>
-
-    <RDerAttr id="1001" derivedSchema_name="displayProperty" owner_id="1"/>
-    <RDerAttr id="1002" derivedSchema_name="displayProperty" owner_id="4"/>
 
     <!-- Authentication and authorization -->
     <Entitlement name="base"/>

Modified: incubator/syncope/trunk/core/src/test/resources/test.csv
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/resources/test.csv?rev=1292842&r1=1292841&r2=1292842&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/resources/test.csv (original)
+++ incubator/syncope/trunk/core/src/test/resources/test.csv Thu Feb 23 16:24:59 2012
@@ -1,10 +1,10 @@
-test0,nome0,cognome0,test0@syncope.org,password0,true,false
-test1,nome1,cognome1,test1@syncope.org,password1,false,false
-test2,nome2,cognome2,test2@syncope.org,notpermitted1,true,false
-test3,nome3,cognome3,test3@syncope.org,password3,true,false
-test4,nome4,cognome4,test4@syncope.org,password4,true,false
-test5,nome5,cognome5,test5@syncope.org,password5,true,false
-test6,nome6,cognome6,test6@syncope.org,password6,true,false
-test7,nome7,cognome7,test7@syncope.org,password7,true,false
-test8,nome8,cognome8,test8@syncope.org,password8,true,false
-test9,nome9,cognome9,test9@syncope.org,password9,true,false
+test0,nome0,cognome0,test0@syncope.org,password0,role1,membership1,true,false
+test1,nome1,cognome1,test1@syncope.org,password1,role1,membership1,false,false
+test2,nome2,cognome2,test2@syncope.org,notpermitted1,role1,membership1,true,false
+test3,nome3,cognome3,test3@syncope.org,password3,role1,membership1,true,false
+test4,nome4,cognome4,test4@syncope.org,password4,role1,membership1,true,false
+test5,nome5,cognome5,test5@syncope.org,password5,role1,membership1,true,false
+test6,nome6,cognome6,test6@syncope.org,password6,role1,membership1,true,false
+test7,nome7,cognome7,test7@syncope.org,password7,role1,membership1,true,false
+test8,nome8,cognome8,test8@syncope.org,password8,role1,membership1,true,false
+test9,nome9,cognome9,test9@syncope.org,password9,role1,membership1,true,false