syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject [14/70] syncope git commit: [SYNCOPE-666] Initial commit, Travis CI builds disabled
Date Thu, 11 Jun 2015 14:17:04 GMT
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMembership.java
deleted file mode 100644
index dc02cf3..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/membership/JPAMembership.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * 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.apache.syncope.core.persistence.jpa.entity.membership;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import javax.validation.Valid;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractAttributable;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
-
-@Entity
-@Table(name = JPAMembership.TABLE, uniqueConstraints =
-        @UniqueConstraint(columnNames = { "user_id", "group_id" }))
-public class JPAMembership extends AbstractAttributable<MPlainAttr, MDerAttr, MVirAttr> implements Membership {
-
-    private static final long serialVersionUID = 5030106264797289469L;
-
-    public static final String TABLE = "Membership";
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    private JPAUser user;
-
-    @ManyToOne
-    private JPAGroup group;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAMPlainAttr> plainAttrs;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAMDerAttr> derAttrs;
-
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
-    @Valid
-    private List<JPAMVirAttr> virAttrs;
-
-    public JPAMembership() {
-        super();
-
-        plainAttrs = new ArrayList<>();
-        derAttrs = new ArrayList<>();
-        virAttrs = new ArrayList<>();
-    }
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public Group getGroup() {
-        return group;
-    }
-
-    @Override
-    public void setGroup(final Group group) {
-        checkType(group, JPAGroup.class);
-        this.group = (JPAGroup) group;
-    }
-
-    @Override
-    public User getUser() {
-        return user;
-    }
-
-    @Override
-    public void setUser(final User user) {
-        checkType(user, JPAUser.class);
-        this.user = (JPAUser) user;
-    }
-
-    @Override
-    public boolean addPlainAttr(final MPlainAttr plainAttr) {
-        checkType(plainAttr, JPAMPlainAttr.class);
-
-        if (getGroup() != null && plainAttr.getSchema() != null) {
-            MPlainAttrTemplate found = CollectionUtils.find(getGroup().getAttrTemplates(MPlainAttrTemplate.class),
-                    new Predicate<MPlainAttrTemplate>() {
-
-                        @Override
-                        public boolean evaluate(final MPlainAttrTemplate template) {
-                            return plainAttr.getSchema().equals(template.getSchema());
-                        }
-
-                    });
-            if (found != null) {
-                plainAttr.setTemplate(found);
-                return plainAttrs.add((JPAMPlainAttr) plainAttr);
-            }
-        }
-
-        LOG.warn("Attribute not added because either group was not yet set, "
-                + "schema was not specified or no template for that schema is available");
-        return false;
-    }
-
-    @Override
-    public boolean removePlainAttr(final MPlainAttr attr) {
-        checkType(attr, JPAMPlainAttr.class);
-        return plainAttrs.remove((JPAMPlainAttr) attr);
-    }
-
-    @Override
-    public List<? extends MPlainAttr> getPlainAttrs() {
-        return plainAttrs;
-    }
-
-    @Override
-    public boolean addDerAttr(final MDerAttr derAttr) {
-        checkType(derAttr, JPAMDerAttr.class);
-
-        if (getGroup() != null && derAttr.getSchema() != null) {
-            MDerAttrTemplate found = CollectionUtils.find(getGroup().getAttrTemplates(MDerAttrTemplate.class),
-                    new Predicate<MDerAttrTemplate>() {
-
-                        @Override
-                        public boolean evaluate(final MDerAttrTemplate template) {
-                            return derAttr.getSchema().equals(template.getSchema());
-                        }
-
-                    });
-            if (found != null) {
-                derAttr.setTemplate(found);
-                return derAttrs.add((JPAMDerAttr) derAttr);
-            }
-        }
-
-        LOG.warn("Attribute not added because either group was not yet set, "
-                + "schema was not specified or no template for that schema is available");
-        return false;
-    }
-
-    @Override
-    public boolean removeDerAttr(final MDerAttr derAttr) {
-        checkType(derAttr, JPAMDerAttr.class);
-        return derAttrs.remove((JPAMDerAttr) derAttr);
-    }
-
-    @Override
-    public List<? extends MDerAttr> getDerAttrs() {
-        return derAttrs;
-    }
-
-    @Override
-    public boolean addVirAttr(final MVirAttr virAttr) {
-        checkType(virAttr, JPAMVirAttr.class);
-
-        if (getGroup() != null && virAttr.getSchema() != null) {
-            MVirAttrTemplate found = null;
-            for (MVirAttrTemplate template : getGroup().getAttrTemplates(MVirAttrTemplate.class)) {
-                if (virAttr.getSchema().equals(template.getSchema())) {
-                    found = template;
-                }
-            }
-            if (found != null) {
-                virAttr.setTemplate(found);
-                return virAttrs.add((JPAMVirAttr) virAttr);
-            }
-        }
-
-        LOG.warn("Attribute not added because either "
-                + "schema was not specified or no template for that schema is available");
-        return false;
-    }
-
-    @Override
-    public boolean removeVirAttr(final MVirAttr virAttr) {
-        checkType(virAttr, JPAMVirAttr.class);
-        return virAttrs.remove((JPAMVirAttr) virAttr);
-    }
-
-    @Override
-    public List<? extends MVirAttr> getVirAttrs() {
-        return virAttrs;
-    }
-
-    @Override
-    public String toString() {
-        return "Membership[" + "id=" + id + ", " + user + ", " + group + ']';
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
new file mode 100644
index 0000000..b4f7f67
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAExternalResource.java
@@ -0,0 +1,394 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.resource;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
+import org.apache.syncope.core.persistence.jpa.validation.entity.ExternalResourceCheck;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractAnnotatedEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAccountPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPasswordPolicy;
+import org.apache.syncope.core.persistence.jpa.entity.JPASyncPolicy;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+
+/**
+ * Resource for propagation and synchronization.
+ */
+@Entity
+@Table(name = JPAExternalResource.TABLE)
+@ExternalResourceCheck
+public class JPAExternalResource extends AbstractAnnotatedEntity<String> implements ExternalResource {
+
+    private static final long serialVersionUID = -6937712883512073278L;
+
+    public static final String TABLE = "ExternalResource";
+
+    /**
+     * The resource identifier is the name.
+     */
+    @Id
+    private String name;
+
+    /**
+     * Should this resource enforce the mandatory constraints?
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer enforceMandatoryCondition;
+
+    /**
+     * The resource type is identified by the associated connector.
+     */
+    @ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.MERGE })
+    @NotNull
+    private JPAConnInstance connector;
+
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "resource")
+    private List<JPAProvision> provisions = new ArrayList<>();
+
+    /**
+     * Is this resource primary, for propagations?
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer propagationPrimary;
+
+    /**
+     * Priority index for propagation ordering.
+     */
+    @Column(nullable = false)
+    private Integer propagationPriority;
+
+    /**
+     * Generate random password for propagation, if not provided?
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer randomPwdIfNotProvided;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private PropagationMode propagationMode;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private TraceLevel createTraceLevel;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private TraceLevel updateTraceLevel;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private TraceLevel deleteTraceLevel;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private TraceLevel syncTraceLevel;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAPasswordPolicy passwordPolicy;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAAccountPolicy accountPolicy;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPASyncPolicy syncPolicy;
+
+    /**
+     * Configuration properties that are overridden from the connector instance.
+     */
+    @Lob
+    private String jsonConf;
+
+    /**
+     * (Optional) classes for PropagationAction.
+     */
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "actionClassName")
+    @CollectionTable(name = "ExternalResource_PropActions",
+            joinColumns =
+            @JoinColumn(name = "resource_name", referencedColumnName = "name"))
+    private List<String> propagationActionsClassNames = new ArrayList<>();
+
+    /**
+     * Default constructor.
+     */
+    public JPAExternalResource() {
+        super();
+
+        enforceMandatoryCondition = getBooleanAsInteger(false);
+        propagationPrimary = 0;
+        propagationPriority = 0;
+        randomPwdIfNotProvided = 0;
+        propagationMode = PropagationMode.TWO_PHASES;
+
+        createTraceLevel = TraceLevel.FAILURES;
+        updateTraceLevel = TraceLevel.FAILURES;
+        deleteTraceLevel = TraceLevel.FAILURES;
+        syncTraceLevel = TraceLevel.FAILURES;
+    }
+
+    @Override
+    public boolean isEnforceMandatoryCondition() {
+        return isBooleanAsInteger(enforceMandatoryCondition);
+    }
+
+    @Override
+    public void setEnforceMandatoryCondition(final boolean enforceMandatoryCondition) {
+        this.enforceMandatoryCondition = getBooleanAsInteger(enforceMandatoryCondition);
+    }
+
+    @Override
+    public ConnInstance getConnector() {
+        return connector;
+    }
+
+    @Override
+    public void setConnector(final ConnInstance connector) {
+        checkType(connector, JPAConnInstance.class);
+        this.connector = (JPAConnInstance) connector;
+    }
+
+    @Override
+    public boolean add(final Provision provision) {
+        checkType(provision, JPAProvision.class);
+        return this.provisions.add((JPAProvision) provision);
+    }
+
+    @Override
+    public boolean remove(final Provision provision) {
+        checkType(provision, JPAProvision.class);
+        return this.provisions.remove((JPAProvision) provision);
+    }
+
+    @Override
+    public Provision getProvision(final ObjectClass objectClass) {
+        return CollectionUtils.find(provisions, new Predicate<Provision>() {
+
+            @Override
+            public boolean evaluate(final Provision provision) {
+                return provision.getObjectClass().equals(objectClass);
+            }
+        });
+    }
+
+    @Override
+    public Provision getProvision(final AnyType anyType) {
+        return CollectionUtils.find(provisions, new Predicate<Provision>() {
+
+            @Override
+            public boolean evaluate(final Provision provision) {
+                return provision.getAnyType().equals(anyType);
+            }
+        });
+    }
+
+    @Override
+    public List<? extends Provision> getProvisions() {
+        return provisions;
+    }
+
+    @Override
+    public boolean isPropagationPrimary() {
+        return isBooleanAsInteger(propagationPrimary);
+    }
+
+    @Override
+    public void setPropagationPrimary(final boolean propagationPrimary) {
+        this.propagationPrimary = getBooleanAsInteger(propagationPrimary);
+    }
+
+    @Override
+    public Integer getPropagationPriority() {
+        return propagationPriority;
+    }
+
+    @Override
+    public void setPropagationPriority(final Integer propagationPriority) {
+        if (propagationPriority != null) {
+            this.propagationPriority = propagationPriority;
+        }
+    }
+
+    @Override
+    public boolean isRandomPwdIfNotProvided() {
+        return isBooleanAsInteger(randomPwdIfNotProvided);
+    }
+
+    @Override
+    public void setRandomPwdIfNotProvided(final boolean randomPwdIfNotProvided) {
+        this.randomPwdIfNotProvided = getBooleanAsInteger(randomPwdIfNotProvided);
+    }
+
+    @Override
+    public PropagationMode getPropagationMode() {
+        return propagationMode;
+    }
+
+    @Override
+    public void setPropagationMode(final PropagationMode propagationMode) {
+        this.propagationMode = propagationMode;
+    }
+
+    @Override
+    public String getKey() {
+        return name;
+    }
+
+    @Override
+    public void setKey(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public TraceLevel getCreateTraceLevel() {
+        return createTraceLevel;
+    }
+
+    @Override
+    public void setCreateTraceLevel(final TraceLevel createTraceLevel) {
+        this.createTraceLevel = createTraceLevel;
+    }
+
+    @Override
+
+    public TraceLevel getDeleteTraceLevel() {
+        return deleteTraceLevel;
+    }
+
+    @Override
+    public void setDeleteTraceLevel(final TraceLevel deleteTraceLevel) {
+        this.deleteTraceLevel = deleteTraceLevel;
+    }
+
+    @Override
+    public TraceLevel getUpdateTraceLevel() {
+        return updateTraceLevel;
+    }
+
+    @Override
+    public void setUpdateTraceLevel(final TraceLevel updateTraceLevel) {
+        this.updateTraceLevel = updateTraceLevel;
+    }
+
+    @Override
+    public TraceLevel getSyncTraceLevel() {
+        return syncTraceLevel;
+    }
+
+    @Override
+    public void setSyncTraceLevel(final TraceLevel syncTraceLevel) {
+        this.syncTraceLevel = syncTraceLevel;
+    }
+
+    @Override
+    public AccountPolicy getAccountPolicy() {
+        return accountPolicy;
+    }
+
+    @Override
+    public void setAccountPolicy(final AccountPolicy accountPolicy) {
+        checkType(accountPolicy, JPAAccountPolicy.class);
+        this.accountPolicy = (JPAAccountPolicy) accountPolicy;
+    }
+
+    @Override
+    public PasswordPolicy getPasswordPolicy() {
+        return passwordPolicy;
+    }
+
+    @Override
+    public void setPasswordPolicy(final PasswordPolicy passwordPolicy) {
+        checkType(passwordPolicy, JPAPasswordPolicy.class);
+        this.passwordPolicy = (JPAPasswordPolicy) passwordPolicy;
+    }
+
+    @Override
+    public SyncPolicy getSyncPolicy() {
+        return syncPolicy;
+    }
+
+    @Override
+    public void setSyncPolicy(final SyncPolicy syncPolicy) {
+        checkType(syncPolicy, JPASyncPolicy.class);
+        this.syncPolicy = (JPASyncPolicy) syncPolicy;
+    }
+
+    @Override
+    public Set<ConnConfProperty> getConnInstanceConfiguration() {
+        Set<ConnConfProperty> configuration = new HashSet<>();
+        if (!StringUtils.isBlank(jsonConf)) {
+            CollectionUtils.addAll(configuration, POJOHelper.deserialize(jsonConf, ConnConfProperty[].class));
+        }
+
+        return configuration;
+    }
+
+    @Override
+    public void setConnInstanceConfiguration(final Set<ConnConfProperty> properties) {
+        jsonConf = POJOHelper.serialize(new HashSet<>(properties));
+    }
+
+    @Override
+    public List<String> getPropagationActionsClassNames() {
+        return propagationActionsClassNames;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
new file mode 100644
index 0000000..227f0fd
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
@@ -0,0 +1,142 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Cacheable;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+
+@Entity
+@Table(name = JPAMapping.TABLE)
+@Cacheable
+public class JPAMapping extends AbstractEntity<Long> implements Mapping {
+
+    private static final long serialVersionUID = 4316047254916259158L;
+
+    public static final String TABLE = "Mapping";
+
+    @Id
+    private Long id;
+
+    @OneToOne
+    private JPAProvision provision;
+
+    /**
+     * Attribute mappings.
+     */
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "mapping")
+    private List<JPAMappingItem> items = new ArrayList<>();
+
+    /**
+     * A JEXL expression for determining how to find the connector object link in external resource's space.
+     */
+    private String connObjectLink;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Provision getProvision() {
+        return provision;
+    }
+
+    @Override
+    public void setProvision(final Provision provision) {
+        checkType(provision, JPAProvision.class);
+        this.provision = (JPAProvision) provision;
+    }
+
+    @Override
+    public void setConnObjectKeyItem(final MappingItem item) {
+        checkType(item, JPAMappingItem.class);
+        this.addConnObjectKeyItem((JPAMappingItem) item);
+    }
+
+    @Override
+    public List<? extends MappingItem> getItems() {
+        return items;
+    }
+
+    @Override
+    public boolean add(final MappingItem item) {
+        checkType(item, JPAMappingItem.class);
+        return items.contains((JPAMappingItem) item) || items.add((JPAMappingItem) item);
+    }
+
+    @Override
+    public boolean remove(final MappingItem item) {
+        checkType(item, JPAMappingItem.class);
+        return items.remove((JPAMappingItem) item);
+    }
+
+    @Override
+    public MappingItem getConnObjectKeyItem() {
+        return CollectionUtils.find(getItems(), new Predicate<MappingItem>() {
+
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return item.isConnObjectKey();
+            }
+        });
+    }
+
+    protected boolean addConnObjectKeyItem(final MappingItem connObjectKeyItem) {
+        if (IntMappingType.UserVirtualSchema == connObjectKeyItem.getIntMappingType()
+                || IntMappingType.GroupVirtualSchema == connObjectKeyItem.getIntMappingType()
+                || IntMappingType.AnyVirtualSchema == connObjectKeyItem.getIntMappingType()
+                || IntMappingType.Password == connObjectKeyItem.getIntMappingType()) {
+
+            throw new IllegalArgumentException("Virtual attributes cannot be set as ConnObjectKey");
+        }
+        if (IntMappingType.Password == connObjectKeyItem.getIntMappingType()) {
+            throw new IllegalArgumentException("Password attributes cannot be set as ConnObjectKey");
+        }
+
+        connObjectKeyItem.setExtAttrName(connObjectKeyItem.getExtAttrName());
+        connObjectKeyItem.setConnObjectKey(true);
+
+        return this.add(connObjectKeyItem);
+    }
+
+    @Override
+    public String getConnObjectLink() {
+        return connObjectLink;
+    }
+
+    @Override
+    public void setConnObjectLink(final String connObjectLink) {
+        this.connObjectLink = connObjectLink;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
new file mode 100644
index 0000000..d9c1af2
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
@@ -0,0 +1,217 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.resource;
+
+import javax.persistence.Basic;
+import javax.persistence.Cacheable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+
+@Entity
+@Table(name = JPAMappingItem.TABLE)
+@Cacheable
+public class JPAMappingItem extends AbstractEntity<Long> implements MappingItem {
+
+    private static final long serialVersionUID = 7383601853619332424L;
+
+    public static final String TABLE = "MappingItem";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPAMapping mapping;
+
+    @Column(nullable = true)
+    private String intAttrName;
+
+    @Column(nullable = false)
+    @Enumerated(EnumType.STRING)
+    private IntMappingType intMappingType;
+
+    /**
+     * Target resource's field to be mapped.
+     */
+    @Column(nullable = true)
+    private String extAttrName;
+
+    /**
+     * Specify if the mapped target resource's field is nullable.
+     */
+    @Column(nullable = false)
+    private String mandatoryCondition;
+
+    /**
+     * Specify if the mapped target resource's field is the key.
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer connObjectKey;
+
+    /**
+     * Specify if the mapped target resource's field is the password.
+     */
+    @Column(nullable = false)
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer password;
+
+    @Column(nullable = false)
+    @Enumerated(EnumType.STRING)
+    private MappingPurpose purpose;
+
+    public JPAMappingItem() {
+        super();
+
+        mandatoryCondition = Boolean.FALSE.toString();
+
+        connObjectKey = getBooleanAsInteger(false);
+        password = getBooleanAsInteger(false);
+    }
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Mapping getMapping() {
+        return mapping;
+    }
+
+    @Override
+    public void setMapping(final Mapping mapping) {
+        checkType(mapping, JPAMapping.class);
+        this.mapping = (JPAMapping) mapping;
+    }
+
+    @Override
+    public String getExtAttrName() {
+        return extAttrName;
+    }
+
+    @Override
+    public void setExtAttrName(final String extAttrName) {
+        this.extAttrName = extAttrName;
+    }
+
+    @Override
+    public String getMandatoryCondition() {
+        return mandatoryCondition;
+    }
+
+    @Override
+    public void setMandatoryCondition(final String mandatoryCondition) {
+        this.mandatoryCondition = mandatoryCondition;
+    }
+
+    @Override
+    public String getIntAttrName() {
+        final String name;
+
+        switch (getIntMappingType()) {
+            case UserId:
+            case GroupId:
+            case AnyId:
+                name = "id";
+                break;
+
+            case Username:
+                name = "username";
+                break;
+
+            case Password:
+                name = "password";
+                break;
+
+            case GroupName:
+                name = "groupName";
+                break;
+
+            case GroupOwnerSchema:
+                name = "groupOwnerSchema";
+                break;
+
+            default:
+                name = intAttrName;
+        }
+
+        return name;
+    }
+
+    @Override
+    public void setIntAttrName(final String intAttrName) {
+        this.intAttrName = intAttrName;
+    }
+
+    @Override
+    public IntMappingType getIntMappingType() {
+        return intMappingType;
+    }
+
+    @Override
+    public void setIntMappingType(final IntMappingType intMappingType) {
+        this.intMappingType = intMappingType;
+    }
+
+    @Override
+    public boolean isConnObjectKey() {
+        return isBooleanAsInteger(connObjectKey);
+    }
+
+    @Override
+    public void setConnObjectKey(final boolean connObjectKey) {
+        this.connObjectKey = getBooleanAsInteger(connObjectKey);
+    }
+
+    @Override
+    public boolean isPassword() {
+        return isBooleanAsInteger(password);
+    }
+
+    @Override
+    public void setPassword(final boolean password) {
+        this.password = getBooleanAsInteger(password);
+    }
+
+    @Override
+    public MappingPurpose getPurpose() {
+        return purpose;
+    }
+
+    @Override
+    public void setPurpose(final MappingPurpose purpose) {
+        this.purpose = purpose;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
new file mode 100644
index 0000000..273b79d
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
@@ -0,0 +1,133 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.resource;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.SyncToken;
+
+@Entity
+@Table(name = JPAProvision.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "resource_name", "anyType_name" }))
+public class JPAProvision extends AbstractEntity<Long> implements Provision {
+
+    private static final long serialVersionUID = -1807889487945989443L;
+
+    public static final String TABLE = "Provision";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPAExternalResource resource;
+
+    @ManyToOne
+    private JPAAnyType anyType;
+
+    private String objectClass;
+
+    @Lob
+    private String serializedSyncToken;
+
+    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "provision")
+    private JPAMapping mapping;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public ExternalResource getResource() {
+        return resource;
+    }
+
+    @Override
+    public void setResource(final ExternalResource resource) {
+        checkType(resource, JPAExternalResource.class);
+        this.resource = (JPAExternalResource) resource;
+    }
+
+    @Override
+    public AnyType getAnyType() {
+        return anyType;
+    }
+
+    @Override
+    public void setAnyType(final AnyType anyType) {
+        checkType(anyType, JPAAnyType.class);
+        this.anyType = (JPAAnyType) anyType;
+    }
+
+    @Override
+    public ObjectClass getObjectClass() {
+        return objectClass == null
+                ? null
+                : new ObjectClass(objectClass);
+    }
+
+    @Override
+    public void setObjectClass(final ObjectClass objectClass) {
+        this.objectClass = objectClass == null ? null : objectClass.getObjectClassValue();
+    }
+
+    @Override
+    public SyncToken getSyncToken() {
+        return serializedSyncToken == null
+                ? null
+                : POJOHelper.deserialize(serializedSyncToken, SyncToken.class);
+    }
+
+    @Override
+    public String getSerializedSyncToken() {
+        return this.serializedSyncToken;
+    }
+
+    @Override
+    public void setSyncToken(final SyncToken syncToken) {
+        this.serializedSyncToken = syncToken == null ? null : POJOHelper.serialize(syncToken);
+    }
+
+    @Override
+    public Mapping getMapping() {
+        return mapping;
+    }
+
+    @Override
+    public void setMapping(final Mapping mapping) {
+        checkType(mapping, JPAMapping.class);
+        this.mapping = (JPAMapping) mapping;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
index 821bbe4..9723f1d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
@@ -29,10 +29,10 @@ import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
 import org.apache.syncope.core.persistence.jpa.validation.entity.ProvisioningTaskCheck;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 
 @MappedSuperclass
 @ProvisioningTaskCheck

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyFilter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyFilter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyFilter.java
new file mode 100644
index 0000000..93e10e3
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyFilter.java
@@ -0,0 +1,91 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.task;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+
+@Entity
+@Table(name = JPAAnyFilter.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "pushTask_id", "anyType_name" }))
+public class JPAAnyFilter extends AbstractEntity<Long> implements AnyFilter {
+
+    private static final long serialVersionUID = 3517381731849788407L;
+
+    public static final String TABLE = "AnyFilter";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPAPushTask pushTask;
+
+    @ManyToOne
+    private JPAAnyType anyType;
+
+    @Lob
+    private String filter;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public PushTask getPushTask() {
+        return pushTask;
+    }
+
+    @Override
+    public void setPushTask(final PushTask syncTask) {
+        checkType(syncTask, JPAPushTask.class);
+        this.pushTask = (JPAPushTask) syncTask;
+    }
+
+    @Override
+    public AnyType getAnyType() {
+        return anyType;
+    }
+
+    @Override
+    public void setAnyType(final AnyType anyType) {
+        checkType(anyType, JPAAnyType.class);
+        this.anyType = (JPAAnyType) anyType;
+    }
+
+    @Override
+    public String get() {
+        return filter;
+    }
+
+    @Override
+    public void set(final String filter) {
+        this.filter = filter;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java
new file mode 100644
index 0000000..d90f605
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAAnyTemplate.java
@@ -0,0 +1,102 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.task;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+
+@Entity
+@Table(name = JPAAnyTemplate.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "syncTask_id", "anyType_name" }))
+public class JPAAnyTemplate extends AbstractEntity<Long> implements AnyTemplate {
+
+    private static final long serialVersionUID = 3517381731849788407L;
+
+    public static final String TABLE = "AnyTemplate";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPASyncTask syncTask;
+
+    @ManyToOne
+    private JPAAnyType anyType;
+
+    @Lob
+    private String template;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public SyncTask getSyncTask() {
+        return syncTask;
+    }
+
+    @Override
+    public void setSyncTask(final SyncTask syncTask) {
+        checkType(syncTask, JPASyncTask.class);
+        this.syncTask = (JPASyncTask) syncTask;
+    }
+
+    @Override
+    public AnyType getAnyType() {
+        return anyType;
+    }
+
+    @Override
+    public void setAnyType(final AnyType anyType) {
+        checkType(anyType, JPAAnyType.class);
+        this.anyType = (JPAAnyType) anyType;
+    }
+
+    @Override
+    public AnyTO get() {
+        return template == null
+                ? anyType == null
+                        ? null
+                        : new JPAAnyUtilsFactory().getInstance(anyType.getKind()).newAnyTO()
+                : POJOHelper.deserialize(template, AnyTO.class);
+    }
+
+    @Override
+    public void set(final AnyTO template) {
+        if (template == null) {
+            this.template = null;
+        } else {
+            this.template = POJOHelper.serialize(template);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
index b63bd10..be72e1e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
@@ -49,7 +49,7 @@ public class JPANotificationTask extends JPATask implements NotificationTask {
     @Column(name = "address")
     @CollectionTable(name = "NotificationTask_recipients",
             joinColumns =
-            @JoinColumn(name = "NotificationTask_id", referencedColumnName = "id"))
+            @JoinColumn(name = "notificationTask_id", referencedColumnName = "id"))
     private Set<String> recipients;
 
     @NotNull

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
index 90104a3..cffc4bf 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
@@ -28,14 +28,14 @@ import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationMode;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.jpa.validation.entity.PropagationTaskCheck;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.identityconnectors.framework.common.objects.Attribute;
 
@@ -62,14 +62,14 @@ public class JPAPropagationTask extends JPATask implements PropagationTask {
     private ResourceOperation propagationOperation;
 
     /**
-     * The accountId on the external resource.
+     * The connObjectKey on the external resource.
      */
-    private String accountId;
+    private String connObjectKey;
 
     /**
-     * The (optional) former accountId on the external resource.
+     * The (optional) former connObjectKey on the external resource.
      */
-    private String oldAccountId;
+    private String oldConnObjectKey;
 
     /**
      * Attributes to be propagated.
@@ -80,9 +80,9 @@ public class JPAPropagationTask extends JPATask implements PropagationTask {
     private String objectClassName;
 
     @Enumerated(EnumType.STRING)
-    private AttributableType subjectType;
+    private AnyTypeKind anyTypeKind;
 
-    private Long subjectId;
+    private Long anyKey;
 
     public JPAPropagationTask() {
         super();
@@ -96,23 +96,23 @@ public class JPAPropagationTask extends JPATask implements PropagationTask {
     private JPAExternalResource resource;
 
     @Override
-    public String getAccountId() {
-        return accountId;
+    public String getConnObjectKey() {
+        return connObjectKey;
     }
 
     @Override
-    public void setAccountId(final String accountId) {
-        this.accountId = accountId;
+    public void setConnObjectKey(final String connObjectKey) {
+        this.connObjectKey = connObjectKey;
     }
 
     @Override
-    public String getOldAccountId() {
-        return oldAccountId;
+    public String getOldConnObjectKey() {
+        return oldConnObjectKey;
     }
 
     @Override
-    public void setOldAccountId(final String oldAccountId) {
-        this.oldAccountId = oldAccountId;
+    public void setOldConnObjectKey(final String oldConnObjectKey) {
+        this.oldConnObjectKey = oldConnObjectKey;
     }
 
     @Override
@@ -176,22 +176,22 @@ public class JPAPropagationTask extends JPATask implements PropagationTask {
     }
 
     @Override
-    public AttributableType getSubjectType() {
-        return subjectType;
+    public AnyTypeKind getAnyTypeKind() {
+        return anyTypeKind;
     }
 
     @Override
-    public void setSubjectType(final AttributableType subjectType) {
-        this.subjectType = subjectType;
+    public void setAnyTypeKind(final AnyTypeKind anyTypeKind) {
+        this.anyTypeKind = anyTypeKind;
     }
 
     @Override
-    public Long getSubjectKey() {
-        return subjectId;
+    public Long getAnyKey() {
+        return anyKey;
     }
 
     @Override
-    public void setSubjectKey(final Long subjectKey) {
-        this.subjectId = subjectKey;
+    public void setAnyKey(final Long anyKey) {
+        this.anyKey = anyKey;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
index c627dd2..07e6f00 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.entity.task;
 
 import java.util.ArrayList;
 import java.util.List;
+import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.DiscriminatorValue;
@@ -27,7 +28,12 @@ import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.task.AnyFilter;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
 import org.apache.syncope.core.provisioning.api.job.PushJob;
 
@@ -41,12 +47,11 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
     @Column(name = "actionClassName")
     @CollectionTable(name = "PushTask_actionsClassNames",
             joinColumns =
-            @JoinColumn(name = "PushTask_id", referencedColumnName = "id"))
+            @JoinColumn(name = "pushTask_id", referencedColumnName = "id"))
     private List<String> actionsClassNames = new ArrayList<>();
 
-    private String userFilter;
-
-    private String groupFilter;
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "pushTask")
+    private List<JPAAnyFilter> filters = new ArrayList<>();
 
     /**
      * Default constructor.
@@ -61,22 +66,30 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
     }
 
     @Override
-    public String getUserFilter() {
-        return userFilter;
+    public boolean add(final AnyFilter filter) {
+        checkType(filter, JPAAnyFilter.class);
+        return this.filters.add((JPAAnyFilter) filter);
     }
 
     @Override
-    public void setUserFilter(final String filter) {
-        this.userFilter = filter;
+    public boolean remove(final AnyFilter filter) {
+        checkType(filter, JPAAnyFilter.class);
+        return this.filters.remove((JPAAnyFilter) filter);
     }
 
     @Override
-    public String getGroupFilter() {
-        return groupFilter;
+    public AnyFilter getFilter(final AnyType anyType) {
+        return CollectionUtils.find(filters, new Predicate<AnyFilter>() {
+
+            @Override
+            public boolean evaluate(final AnyFilter filter) {
+                return anyType != null && anyType.equals(filter.getAnyType());
+            }
+        });
     }
 
     @Override
-    public void setGroupFilter(final String filter) {
-        this.groupFilter = filter;
+    public List<? extends AnyFilter> getFilters() {
+        return filters;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
index f98074d..0106a65 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity.task;
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.Basic;
+import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
 import javax.persistence.DiscriminatorValue;
@@ -28,17 +29,18 @@ import javax.persistence.ElementCollection;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.JoinColumn;
-import javax.persistence.Lob;
 import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
-import org.apache.syncope.common.lib.to.GroupTO;
-import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplate;
 import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
 
 @Entity
@@ -54,14 +56,11 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     @Column(name = "actionClassName")
     @CollectionTable(name = "SyncTask_actionsClassNames",
             joinColumns =
-            @JoinColumn(name = "SyncTask_id", referencedColumnName = "id"))
+            @JoinColumn(name = "syncTask_id", referencedColumnName = "id"))
     private List<String> actionsClassNames = new ArrayList<>();
 
-    @Lob
-    private String userTemplate;
-
-    @Lob
-    private String groupTemplate;
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "syncTask")
+    private List<JPAAnyTemplate> templates = new ArrayList<>();
 
     @Basic
     @Min(0)
@@ -92,36 +91,41 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     }
 
     @Override
-    public UserTO getUserTemplate() {
-        return userTemplate == null
-                ? new UserTO()
-                : POJOHelper.deserialize(userTemplate, UserTO.class);
+    public boolean isFullReconciliation() {
+        return isBooleanAsInteger(fullReconciliation);
     }
 
     @Override
-    public void setUserTemplate(final UserTO userTemplate) {
-        this.userTemplate = POJOHelper.serialize(userTemplate);
+    public void setFullReconciliation(final boolean fullReconciliation) {
+        this.fullReconciliation = getBooleanAsInteger(fullReconciliation);
     }
 
     @Override
-    public GroupTO getGroupTemplate() {
-        return userTemplate == null
-                ? new GroupTO()
-                : POJOHelper.deserialize(groupTemplate, GroupTO.class);
+    public boolean add(final AnyTemplate template) {
+        checkType(template, JPAAnyTemplate.class);
+        return this.templates.add((JPAAnyTemplate) template);
     }
 
     @Override
-    public void setGroupTemplate(final GroupTO groupTemplate) {
-        this.groupTemplate = POJOHelper.serialize(groupTemplate);
+    public boolean remove(final AnyTemplate template) {
+        checkType(template, JPAAnyTemplate.class);
+        return this.templates.remove((JPAAnyTemplate) template);
     }
 
     @Override
-    public boolean isFullReconciliation() {
-        return isBooleanAsInteger(fullReconciliation);
+    public AnyTemplate getTemplate(final AnyType anyType) {
+        return CollectionUtils.find(templates, new Predicate<AnyTemplate>() {
+
+            @Override
+            public boolean evaluate(final AnyTemplate template) {
+                return anyType != null && anyType.equals(template.getAnyType());
+            }
+        });
     }
 
     @Override
-    public void setFullReconciliation(final boolean fullReconciliation) {
-        this.fullReconciliation = getBooleanAsInteger(fullReconciliation);
+    public List<? extends AnyTemplate> getTemplates() {
+        return templates;
     }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
new file mode 100644
index 0000000..00e85c4
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/AbstractUDynMembership.java
@@ -0,0 +1,50 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.user;
+
+import java.util.List;
+import javax.persistence.MappedSuperclass;
+import org.apache.syncope.core.persistence.api.entity.user.UDynMembership;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractDynMembership;
+
+@MappedSuperclass
+public abstract class AbstractUDynMembership extends AbstractDynMembership<User> implements UDynMembership {
+
+    private static final long serialVersionUID = 6296230283800203205L;
+
+    protected abstract List<JPAUser> internalGetUsers();
+
+    @Override
+    public boolean add(final User user) {
+        checkType(user, JPAUser.class);
+        return internalGetUsers().add((JPAUser) user);
+    }
+
+    @Override
+    public boolean remove(final User user) {
+        checkType(user, JPAUser.class);
+        return internalGetUsers().remove((JPAUser) user);
+    }
+
+    @Override
+    public List<? extends User> getMembers() {
+        return internalGetUsers();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPADynRoleMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPADynRoleMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPADynRoleMembership.java
new file mode 100644
index 0000000..f812b28
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPADynRoleMembership.java
@@ -0,0 +1,76 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.user;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
+import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.jpa.entity.JPARole;
+
+@Entity
+@Table(name = JPADynRoleMembership.TABLE)
+public class JPADynRoleMembership extends AbstractUDynMembership implements DynRoleMembership {
+
+    private static final long serialVersionUID = -7336814163949640354L;
+
+    public static final String TABLE = "DynRoleMembership";
+
+    @Id
+    private Long id;
+
+    @OneToOne
+    private JPARole role;
+
+    @ManyToMany
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "dynRoleMembership_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "user_id"))
+    private List<JPAUser> users = new ArrayList<>();
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    protected List<JPAUser> internalGetUsers() {
+        return users;
+    }
+
+    @Override
+    public Role getRole() {
+        return role;
+    }
+
+    @Override
+    public void setRole(final Role role) {
+        checkType(role, JPARole.class);
+        this.role = (JPARole) role;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
index b9cfb2c..90bee1b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
@@ -19,19 +19,15 @@
 package org.apache.syncope.core.persistence.jpa.entity.user;
 
 import javax.persistence.Entity;
-import javax.persistence.FetchType;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractDerAttr;
 
 @Entity
 @Table(name = JPAUDerAttr.TABLE)
-public class JPAUDerAttr extends AbstractDerAttr implements UDerAttr {
+public class JPAUDerAttr extends AbstractDerAttr<User> implements UDerAttr {
 
     private static final long serialVersionUID = 4723044452807292060L;
 
@@ -40,28 +36,15 @@ public class JPAUDerAttr extends AbstractDerAttr implements UDerAttr {
     @ManyToOne
     private JPAUser owner;
 
-    @ManyToOne(fetch = FetchType.EAGER)
-    private JPAUDerSchema derSchema;
-
     @Override
     public User getOwner() {
         return owner;
     }
 
     @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
+    public void setOwner(final User owner) {
         checkType(owner, JPAUser.class);
         this.owner = (JPAUser) owner;
     }
 
-    @Override
-    public UDerSchema getSchema() {
-        return derSchema;
-    }
-
-    @Override
-    public void setSchema(final DerSchema derSchema) {
-        checkType(derSchema, JPAUDerSchema.class);
-        this.derSchema = (JPAUDerSchema) derSchema;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java
deleted file mode 100644
index eb9ae93..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.apache.syncope.core.persistence.jpa.entity.user;
-
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractDerSchema;
-
-@Entity
-@Table(name = JPAUDerSchema.TABLE)
-public class JPAUDerSchema extends AbstractDerSchema implements UDerSchema {
-
-    private static final long serialVersionUID = 6244467775394201229L;
-
-    public static final String TABLE = "UDerSchema";
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java
new file mode 100644
index 0000000..ac150dc
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java
@@ -0,0 +1,76 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.user;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+
+@Entity
+@Table(name = JPAUDynGroupMembership.TABLE)
+public class JPAUDynGroupMembership extends AbstractUDynMembership implements UDynGroupMembership {
+
+    private static final long serialVersionUID = -7336814163949640354L;
+
+    public static final String TABLE = "UDynGroupMembership";
+
+    @Id
+    private Long id;
+
+    @OneToOne
+    private JPAGroup group;
+
+    @ManyToMany
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "uDynGroupMembership_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "user_id"))
+    private List<JPAUser> users = new ArrayList<>();
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    protected List<JPAUser> internalGetUsers() {
+        return users;
+    }
+
+    @Override
+    public Group getGroup() {
+        return group;
+    }
+
+    @Override
+    public void setGroup(final Group role) {
+        checkType(role, JPAGroup.class);
+        this.group = (JPAGroup) role;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java
deleted file mode 100644
index 86b349a..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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.apache.syncope.core.persistence.jpa.entity.user;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.CascadeType;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.Id;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.user.UMapping;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractMapping;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
-import org.identityconnectors.framework.common.objects.OperationalAttributes;
-
-@Entity
-@Table(name = JPAUMapping.TABLE)
-public class JPAUMapping extends AbstractMapping<UMappingItem> implements UMapping {
-
-    private static final long serialVersionUID = 4285801404504561073L;
-
-    public static final String TABLE = "UMapping";
-
-    @Id
-    private Long id;
-
-    /**
-     * Resource owning this mapping.
-     */
-    @OneToOne
-    private JPAExternalResource resource;
-
-    /**
-     * Attribute mappings.
-     */
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "mapping")
-    private List<JPAUMappingItem> items;
-
-    public JPAUMapping() {
-        super();
-
-        items = new ArrayList<>();
-    }
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public ExternalResource getResource() {
-        return resource;
-    }
-
-    @Override
-    public void setResource(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        this.resource = (JPAExternalResource) resource;
-    }
-
-    @Override
-    public void setAccountIdItem(final UMappingItem item) {
-        checkType(item, JPAUMappingItem.class);
-        this.addAccountIdItem((JPAUMappingItem) item);
-    }
-
-    @Override
-    public UMappingItem getPasswordItem() {
-        UMappingItem passwordItem = null;
-        for (MappingItem item : getItems()) {
-            if (item.isPassword()) {
-                passwordItem = (JPAUMappingItem) item;
-            }
-        }
-        return passwordItem;
-    }
-
-    @Override
-    public boolean setPasswordItem(final UMappingItem passwordItem) {
-        checkType(passwordItem, JPAUMappingItem.class);
-
-        passwordItem.setExtAttrName(OperationalAttributes.PASSWORD_NAME);
-        passwordItem.setPassword(true);
-        return this.addItem((JPAUMappingItem) passwordItem);
-    }
-
-    @Override
-    public List<? extends UMappingItem> getItems() {
-        return items;
-    }
-
-    @Override
-    public boolean addItem(final UMappingItem item) {
-        checkType(item, JPAUMappingItem.class);
-        return items.contains((JPAUMappingItem) item) || items.add((JPAUMappingItem) item);
-    }
-
-    @Override
-    public boolean removeItem(final UMappingItem item) {
-        checkType(item, JPAUMappingItem.class);
-        return items.remove((JPAUMappingItem) item);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java
deleted file mode 100644
index 14b94f0..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.apache.syncope.core.persistence.jpa.entity.user;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractMappingItem;
-
-@Entity
-@Table(name = JPAUMappingItem.TABLE)
-public class JPAUMappingItem extends AbstractMappingItem implements UMappingItem {
-
-    private static final long serialVersionUID = 2936446317887310833L;
-
-    public static final String TABLE = "UMappingItem";
-
-    @Id
-    private Long id;
-
-    @ManyToOne
-    private JPAUMapping mapping;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
-    public Mapping<UMappingItem> getMapping() {
-        return mapping;
-    }
-
-    @Override
-    public void setMapping(final Mapping<?> mapping) {
-        checkType(mapping, JPAUMapping.class);
-        this.mapping = (JPAUMapping) mapping;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java
new file mode 100644
index 0000000..dd79434
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java
@@ -0,0 +1,77 @@
+/*
+ * 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.apache.syncope.core.persistence.jpa.entity.user;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
+import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
+
+@Entity
+@Table(name = JPAUMembership.TABLE)
+public class JPAUMembership extends AbstractEntity<Long> implements UMembership {
+
+    private static final long serialVersionUID = -14584450896965100L;
+
+    public static final String TABLE = "UMembership";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    @Column(name = "user_id")
+    private JPAUser leftEnd;
+
+    @ManyToOne
+    @Column(name = "group_id")
+    private JPAGroup rightEnd;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public JPAUser getLeftEnd() {
+        return leftEnd;
+    }
+
+    @Override
+    public void setLeftEnd(final User leftEnd) {
+        checkType(leftEnd, JPAUser.class);
+        this.leftEnd = (JPAUser) leftEnd;
+    }
+
+    @Override
+    public JPAGroup getRightEnd() {
+        return rightEnd;
+    }
+
+    @Override
+    public void setRightEnd(final Group rightEnd) {
+        checkType(rightEnd, JPAGroup.class);
+        this.rightEnd = (JPAGroup) rightEnd;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
index 8c2e06a..56898d4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
@@ -24,26 +24,22 @@ import javax.persistence.CascadeType;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
-import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.validation.Valid;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
-import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
 
 @Entity
 @Table(name = JPAUPlainAttr.TABLE)
-public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr {
+public class JPAUPlainAttr extends AbstractPlainAttr<User> implements UPlainAttr {
 
     private static final long serialVersionUID = 6333601983691157406L;
 
@@ -62,18 +58,11 @@ public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr {
     private JPAUser owner;
 
     /**
-     * The schema of this attribute.
-     */
-    @ManyToOne(fetch = FetchType.EAGER)
-    @JoinColumn(name = "schema_name")
-    private JPAUPlainSchema schema;
-
-    /**
      * Values of this attribute (if schema is not UNIQUE).
      */
     @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
     @Valid
-    private List<JPAUPlainAttrValue> values;
+    private List<JPAUPlainAttrValue> values = new ArrayList<>();
 
     /**
      * Value of this attribute (if schema is UNIQUE).
@@ -82,14 +71,6 @@ public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr {
     @Valid
     private JPAUPlainAttrUniqueValue uniqueValue;
 
-    /**
-     * Default constructor.
-     */
-    public JPAUPlainAttr() {
-        super();
-        values = new ArrayList<>();
-    }
-
     @Override
     public Long getKey() {
         return id;
@@ -101,30 +82,19 @@ public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr {
     }
 
     @Override
-    public void setOwner(final Attributable<?, ?, ?> owner) {
+    public void setOwner(final User owner) {
         checkType(owner, JPAUser.class);
         this.owner = (JPAUser) owner;
     }
 
     @Override
-    public UPlainSchema getSchema() {
-        return schema;
-    }
-
-    @Override
-    public void setSchema(final PlainSchema schema) {
-        checkType(schema, JPAUPlainSchema.class);
-        this.schema = (JPAUPlainSchema) schema;
-    }
-
-    @Override
-    protected boolean addValue(final PlainAttrValue attrValue) {
+    protected boolean addForMultiValue(final PlainAttrValue attrValue) {
         checkType(attrValue, JPAUPlainAttrValue.class);
         return values.add((JPAUPlainAttrValue) attrValue);
     }
 
     @Override
-    public boolean removeValue(final PlainAttrValue attrValue) {
+    public boolean remove(final PlainAttrValue attrValue) {
         checkType(attrValue, JPAUPlainAttrValue.class);
         return values.remove((JPAUPlainAttrValue) attrValue);
     }


Mime
View raw message