You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/01/12 17:32:06 UTC
[27/52] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Unit
tests all in
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAMembershipDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAMembershipDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAMembershipDAO.java
new file mode 100644
index 0000000..0e9d6ad
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAMembershipDAO.java
@@ -0,0 +1,103 @@
+/*
+ * 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.server.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.server.persistence.api.dao.MembershipDAO;
+import org.apache.syncope.server.persistence.api.dao.NotFoundException;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.membership.Membership;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMembership;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAMembershipDAO extends AbstractDAO<Membership, Long> implements MembershipDAO {
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ public Membership find(final Long key) {
+ return entityManager.find(JPAMembership.class, key);
+ }
+
+ @Override
+ public Membership find(final User user, final Role role) {
+ Query query = entityManager.createQuery(
+ "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e WHERE e.user = :user AND e.role = :role");
+ query.setParameter("user", user);
+ query.setParameter("role", role);
+
+ Membership result = null;
+
+ try {
+ result = (Membership) query.getSingleResult();
+ } catch (NoResultException e) {
+ LOG.debug("No membership was found for user {} and role {}", user, role, e);
+ }
+
+ return result;
+ }
+
+ @Override
+ public List<Membership> findAll() {
+ TypedQuery<Membership> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e", Membership.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public Membership save(final Membership membership) {
+ return entityManager.merge(membership);
+ }
+
+ @Override
+ public void delete(final Long key) {
+ Membership membership = find(key);
+ if (membership == null) {
+ return;
+ }
+
+ membership.getUser().removeMembership(membership);
+ userDAO.save(membership.getUser());
+
+ entityManager.remove(membership);
+ }
+
+ @Override
+ public Membership authFetch(final Long key) {
+ if (key == null) {
+ throw new NotFoundException("Null membership key");
+ }
+
+ Membership membership = find(key);
+ if (membership == null) {
+ throw new NotFoundException("Membership " + key);
+ }
+
+ return membership;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPANotificationDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPANotificationDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPANotificationDAO.java
new file mode 100644
index 0000000..7023191
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPANotificationDAO.java
@@ -0,0 +1,53 @@
+/*
+ * 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.server.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.server.persistence.api.dao.NotificationDAO;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.entity.Notification;
+import org.apache.syncope.server.persistence.jpa.entity.JPANotification;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPANotificationDAO extends AbstractDAO<Notification, Long> implements NotificationDAO {
+
+ @Override
+ public Notification find(final Long key) {
+ return entityManager.find(JPANotification.class, key);
+ }
+
+ @Override
+ public List<Notification> findAll() {
+ TypedQuery<Notification> query = entityManager.createQuery(
+ "SELECT e FROM " + JPANotification.class.getSimpleName() + " e", Notification.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public Notification save(final Notification notification) throws InvalidEntityException {
+ return entityManager.merge(notification);
+ }
+
+ @Override
+ public void delete(final Long key) {
+ entityManager.remove(find(key));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainAttrDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainAttrDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainAttrDAO.java
new file mode 100644
index 0000000..51d76e7
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainAttrDAO.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.server.persistence.jpa.dao;
+
+import org.apache.syncope.server.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.server.persistence.api.entity.Attributable;
+import org.apache.syncope.server.persistence.api.entity.PlainAttr;
+import org.apache.syncope.server.persistence.api.entity.conf.CPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractPlainAttr;
+import org.apache.syncope.server.persistence.jpa.entity.conf.JPACPlainAttr;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttr;
+import org.apache.syncope.server.persistence.jpa.entity.role.JPARPlainAttr;
+import org.apache.syncope.server.persistence.jpa.entity.user.JPAUPlainAttr;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr, Long> implements PlainAttrDAO {
+
+ public <T extends PlainAttr> Class<? extends AbstractPlainAttr> getJPAEntityReference(
+ final Class<T> reference) {
+
+ return CPlainAttr.class.isAssignableFrom(reference)
+ ? JPACPlainAttr.class
+ : RPlainAttr.class.isAssignableFrom(reference)
+ ? JPARPlainAttr.class
+ : MPlainAttr.class.isAssignableFrom(reference)
+ ? JPAMPlainAttr.class
+ : UPlainAttr.class.isAssignableFrom(reference)
+ ? JPAUPlainAttr.class
+ : null;
+ }
+
+ @Override
+ public <T extends PlainAttr> T find(final Long key, final Class<T> reference) {
+ return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+ }
+
+ @Override
+ public <T extends PlainAttr> void delete(final Long key, final Class<T> reference) {
+ T attribute = find(key, reference);
+ if (attribute == null) {
+ return;
+ }
+
+ delete(attribute);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T extends PlainAttr> void delete(final T plainAttr) {
+ if (plainAttr.getOwner() != null) {
+ ((Attributable<T, ?, ?>) plainAttr.getOwner()).removePlainAttr(plainAttr);
+ }
+
+ entityManager.remove(plainAttr);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainAttrValueDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainAttrValueDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainAttrValueDAO.java
new file mode 100644
index 0000000..d93ace3
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainAttrValueDAO.java
@@ -0,0 +1,104 @@
+/*
+ * 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.server.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.server.persistence.api.dao.PlainAttrValueDAO;
+import org.apache.syncope.server.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.server.persistence.api.entity.conf.CPlainAttrUniqueValue;
+import org.apache.syncope.server.persistence.api.entity.conf.CPlainAttrValue;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttrUniqueValue;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttrValue;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttrUniqueValue;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttrValue;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainAttrUniqueValue;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainAttrValue;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractPlainAttrValue;
+import org.apache.syncope.server.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue;
+import org.apache.syncope.server.persistence.jpa.entity.conf.JPACPlainAttrValue;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttrValue;
+import org.apache.syncope.server.persistence.jpa.entity.role.JPARPlainAttrUniqueValue;
+import org.apache.syncope.server.persistence.jpa.entity.role.JPARPlainAttrValue;
+import org.apache.syncope.server.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue;
+import org.apache.syncope.server.persistence.jpa.entity.user.JPAUPlainAttrValue;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> implements PlainAttrValueDAO {
+
+ private <T extends PlainAttrValue> Class<? extends AbstractPlainAttrValue> getJPAEntityReference(
+ final Class<T> reference) {
+
+ return reference.equals(CPlainAttrValue.class)
+ ? JPACPlainAttrValue.class
+ : reference.equals(CPlainAttrUniqueValue.class)
+ ? JPACPlainAttrUniqueValue.class
+ : reference.equals(RPlainAttrValue.class)
+ ? JPARPlainAttrValue.class
+ : reference.equals(RPlainAttrUniqueValue.class)
+ ? JPARPlainAttrUniqueValue.class
+ : reference.equals(MPlainAttrValue.class)
+ ? JPAMPlainAttrValue.class
+ : reference.equals(MPlainAttrUniqueValue.class)
+ ? JPAMPlainAttrUniqueValue.class
+ : reference.equals(UPlainAttrValue.class)
+ ? JPAUPlainAttrValue.class
+ : reference.equals(UPlainAttrUniqueValue.class)
+ ? JPAUPlainAttrUniqueValue.class
+ : null;
+ }
+
+ @Override
+ public <T extends PlainAttrValue> T find(final Long key, final Class<T> reference) {
+ return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+ }
+
+ @Override
+ public <T extends PlainAttrValue> List<T> findAll(final Class<T> reference) {
+ TypedQuery<T> query = entityManager.createQuery(
+ "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
+ return query.getResultList();
+ }
+
+ @Override
+ public <T extends PlainAttrValue> T save(final T attributeValue) {
+ return entityManager.merge(attributeValue);
+ }
+
+ @Override
+ public <T extends PlainAttrValue> void delete(final Long id, final Class<T> reference) {
+ T attributeValue = find(id, reference);
+ if (attributeValue == null) {
+ return;
+ }
+
+ delete(attributeValue);
+ }
+
+ @Override
+ public <T extends PlainAttrValue> void delete(final T attrValue) {
+ if (attrValue.getAttr() != null) {
+ attrValue.getAttr().removeValue(attrValue);
+ }
+
+ entityManager.remove(attrValue);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainSchemaDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainSchemaDAO.java
new file mode 100644
index 0000000..c9aa77a
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPlainSchemaDAO.java
@@ -0,0 +1,141 @@
+/*
+ * 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.server.persistence.jpa.dao;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.server.persistence.api.dao.AttrTemplateDAO;
+import org.apache.syncope.server.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.server.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.server.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.server.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.server.persistence.api.entity.PlainAttr;
+import org.apache.syncope.server.persistence.api.entity.PlainSchema;
+import org.apache.syncope.server.persistence.api.entity.conf.CPlainSchema;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainSchema;
+import org.apache.syncope.server.persistence.api.entity.role.RMappingItem;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainSchema;
+import org.apache.syncope.server.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractPlainSchema;
+import org.apache.syncope.server.persistence.jpa.entity.conf.JPACPlainSchema;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainSchema;
+import org.apache.syncope.server.persistence.jpa.entity.role.JPARPlainSchema;
+import org.apache.syncope.server.persistence.jpa.entity.user.JPAUPlainSchema;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implements PlainSchemaDAO {
+
+ @Autowired
+ private PlainAttrDAO attrDAO;
+
+ @Autowired
+ private AttrTemplateDAO<PlainSchema> attrTemplateDAO;
+
+ @Autowired
+ private ExternalResourceDAO resourceDAO;
+
+ private <T extends PlainSchema> Class<? extends AbstractPlainSchema> getJPAEntityReference(
+ final Class<T> reference) {
+
+ return CPlainSchema.class.isAssignableFrom(reference)
+ ? JPACPlainSchema.class
+ : RPlainSchema.class.isAssignableFrom(reference)
+ ? JPARPlainSchema.class
+ : MPlainSchema.class.isAssignableFrom(reference)
+ ? JPAMPlainSchema.class
+ : UPlainSchema.class.isAssignableFrom(reference)
+ ? JPAUPlainSchema.class
+ : null;
+ }
+
+ @Override
+ public <T extends PlainSchema> T find(final String key, final Class<T> reference) {
+ return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+ }
+
+ @Override
+ public <T extends PlainSchema> List<T> findAll(final Class<T> reference) {
+ TypedQuery<T> query = entityManager.createQuery(
+ "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
+ return query.getResultList();
+ }
+
+ @Override
+ public <T extends PlainAttr> List<T> findAttrs(final PlainSchema schema, final Class<T> reference) {
+ final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+ append(((JPAPlainAttrDAO) attrDAO).getJPAEntityReference(reference).getSimpleName()).
+ append(" e WHERE e.");
+ if (RPlainAttr.class.isAssignableFrom(reference) || MPlainAttr.class.isAssignableFrom(reference)) {
+ queryString.append("template.");
+ }
+ queryString.append("schema=:schema");
+
+ TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+ query.setParameter("schema", schema);
+
+ return query.getResultList();
+ }
+
+ @Override
+ public <T extends PlainSchema> T save(final T schema) {
+ return entityManager.merge(schema);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void delete(final String key, final AttributableUtil attributableUtil) {
+ PlainSchema schema = find(key, attributableUtil.plainSchemaClass());
+ if (schema == null) {
+ return;
+ }
+
+ final Set<Long> attrIds = new HashSet<>();
+ for (PlainAttr attr : findAttrs(schema, attributableUtil.plainAttrClass())) {
+ attrIds.add(attr.getKey());
+ }
+ for (Long attrId : attrIds) {
+ attrDAO.delete(attrId, attributableUtil.plainAttrClass());
+ }
+
+ if (attributableUtil.getType() == AttributableType.ROLE
+ || attributableUtil.getType() == AttributableType.MEMBERSHIP) {
+
+ for (Iterator<Number> it = attrTemplateDAO.
+ findBySchemaName(schema.getKey(), attributableUtil.plainAttrTemplateClass()).iterator();
+ it.hasNext();) {
+
+ attrTemplateDAO.delete(it.next().longValue(), attributableUtil.plainAttrTemplateClass());
+ }
+ }
+
+ resourceDAO.deleteMapping(key, attributableUtil.intMappingType(), UMappingItem.class);
+ resourceDAO.deleteMapping(key, attributableUtil.intMappingType(), RMappingItem.class);
+
+ entityManager.remove(schema);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPolicyDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPolicyDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPolicyDAO.java
new file mode 100644
index 0000000..e0543fe
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAPolicyDAO.java
@@ -0,0 +1,150 @@
+/*
+ * 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.server.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.server.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.server.persistence.api.entity.ExternalResource;
+import org.apache.syncope.server.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.server.persistence.api.entity.Policy;
+import org.apache.syncope.server.persistence.api.entity.SyncPolicy;
+import org.apache.syncope.server.persistence.jpa.entity.JPAPolicy;
+import org.apache.syncope.server.persistence.jpa.entity.JPAAccountPolicy;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAPolicyDAO extends AbstractDAO<Policy, Long> implements PolicyDAO {
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T extends Policy> T find(final Long key) {
+ final Query query = entityManager.createQuery(
+ "SELECT e FROM " + JPAPolicy.class.getSimpleName() + " e WHERE e.id=:id");
+ query.setParameter("id", key);
+
+ List<T> result = query.getResultList();
+ return result.isEmpty()
+ ? null
+ : result.iterator().next();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T extends Policy> List<T> find(final PolicyType type) {
+ final Query query = entityManager.createQuery(
+ "SELECT e FROM " + JPAPolicy.class.getSimpleName() + " e WHERE e.type=:type");
+ query.setParameter("type", type);
+
+ return (List<T>) query.getResultList();
+ }
+
+ @Override
+ public List<AccountPolicy> findByResource(final ExternalResource resource) {
+ TypedQuery<AccountPolicy> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAAccountPolicy.class.getSimpleName() + " e "
+ + "WHERE :resource MEMBER OF e.resources", AccountPolicy.class);
+ query.setParameter("resource", resource);
+
+ return query.getResultList();
+ }
+
+ @Override
+ public PasswordPolicy getGlobalPasswordPolicy() {
+ List<? extends Policy> policies = find(PolicyType.GLOBAL_PASSWORD);
+ return policies == null || policies.isEmpty()
+ ? null
+ : (PasswordPolicy) policies.get(0);
+ }
+
+ @Override
+ public AccountPolicy getGlobalAccountPolicy() {
+ List<? extends Policy> policies = find(PolicyType.GLOBAL_ACCOUNT);
+ return policies == null || policies.isEmpty()
+ ? null
+ : (AccountPolicy) policies.get(0);
+ }
+
+ @Override
+ public SyncPolicy getGlobalSyncPolicy() {
+ List<? extends Policy> policies = find(PolicyType.GLOBAL_SYNC);
+ return policies == null || policies.isEmpty()
+ ? null
+ : (SyncPolicy) policies.get(0);
+ }
+
+ @Override
+ public List<Policy> findAll() {
+ TypedQuery<Policy> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAPolicy.class.getSimpleName() + " e", Policy.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public <T extends Policy> T save(final T policy) {
+ switch (policy.getType()) {
+ case GLOBAL_PASSWORD:
+ // just one GLOBAL_PASSWORD policy
+ final PasswordPolicy passwordPolicy = getGlobalPasswordPolicy();
+
+ if (passwordPolicy != null && !passwordPolicy.getKey().equals(policy.getKey())) {
+ throw new InvalidEntityException(PasswordPolicy.class, EntityViolationType.InvalidPasswordPolicy,
+ "Global Password policy already exists");
+ }
+ break;
+
+ case GLOBAL_ACCOUNT:
+ // just one GLOBAL_ACCOUNT policy
+ final AccountPolicy accountPolicy = getGlobalAccountPolicy();
+
+ if (accountPolicy != null && !accountPolicy.getKey().equals(policy.getKey())) {
+ throw new InvalidEntityException(PasswordPolicy.class, EntityViolationType.InvalidAccountPolicy,
+ "Global Account policy already exists");
+ }
+ break;
+
+ case GLOBAL_SYNC:
+ // just one GLOBAL_SYNC policy
+ final SyncPolicy syncPolicy = getGlobalSyncPolicy();
+
+ if (syncPolicy != null && !syncPolicy.getKey().equals(policy.getKey())) {
+ throw new InvalidEntityException(PasswordPolicy.class, EntityViolationType.InvalidSyncPolicy,
+ "Global Synchronization policy already exists");
+ }
+ break;
+
+ case PASSWORD:
+ case ACCOUNT:
+ case SYNC:
+ default:
+ }
+
+ return entityManager.merge(policy);
+ }
+
+ @Override
+ public <T extends Policy> void delete(final T policy) {
+ entityManager.remove(policy);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAReportDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAReportDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAReportDAO.java
new file mode 100644
index 0000000..16e2321
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAReportDAO.java
@@ -0,0 +1,90 @@
+/*
+ * 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.server.persistence.jpa.dao;
+
+import java.util.Collections;
+import java.util.List;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.server.persistence.api.dao.ReportDAO;
+import org.apache.syncope.server.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.entity.Report;
+import org.apache.syncope.server.persistence.jpa.entity.JPAReport;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAReportDAO extends AbstractDAO<Report, Long> implements ReportDAO {
+
+ @Override
+ @Transactional(readOnly = true)
+ public Report find(final Long key) {
+ return entityManager.find(JPAReport.class, key);
+ }
+
+ @Override
+ public List<Report> findAll() {
+ return findAll(-1, -1, Collections.<OrderByClause>emptyList());
+ }
+
+ @Override
+ public List<Report> findAll(final int page, final int itemsPerPage, final List<OrderByClause> orderByClauses) {
+ final TypedQuery<Report> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAReport.class.getSimpleName() + " e "
+ + toOrderByStatement(Report.class, "e", orderByClauses), Report.class);
+
+ query.setFirstResult(itemsPerPage * (page <= 0
+ ? 0
+ : page - 1));
+
+ if (itemsPerPage > 0) {
+ query.setMaxResults(itemsPerPage);
+ }
+
+ return query.getResultList();
+ }
+
+ @Override
+ public int count() {
+ Query countQuery = entityManager.createNativeQuery("SELECT COUNT(id) FROM " + JPAReport.TABLE);
+ return ((Number) countQuery.getSingleResult()).intValue();
+ }
+
+ @Override
+ @Transactional(rollbackFor = Throwable.class)
+ public Report save(final Report report) throws InvalidEntityException {
+ return entityManager.merge(report);
+ }
+
+ @Override
+ public void delete(final Long key) {
+ Report report = find(key);
+ if (report == null) {
+ return;
+ }
+
+ delete(report);
+ }
+
+ @Override
+ public void delete(final Report report) {
+ entityManager.remove(report);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAReportExecDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAReportExecDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAReportExecDAO.java
new file mode 100644
index 0000000..41c2485
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAReportExecDAO.java
@@ -0,0 +1,101 @@
+/*
+ * 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.server.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.server.persistence.api.dao.ReportExecDAO;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.entity.Report;
+import org.apache.syncope.server.persistence.api.entity.ReportExec;
+import org.apache.syncope.server.persistence.jpa.entity.JPAReportExec;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAReportExecDAO extends AbstractDAO<ReportExec, Long> implements ReportExecDAO {
+
+ @Override
+ public ReportExec find(final Long key) {
+ return entityManager.find(JPAReportExec.class, key);
+ }
+
+ private ReportExec findLatest(final Report report, final String field) {
+ TypedQuery<ReportExec> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e "
+ + "WHERE e.report=:report ORDER BY e." + field + " DESC", ReportExec.class);
+ query.setParameter("report", report);
+ query.setMaxResults(1);
+
+ List<ReportExec> result = query.getResultList();
+ return result == null || result.isEmpty()
+ ? null
+ : result.iterator().next();
+ }
+
+ @Override
+ public ReportExec findLatestStarted(final Report report) {
+ return findLatest(report, "startDate");
+ }
+
+ @Override
+ public ReportExec findLatestEnded(final Report report) {
+ return findLatest(report, "endDate");
+ }
+
+ @Override
+ public List<ReportExec> findAll() {
+ TypedQuery<ReportExec> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAReportExec.class.getSimpleName() + " e", ReportExec.class);
+ return query.getResultList();
+ }
+
+ /**
+ * This method is annotated as transactional because called from ReportJob.
+ *
+ * @see org.apache.syncope.core.report.ReportJob
+ * @param execution to be merged
+ * @return merged execution
+ * @throws InvalidEntityException if any validation error occurs
+ */
+ @Override
+ @Transactional(rollbackFor = Throwable.class)
+ public ReportExec save(final ReportExec execution) throws InvalidEntityException {
+ return entityManager.merge(execution);
+ }
+
+ @Override
+ public void delete(final Long key) {
+ ReportExec execution = find(key);
+ if (execution == null) {
+ return;
+ }
+
+ delete(execution);
+ }
+
+ @Override
+ public void delete(final ReportExec execution) {
+ if (execution.getReport() != null) {
+ execution.getReport().removeExec(execution);
+ }
+
+ entityManager.remove(execution);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPARoleDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPARoleDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPARoleDAO.java
new file mode 100644
index 0000000..1bb81b4
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPARoleDAO.java
@@ -0,0 +1,584 @@
+/*
+ * 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.server.persistence.jpa.dao;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.server.persistence.api.RoleEntitlementUtil;
+import org.apache.syncope.server.persistence.api.dao.DerAttrDAO;
+import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
+import org.apache.syncope.server.persistence.api.dao.NotFoundException;
+import org.apache.syncope.server.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.dao.VirAttrDAO;
+import org.apache.syncope.server.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.server.persistence.api.entity.AttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.AttributableUtilFactory;
+import org.apache.syncope.server.persistence.api.entity.DerAttr;
+import org.apache.syncope.server.persistence.api.entity.Entitlement;
+import org.apache.syncope.server.persistence.api.entity.ExternalResource;
+import org.apache.syncope.server.persistence.api.entity.PlainAttr;
+import org.apache.syncope.server.persistence.api.entity.Policy;
+import org.apache.syncope.server.persistence.api.entity.Subject;
+import org.apache.syncope.server.persistence.api.entity.VirAttr;
+import org.apache.syncope.server.persistence.api.entity.membership.MDerAttr;
+import org.apache.syncope.server.persistence.api.entity.membership.MDerAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.membership.MVirAttr;
+import org.apache.syncope.server.persistence.api.entity.membership.MVirAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.membership.Membership;
+import org.apache.syncope.server.persistence.api.entity.role.RDerAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RDerAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttrValue;
+import org.apache.syncope.server.persistence.api.entity.role.RVirAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RVirAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMembership;
+import org.apache.syncope.server.persistence.jpa.entity.role.JPARole;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.server.misc.security.AuthContextUtil;
+import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPARoleDAO extends AbstractSubjectDAO<RPlainAttr, RDerAttr, RVirAttr> implements RoleDAO {
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private PlainAttrDAO plainAttrDAO;
+
+ @Autowired
+ private DerAttrDAO derAttrDAO;
+
+ @Autowired
+ private VirAttrDAO virAttrDAO;
+
+ @Autowired
+ private EntitlementDAO entitlementDAO;
+
+ @Autowired
+ private AttributableUtilFactory attrUtilFactory;
+
+ @Override
+ protected Subject<RPlainAttr, RDerAttr, RVirAttr> findInternal(final Long key) {
+ return find(key);
+ }
+
+ @Override
+ public Role find(final Long key) {
+ TypedQuery<Role> query = entityManager.createQuery(
+ "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE e.id = :id", Role.class);
+ query.setParameter("id", key);
+
+ Role result = null;
+ try {
+ result = query.getSingleResult();
+ } catch (NoResultException e) {
+ LOG.debug("No role found with id {}", key, e);
+ }
+
+ return result;
+ }
+
+ @Override
+ public List<Role> find(final String name) {
+ TypedQuery<Role> query = entityManager.createQuery(
+ "SELECT e FROM " + JPARole.class.getSimpleName() + " e WHERE e.name = :name", Role.class);
+ query.setParameter("name", name);
+
+ return query.getResultList();
+ }
+
+ @Override
+ public Role find(final String name, final Long parentId) {
+ TypedQuery<Role> query;
+ if (parentId == null) {
+ query = entityManager.createQuery("SELECT r FROM " + JPARole.class.getSimpleName() + " r WHERE "
+ + "r.name=:name AND r.parent IS NULL", Role.class);
+ } else {
+ query = entityManager.createQuery("SELECT r FROM " + JPARole.class.getSimpleName() + " r WHERE "
+ + "r.name=:name AND r.parent.id=:parentId", Role.class);
+ query.setParameter("parentId", parentId);
+ }
+ query.setParameter("name", name);
+
+ List<Role> result = query.getResultList();
+ return result.isEmpty()
+ ? null
+ : result.get(0);
+ }
+
+ private void findSameOwnerDescendants(final List<Role> result, final Role role) {
+ List<Role> children = findChildren(role);
+ if (children != null) {
+ for (Role child : children) {
+ if ((child.getUserOwner() == null && child.getRoleOwner() == null && child.isInheritOwner())
+ || (child.getUserOwner() != null && child.getUserOwner().equals(role.getUserOwner()))
+ || (child.getRoleOwner() != null && child.getRoleOwner().equals(role.getRoleOwner()))) {
+
+ findDescendants(result, child);
+ }
+ }
+ }
+ result.add(role);
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public List<Role> findOwnedByUser(final Long userKey) {
+ User owner = userDAO.find(userKey);
+ if (owner == null) {
+ return Collections.<Role>emptyList();
+ }
+
+ StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPARole.class.getSimpleName()).
+ append(" e WHERE e.userOwner=:owner ");
+ for (Long roleId : owner.getRoleIds()) {
+ queryString.append("OR e.roleOwner.id=").append(roleId).append(' ');
+ }
+
+ TypedQuery<Role> query = entityManager.createQuery(queryString.toString(), Role.class);
+ query.setParameter("owner", owner);
+
+ List<Role> result = new ArrayList<>();
+ for (Role role : query.getResultList()) {
+ findSameOwnerDescendants(result, role);
+ }
+
+ return result;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public List<Role> findOwnedByRole(final Long roleId) {
+ Role owner = find(roleId);
+ if (owner == null) {
+ return Collections.<Role>emptyList();
+ }
+
+ StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(JPARole.class.getSimpleName()).
+ append(" e WHERE e.roleOwner=:owner ");
+
+ TypedQuery<Role> query = entityManager.createQuery(queryString.toString(), Role.class);
+ query.setParameter("owner", owner);
+
+ List<Role> result = new ArrayList<Role>();
+ for (Role role : query.getResultList()) {
+ findSameOwnerDescendants(result, role);
+ }
+
+ return result;
+ }
+
+ @Override
+ public List<Role> findByEntitlement(final Entitlement entitlement) {
+ TypedQuery<Role> query = entityManager.createQuery(
+ "SELECT e FROM " + JPARole.class.getSimpleName() + " e "
+ + "WHERE :entitlement MEMBER OF e.entitlements", Role.class);
+ query.setParameter("entitlement", entitlement);
+
+ return query.getResultList();
+ }
+
+ private Map.Entry<String, String> getPolicyFields(final PolicyType type) {
+ String policyField;
+ String inheritPolicyField;
+ if (type == PolicyType.GLOBAL_ACCOUNT || type == PolicyType.ACCOUNT) {
+ policyField = "accountPolicy";
+ inheritPolicyField = "inheritAccountPolicy";
+ } else {
+ policyField = "passwordPolicy";
+ inheritPolicyField = "inheritPasswordPolicy";
+ }
+
+ return new AbstractMap.SimpleEntry<>(policyField, inheritPolicyField);
+ }
+
+ private List<Role> findSamePolicyChildren(final Role role, final PolicyType type) {
+ List<Role> result = new ArrayList<Role>();
+
+ for (Role child : findChildren(role)) {
+ boolean inherit = type == PolicyType.GLOBAL_ACCOUNT || type == PolicyType.ACCOUNT
+ ? child.isInheritAccountPolicy()
+ : child.isInheritPasswordPolicy();
+ if (inherit) {
+ result.add(child);
+ result.addAll(findSamePolicyChildren(child, type));
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public List<Role> findByPolicy(final Policy policy) {
+ if (policy.getType() == PolicyType.GLOBAL_SYNC || policy.getType() == PolicyType.SYNC) {
+ return Collections.<Role>emptyList();
+ }
+
+ Map.Entry<String, String> policyFields = getPolicyFields(policy.getType());
+ StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+ append(JPARole.class.getSimpleName()).append(" e WHERE e.").
+ append(policyFields.getKey()).append(" = :policy AND (e.").
+ append(policyFields.getValue()).append(" IS NULL OR e.").
+ append(policyFields.getValue()).append(" = 0)");
+
+ TypedQuery<Role> query = entityManager.createQuery(queryString.toString(), Role.class);
+ query.setParameter("policy", policy);
+
+ List<Role> result = new ArrayList<Role>();
+ for (Role role : query.getResultList()) {
+ result.add(role);
+ result.addAll(findSamePolicyChildren(role, policy.getType()));
+ }
+ return result;
+ }
+
+ @Override
+ public List<Role> findWithoutPolicy(final PolicyType type) {
+ if (type == PolicyType.GLOBAL_SYNC || type == PolicyType.SYNC) {
+ return Collections.<Role>emptyList();
+ }
+
+ Map.Entry<String, String> policyFields = getPolicyFields(type);
+ StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+ append(JPARole.class.getSimpleName()).append(" e WHERE e.").
+ append(policyFields.getKey()).append(" IS NULL AND (e.").
+ append(policyFields.getValue()).append(" IS NULL OR e.").
+ append(policyFields.getValue()).append(" = 0)");
+
+ TypedQuery<Role> query = entityManager.createQuery(queryString.toString(), Role.class);
+ return query.getResultList();
+ }
+
+ private void findAncestors(final List<Role> result, final Role role) {
+ if (role.getParent() != null && !result.contains(role.getParent())) {
+ result.add(role.getParent());
+ findAncestors(result, role.getParent());
+ }
+ }
+
+ @Override
+ public List<Role> findAncestors(final Role role) {
+ List<Role> result = new ArrayList<>();
+ findAncestors(result, role);
+ return result;
+ }
+
+ @Override
+ public List<Role> findChildren(final Role role) {
+ TypedQuery<Role> query = entityManager.createQuery(
+ "SELECT r FROM " + JPARole.class.getSimpleName() + " r WHERE r.parent=:role", Role.class);
+ query.setParameter("role", role);
+
+ return query.getResultList();
+ }
+
+ private void findDescendants(final List<Role> result, final Role role) {
+ List<Role> children = findChildren(role);
+ if (children != null) {
+ for (Role child : children) {
+ findDescendants(result, child);
+ }
+ }
+ result.add(role);
+ }
+
+ @Override
+ public List<Role> findDescendants(final Role role) {
+ List<Role> result = new ArrayList<>();
+ findDescendants(result, role);
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<Role> findByAttrValue(final String schemaName, final RPlainAttrValue attrValue) {
+ return (List<Role>) findByAttrValue(
+ schemaName, attrValue, attrUtilFactory.getInstance(AttributableType.ROLE));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Role findByAttrUniqueValue(final String schemaName, final RPlainAttrValue attrUniqueValue) {
+ return (Role) findByAttrUniqueValue(schemaName, attrUniqueValue,
+ attrUtilFactory.getInstance(AttributableType.ROLE));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<Role> findByDerAttrValue(final String schemaName, final String value) {
+ return (List<Role>) findByDerAttrValue(
+ schemaName, value, attrUtilFactory.getInstance(AttributableType.ROLE));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<Role> findByResource(final ExternalResource resource) {
+ return (List<Role>) findByResource(resource, attrUtilFactory.getInstance(AttributableType.ROLE));
+ }
+
+ @Override
+ public List<Role> findAll() {
+ return findAll(-1, -1, Collections.<OrderByClause>emptyList());
+ }
+
+ @Override
+ public List<Role> findAll(final int page, final int itemsPerPage, final List<OrderByClause> orderBy) {
+ TypedQuery<Role> query = entityManager.createQuery(
+ "SELECT e FROM " + JPARole.class.getSimpleName() + " e "
+ + toOrderByStatement(Role.class, "e", orderBy), Role.class);
+
+ query.setFirstResult(itemsPerPage * (page <= 0
+ ? 0
+ : page - 1));
+
+ if (itemsPerPage > 0) {
+ query.setMaxResults(itemsPerPage);
+ }
+
+ return query.getResultList();
+ }
+
+ @Override
+ public List<Membership> findMemberships(final Role role) {
+ TypedQuery<Membership> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e"
+ + " WHERE e.role=:role", Membership.class);
+ query.setParameter("role", role);
+
+ return query.getResultList();
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<Long> unmatched(final Long roleId,
+ final Class<?> attrClass, final Class<? extends AttrTemplate<?>> attrTemplateClass) {
+
+ final Query query = entityManager.createNativeQuery(new StringBuilder().
+ append("SELECT ma.id ").
+ append("FROM ").append(JPAMembership.TABLE).append(" m, ").
+ append(attrClass.getSimpleName()).append(" ma ").
+ append("WHERE m.role_id = ?1 ").
+ append("AND ma.owner_id = m.id ").
+ append("AND ma.template_id NOT IN (").
+ append("SELECT id ").
+ append("FROM ").append(attrTemplateClass.getSimpleName()).append(' ').
+ append("WHERE owner_id = ?1)").toString());
+ query.setParameter(1, roleId);
+
+ return query.getResultList();
+ }
+
+ @Override
+ public final int count() {
+ Query countQuery = entityManager.createNativeQuery(
+ "SELECT COUNT(e.id) FROM " + JPARole.TABLE + " e");
+
+ return ((Number) countQuery.getSingleResult()).intValue();
+ }
+
+ @Override
+ public Role save(final Role role) {
+ // reset account policy in case of inheritance
+ if (role.isInheritAccountPolicy()) {
+ role.setAccountPolicy(null);
+ }
+
+ // reset password policy in case of inheritance
+ if (role.isInheritPasswordPolicy()) {
+ role.setPasswordPolicy(null);
+ }
+
+ // remove attributes without a valid template
+ List<RPlainAttr> rToBeDeleted = new ArrayList<>();
+ for (PlainAttr attr : role.getPlainAttrs()) {
+ boolean found = false;
+ for (RPlainAttrTemplate template : role.findInheritedTemplates(RPlainAttrTemplate.class)) {
+ if (template.getSchema().equals(attr.getSchema())) {
+ found = true;
+ }
+ }
+ if (!found) {
+ rToBeDeleted.add((RPlainAttr) attr);
+ }
+ }
+ for (RPlainAttr attr : rToBeDeleted) {
+ LOG.debug("Removing {} from {} because no template is available for it", attr, role);
+ role.removePlainAttr(attr);
+ }
+
+ // remove derived attributes without a valid template
+ List<RDerAttr> rDerToBeDeleted = new ArrayList<RDerAttr>();
+ for (DerAttr attr : role.getDerAttrs()) {
+ boolean found = false;
+ for (RDerAttrTemplate template : role.findInheritedTemplates(RDerAttrTemplate.class)) {
+ if (template.getSchema().equals(attr.getSchema())) {
+ found = true;
+ }
+ }
+ if (!found) {
+ rDerToBeDeleted.add((RDerAttr) attr);
+ }
+ }
+ for (RDerAttr attr : rDerToBeDeleted) {
+ LOG.debug("Removing {} from {} because no template is available for it", attr, role);
+ role.removeDerAttr(attr);
+ }
+
+ // remove virtual attributes without a valid template
+ List<RVirAttr> rVirToBeDeleted = new ArrayList<RVirAttr>();
+ for (VirAttr attr : role.getVirAttrs()) {
+ boolean found = false;
+ for (RVirAttrTemplate template : role.findInheritedTemplates(RVirAttrTemplate.class)) {
+ if (template.getSchema().equals(attr.getSchema())) {
+ found = true;
+ }
+ }
+ if (!found) {
+ LOG.debug("Removing {} from {} because no template is available for it", attr, role);
+ rVirToBeDeleted.add((RVirAttr) attr);
+ }
+ }
+ for (RVirAttr attr : rVirToBeDeleted) {
+ role.removeVirAttr(attr);
+ }
+
+ Role merged = entityManager.merge(role);
+
+ // Now the same process for any exising membership of the role being saved
+ if (role.getKey() != null) {
+ for (Long key : unmatched(role.getKey(), MPlainAttr.class, MPlainAttrTemplate.class)) {
+ LOG.debug("Removing MAttr[{}] because no template is available for it in {}", key, role);
+ plainAttrDAO.delete(key, MPlainAttr.class);
+ }
+ for (Long id : unmatched(role.getKey(), MDerAttr.class, MDerAttrTemplate.class)) {
+ LOG.debug("Removing MDerAttr[{}] because no template is available for it in {}", id, role);
+ derAttrDAO.delete(id, MDerAttr.class);
+ }
+ for (Long id : unmatched(role.getKey(), MVirAttr.class, MVirAttrTemplate.class)) {
+ LOG.debug("Removing MVirAttr[{}] because no template is available for it in {}", id, role);
+ virAttrDAO.delete(id, MVirAttr.class);
+ }
+ }
+
+ merged = entityManager.merge(merged);
+ for (VirAttr attr : merged.getVirAttrs()) {
+ attr.getValues().clear();
+ attr.getValues().addAll(role.getVirAttr(attr.getSchema().getKey()).getValues());
+ }
+
+ entitlementDAO.saveRoleEntitlement(merged);
+
+ return merged;
+ }
+
+ @Override
+ public void delete(final Role role) {
+ for (Role roleToBeDeleted : findDescendants(role)) {
+ for (Membership membership : findMemberships(roleToBeDeleted)) {
+ membership.getUser().removeMembership(membership);
+ userDAO.save(membership.getUser());
+
+ entityManager.remove(membership);
+ }
+
+ roleToBeDeleted.getEntitlements().clear();
+
+ roleToBeDeleted.setParent(null);
+ roleToBeDeleted.setUserOwner(null);
+ roleToBeDeleted.setRoleOwner(null);
+ entityManager.remove(roleToBeDeleted);
+
+ entitlementDAO.delete(RoleEntitlementUtil.getEntitlementNameFromRoleKey(roleToBeDeleted.getKey()));
+ }
+ }
+
+ @Override
+ public void delete(final Long key) {
+ Role role = (Role) findInternal(key);
+ if (role == null) {
+ return;
+ }
+
+ delete(role);
+ }
+
+ @Override
+ public Role authFetch(Long key) {
+ if (key == null) {
+ throw new NotFoundException("Null role id");
+ }
+
+ Role role = find(key);
+ if (role == null) {
+ throw new NotFoundException("Role " + key);
+ }
+
+ Set<Long> allowedRoleIds = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames());
+ if (!allowedRoleIds.contains(role.getKey())) {
+ throw new UnauthorizedRoleException(role.getKey());
+ }
+ return role;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public Map<Long, PropagationByResource> findUsersWithIndirectResources(final Long roleKey) {
+ Role role = authFetch(roleKey);
+
+ Map<Long, PropagationByResource> result = new HashMap<>();
+
+ for (Membership membership : findMemberships(role)) {
+ User user = membership.getUser();
+
+ PropagationByResource propByRes = new PropagationByResource();
+ for (ExternalResource resource : role.getResources()) {
+ if (!user.getOwnResources().contains(resource)) {
+ propByRes.add(ResourceOperation.DELETE, resource.getKey());
+ }
+
+ if (!propByRes.isEmpty()) {
+ result.put(user.getKey(), propByRes);
+ }
+ }
+ }
+
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASecurityQuestionDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASecurityQuestionDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASecurityQuestionDAO.java
new file mode 100644
index 0000000..8bcf094
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASecurityQuestionDAO.java
@@ -0,0 +1,71 @@
+/*
+ * 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.server.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.dao.SecurityQuestionDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.user.SecurityQuestion;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.entity.JPASecurityQuestion;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPASecurityQuestionDAO extends AbstractDAO<SecurityQuestion, Long> implements SecurityQuestionDAO {
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ public SecurityQuestion find(final Long key) {
+ return entityManager.find(JPASecurityQuestion.class, key);
+ }
+
+ @Override
+ public List<SecurityQuestion> findAll() {
+ final TypedQuery<SecurityQuestion> query = entityManager.createQuery(
+ "SELECT e FROM " + JPASecurityQuestion.class.getSimpleName() + " e ", SecurityQuestion.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public SecurityQuestion save(final SecurityQuestion securityQuestion) throws InvalidEntityException {
+ return entityManager.merge(securityQuestion);
+ }
+
+ @Override
+ public void delete(final Long key) {
+ SecurityQuestion securityQuestion = find(key);
+ if (securityQuestion == null) {
+ return;
+ }
+
+ for (User user : userDAO.findBySecurityQuestion(securityQuestion)) {
+ user.setSecurityQuestion(null);
+ user.setSecurityAnswer(null);
+ userDAO.save(user);
+ }
+
+ entityManager.remove(securityQuestion);
+ }
+
+}