http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java index 4e6b985..22ce79e 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGroupDAO.java @@ -18,101 +18,72 @@ */ package org.apache.syncope.core.persistence.jpa.dao; -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.commons.collections4.CollectionUtils; import org.apache.commons.collections4.Predicate; import org.apache.syncope.common.lib.SyncopeConstants; -import org.apache.syncope.common.lib.types.AttributableType; +import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.Entitlement; import org.apache.syncope.common.lib.types.ResourceOperation; -import org.apache.syncope.core.persistence.api.dao.DerAttrDAO; -import org.apache.syncope.core.persistence.api.dao.NotFoundException; -import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirAttrDAO; -import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; -import org.apache.syncope.core.persistence.api.entity.AttrTemplate; -import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory; -import org.apache.syncope.core.persistence.api.entity.DerAttr; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.Subject; -import org.apache.syncope.core.persistence.api.entity.VirAttr; -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.MPlainAttrTemplate; -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.GDerAttr; -import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.group.GVirAttr; -import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate; +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership; import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup; import org.apache.syncope.common.lib.types.PropagationByResource; -import org.apache.syncope.common.lib.types.SubjectType; import org.apache.syncope.core.misc.RealmUtils; import org.apache.syncope.core.misc.search.SearchCondConverter; import org.apache.syncope.core.misc.security.AuthContextUtils; import org.apache.syncope.core.misc.security.UnauthorizedException; +import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; +import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.AnyUtils; +import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.persistence.api.entity.user.UMembership; +import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Repository -public class JPAGroupDAO extends AbstractSubjectDAO<GPlainAttr, GDerAttr, GVirAttr> implements GroupDAO { +public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO { @Autowired - private UserDAO userDAO; - - @Autowired - private PlainAttrDAO plainAttrDAO; - - @Autowired - private DerAttrDAO derAttrDAO; - - @Autowired - private VirAttrDAO virAttrDAO; + private AnyObjectDAO anyObjectDAO; @Autowired - private AttributableUtilsFactory attrUtilsFactory; + private UserDAO userDAO; @Override - protected Subject<GPlainAttr, GDerAttr, GVirAttr> findInternal(final Long key) { - return find(key); + protected AnyUtils init() { + return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.GROUP); } @Override - public Group find(final Long key) { - TypedQuery<Group> query = entityManager.createQuery( - "SELECT e FROM " + JPAGroup.class.getSimpleName() + " e WHERE e.id = :id", Group.class); - query.setParameter("id", key); + protected void securityChecks(final Group group) { + Set<String> authRealms = AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_READ); + boolean authorized = CollectionUtils.exists(authRealms, new Predicate<String>() { - Group result = null; - try { - result = query.getSingleResult(); - } catch (NoResultException e) { - LOG.debug("No group found with id {}", key, e); + @Override + public boolean evaluate(final String realm) { + return group.getRealm().getFullPath().startsWith(realm) + || realm.equals(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey())); + } + }); + if (authRealms == null || authRealms.isEmpty() || !authorized) { + throw new UnauthorizedException(AnyTypeKind.GROUP, group.getKey()); } - - return result; } @Override @@ -168,74 +139,22 @@ public class JPAGroupDAO extends AbstractSubjectDAO<GPlainAttr, GDerAttr, GVirAt return query.getResultList(); } - @SuppressWarnings("unchecked") @Override - public List<Group> findByAttrValue(final String schemaName, final GPlainAttrValue attrValue) { - return (List<Group>) findByAttrValue( - schemaName, attrValue, attrUtilsFactory.getInstance(AttributableType.GROUP)); - } - - @SuppressWarnings("unchecked") - @Override - public Group findByAttrUniqueValue(final String schemaName, final GPlainAttrValue attrUniqueValue) { - return (Group) findByAttrUniqueValue( - schemaName, attrUniqueValue, attrUtilsFactory.getInstance(AttributableType.GROUP)); - } - - @SuppressWarnings("unchecked") - @Override - public List<Group> findByDerAttrValue(final String schemaName, final String value) { - return (List<Group>) findByDerAttrValue( - schemaName, value, attrUtilsFactory.getInstance(AttributableType.GROUP)); - } - - @SuppressWarnings("unchecked") - @Override - public List<Group> findByResource(final ExternalResource resource) { - return (List<Group>) findByResource(resource, attrUtilsFactory.getInstance(AttributableType.GROUP)); - } - - @Override - public final List<Group> findAll(final Set<String> adminRealms, final int page, final int itemsPerPage) { - return findAll(adminRealms, page, itemsPerPage, Collections.<OrderByClause>emptyList()); - } - - @Override - public List<Group> findAll(final Set<String> adminRealms, - final int page, final int itemsPerPage, final List<OrderByClause> orderBy) { - - return searchDAO.search(adminRealms, getAllMatchingCond(), page, itemsPerPage, orderBy, SubjectType.GROUP); - } - - @Override - public final int count(final Set<String> adminRealms) { - return searchDAO.count(adminRealms, getAllMatchingCond(), SubjectType.GROUP); - } - - @Override - public List<Membership> findMemberships(final Group group) { - TypedQuery<Membership> query = entityManager.createQuery( - "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e WHERE e.group=:group", Membership.class); + public List<AMembership> findAMemberships(final Group group) { + TypedQuery<AMembership> query = entityManager.createQuery( + "SELECT e FROM " + JPAAMembership.class.getSimpleName() + + " e WHERE e.rightEnd=:group", AMembership.class); query.setParameter("group", group); return query.getResultList(); } - @SuppressWarnings("unchecked") - private List<Long> unmatched(final Long groupId, - 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.group_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, groupId); + @Override + public List<UMembership> findUMemberships(final Group group) { + TypedQuery<UMembership> query = entityManager.createQuery( + "SELECT e FROM " + JPAUMembership.class.getSimpleName() + + " e WHERE e.rightEnd=:group", UMembership.class); + query.setParameter("group", group); return query.getResultList(); } @@ -243,108 +162,39 @@ public class JPAGroupDAO extends AbstractSubjectDAO<GPlainAttr, GDerAttr, GVirAt @Override public Group save(final Group group) { // refresh dynaminc memberships - if (group.getDynMembership() != null) { - List<User> matchingUsers = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, - SearchCondConverter.convert(group.getDynMembership().getFIQLCond()), SubjectType.USER); - - group.getDynMembership().getUsers().clear(); - for (User user : matchingUsers) { - group.getDynMembership().addUser(user); - } - } + if (group.getADynMembership() != null) { + List<AnyObject> matching = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, + SearchCondConverter.convert(group.getADynMembership().getFIQLCond()), AnyTypeKind.ANY_OBJECT); - // remove plain attributes without a valid template - List<GPlainAttr> rToBeDeleted = new ArrayList<>(); - for (final PlainAttr attr : group.getPlainAttrs()) { - boolean found = CollectionUtils.exists(group.getAttrTemplates(GPlainAttrTemplate.class), - new Predicate<GPlainAttrTemplate>() { - - @Override - public boolean evaluate(final GPlainAttrTemplate template) { - return template.getSchema().equals(attr.getSchema()); - } - }); - if (!found) { - rToBeDeleted.add((GPlainAttr) attr); + group.getADynMembership().getMembers().clear(); + for (AnyObject anyObject : matching) { + group.getADynMembership().add(anyObject); } } - for (GPlainAttr attr : rToBeDeleted) { - LOG.debug("Removing {} from {} because no template is available for it", attr, group); - group.removePlainAttr(attr); - } + if (group.getUDynMembership() != null) { + List<User> matching = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, + SearchCondConverter.convert(group.getUDynMembership().getFIQLCond()), AnyTypeKind.USER); - // remove derived attributes without a valid template - List<GDerAttr> rDerToBeDeleted = new ArrayList<>(); - for (final DerAttr attr : group.getDerAttrs()) { - boolean found = CollectionUtils.exists(group.getAttrTemplates(GDerAttrTemplate.class), - new Predicate<GDerAttrTemplate>() { - - @Override - public boolean evaluate(final GDerAttrTemplate template) { - return template.getSchema().equals(attr.getSchema()); - } - }); - if (!found) { - rDerToBeDeleted.add((GDerAttr) attr); + group.getUDynMembership().getMembers().clear(); + for (User user : matching) { + group.getUDynMembership().add(user); } } - for (GDerAttr attr : rDerToBeDeleted) { - LOG.debug("Removing {} from {} because no template is available for it", attr, group); - group.removeDerAttr(attr); - } - // remove virtual attributes without a valid template - List<GVirAttr> rVirToBeDeleted = new ArrayList<>(); - for (final VirAttr attr : group.getVirAttrs()) { - boolean found = CollectionUtils.exists(group.getAttrTemplates(GVirAttrTemplate.class), - new Predicate<GVirAttrTemplate>() { - - @Override - public boolean evaluate(final GVirAttrTemplate template) { - return template.getSchema().equals(attr.getSchema()); - } - }); - if (!found) { - LOG.debug("Removing {} from {} because no template is available for it", attr, group); - rVirToBeDeleted.add((GVirAttr) attr); - } - } - for (GVirAttr attr : rVirToBeDeleted) { - group.removeVirAttr(attr); - } - - Group merged = entityManager.merge(group); - - // Now the same process for any exising membership of the group being saved - if (group.getKey() != null) { - for (Long key : unmatched(group.getKey(), MPlainAttr.class, MPlainAttrTemplate.class)) { - LOG.debug("Removing MAttr[{}] because no template is available for it in {}", key, group); - plainAttrDAO.delete(key, MPlainAttr.class); - } - for (Long id : unmatched(group.getKey(), MDerAttr.class, MDerAttrTemplate.class)) { - LOG.debug("Removing MDerAttr[{}] because no template is available for it in {}", id, group); - derAttrDAO.delete(id, MDerAttr.class); - } - for (Long id : unmatched(group.getKey(), MVirAttr.class, MVirAttrTemplate.class)) { - LOG.debug("Removing MVirAttr[{}] because no template is available for it in {}", id, group); - virAttrDAO.delete(id, MVirAttr.class); - } - } - - merged = entityManager.merge(merged); - for (VirAttr attr : merged.getVirAttrs()) { - attr.getValues().clear(); - attr.getValues().addAll(group.getVirAttr(attr.getSchema().getKey()).getValues()); - } - - return merged; + return super.save(group); } @Override public void delete(final Group group) { - for (Membership membership : findMemberships(group)) { - membership.getUser().removeMembership(membership); - userDAO.save(membership.getUser()); + for (AMembership membership : findAMemberships(group)) { + membership.getLeftEnd().remove(membership); + anyObjectDAO.save(membership.getLeftEnd()); + + entityManager.remove(membership); + } + for (UMembership membership : findUMemberships(group)) { + membership.getLeftEnd().remove(membership); + userDAO.save(membership.getLeftEnd()); entityManager.remove(membership); } @@ -352,76 +202,69 @@ public class JPAGroupDAO extends AbstractSubjectDAO<GPlainAttr, GDerAttr, GVirAt entityManager.remove(group); } - @Override - public void delete(final Long key) { - Group group = (Group) findInternal(key); - if (group == null) { - return; - } + private void populateTransitiveResources( + final Group group, final Any<?, ?, ?> any, final Map<Long, PropagationByResource> result) { - delete(group); - } + PropagationByResource propByRes = new PropagationByResource(); + for (ExternalResource resource : group.getResources()) { + if (!any.getResources().contains(resource)) { + propByRes.add(ResourceOperation.DELETE, resource.getKey()); + } - @Override - public Group authFetch(final Long key) { - if (key == null) { - throw new NotFoundException("Null group id"); + if (!propByRes.isEmpty()) { + result.put(any.getKey(), propByRes); + } } + } - final Group group = find(key); - if (group == null) { - throw new NotFoundException("Group " + key); - } + @Transactional(readOnly = true) + @Override + public Map<Long, PropagationByResource> findAnyObjectsWithTransitiveResources(final Long groupKey) { + Group group = authFind(groupKey); - Set<String> authRealms = AuthContextUtils.getAuthorizations().get(Entitlement.GROUP_READ); - boolean authorized = CollectionUtils.exists(authRealms, new Predicate<String>() { + Map<Long, PropagationByResource> result = new HashMap<>(); - @Override - public boolean evaluate(final String realm) { - return group.getRealm().getFullPath().startsWith(realm) - || realm.equals(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey())); - } - }); - if (authRealms == null || authRealms.isEmpty() || !authorized) { - throw new UnauthorizedException(SubjectType.GROUP, group.getKey()); + for (AMembership membership : findAMemberships(group)) { + populateTransitiveResources(group, membership.getLeftEnd(), result); } - return group; + return result; } @Transactional(readOnly = true) @Override - public Map<Long, PropagationByResource> findUsersWithIndirectResources(final Long groupKey) { - Group group = authFetch(groupKey); + public Map<Long, PropagationByResource> findUsersWithTransitiveResources(final Long groupKey) { + Group group = authFind(groupKey); Map<Long, PropagationByResource> result = new HashMap<>(); - for (Membership membership : findMemberships(group)) { - User user = membership.getUser(); + for (UMembership membership : findUMemberships(group)) { + populateTransitiveResources(group, membership.getLeftEnd(), result); + } + + return result; + } - PropagationByResource propByRes = new PropagationByResource(); - for (ExternalResource resource : group.getResources()) { - if (!user.getResources().contains(resource)) { - propByRes.add(ResourceOperation.DELETE, resource.getKey()); - } + @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) + @Override + public void refreshDynMemberships(final AnyObject anyObject) { + for (Group role : findAll(SyncopeConstants.FULL_ADMIN_REALMS, -1, -1)) { + if (role.getADynMembership() != null && !searchDAO.matches(anyObject, + SearchCondConverter.convert(role.getADynMembership().getFIQLCond()), AnyTypeKind.ANY_OBJECT)) { - if (!propByRes.isEmpty()) { - result.put(user.getKey(), propByRes); - } + role.getADynMembership().remove(anyObject); } } - - return result; } @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) @Override public void refreshDynMemberships(final User user) { for (Group role : findAll(SyncopeConstants.FULL_ADMIN_REALMS, -1, -1)) { - if (role.getDynMembership() != null && !searchDAO.matches(user, - SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), SubjectType.USER)) { + if (role.getUDynMembership() != null && !searchDAO.matches(user, + SearchCondConverter.convert(role.getUDynMembership().getFIQLCond()), AnyTypeKind.USER)) { - role.getDynMembership().removeUser(user); + role.getUDynMembership().remove(user); } } }
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java deleted file mode 100644 index 998f680..0000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java +++ /dev/null @@ -1,104 +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.dao; - -import java.util.List; -import javax.persistence.NoResultException; -import javax.persistence.Query; -import javax.persistence.TypedQuery; -import org.apache.syncope.core.persistence.api.dao.MembershipDAO; -import org.apache.syncope.core.persistence.api.dao.NotFoundException; -import org.apache.syncope.core.persistence.api.dao.UserDAO; -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.user.User; -import org.apache.syncope.core.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 Group group) { - Query query = entityManager.createQuery( - "SELECT e FROM " + JPAMembership.class.getSimpleName() - + " e WHERE e.user = :user AND e.group = :group"); - query.setParameter("user", user); - query.setParameter("group", group); - - Membership result = null; - - try { - result = (Membership) query.getSingleResult(); - } catch (NoResultException e) { - LOG.debug("No membership was found for user {} and group {}", user, group, 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/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java index b41066c..5e232fd 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java @@ -19,43 +19,43 @@ package org.apache.syncope.core.persistence.jpa.dao; import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO; -import org.apache.syncope.core.persistence.api.entity.Attributable; +import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.PlainAttr; +import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr; -import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr; import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr; import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr; import org.springframework.stereotype.Repository; @Repository -public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr, Long> implements PlainAttrDAO { +public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr<?>, Long> implements PlainAttrDAO { - public <T extends PlainAttr> Class<? extends AbstractPlainAttr> getJPAEntityReference( + public <T extends PlainAttr<?>> Class<? extends AbstractPlainAttr<?>> getJPAEntityReference( final Class<T> reference) { return CPlainAttr.class.isAssignableFrom(reference) ? JPACPlainAttr.class : GPlainAttr.class.isAssignableFrom(reference) ? JPAGPlainAttr.class - : MPlainAttr.class.isAssignableFrom(reference) - ? JPAMPlainAttr.class + : APlainAttr.class.isAssignableFrom(reference) + ? JPAAPlainAttr.class : UPlainAttr.class.isAssignableFrom(reference) ? JPAUPlainAttr.class : null; } @Override - public <T extends PlainAttr> T find(final Long key, final Class<T> reference) { + 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) { + public <T extends PlainAttr<?>> void delete(final Long key, final Class<T> reference) { T attribute = find(key, reference); if (attribute == null) { return; @@ -66,9 +66,9 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr, Long> implements Pla @Override @SuppressWarnings("unchecked") - public <T extends PlainAttr> void delete(final T plainAttr) { + public <T extends PlainAttr<?>> void delete(final T plainAttr) { if (plainAttr.getOwner() != null) { - ((Attributable<T, ?, ?>) plainAttr.getOwner()).removePlainAttr(plainAttr); + ((Any<T, ?, ?>) plainAttr.getOwner()).remove(plainAttr); } entityManager.remove(plainAttr); http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java index 4b99051..655decd 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java @@ -22,19 +22,19 @@ import java.util.List; import javax.persistence.TypedQuery; import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue; +import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; 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.jpa.entity.AbstractPlainAttrValue; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue; import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue; import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue; @@ -55,10 +55,10 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl ? JPAGPlainAttrValue.class : reference.equals(GPlainAttrUniqueValue.class) ? JPAGPlainAttrUniqueValue.class - : reference.equals(MPlainAttrValue.class) - ? JPAMPlainAttrValue.class - : reference.equals(MPlainAttrUniqueValue.class) - ? JPAMPlainAttrUniqueValue.class + : reference.equals(APlainAttrValue.class) + ? JPAAPlainAttrValue.class + : reference.equals(APlainAttrUniqueValue.class) + ? JPAAPlainAttrUniqueValue.class : reference.equals(UPlainAttrValue.class) ? JPAUPlainAttrValue.class : reference.equals(UPlainAttrUniqueValue.class) @@ -96,7 +96,7 @@ public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> impl @Override public <T extends PlainAttrValue> void delete(final T attrValue) { if (attrValue.getAttr() != null) { - attrValue.getAttr().removeValue(attrValue); + attrValue.getAttr().remove(attrValue); } entityManager.remove(attrValue); http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java index cc7df33..a922946 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java @@ -20,29 +20,16 @@ package org.apache.syncope.core.persistence.jpa.dao; import java.util.List; import javax.persistence.TypedQuery; -import org.apache.commons.collections4.Closure; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.syncope.common.lib.types.AttributableType; -import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO; +import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.AttributableUtils; +import org.apache.syncope.core.persistence.api.entity.AnyUtils; +import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema; -import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr; -import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema; -import org.apache.syncope.core.persistence.api.entity.group.GMappingItem; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema; -import org.apache.syncope.core.persistence.api.entity.user.UMappingItem; -import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainSchema; -import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainSchema; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainSchema; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainSchema; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainSchema; +import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory; +import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @@ -53,46 +40,25 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen private PlainAttrDAO plainAttrDAO; @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 - : GPlainSchema.class.isAssignableFrom(reference) - ? JPAGPlainSchema.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)); + public PlainSchema find(final String key) { + return entityManager.find(JPAPlainSchema.class, 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); + public List<PlainSchema> findAll() { + TypedQuery<PlainSchema> query = entityManager.createQuery( + "SELECT e FROM " + JPAPlainSchema.class.getSimpleName() + " e", PlainSchema.class); 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 "). + public <T extends PlainAttr<?>> List<T> findAttrs(final PlainSchema schema, final Class<T> reference) { + StringBuilder queryString = new StringBuilder("SELECT e FROM "). append(((JPAPlainAttrDAO) plainAttrDAO).getJPAEntityReference(reference).getSimpleName()). - append(" e WHERE e."); - if (GPlainAttr.class.isAssignableFrom(reference) || MPlainAttr.class.isAssignableFrom(reference)) { - queryString.append("template."); - } - queryString.append("schema=:schema"); + append(" e WHERE e.schema=:schema"); TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference); query.setParameter("schema", schema); @@ -101,45 +67,28 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen } @Override - public <T extends PlainSchema> T save(final T schema) { + public PlainSchema save(final PlainSchema schema) { return entityManager.merge(schema); } @Override - @SuppressWarnings("unchecked") - public void delete(final String key, final AttributableUtils attributableUtil) { - PlainSchema schema = find(key, attributableUtil.plainSchemaClass()); + public void delete(final String key) { + PlainSchema schema = find(key); if (schema == null) { return; } - CollectionUtils.forAllDo(findAttrs(schema, attributableUtil.plainAttrClass()), new Closure<PlainAttr>() { + AnyUtilsFactory anyUtilsFactory = new JPAAnyUtilsFactory(); + for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) { + AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind); - @Override - public void execute(final PlainAttr input) { - plainAttrDAO.delete(input.getKey(), attributableUtil.plainAttrClass()); + for (PlainAttr<?> attr : findAttrs(schema, anyUtils.plainAttrClass())) { + plainAttrDAO.delete(attr.getKey(), anyUtils.plainAttrClass()); } - }); - - if (attributableUtil.getType() == AttributableType.GROUP - || attributableUtil.getType() == AttributableType.MEMBERSHIP) { - - CollectionUtils.forAllDo(attrTemplateDAO. - findBySchemaName(schema.getKey(), attributableUtil.plainAttrTemplateClass()).iterator(), - new Closure<Number>() { - - @Override - public void execute(final Number input) { - attrTemplateDAO.delete(input.longValue(), attributableUtil.plainAttrTemplateClass()); - } - - }); + resourceDAO.deleteMapping(key, anyUtils.plainIntMappingType()); } - resourceDAO.deleteMapping(key, attributableUtil.plainIntMappingType(), UMappingItem.class); - resourceDAO.deleteMapping(key, attributableUtil.plainIntMappingType(), GMappingItem.class); - entityManager.remove(schema); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java index 1007ac4..176cfbd 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPolicyDAO.java @@ -25,7 +25,7 @@ import org.apache.syncope.common.lib.types.PolicyType; import org.apache.syncope.core.persistence.api.dao.PolicyDAO; import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.entity.AccountPolicy; -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.PasswordPolicy; import org.apache.syncope.core.persistence.api.entity.Policy; import org.apache.syncope.core.persistence.api.entity.Realm; http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java index c195bd9..5f600b6 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARoleDAO.java @@ -22,10 +22,10 @@ import java.util.List; import javax.persistence.NoResultException; import javax.persistence.TypedQuery; import org.apache.syncope.common.lib.SyncopeConstants; -import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.core.misc.search.SearchCondConverter; import org.apache.syncope.core.persistence.api.dao.RoleDAO; -import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO; +import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.Role; import org.apache.syncope.core.persistence.api.entity.user.User; @@ -39,7 +39,7 @@ import org.springframework.transaction.annotation.Transactional; public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO { @Autowired - private SubjectSearchDAO searchDAO; + private AnySearchDAO searchDAO; @Override public Role find(final Long key) { @@ -82,11 +82,11 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO { // refresh dynaminc memberships if (role.getDynMembership() != null) { List<User> matchingUsers = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, - SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), SubjectType.USER); + SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), AnyTypeKind.USER); - role.getDynMembership().getUsers().clear(); + role.getDynMembership().getMembers().clear(); for (User user : matchingUsers) { - role.getDynMembership().addUser(user); + role.getDynMembership().add(user); } } @@ -113,9 +113,9 @@ public class JPARoleDAO extends AbstractDAO<Role, Long> implements RoleDAO { public void refreshDynMemberships(final User user) { for (Role role : findAll()) { if (role.getDynMembership() != null && !searchDAO.matches(user, - SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), SubjectType.USER)) { + SearchCondConverter.convert(role.getDynMembership().getFIQLCond()), AnyTypeKind.USER)) { - role.getDynMembership().removeUser(user); + role.getDynMembership().remove(user); } } } http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java deleted file mode 100644 index b4cbad8..0000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPASubjectSearchDAO.java +++ /dev/null @@ -1,778 +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.dao; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import javax.persistence.Entity; -import javax.persistence.Query; -import javax.persistence.TemporalType; -import javax.validation.ValidationException; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.Transformer; -import org.apache.commons.lang3.ClassUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.common.lib.types.AttrSchemaType; -import org.apache.syncope.common.lib.types.SubjectType; -import org.apache.syncope.core.misc.RealmUtils; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.RealmDAO; -import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO; -import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.search.AttributeCond; -import org.apache.syncope.core.persistence.api.dao.search.GroupCond; -import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; -import org.apache.syncope.core.persistence.api.dao.search.ResourceCond; -import org.apache.syncope.core.persistence.api.dao.search.RoleCond; -import org.apache.syncope.core.persistence.api.dao.search.SearchCond; -import org.apache.syncope.core.persistence.api.dao.search.SubjectCond; -import org.apache.syncope.core.persistence.api.entity.AttributableUtils; -import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory; -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.Realm; -import org.apache.syncope.core.persistence.api.entity.Subject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Repository; -import org.springframework.util.ReflectionUtils; - -@Repository -public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> implements SubjectSearchDAO { - - private static final String EMPTY_ATTR_QUERY = "SELECT subject_id FROM user_search_attr WHERE 1=2"; - - @Autowired - private RealmDAO realmDAO; - - @Autowired - private UserDAO userDAO; - - @Autowired - private GroupDAO groupDAO; - - @Autowired - private PlainSchemaDAO schemaDAO; - - @Autowired - private AttributableUtilsFactory attrUtilsFactory; - - private String getAdminRealmsFilter(final Set<String> adminRealms, final SearchSupport svs) { - Set<Long> realmKeys = new HashSet<>(); - for (String realmPath : RealmUtils.normalize(adminRealms)) { - Realm realm = realmDAO.find(realmPath); - if (realm == null) { - LOG.warn("Ignoring invalid realm {}", realmPath); - } else { - CollectionUtils.collect(realmDAO.findDescendants(realm), new Transformer<Realm, Long>() { - - @Override - public Long transform(final Realm descendant) { - return descendant.getKey(); - } - }, realmKeys); - } - } - - StringBuilder adminRealmFilter = new StringBuilder(). - append("SELECT subject_id FROM ").append(svs.field().name). - append(" WHERE realm_id IN (SELECT id AS realm_id FROM Realm"); - - boolean firstRealm = true; - for (Long realmKey : realmKeys) { - if (firstRealm) { - adminRealmFilter.append(" WHERE"); - firstRealm = false; - } else { - adminRealmFilter.append(" OR"); - } - adminRealmFilter.append(" id = ").append(realmKey); - } - - adminRealmFilter.append(')'); - - return adminRealmFilter.toString(); - } - - @Override - public int count(final Set<String> adminRealms, final SearchCond searchCondition, final SubjectType type) { - List<Object> parameters = Collections.synchronizedList(new ArrayList<>()); - - // 1. get the query string from the search condition - SearchSupport svs = new SearchSupport(type); - StringBuilder queryString = getQuery(searchCondition, parameters, type, svs); - - // 2. take into account administrative realms - queryString.insert(0, "SELECT u.subject_id FROM ("); - queryString.append(") u WHERE subject_id IN ("); - queryString.append(getAdminRealmsFilter(adminRealms, svs)).append(')'); - - // 3. prepare the COUNT query - queryString.insert(0, "SELECT COUNT(subject_id) FROM ("); - queryString.append(") count_subject_id"); - - Query countQuery = entityManager.createNativeQuery(queryString.toString()); - fillWithParameters(countQuery, parameters); - - LOG.debug("Native count query\n{}\nwith parameters\n{}", queryString.toString(), parameters); - - int result = ((Number) countQuery.getSingleResult()).intValue(); - LOG.debug("Native count query result: {}", result); - - return result; - } - - @Override - public <T extends Subject<?, ?, ?>> List<T> search( - final Set<String> adminRealms, final SearchCond searchCondition, final SubjectType type) { - - return search(adminRealms, searchCondition, Collections.<OrderByClause>emptyList(), type); - } - - @Override - public <T extends Subject<?, ?, ?>> List<T> search( - final Set<String> adminRealms, final SearchCond searchCondition, final List<OrderByClause> orderBy, - final SubjectType type) { - - return search(adminRealms, searchCondition, -1, -1, orderBy, type); - } - - @Override - public <T extends Subject<?, ?, ?>> List<T> search( - final Set<String> adminRealms, final SearchCond searchCondition, final int page, final int itemsPerPage, - final List<OrderByClause> orderBy, final SubjectType type) { - - List<T> result = Collections.<T>emptyList(); - - if (adminRealms != null && !adminRealms.isEmpty()) { - LOG.debug("Search condition:\n{}", searchCondition); - - if (searchCondition != null && searchCondition.isValid()) { - try { - result = doSearch(adminRealms, searchCondition, page, itemsPerPage, orderBy, type); - } catch (Exception e) { - LOG.error("While searching for {}", type, e); - } - } else { - LOG.error("Invalid search condition:\n{}", searchCondition); - } - } - - return result; - } - - @Override - public <T extends Subject<?, ?, ?>> boolean matches( - final T subject, final SearchCond searchCondition, final SubjectType type) { - - List<Object> parameters = Collections.synchronizedList(new ArrayList<>()); - - // 1. get the query string from the search condition - SearchSupport svs = new SearchSupport(type); - StringBuilder queryString = getQuery(searchCondition, parameters, type, svs); - - boolean matches; - if (queryString.length() == 0) { - // Could be empty: got into a group search with a single membership condition ... - matches = false; - } else { - // 2. take into account the passed user - queryString.insert(0, "SELECT u.subject_id FROM ("); - queryString.append(") u WHERE subject_id=?").append(setParameter(parameters, subject.getKey())); - - // 3. prepare the search query - Query query = entityManager.createNativeQuery(queryString.toString()); - - // 4. populate the search query with parameter values - fillWithParameters(query, parameters); - - // 5. executes query - matches = !query.getResultList().isEmpty(); - } - - return matches; - } - - private int setParameter(final List<Object> parameters, final Object parameter) { - int key; - synchronized (parameters) { - parameters.add(parameter); - key = parameters.size(); - } - - return key; - } - - private void fillWithParameters(final Query query, final List<Object> parameters) { - for (int i = 0; i < parameters.size(); i++) { - if (parameters.get(i) instanceof Date) { - query.setParameter(i + 1, (Date) parameters.get(i), TemporalType.TIMESTAMP); - } else if (parameters.get(i) instanceof Boolean) { - query.setParameter(i + 1, ((Boolean) parameters.get(i)) - ? 1 - : 0); - } else { - query.setParameter(i + 1, parameters.get(i)); - } - } - } - - private StringBuilder buildSelect(final OrderBySupport orderBySupport) { - final StringBuilder select = new StringBuilder("SELECT u.subject_id"); - - for (OrderBySupport.Item obs : orderBySupport.items) { - select.append(',').append(obs.select); - } - select.append(" FROM "); - - return select; - } - - private StringBuilder buildWhere(final OrderBySupport orderBySupport) { - final StringBuilder where = new StringBuilder(" u"); - for (SearchSupport.SearchView searchView : orderBySupport.views) { - where.append(',').append(searchView.name).append(' ').append(searchView.alias); - } - where.append(" WHERE "); - for (SearchSupport.SearchView searchView : orderBySupport.views) { - where.append("u.subject_id=").append(searchView.alias).append(".subject_id AND "); - } - - for (OrderBySupport.Item obs : orderBySupport.items) { - if (StringUtils.isNotBlank(obs.where)) { - where.append(obs.where).append(" AND "); - } - } - where.append("u.subject_id IN ("); - - return where; - } - - private StringBuilder buildOrderBy(final OrderBySupport orderBySupport) { - final StringBuilder orderBy = new StringBuilder(); - - for (OrderBySupport.Item obs : orderBySupport.items) { - orderBy.append(obs.orderBy).append(','); - } - if (!orderBySupport.items.isEmpty()) { - orderBy.insert(0, " ORDER BY "); - orderBy.deleteCharAt(orderBy.length() - 1); - } - - return orderBy; - } - - private OrderBySupport parseOrderBy(final SubjectType type, final SearchSupport svs, - final List<OrderByClause> orderByClauses) { - - final AttributableUtils attrUtils = attrUtilsFactory.getInstance(type.asAttributableType()); - - OrderBySupport orderBySupport = new OrderBySupport(); - - for (OrderByClause clause : orderByClauses) { - OrderBySupport.Item obs = new OrderBySupport.Item(); - - // Manage difference among external key attribute and internal JPA @Id - String fieldName = "key".equals(clause.getField()) ? "id" : clause.getField(); - - Field subjectField = ReflectionUtils.findField(attrUtils.attributableClass(), fieldName); - if (subjectField == null) { - PlainSchema schema = schemaDAO.find(fieldName, attrUtils.plainSchemaClass()); - if (schema != null) { - if (schema.isUniqueConstraint()) { - orderBySupport.views.add(svs.uniqueAttr()); - - obs.select = new StringBuilder(). - append(svs.uniqueAttr().alias).append('.').append(svs.fieldName(schema.getType())). - append(" AS ").append(fieldName).toString(); - obs.where = new StringBuilder(). - append(svs.uniqueAttr().alias). - append(".schema_name='").append(fieldName).append("'").toString(); - obs.orderBy = fieldName + " " + clause.getDirection().name(); - } else { - orderBySupport.views.add(svs.attr()); - - obs.select = new StringBuilder(). - append(svs.attr().alias).append('.').append(svs.fieldName(schema.getType())). - append(" AS ").append(fieldName).toString(); - obs.where = new StringBuilder(). - append(svs.attr().alias). - append(".schema_name='").append(fieldName).append("'").toString(); - obs.orderBy = fieldName + " " + clause.getDirection().name(); - } - } - } else { - orderBySupport.views.add(svs.field()); - - obs.select = svs.field().alias + "." + fieldName; - obs.where = StringUtils.EMPTY; - obs.orderBy = svs.field().alias + "." + fieldName + " " + clause.getDirection().name(); - } - - if (obs.isEmpty()) { - LOG.warn("Cannot build any valid clause from {}", clause); - } else { - orderBySupport.items.add(obs); - } - } - - return orderBySupport; - } - - @SuppressWarnings("unchecked") - private <T extends Subject<?, ?, ?>> List<T> doSearch(final Set<String> adminRealms, - final SearchCond nodeCond, final int page, final int itemsPerPage, final List<OrderByClause> orderBy, - final SubjectType type) { - - List<Object> parameters = Collections.synchronizedList(new ArrayList<>()); - - // 1. get the query string from the search condition - SearchSupport svs = new SearchSupport(type); - StringBuilder queryString = getQuery(nodeCond, parameters, type, svs); - - // 2. take into account administrative groups and ordering - OrderBySupport orderBySupport = parseOrderBy(type, svs, orderBy); - if (queryString.charAt(0) == '(') { - queryString.insert(0, buildSelect(orderBySupport)); - queryString.append(buildWhere(orderBySupport)); - } else { - queryString.insert(0, buildSelect(orderBySupport).append('(')); - queryString.append(')').append(buildWhere(orderBySupport)); - } - queryString. - append(getAdminRealmsFilter(adminRealms, svs)).append(')'). - append(buildOrderBy(orderBySupport)); - - // 3. prepare the search query - Query query = entityManager.createNativeQuery(queryString.toString()); - - // 4. page starts from 1, while setFirtResult() starts from 0 - query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1)); - - if (itemsPerPage >= 0) { - query.setMaxResults(itemsPerPage); - } - - // 5. populate the search query with parameter values - fillWithParameters(query, parameters); - - LOG.debug("Native query\n{}\nwith parameters\n{}", queryString.toString(), parameters); - - // 6. Prepare the result (avoiding duplicates) - List<T> result = new ArrayList<>(); - - for (Object subjectId : query.getResultList()) { - long actualId; - if (subjectId instanceof Object[]) { - actualId = ((Number) ((Object[]) subjectId)[0]).longValue(); - } else { - actualId = ((Number) subjectId).longValue(); - } - - T subject = type == SubjectType.USER - ? (T) userDAO.find(actualId) - : (T) groupDAO.find(actualId); - if (subject == null) { - LOG.error("Could not find {} with id {}, even though returned by the native query", - type, actualId); - } else { - if (!result.contains(subject)) { - result.add(subject); - } - } - } - - return result; - } - - private StringBuilder getQuery(final SearchCond nodeCond, final List<Object> parameters, - final SubjectType type, final SearchSupport svs) { - - StringBuilder query = new StringBuilder(); - - switch (nodeCond.getType()) { - - case LEAF: - case NOT_LEAF: - if (nodeCond.getGroupCond() != null && SubjectType.USER == type) { - query.append(getQuery(nodeCond.getGroupCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } - if (nodeCond.getRoleCond() != null && SubjectType.USER == type) { - query.append(getQuery(nodeCond.getRoleCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } - if (nodeCond.getResourceCond() != null) { - query.append(getQuery(nodeCond.getResourceCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs)); - } - if (nodeCond.getAttributeCond() != null) { - query.append(getQuery(nodeCond.getAttributeCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs)); - } - if (nodeCond.getSubjectCond() != null) { - query.append(getQuery(nodeCond.getSubjectCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs)); - } - break; - - case AND: - query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)). - append(" AND subject_id IN ( "). - append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)). - append(")"); - break; - - case OR: - query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)). - append(" OR subject_id IN ( "). - append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)). - append(")"); - break; - - default: - } - - return query; - } - - private String getQuery(final GroupCond cond, final boolean not, final List<Object> parameters, - final SearchSupport svs) { - - StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM "). - append(svs.field().name).append(" WHERE "); - - if (not) { - query.append("subject_id NOT IN ("); - } else { - query.append("subject_id IN ("); - } - - query.append("SELECT DISTINCT subject_id ").append("FROM "). - append(svs.membership().name).append(" WHERE "). - append("group_id=?").append(setParameter(parameters, cond.getGroupKey())). - append(')'); - - if (not) { - query.append("AND subject_id NOT IN ("); - } else { - query.append("OR subject_id IN ("); - } - - query.append("SELECT DISTINCT subject_id ").append("FROM "). - append(svs.dyngroupmembership().name).append(" WHERE "). - append("group_id=?").append(setParameter(parameters, cond.getGroupKey())). - append(')'); - - return query.toString(); - } - - private String getQuery(final RoleCond cond, final boolean not, final List<Object> parameters, - final SearchSupport svs) { - - StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM "). - append(svs.field().name).append(" WHERE "); - - if (not) { - query.append("subject_id NOT IN ("); - } else { - query.append("subject_id IN ("); - } - - query.append("SELECT DISTINCT subject_id ").append("FROM "). - append(svs.role().name).append(" WHERE "). - append("role_id=?").append(setParameter(parameters, cond.getRoleKey())). - append(')'); - - if (not) { - query.append("AND subject_id NOT IN ("); - } else { - query.append("OR subject_id IN ("); - } - - query.append("SELECT DISTINCT subject_id ").append("FROM "). - append(svs.dynrolemembership().name).append(" WHERE "). - append("role_id=?").append(setParameter(parameters, cond.getRoleKey())). - append(')'); - - return query.toString(); - } - - private String getQuery(final ResourceCond cond, final boolean not, final List<Object> parameters, - final SubjectType type, final SearchSupport svs) { - - final StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM "). - append(svs.field().name).append(" WHERE "); - - if (not) { - query.append("subject_id NOT IN ("); - } else { - query.append("subject_id IN ("); - } - - query.append("SELECT DISTINCT subject_id FROM "). - append(svs.resource().name). - append(" WHERE resource_name=?"). - append(setParameter(parameters, cond.getResourceName())); - - if (type == SubjectType.USER) { - query.append(" UNION SELECT DISTINCT subject_id FROM "). - append(svs.groupResource().name). - append(" WHERE resource_name=?"). - append(setParameter(parameters, cond.getResourceName())); - } - - query.append(')'); - - return query.toString(); - } - - private void fillAttributeQuery(final StringBuilder query, final PlainAttrValue attrValue, - final PlainSchema schema, final AttributeCond cond, final boolean not, - final List<Object> parameters, final SearchSupport svs) { - - String column = (cond instanceof SubjectCond) - ? cond.getSchema() - : "' AND " + svs.fieldName(schema.getType()); - - switch (cond.getType()) { - - case ISNULL: - query.append(column).append(not - ? " IS NOT NULL" - : " IS NULL"); - break; - - case ISNOTNULL: - query.append(column).append(not - ? " IS NULL" - : " IS NOT NULL"); - break; - - case LIKE: - if (schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) { - query.append(column); - if (not) { - query.append(" NOT "); - } - query.append(" LIKE ?").append(setParameter(parameters, cond.getExpression())); - } else { - if (!(cond instanceof SubjectCond)) { - query.append("' AND"); - } - query.append(" 1=2"); - LOG.error("LIKE is only compatible with string or enum schemas"); - } - break; - - case EQ: - query.append(column); - if (not) { - query.append("<>"); - } else { - query.append('='); - } - query.append('?').append(setParameter(parameters, attrValue.getValue())); - break; - - case GE: - query.append(column); - if (not) { - query.append('<'); - } else { - query.append(">="); - } - query.append('?').append(setParameter(parameters, attrValue.getValue())); - break; - - case GT: - query.append(column); - if (not) { - query.append("<="); - } else { - query.append('>'); - } - query.append('?').append(setParameter(parameters, attrValue.getValue())); - break; - - case LE: - query.append(column); - if (not) { - query.append('>'); - } else { - query.append("<="); - } - query.append('?').append(setParameter(parameters, attrValue.getValue())); - break; - - case LT: - query.append(column); - if (not) { - query.append(">="); - } else { - query.append('<'); - } - query.append('?').append(setParameter(parameters, attrValue.getValue())); - break; - - default: - } - } - - private String getQuery(final AttributeCond cond, final boolean not, final List<Object> parameters, - final SubjectType type, final SearchSupport svs) { - - final AttributableUtils attrUtils = attrUtilsFactory.getInstance(type.asAttributableType()); - - PlainSchema schema = schemaDAO.find(cond.getSchema(), attrUtils.plainSchemaClass()); - if (schema == null) { - LOG.warn("Ignoring invalid schema '{}'", cond.getSchema()); - return EMPTY_ATTR_QUERY; - } - - PlainAttrValue attrValue = attrUtils.newPlainAttrValue(); - try { - if (cond.getType() != AttributeCond.Type.LIKE && cond.getType() != AttributeCond.Type.ISNULL - && cond.getType() != AttributeCond.Type.ISNOTNULL) { - - schema.getValidator().validate(cond.getExpression(), attrValue); - } - } catch (ValidationException e) { - LOG.error("Could not validate expression '" + cond.getExpression() + "'", e); - return EMPTY_ATTR_QUERY; - } - - StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM "); - if (cond.getType() == AttributeCond.Type.ISNOTNULL) { - query.append(svs.field().name). - append(" WHERE subject_id NOT IN (SELECT subject_id FROM "). - append(svs.nullAttr().name). - append(" WHERE schema_name='").append(schema.getKey()).append("')"); - } else { - if (cond.getType() == AttributeCond.Type.ISNULL) { - query.append(svs.nullAttr().name). - append(" WHERE schema_name='").append(schema.getKey()).append("'"); - } else { - if (schema.isUniqueConstraint()) { - query.append(svs.uniqueAttr().name); - } else { - query.append(svs.attr().name); - } - query.append(" WHERE schema_name='").append(schema.getKey()); - - fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs); - } - } - - return query.toString(); - } - - @SuppressWarnings("rawtypes") - private String getQuery(final SubjectCond cond, final boolean not, final List<Object> parameters, - final SubjectType type, final SearchSupport svs) { - - final AttributableUtils attrUtils = attrUtilsFactory.getInstance(type.asAttributableType()); - - // Keeps track of difference between entity's getKey() and JPA @Id fields - if ("key".equals(cond.getSchema())) { - cond.setSchema("id"); - } - - Field subjectField = ReflectionUtils.findField(attrUtils.attributableClass(), cond.getSchema()); - if (subjectField == null) { - LOG.warn("Ignoring invalid schema '{}'", cond.getSchema()); - return EMPTY_ATTR_QUERY; - } - - PlainSchema schema = attrUtils.newPlainSchema(); - schema.setKey(subjectField.getName()); - for (AttrSchemaType attrSchemaType : AttrSchemaType.values()) { - if (subjectField.getType().isAssignableFrom(attrSchemaType.getType())) { - schema.setType(attrSchemaType); - } - } - - // Deal with subject Integer fields logically mapping to boolean values - // (JPAGroup.inheritPlainAttrs, for example) - boolean foundBooleanMin = false; - boolean foundBooleanMax = false; - if (Integer.class.equals(subjectField.getType())) { - for (Annotation annotation : subjectField.getAnnotations()) { - if (Min.class.equals(annotation.annotationType())) { - foundBooleanMin = ((Min) annotation).value() == 0; - } else if (Max.class.equals(annotation.annotationType())) { - foundBooleanMax = ((Max) annotation).value() == 1; - } - } - } - if (foundBooleanMin && foundBooleanMax) { - schema.setType(AttrSchemaType.Boolean); - } - - // Deal with subject fields representing relationships to other entities - if (subjectField.getType().getAnnotation(Entity.class) != null) { - Method relMethod = null; - try { - relMethod = ClassUtils.getPublicMethod(subjectField.getType(), "getKey", new Class[0]); - } catch (Exception e) { - LOG.error("Could not find {}#getKey", subjectField.getType(), e); - } - - if (relMethod != null) { - if (Long.class.isAssignableFrom(relMethod.getReturnType())) { - cond.setSchema(cond.getSchema() + "_id"); - schema.setType(AttrSchemaType.Long); - } - if (String.class.isAssignableFrom(relMethod.getReturnType())) { - cond.setSchema(cond.getSchema() + "_name"); - schema.setType(AttrSchemaType.String); - } - } - } - - PlainAttrValue attrValue = attrUtils.newPlainAttrValue(); - if (cond.getType() != AttributeCond.Type.LIKE - && cond.getType() != AttributeCond.Type.ISNULL - && cond.getType() != AttributeCond.Type.ISNOTNULL) { - - try { - schema.getValidator().validate(cond.getExpression(), attrValue); - } catch (ValidationException e) { - LOG.error("Could not validate expression '" + cond.getExpression() + "'", e); - return EMPTY_ATTR_QUERY; - } - } - - final StringBuilder query = new StringBuilder("SELECT DISTINCT subject_id FROM "). - append(svs.field().name).append(" WHERE "); - - fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs); - - return query.toString(); - } -} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java index d90ddbd..ff93071 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPATaskDAO.java @@ -26,7 +26,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.syncope.common.lib.types.TaskType; import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; -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.Task; import org.apache.syncope.core.persistence.jpa.entity.task.JPANotificationTask; import org.apache.syncope.core.persistence.jpa.entity.task.JPAPropagationTask;
