http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java index 60be1fe..5280c3c 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java @@ -27,6 +27,7 @@ import java.util.LinkedHashMap; 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; @@ -40,6 +41,7 @@ import org.apache.syncope.core.spring.security.DelegatedAdministrationException; import org.apache.syncope.core.provisioning.api.utils.EntityUtils; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; +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.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyUtils; @@ -124,6 +126,38 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj } @Override + public AnyObject findByName(final String name) { + TypedQuery<AnyObject> query = entityManager().createQuery( + "SELECT e FROM " + JPAAnyObject.class.getSimpleName() + " e WHERE e.name = :name", AnyObject.class); + query.setParameter("name", name); + + AnyObject result = null; + try { + result = query.getSingleResult(); + } catch (NoResultException e) { + LOG.debug("No any object found with name {}", name, e); + } + + return result; + } + + @Override + public AnyObject authFindByName(final String name) { + if (name == null) { + throw new NotFoundException("Null name"); + } + + AnyObject anyObject = findByName(name); + if (anyObject == null) { + throw new NotFoundException("Any Object " + name); + } + + securityChecks(anyObject); + + return anyObject; + } + + @Override public List<ARelationship> findARelationships(final AnyObject anyObject) { TypedQuery<ARelationship> query = entityManager().createQuery( "SELECT e FROM " + JPAARelationship.class.getSimpleName()
http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java index 07e18e2..d1df518 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java @@ -19,7 +19,6 @@ package org.apache.syncope.core.persistence.jpa.dao; import org.apache.syncope.core.persistence.api.dao.ConfDAO; -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.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; @@ -40,9 +39,6 @@ public class JPAConfDAO extends AbstractDAO<Conf> implements ConfDAO { @Autowired private PlainSchemaDAO schemaDAO; - @Autowired - private PlainAttrDAO attrDAO; - @Override public Conf get() { Conf instance = entityManager().find(JPAConf.class, KEY); @@ -96,8 +92,8 @@ public class JPAConfDAO extends AbstractDAO<Conf> implements ConfDAO { if (old != null && (!attr.getSchema().isUniqueConstraint() || (!attr.getUniqueValue().getStringValue().equals(old.getUniqueValue().getStringValue())))) { - instance.getPlainAttrs().remove(old); - attrDAO.delete(old.getKey(), CPlainAttr.class); + old.setOwner(null); + instance.remove(old); } instance.add(attr); @@ -111,8 +107,8 @@ public class JPAConfDAO extends AbstractDAO<Conf> implements ConfDAO { Conf instance = get(); CPlainAttr attr = instance.getPlainAttr(key); if (attr != null) { - instance.getPlainAttrs().remove(attr); - attrDAO.delete(attr.getKey(), CPlainAttr.class); + attr.setOwner(null); + instance.remove(attr); instance = entityManager().merge(instance); } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/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 38d4add..af5220f 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 @@ -44,6 +44,7 @@ import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.DelegatedAdministrationException; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; 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.search.AssignableCond; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; import org.apache.syncope.core.persistence.api.entity.Any; @@ -52,9 +53,11 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; +import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; import org.apache.syncope.core.persistence.api.entity.user.UMembership; +import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; 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.group.JPATypeExtension; @@ -72,6 +75,9 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO { @Autowired private UserDAO userDAO; + @Autowired + private PlainAttrDAO plainAttrDAO; + @Override protected AnyUtils init() { return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.GROUP); @@ -242,16 +248,30 @@ public class JPAGroupDAO extends AbstractAnyDAO<Group> implements GroupDAO { @Override public void delete(final Group group) { for (AMembership membership : findAMemberships(group)) { - membership.getLeftEnd().getMemberships().remove(membership); - anyObjectDAO.save(membership.getLeftEnd()); + AnyObject leftEnd = membership.getLeftEnd(); + leftEnd.getMemberships().remove(membership); + membership.setRightEnd(null); + for (APlainAttr attr : leftEnd.getPlainAttrs(membership)) { + leftEnd.remove(attr); + attr.setOwner(null); + attr.setMembership(null); + plainAttrDAO.delete(attr); + } - entityManager().remove(membership); + anyObjectDAO.save(leftEnd); } for (UMembership membership : findUMemberships(group)) { - membership.getLeftEnd().getMemberships().remove(membership); - userDAO.save(membership.getLeftEnd()); + User leftEnd = membership.getLeftEnd(); + leftEnd.getMemberships().remove(membership); + membership.setRightEnd(null); + for (UPlainAttr attr : leftEnd.getPlainAttrs(membership)) { + leftEnd.remove(attr); + attr.setOwner(null); + attr.setMembership(null); + plainAttrDAO.delete(attr); + } - entityManager().remove(membership); + userDAO.save(leftEnd); } entityManager().remove(group); http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/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 3e8a38c..d4ba926 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 @@ -68,7 +68,7 @@ public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr<?>> implements PlainA @SuppressWarnings("unchecked") public <T extends PlainAttr<?>> void delete(final T plainAttr) { if (plainAttr.getOwner() != null) { - ((Any<T>) plainAttr.getOwner()).getPlainAttrs().remove(plainAttr); + ((Any<T>) plainAttr.getOwner()).remove(plainAttr); } entityManager().remove(plainAttr); http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java index 496e689..cf3ede1 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java @@ -25,14 +25,11 @@ import javax.persistence.FetchType; import javax.persistence.ManyToOne; import javax.persistence.MappedSuperclass; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.IterableUtils; -import org.apache.commons.collections4.Predicate; import org.apache.syncope.core.provisioning.api.utils.EntityUtils; 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.Realm; import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; -import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource; import org.apache.syncope.core.persistence.jpa.validation.entity.AnyCheck; @AnyCheck @@ -81,33 +78,8 @@ public abstract class AbstractAny<P extends PlainAttr<?>> extends AbstractAnnota } @Override - public P getPlainAttr(final String plainSchemaName) { - return IterableUtils.find(getPlainAttrs(), new Predicate<P>() { - - @Override - public boolean evaluate(final P plainAttr) { - return plainAttr != null && plainAttr.getSchema() != null - && plainSchemaName.equals(plainAttr.getSchema().getKey()); - } - }); - } - - protected abstract List<JPAExternalResource> internalGetResources(); - - @Override - public boolean add(final ExternalResource resource) { - checkType(resource, JPAExternalResource.class); - return internalGetResources().add((JPAExternalResource) resource); - } - - @Override public List<String> getResourceNames() { return CollectionUtils.collect( getResources(), EntityUtils.<ExternalResource>keyTransformer(), new ArrayList<String>()); } - - @Override - public List<? extends ExternalResource> getResources() { - return internalGetResources(); - } } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java new file mode 100644 index 0000000..a2a41fa --- /dev/null +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.jpa.entity; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.collections4.Predicate; +import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.GroupablePlainAttr; +import org.apache.syncope.core.persistence.api.entity.Membership; +import org.apache.syncope.core.persistence.api.entity.GroupableRelatable; +import org.apache.syncope.core.persistence.api.entity.Relationship; +import org.apache.syncope.core.persistence.api.entity.RelationshipType; + +public abstract class AbstractGroupableRelatable< + L extends Any<P>, + M extends Membership<L>, + P extends GroupablePlainAttr<L, M>, + R extends Any<?>, + REL extends Relationship<L, R>> + extends AbstractAny<P> implements GroupableRelatable<L, M, P, R, REL> { + + private static final long serialVersionUID = -2269285197388729673L; + + protected abstract List<? extends P> internalGetPlainAttrs(); + + @Override + public boolean remove(final P attr) { + return internalGetPlainAttrs().remove(attr); + } + + @Override + public P getPlainAttr(final String plainSchemaName) { + return IterableUtils.find(internalGetPlainAttrs(), new Predicate<P>() { + + @Override + public boolean evaluate(final P plainAttr) { + return plainAttr != null && plainAttr.getSchema() != null + && plainAttr.getMembership() == null + && plainSchemaName.equals(plainAttr.getSchema().getKey()); + } + }); + } + + @Override + public P getPlainAttr(final String plainSchemaName, final Membership<?> membership) { + return IterableUtils.find(internalGetPlainAttrs(), new Predicate<P>() { + + @Override + public boolean evaluate(final P plainAttr) { + return plainAttr != null && plainAttr.getSchema() != null + && plainAttr.getMembership() != null && plainAttr.getMembership().equals(membership) + && plainSchemaName.equals(plainAttr.getSchema().getKey()); + } + }); + } + + @Override + public List<? extends P> getPlainAttrs() { + return CollectionUtils.select(internalGetPlainAttrs(), new Predicate<P>() { + + @Override + public boolean evaluate(final P plainAttr) { + return plainAttr != null && plainAttr.getSchema() != null + && plainAttr.getMembership() == null; + } + }, new ArrayList<P>()); + } + + @Override + public Collection<? extends P> getPlainAttrs(final String plainSchemaName) { + return CollectionUtils.select(internalGetPlainAttrs(), new Predicate<P>() { + + @Override + public boolean evaluate(final P plainAttr) { + return plainAttr != null && plainAttr.getSchema() != null + && plainSchemaName.equals(plainAttr.getSchema().getKey()); + } + }); + } + + @Override + public Collection<? extends P> getPlainAttrs(final Membership<?> membership) { + return CollectionUtils.select(internalGetPlainAttrs(), new Predicate<P>() { + + @Override + public boolean evaluate(final P plainAttr) { + return plainAttr != null && plainAttr.getSchema() != null + && membership.equals(plainAttr.getMembership()); + } + }); + } + + @Override + public M getMembership(final String groupKey) { + return IterableUtils.find(getMemberships(), new Predicate<M>() { + + @Override + public boolean evaluate(final M membership) { + return groupKey != null && groupKey.equals(membership.getRightEnd().getKey()); + } + }); + } + + @Override + public REL getRelationship(final RelationshipType relationshipType, final String otherEndKey) { + return IterableUtils.find(getRelationships(), new Predicate<REL>() { + + @Override + public boolean evaluate(final REL relationship) { + return otherEndKey != null && otherEndKey.equals(relationship.getRightEnd().getKey()) + && ((relationshipType == null && relationship.getType() == null) + || (relationshipType != null && relationshipType.equals(relationship.getType()))); + } + }); + } + + @Override + public Collection<? extends REL> getRelationships(final RelationshipType relationshipType) { + return CollectionUtils.select(getRelationships(), new Predicate<REL>() { + + @Override + public boolean evaluate(final REL relationship) { + return relationshipType != null && relationshipType.equals(relationship.getType()); + } + }); + } + + @Override + public Collection<? extends REL> getRelationships(final String otherEndKey) { + return CollectionUtils.select(getRelationships(), new Predicate<REL>() { + + @Override + public boolean evaluate(final REL relationship) { + return otherEndKey != null && otherEndKey.equals(relationship.getRightEnd().getKey()); + } + }); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java index a4d6eea..5c1b203 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java @@ -26,6 +26,7 @@ import org.apache.syncope.common.lib.to.GroupTO; import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.IntMappingType; +import org.apache.syncope.core.persistence.api.dao.AllowedSchemas; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; @@ -342,17 +343,17 @@ public class JPAAnyUtils implements AnyUtils { @Transactional(readOnly = true) @Override - public <S extends Schema> Set<S> getAllowedSchemas(final Any<?> any, final Class<S> reference) { - Set<S> schemas = new HashSet<>(); + public <S extends Schema> AllowedSchemas<S> getAllowedSchemas(final Any<?> any, final Class<S> reference) { + AllowedSchemas<S> result = null; if (any instanceof User) { - schemas.addAll(userDAO.findAllowedSchemas((User) any, reference)); + result = userDAO.findAllowedSchemas((User) any, reference); } else if (any instanceof Group) { - schemas.addAll(groupDAO.findAllowedSchemas((Group) any, reference)); + result = groupDAO.findAllowedSchemas((Group) any, reference); } else if (any instanceof AnyObject) { - schemas.addAll(anyObjectDAO.findAllowedSchemas((AnyObject) any, reference)); + result = anyObjectDAO.findAllowedSchemas((AnyObject) any, reference); } - return schemas; + return result; } } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java index f9a8151..044faae 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java @@ -27,9 +27,11 @@ import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; +import javax.persistence.UniqueConstraint; import javax.validation.Valid; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; @@ -37,7 +39,8 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; @Entity -@Table(name = JPAAPlainAttr.TABLE) +@Table(name = JPAAPlainAttr.TABLE, uniqueConstraints = + @UniqueConstraint(columnNames = { "owner_id", "membership_id", "schema_id" })) public class JPAAPlainAttr extends AbstractPlainAttr<AnyObject> implements APlainAttr { private static final long serialVersionUID = 8066058729580952116L; @@ -47,6 +50,12 @@ public class JPAAPlainAttr extends AbstractPlainAttr<AnyObject> implements APlai @ManyToOne(fetch = FetchType.EAGER) private JPAAnyObject owner; + /** + * The membership of this attribute; might be {@code NULL} if this attribute is not related to a membership. + */ + @ManyToOne(fetch = FetchType.EAGER) + private JPAAMembership membership; + @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute") @Valid private List<JPAAPlainAttrValue> values = new ArrayList<>(); @@ -67,6 +76,17 @@ public class JPAAPlainAttr extends AbstractPlainAttr<AnyObject> implements APlai } @Override + public AMembership getMembership() { + return membership; + } + + @Override + public void setMembership(final AMembership membership) { + checkType(membership, JPAAMembership.class); + this.membership = (JPAAMembership) membership; + } + + @Override protected boolean addForMultiValue(final PlainAttrValue attrValue) { checkType(attrValue, JPAAPlainAttrValue.class); return values.add((JPAAPlainAttrValue) attrValue); http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java index 44f55df..d790082 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java @@ -19,10 +19,10 @@ package org.apache.syncope.core.persistence.jpa.entity.anyobject; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import javax.persistence.Cacheable; import javax.persistence.CascadeType; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; @@ -33,17 +33,14 @@ import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.Valid; import javax.validation.constraints.NotNull; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.IterableUtils; -import org.apache.commons.collections4.Predicate; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; -import org.apache.syncope.core.persistence.api.entity.RelationshipType; import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -import org.apache.syncope.core.persistence.jpa.entity.AbstractAny; +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; +import org.apache.syncope.core.persistence.jpa.entity.AbstractGroupableRelatable; import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType; import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass; import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource; @@ -51,12 +48,18 @@ import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResour @Entity @Table(name = JPAAnyObject.TABLE) @Cacheable -public class JPAAnyObject extends AbstractAny<APlainAttr> implements AnyObject { +public class JPAAnyObject + extends AbstractGroupableRelatable<AnyObject, AMembership, APlainAttr, AnyObject, ARelationship> + implements AnyObject { private static final long serialVersionUID = 9063766472970643492L; public static final String TABLE = "AnyObject"; + @Column(unique = true) + @NotNull + private String name; + @NotNull @ManyToOne(fetch = FetchType.EAGER, optional = false) private JPAAnyType type; @@ -79,15 +82,25 @@ public class JPAAnyObject extends AbstractAny<APlainAttr> implements AnyObject { @JoinColumn(name = "anyTypeClass_id")) private List<JPAAnyTypeClass> auxClasses = new ArrayList<>(); - @OneToMany(cascade = CascadeType.ALL, mappedBy = "leftEnd") + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "leftEnd") @Valid private List<JPAARelationship> relationships = new ArrayList<>(); - @OneToMany(cascade = CascadeType.ALL, mappedBy = "leftEnd") + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "leftEnd") @Valid private List<JPAAMembership> memberships = new ArrayList<>(); @Override + public String getName() { + return name; + } + + @Override + public void setName(final String name) { + this.name = name; + } + + @Override public AnyType getType() { return type; } @@ -99,22 +112,28 @@ public class JPAAnyObject extends AbstractAny<APlainAttr> implements AnyObject { } @Override + public boolean add(final ExternalResource resource) { + checkType(resource, JPAExternalResource.class); + return resources.add((JPAExternalResource) resource); + } + + @Override + public List<? extends ExternalResource> getResources() { + return resources; + } + + @Override public boolean add(final APlainAttr attr) { checkType(attr, JPAAPlainAttr.class); return plainAttrs.add((JPAAPlainAttr) attr); } @Override - public List<? extends APlainAttr> getPlainAttrs() { + protected List<? extends APlainAttr> internalGetPlainAttrs() { return plainAttrs; } @Override - protected List<JPAExternalResource> internalGetResources() { - return resources; - } - - @Override public boolean add(final AnyTypeClass auxClass) { checkType(auxClass, JPAAnyTypeClass.class); return this.auxClasses.add((JPAAnyTypeClass) auxClass); @@ -132,41 +151,6 @@ public class JPAAnyObject extends AbstractAny<APlainAttr> implements AnyObject { } @Override - public ARelationship getRelationship(final RelationshipType relationshipType, final String anyObjectKey) { - return IterableUtils.find(getRelationships(), new Predicate<ARelationship>() { - - @Override - public boolean evaluate(final ARelationship relationship) { - return anyObjectKey != null && anyObjectKey.equals(relationship.getRightEnd().getKey()) - && ((relationshipType == null && relationship.getType() == null) - || (relationshipType != null && relationshipType.equals(relationship.getType()))); - } - }); - } - - @Override - public Collection<? extends ARelationship> getRelationships(final RelationshipType relationshipType) { - return CollectionUtils.select(getRelationships(), new Predicate<ARelationship>() { - - @Override - public boolean evaluate(final ARelationship relationship) { - return relationshipType != null && relationshipType.equals(relationship.getType()); - } - }); - } - - @Override - public Collection<? extends ARelationship> getRelationships(final String anyObjectKey) { - return CollectionUtils.select(getRelationships(), new Predicate<ARelationship>() { - - @Override - public boolean evaluate(final ARelationship relationship) { - return anyObjectKey != null && anyObjectKey.equals(relationship.getRightEnd().getKey()); - } - }); - } - - @Override public List<? extends ARelationship> getRelationships() { return relationships; } @@ -178,17 +162,6 @@ public class JPAAnyObject extends AbstractAny<APlainAttr> implements AnyObject { } @Override - public AMembership getMembership(final String groupKey) { - return IterableUtils.find(getMemberships(), new Predicate<AMembership>() { - - @Override - public boolean evaluate(final AMembership membership) { - return groupKey != null && groupKey.equals(membership.getRightEnd().getKey()); - } - }); - } - - @Override public List<? extends AMembership> getMemberships() { return memberships; } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java index 1ceaaa7..88ce38f 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/conf/JPAConf.java @@ -47,7 +47,7 @@ public class JPAConf extends AbstractProvidedKeyEntity implements Conf { public static final String TABLE = "SyncopeConf"; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "owner") @Valid private List<JPACPlainAttr> plainAttrs = new ArrayList<>(); @@ -58,6 +58,12 @@ public class JPAConf extends AbstractProvidedKeyEntity implements Conf { } @Override + public boolean remove(final CPlainAttr attr) { + checkType(attr, JPACPlainAttr.class); + return plainAttrs.remove((JPACPlainAttr) attr); + } + + @Override public CPlainAttr getPlainAttr(final String plainSchemaName) { return IterableUtils.find(plainAttrs, new Predicate<CPlainAttr>() { http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java index 644fa27..53cf335 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java @@ -27,6 +27,7 @@ import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; +import javax.persistence.UniqueConstraint; import javax.validation.Valid; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; @@ -37,7 +38,8 @@ import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; @Entity -@Table(name = JPAGPlainAttr.TABLE) +@Table(name = JPAGPlainAttr.TABLE, uniqueConstraints = + @UniqueConstraint(columnNames = { "owner_id", "schema_id" })) public class JPAGPlainAttr extends AbstractPlainAttr<Group> implements GPlainAttr { private static final long serialVersionUID = 2848159565890995780L; http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java index 8afb1ae..bcfa9b0 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java @@ -44,6 +44,7 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembers import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.jpa.entity.AbstractAny; @@ -74,7 +75,7 @@ public class JPAGroup extends AbstractAny<GPlainAttr> implements Group { @ManyToOne private JPAGroup groupOwner; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "owner") @Valid private List<JPAGPlainAttr> plainAttrs = new ArrayList<>(); @@ -104,6 +105,16 @@ public class JPAGroup extends AbstractAny<GPlainAttr> implements Group { private List<JPATypeExtension> typeExtensions = new ArrayList<>(); @Override + public String getName() { + return name; + } + + @Override + public void setName(final String name) { + this.name = name; + } + + @Override public AnyType getType() { return ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class).findGroup(); } @@ -114,18 +125,14 @@ public class JPAGroup extends AbstractAny<GPlainAttr> implements Group { } @Override - protected List<JPAExternalResource> internalGetResources() { - return resources; - } - - @Override - public String getName() { - return name; + public boolean add(final ExternalResource resource) { + checkType(resource, JPAExternalResource.class); + return resources.add((JPAExternalResource) resource); } @Override - public void setName(final String name) { - this.name = name; + public List<? extends ExternalResource> getResources() { + return resources; } @Override @@ -157,6 +164,24 @@ public class JPAGroup extends AbstractAny<GPlainAttr> implements Group { } @Override + public boolean remove(final GPlainAttr attr) { + checkType(attr, JPAGPlainAttr.class); + return plainAttrs.remove((JPAGPlainAttr) attr); + } + + @Override + public GPlainAttr getPlainAttr(final String plainSchemaName) { + return IterableUtils.find(getPlainAttrs(), new Predicate<GPlainAttr>() { + + @Override + public boolean evaluate(final GPlainAttr plainAttr) { + return plainAttr != null && plainAttr.getSchema() != null + && plainSchemaName.equals(plainAttr.getSchema().getKey()); + } + }); + } + + @Override public List<? extends GPlainAttr> getPlainAttrs() { return plainAttrs; } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java index 438994f..1d00f89 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java @@ -183,6 +183,10 @@ public class JPAMappingItem extends AbstractGeneratedKeyEntity implements Mappin name = "groupOwnerSchema"; break; + case AnyObjectName: + name = "anyObjectName"; + break; + default: name = intAttrName; } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java index 84c9c84..bdabf2c 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java @@ -27,9 +27,11 @@ import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; +import javax.persistence.UniqueConstraint; import javax.validation.Valid; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.user.UMembership; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; @@ -37,7 +39,8 @@ import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; @Entity -@Table(name = JPAUPlainAttr.TABLE) +@Table(name = JPAUPlainAttr.TABLE, uniqueConstraints = + @UniqueConstraint(columnNames = { "owner_id", "membership_id", "schema_id" })) public class JPAUPlainAttr extends AbstractPlainAttr<User> implements UPlainAttr { private static final long serialVersionUID = 6333601983691157406L; @@ -51,6 +54,12 @@ public class JPAUPlainAttr extends AbstractPlainAttr<User> implements UPlainAttr private JPAUser owner; /** + * The membership of this attribute; might be {@code NULL} if this attribute is not related to a membership. + */ + @ManyToOne(fetch = FetchType.EAGER) + private JPAUMembership membership; + + /** * Values of this attribute (if schema is not UNIQUE). */ @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute") @@ -76,6 +85,17 @@ public class JPAUPlainAttr extends AbstractPlainAttr<User> implements UPlainAttr } @Override + public UMembership getMembership() { + return membership; + } + + @Override + public void setMembership(final UMembership membership) { + checkType(membership, JPAUMembership.class); + this.membership = (JPAUMembership) membership; + } + + @Override protected boolean addForMultiValue(final PlainAttrValue attrValue) { checkType(attrValue, JPAUPlainAttrValue.class); return values.add((JPAUPlainAttrValue) attrValue); http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java index a0ecf00..f207cfe 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java @@ -20,7 +20,6 @@ package org.apache.syncope.core.persistence.jpa.entity.user; import java.util.ArrayList; import java.util.Calendar; -import java.util.Collection; import java.util.Date; import java.util.List; import javax.persistence.Basic; @@ -47,9 +46,6 @@ import javax.validation.Valid; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.IterableUtils; -import org.apache.commons.collections4.Predicate; import org.apache.syncope.common.lib.types.CipherAlgorithm; import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; @@ -62,18 +58,21 @@ import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; -import org.apache.syncope.core.persistence.api.entity.RelationshipType; import org.apache.syncope.core.persistence.api.entity.Role; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; import org.apache.syncope.core.persistence.api.entity.user.UMembership; import org.apache.syncope.core.persistence.api.entity.user.URelationship; -import org.apache.syncope.core.persistence.jpa.entity.AbstractAny; +import org.apache.syncope.core.persistence.jpa.entity.AbstractGroupableRelatable; import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass; import org.apache.syncope.core.persistence.jpa.entity.JPARole; @Entity @Table(name = JPAUser.TABLE) @Cacheable -public class JPAUser extends AbstractAny<UPlainAttr> implements User { +public class JPAUser + extends AbstractGroupableRelatable<User, UMembership, UPlainAttr, AnyObject, URelationship> + implements User { private static final long serialVersionUID = -3905046855521446823L; @@ -172,11 +171,11 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User { @JoinColumn(name = "anyTypeClass_id")) private List<JPAAnyTypeClass> auxClasses = new ArrayList<>(); - @OneToMany(cascade = CascadeType.ALL, mappedBy = "leftEnd") + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "leftEnd") @Valid private List<JPAURelationship> relationships = new ArrayList<>(); - @OneToMany(cascade = CascadeType.ALL, mappedBy = "leftEnd") + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "leftEnd") @Valid private List<JPAUMembership> memberships = new ArrayList<>(); @@ -197,7 +196,13 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User { } @Override - protected List<JPAExternalResource> internalGetResources() { + public boolean add(final ExternalResource resource) { + checkType(resource, JPAExternalResource.class); + return resources.add((JPAExternalResource) resource); + } + + @Override + public List<? extends ExternalResource> getResources() { return resources; } @@ -270,7 +275,7 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User { } @Override - public List<? extends UPlainAttr> getPlainAttrs() { + protected List<? extends UPlainAttr> internalGetPlainAttrs() { return plainAttrs; } @@ -471,41 +476,6 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User { } @Override - public URelationship getRelationship(final RelationshipType relationshipType, final String anyObjectKey) { - return IterableUtils.find(getRelationships(), new Predicate<URelationship>() { - - @Override - public boolean evaluate(final URelationship relationship) { - return anyObjectKey != null && anyObjectKey.equals(relationship.getRightEnd().getKey()) - && ((relationshipType == null && relationship.getType() == null) - || (relationshipType != null && relationshipType.equals(relationship.getType()))); - } - }); - } - - @Override - public Collection<? extends URelationship> getRelationships(final RelationshipType relationshipType) { - return CollectionUtils.select(getRelationships(), new Predicate<URelationship>() { - - @Override - public boolean evaluate(final URelationship relationship) { - return relationshipType != null && relationshipType.equals(relationship.getType()); - } - }); - } - - @Override - public Collection<? extends URelationship> getRelationships(final String anyObjectKey) { - return CollectionUtils.select(getRelationships(), new Predicate<URelationship>() { - - @Override - public boolean evaluate(final URelationship relationship) { - return anyObjectKey != null && anyObjectKey.equals(relationship.getRightEnd().getKey()); - } - }); - } - - @Override public List<? extends URelationship> getRelationships() { return relationships; } @@ -517,17 +487,6 @@ public class JPAUser extends AbstractAny<UPlainAttr> implements User { } @Override - public UMembership getMembership(final String groupKey) { - return IterableUtils.find(getMemberships(), new Predicate<UMembership>() { - - @Override - public boolean evaluate(final UMembership membership) { - return groupKey != null && groupKey.equals(membership.getRightEnd().getKey()); - } - }); - } - - @Override public List<? extends UMembership> getMemberships() { return memberships; } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyValidator.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyValidator.java index fb28c4e..37e227f 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyValidator.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyValidator.java @@ -18,42 +18,63 @@ */ package org.apache.syncope.core.persistence.jpa.validation.entity; -import java.util.Collection; import javax.validation.ConstraintValidatorContext; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.Transformer; import org.apache.syncope.common.lib.types.EntityViolationType; +import org.apache.syncope.core.persistence.api.dao.AllowedSchemas; import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.GroupableRelatable; +import org.apache.syncope.core.persistence.api.entity.Membership; 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.Conf; +import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory; @SuppressWarnings("rawtypes") public class AnyValidator extends AbstractValidator<AnyCheck, Any> { + private boolean raiseNotAllowedViolation( + final ConstraintValidatorContext context, + final String schema, + final Group group) { + + if (group == null) { + context.buildConstraintViolationWithTemplate( + getTemplate(EntityViolationType.InvalidPlainAttr, + schema + " not allowed for this instance")). + addPropertyNode("plainAttrs").addConstraintViolation(); + } else { + context.buildConstraintViolationWithTemplate( + getTemplate(EntityViolationType.InvalidPlainAttr, + schema + " not allowed for membership of group " + group.getName())). + addPropertyNode("plainAttrs").addConstraintViolation(); + } + return false; + } + @Override public boolean isValid(final Any any, final ConstraintValidatorContext context) { context.disableDefaultConstraintViolation(); if (!(any instanceof Conf)) { - Collection<String> allowedPlainSchemas = CollectionUtils.collect(new JPAAnyUtilsFactory(). - getInstance(any.getType().getKind()).getAllowedSchemas(any, PlainSchema.class), - new Transformer<PlainSchema, String>() { + AllowedSchemas<PlainSchema> allowedPlainSchemas = new JPAAnyUtilsFactory(). + getInstance(any.getType().getKind()).getAllowedSchemas(any, PlainSchema.class); - @Override - public String transform(final PlainSchema schema) { - return schema.getKey(); + for (PlainAttr<?> attr : ((Any<?>) any).getPlainAttrs()) { + if (attr != null && !allowedPlainSchemas.forSelfContains(attr.getSchema().getKey())) { + return raiseNotAllowedViolation(context, attr.getSchema().getKey(), null); } - }); + } + if (any instanceof GroupableRelatable) { + for (Membership<?> membership : ((GroupableRelatable<?, ?, ?, ?, ?>) any).getMemberships()) { + for (PlainAttr<?> attr : ((GroupableRelatable<?, ?, ?, ?, ?>) any).getPlainAttrs(membership)) { + if (attr != null && !allowedPlainSchemas.forMembershipsContains( + membership.getRightEnd(), attr.getSchema().getKey())) { - for (PlainAttr<?> attr : ((Any<?>) any).getPlainAttrs()) { - if (attr != null && !allowedPlainSchemas.contains(attr.getSchema().getKey())) { - context.buildConstraintViolationWithTemplate( - getTemplate(EntityViolationType.InvalidPlainSchema, - attr.getSchema().getKey() + " not allowed for this instance")). - addPropertyNode("plainAttrs").addConstraintViolation(); - return false; + return raiseNotAllowedViolation( + context, attr.getSchema().getKey(), membership.getRightEnd()); + } + } } } } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java index 387e368..e1bdf68 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/EntityValidationListener.java @@ -29,6 +29,7 @@ import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.entity.AnnotatedEntity; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.Entity; +import org.apache.syncope.core.persistence.api.entity.GroupableRelatable; import org.apache.syncope.core.persistence.api.entity.Policy; import org.apache.syncope.core.persistence.api.entity.ProvidedKeyEntity; import org.apache.syncope.core.persistence.api.entity.Schema; @@ -41,9 +42,6 @@ import org.slf4j.LoggerFactory; */ public class EntityValidationListener { - /** - * Logger. - */ private static final Logger LOG = LoggerFactory.getLogger(EntityValidationListener.class); @PrePersist @@ -62,6 +60,7 @@ public class EntityValidationListener { && !Schema.class.equals(interf) && !Task.class.equals(interf) && !Policy.class.equals(interf) + && !GroupableRelatable.class.equals(interf) && !Any.class.equals(interf) && Entity.class.isAssignableFrom(interf)) { http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java index da00ebd..64ec693 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/PlainAttrValueValidator.java @@ -74,7 +74,7 @@ public class PlainAttrValueValidator extends AbstractValidator<PlainAttrValueChe + "]" + " is " + uniqueValueSchema + ", while owning attribute schema is " + attrSchema); context.disableDefaultConstraintViolation(); - context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidPlainSchema, + context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidPlainAttr, "Unique value schema is " + uniqueValueSchema + ", while owning attribute schema is " + attrSchema)).addPropertyNode("schema"). addConstraintViolation(); http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyObjectTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyObjectTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyObjectTest.java index f12e913..cc324c6 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyObjectTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyObjectTest.java @@ -62,6 +62,7 @@ public class AnyObjectTest extends AbstractTest { @Test public void save() { AnyObject anyObject = entityFactory.newEntity(AnyObject.class); + anyObject.setName("a name"); anyObject.setType(anyTypeDAO.find("PRINTER")); anyObject.setRealm(realmDAO.findByFullPath(SyncopeConstants.ROOT_REALM)); http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java index 712aa51..2b7f441 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java @@ -170,7 +170,7 @@ public class PlainAttrTest extends AbstractTest { // for attribute assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList)); // for uauv - assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainSchema)); + assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainAttr)); } @Test http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConfTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConfTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConfTest.java new file mode 100644 index 0000000..f9bcff1 --- /dev/null +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConfTest.java @@ -0,0 +1,72 @@ +/* + * 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.outer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.apache.syncope.core.persistence.api.dao.ConfDAO; +import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; +import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; +import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr; +import org.apache.syncope.core.persistence.jpa.AbstractTest; +import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@Transactional("Master") +public class ConfTest extends AbstractTest { + + @Autowired + private ConfDAO confDAO; + + @Autowired + private PlainSchemaDAO plainSchemaDAO; + + private void add(final CPlainAttr newAttr, final String value) { + JPACPlainAttrValue attrValue; + if (newAttr.getSchema().isUniqueConstraint()) { + attrValue = new JPACPlainAttrValue(); + ((PlainAttrUniqueValue) attrValue).setSchema(newAttr.getSchema()); + } else { + attrValue = new JPACPlainAttrValue(); + } + newAttr.add(value, attrValue); + } + + @Test + public void update() { + CPlainAttr expireTime = confDAO.find("token.expireTime"); + assertNotNull(expireTime); + long value = expireTime.getValues().get(0).getLongValue(); + value++; + + CPlainAttr attr = entityFactory.newEntity(CPlainAttr.class); + attr.setSchema(plainSchemaDAO.find("token.expireTime")); + add(attr, String.valueOf(value)); + + confDAO.save(expireTime); + confDAO.flush(); + + CPlainAttr actual = confDAO.find("token.expireTime"); + assertEquals(expireTime, actual); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java index ae450aa..8037a2b 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java @@ -271,6 +271,7 @@ public class GroupTest extends AbstractTest { public void adynMembership() { // 0. create any object matching the condition below AnyObject anyObject = entityFactory.newEntity(AnyObject.class); + anyObject.setName("name"); anyObject.setType(anyTypeDAO.find("PRINTER")); anyObject.setRealm(realmDAO.findByFullPath("/even/two")); http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java index 1a5a62d..cdb3067 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java @@ -23,9 +23,14 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.util.List; import java.util.UUID; +import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.collections4.Predicate; +import org.apache.syncope.common.lib.types.AnyTypeKind; +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO; @@ -145,7 +150,91 @@ public class UserTest extends AbstractTest { user.getRelationships().get(0).getRightEnd().getKey()); } - @Test // search by derived attribute + @Test + public void membershipWithAttrs() { + User user = userDAO.findByUsername("vivaldi"); + assertNotNull(user); + assertTrue(user.getMemberships().isEmpty()); + + // add 'obscure' to user (no membership): works because 'obscure' is from 'other', default class for USER + UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class); + attr.setOwner(user); + attr.setSchema(plainSchemaDAO.find("obscure")); + attr.add("testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER)); + user.add(attr); + + // add 'obscure' to user (via 'artDirector' membership): does not work because 'obscure' is from 'other' + // but 'artDirector' defines no type extension + UMembership membership = entityFactory.newEntity(UMembership.class); + membership.setLeftEnd(user); + membership.setRightEnd(groupDAO.findByName("artDirector")); + user.add(membership); + + attr = entityFactory.newEntity(UPlainAttr.class); + attr.setOwner(user); + attr.setMembership(membership); + attr.setSchema(plainSchemaDAO.find("obscure")); + attr.add("testvalue2", anyUtilsFactory.getInstance(AnyTypeKind.USER)); + user.add(attr); + + try { + userDAO.save(user); + fail(); + } catch (InvalidEntityException e) { + assertNotNull(e); + } + + // replace 'artDirector' with 'additional', which defines type extension with class 'other' and 'csv': + // now it works + membership = user.getMembership(groupDAO.findByName("artDirector").getKey()); + user.remove(user.getPlainAttr("obscure", membership)); + user.getMemberships().remove(membership); + membership.setLeftEnd(null); + + membership = entityFactory.newEntity(UMembership.class); + membership.setLeftEnd(user); + membership.setRightEnd(groupDAO.findByName("additional")); + user.add(membership); + + attr = entityFactory.newEntity(UPlainAttr.class); + attr.setOwner(user); + attr.setMembership(membership); + attr.setSchema(plainSchemaDAO.find("obscure")); + attr.add("testvalue2", anyUtilsFactory.getInstance(AnyTypeKind.USER)); + user.add(attr); + + userDAO.save(user); + userDAO.flush(); + + user = userDAO.findByUsername("vivaldi"); + assertEquals(1, user.getMemberships().size()); + + final UMembership newM = user.getMembership(groupDAO.findByName("additional").getKey()); + assertEquals(1, user.getPlainAttrs(newM).size()); + + assertNull(user.getPlainAttr("obscure").getMembership()); + assertEquals(2, user.getPlainAttrs("obscure").size()); + assertTrue(user.getPlainAttrs("obscure").contains(user.getPlainAttr("obscure"))); + assertTrue(IterableUtils.matchesAny(user.getPlainAttrs("obscure"), new Predicate<UPlainAttr>() { + + @Override + public boolean evaluate(final UPlainAttr object) { + return object.getMembership() == null; + } + })); + assertTrue(IterableUtils.matchesAny(user.getPlainAttrs("obscure"), new Predicate<UPlainAttr>() { + + @Override + public boolean evaluate(final UPlainAttr object) { + return newM.equals(object.getMembership()); + } + })); + } + + /** + * Search by derived attribute. + */ + @Test public void issueSYNCOPE800() { // create derived attribute (literal as prefix) DerSchema prefix = entityFactory.newEntity(DerSchema.class); http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/persistence-jpa/src/test/resources/domains/MasterContent.xml ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index 37fc8a1..e956a90 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -175,15 +175,15 @@ under the License. accountPolicy_id="20ab5a8c-4b0c-432c-b957-f7fb9784d9f7" passwordPolicy_id="ce93fcda-dc3a-4369-a7b0-a6108c261c85"/> - <AnyObject id="fc6dbc3a-6c07-4965-8781-921e7401a4a5" + <AnyObject id="fc6dbc3a-6c07-4965-8781-921e7401a4a5" name="HP LJ 1300n" realm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28" type_id="PRINTER" creator="admin" lastModifier="admin" creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/> - <AnyObject id="8559d14d-58c2-46eb-a2d4-a7d35161e8f8" + <AnyObject id="8559d14d-58c2-46eb-a2d4-a7d35161e8f8" name="Canon MF 8030cn" realm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28" type_id="PRINTER" creator="admin" lastModifier="admin" creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/> - <AnyObject id="9e1d130c-d6a3-48b1-98b3-182477ed0688" + <AnyObject id="9e1d130c-d6a3-48b1-98b3-182477ed0688" name="Epson Stylus Color" realm_id="0679e069-7355-4b20-bd11-a5a0a5453c7c" type_id="PRINTER" creator="admin" lastModifier="admin" creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/> @@ -966,6 +966,9 @@ under the License. <MappingItem id="23aa0299-ddbb-4e59-8918-0ab2a32465fa" mapping_id="16439b5f-50c3-4604-97e9-f4004933abd8" extAttrName="ID" intMappingType="AnyObjectKey" mandatoryCondition="true" connObjectKey="1" password="0" purpose="BOTH"/> + <MappingItem id="3dc96af0-5d0a-4ec1-be84-244716d88401" mapping_id="16439b5f-50c3-4604-97e9-f4004933abd8" extAttrName="PRINTERNAME" + intMappingType="AnyObjectName" mandatoryCondition="true" + connObjectKey="0" password="0" purpose="BOTH"/> <MappingItem id="f3ef9f8b-e667-4b18-969f-ba98c3d78bc0" mapping_id="16439b5f-50c3-4604-97e9-f4004933abd8" extAttrName="LOCATION" intAttrName="location" intMappingType="AnyObjectPlainSchema" mandatoryCondition="false" connObjectKey="0" password="0" purpose="BOTH"/> @@ -985,7 +988,7 @@ under the License. pullMode="INCREMENTAL" unmatchingRule="ASSIGN" matchingRule="UPDATE" active="1"/> <AnyTemplatePullTask id="3a6173a9-8c34-4e37-b3b1-0c2ea385fac0" pullTask_id="c41b9b71-9bfa-4f90-89f2-84787def4c5c" anyType_id="USER" - template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["csv"],"derAttrs":[{"schema":"cn","readonly":false,"values":[""]}],"virAttrs":[],"resources":["resource-testdb"],"relationships":[],"memberships":[{"leftType":null,"leftKey":0,"rightType":"GROUP","rightKey":"f779c0d4-633b-4be5-8f57-32eb478a3ca5","groupName":null}],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"ctype","readonly":false,"values":["email == 'te...@syncope.apache.org'? 'TYPE_8': 'TYPE_OTHER'"]}]}'/> + template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["csv"],"derAttrs":[{"schema":"cn","readonly":false,"values":[""]}],"virAttrs":[],"resources":["resource-testdb"],"relationships":[],"memberships":[{"rightType":"GROUP","rightKey":"f779c0d4-633b-4be5-8f57-32eb478a3ca5","groupName":null}],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"ctype","readonly":false,"values":["email == 'te...@syncope.apache.org'? 'TYPE_8': 'TYPE_OTHER'"]}]}'/> <AnyTemplatePullTask id="b3772d66-ec06-4133-bf38-b3273845ac5b" pullTask_id="c41b9b71-9bfa-4f90-89f2-84787def4c5c" anyType_id="GROUP" template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"plainAttrs":[]}'/> http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/DerAttrHandler.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/DerAttrHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/DerAttrHandler.java index bc70fb8..c4f44bd 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/DerAttrHandler.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/DerAttrHandler.java @@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.api; import java.util.Map; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.DerSchema; +import org.apache.syncope.core.persistence.api.entity.Membership; public interface DerAttrHandler { @@ -37,7 +38,27 @@ public interface DerAttrHandler { * Calculates derived attributes values associated to the given any. * * @param any any object - * @return derived attribute values, either for local cache or external resources + * @return derived attribute values */ Map<DerSchema, String> getValues(Any<?> any); + + /** + * Calculates derived attribute value associated to the given any, for the given membership and + * derived schema. + * + * @param any any object + * @param membership membership + * @param schema derived schema + * @return derived attribute value + */ + String getValue(Any<?> any, Membership<?> membership, DerSchema schema); + + /** + * Calculates derived attributes values associated to the given any, for the given membership. + * + * @param any any object + * @param membership membership + * @return derived attribute values + */ + Map<DerSchema, String> getValues(final Any<?> any, final Membership<?> membership); } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java ---------------------------------------------------------------------- diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java index 0b8d60f..72bb198 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java @@ -21,13 +21,14 @@ package org.apache.syncope.core.provisioning.api; import java.util.List; import java.util.Map; import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.Membership; import org.apache.syncope.core.persistence.api.entity.VirSchema; public interface VirAttrHandler { /** * Query external resource (or cache, if configured) associated to the given any for values associated to the given - * virtual schema. + * virtual schema, not related to any membership. * * @param any any object * @param schema virtual schema @@ -37,13 +38,36 @@ public interface VirAttrHandler { List<String> getValues(Any<?> any, VirSchema schema); /** + * Query external resource (or cache, if configured) associated to the given any for values associated to the given + * virtual schema, for the given membership. + * + * @param any any object + * @param membership membership + * @param schema virtual schema + * @return virtual attribute values, either for local cache or external resource, if resource is owned by the given + * any and associated to the given virtual schema; empty list otherwise. + */ + List<String> getValues(Any<?> any, Membership<?> membership, VirSchema schema); + + /** * Query external resources (or cache, if configured) associated to the given any for values associated to all * {@link VirSchema} instances in the {@link org.apache.syncope.core.persistence.api.entity.AnyTypeClass} - * associated to the given any. + * associated to the given any, with no membership. * * @param any any object * @return virtual attribute values, either for local cache or external resources */ Map<VirSchema, List<String>> getValues(Any<?> any); + /** + * Query external resources (or cache, if configured) associated to the given any for values associated to all + * {@link VirSchema} instances in the {@link org.apache.syncope.core.persistence.api.entity.AnyTypeClass} + * associated to the given any, for the given membership. + * + * @param any any object + * @param membership membership + * @return virtual attribute values, either for local cache or external resources + */ + Map<VirSchema, List<String>> getValues(Any<?> any, Membership<?> membership); + } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java index f827f46..0261752 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DerAttrHandlerImpl.java @@ -28,6 +28,7 @@ import org.apache.syncope.core.provisioning.java.jexl.JexlUtils; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.DerSchema; +import org.apache.syncope.core.persistence.api.entity.Membership; import org.apache.syncope.core.provisioning.api.DerAttrHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +@Transactional(readOnly = true) @Component public class DerAttrHandlerImpl implements DerAttrHandler { @@ -57,10 +59,23 @@ public class DerAttrHandlerImpl implements DerAttrHandler { return result; } - @Transactional(readOnly = true) @Override public String getValue(final Any<?> any, final DerSchema schema) { - if (!anyUtilsFactory.getInstance(any).getAllowedSchemas(any, DerSchema.class).contains(schema)) { + if (!anyUtilsFactory.getInstance(any). + getAllowedSchemas(any, DerSchema.class).forSelfContains(schema)) { + + LOG.debug("{} not allowed for {}", schema, any); + return null; + } + + return getValues(any, Collections.singleton(schema)).get(schema); + } + + @Override + public String getValue(final Any<?> any, final Membership<?> membership, final DerSchema schema) { + if (!anyUtilsFactory.getInstance(any). + getAllowedSchemas(any, DerSchema.class).getForMembership(membership.getRightEnd()).contains(schema)) { + LOG.debug("{} not allowed for {}", schema, any); return null; } @@ -68,10 +83,19 @@ public class DerAttrHandlerImpl implements DerAttrHandler { return getValues(any, Collections.singleton(schema)).get(schema); } - @Transactional(readOnly = true) @Override public Map<DerSchema, String> getValues(final Any<?> any) { - return getValues(any, anyUtilsFactory.getInstance(any).getAllowedSchemas(any, DerSchema.class)); + return getValues( + any, + anyUtilsFactory.getInstance(any).getAllowedSchemas(any, DerSchema.class).getForSelf()); + } + + @Override + public Map<DerSchema, String> getValues(final Any<?> any, final Membership<?> membership) { + return getValues( + any, + anyUtilsFactory.getInstance(any).getAllowedSchemas(any, DerSchema.class). + getForMembership(membership.getRightEnd())); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/acce340d/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java index c742c1a..b84799a 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java @@ -32,6 +32,7 @@ import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import org.apache.syncope.common.lib.to.AnyObjectTO; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.AttrTO; import org.apache.syncope.common.lib.to.GroupTO; @@ -68,6 +69,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Schema; import org.apache.syncope.core.persistence.api.entity.VirSchema; +import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.resource.Mapping; import org.apache.syncope.core.persistence.api.entity.resource.Provision; @@ -698,6 +700,16 @@ public class MappingManagerImpl implements MappingManager { } break; + case AnyObjectName: + for (Any<?> any : anys) { + if (any instanceof AnyObject) { + APlainAttrValue attrValue = entityFactory.newEntity(APlainAttrValue.class); + attrValue.setStringValue(((AnyObject) any).getName()); + values.add(attrValue); + } + } + break; + default: } @@ -800,6 +812,14 @@ public class MappingManagerImpl implements MappingManager { } break; + case AnyObjectName: + if (anyTO instanceof AnyObjectTO) { + ((AnyObjectTO) anyTO).setName(values.isEmpty() || values.get(0) == null + ? null + : values.get(0).toString()); + } + break; + case UserPlainSchema: case GroupPlainSchema: case AnyObjectPlainSchema: